summaryrefslogtreecommitdiff
path: root/gnu/packages
diff options
context:
space:
mode:
authorEkaitz Zarraga <ekaitz@elenq.tech>2024-10-08 08:21:27 +0300
committerJanneke Nieuwenhuizen <janneke@gnu.org>2026-01-28 21:47:38 +0100
commit2ddbd6b30e699d543fc8a7ffbede13578fc071cc (patch)
tree0a40a0259835a1252164dd4f01d92e6d956785d6 /gnu/packages
parent892e2a41dedf09452bc96c57e5e4f0c41260ae45 (diff)
gnu: Add gcc-muslboot0.
* gnu/packages/commencement.scm (gcc-muslboot0): New variable. * gnu/packages/patches/gcc-boot-4.6.4-riscv64-support.patch: New file. * gnu/local.mk (dist_patch_DATA): Register it. Co-authored-by: Efraim Flashner <efraim@flashner.co.il> Change-Id: I9a96fe502d739ddf1d73b0f3973f7f9e1e70dcb3
Diffstat (limited to 'gnu/packages')
-rw-r--r--gnu/packages/commencement.scm111
-rw-r--r--gnu/packages/patches/gcc-boot-4.6.4-riscv64-support.patch10974
2 files changed, 11085 insertions, 0 deletions
diff --git a/gnu/packages/commencement.scm b/gnu/packages/commencement.scm
index 8a8cff599ec..cdc3999a783 100644
--- a/gnu/packages/commencement.scm
+++ b/gnu/packages/commencement.scm
@@ -1795,6 +1795,117 @@ ac_cv_c_float_format='IEEE (little-endian)'
1795 (search-patch "gcc-boot-4.6.4.patch")))) 1795 (search-patch "gcc-boot-4.6.4.patch"))))
1796 (invoke "patch" "--force" "-p1" "-i" patch-file))))))))) 1796 (invoke "patch" "--force" "-p1" "-i" patch-file)))))))))
1797 1797
1798(define gcc-muslboot0
1799 (package
1800 (inherit gcc-4.7)
1801 (name "gcc-muslboot0")
1802 (version "4.6.4")
1803 (source (origin
1804 (method url-fetch)
1805 (uri (string-append "mirror://gnu/gcc/gcc-"
1806 version "/gcc-core-" version ".tar.gz"))
1807 (sha256
1808 (base32
1809 "173kdb188qg79pcz073cj9967rs2vzanyjdjyxy9v0xb0p5sad75"))))
1810 (outputs '("out"))
1811 (inputs (list gmp-boot mpfr-boot mpc-boot))
1812 (native-inputs (%boot-tcc-musl-inputs))
1813 (arguments
1814 (list #:implicit-inputs? #f
1815 #:guile %bootstrap-guile
1816 #:tests? #f
1817 #:modules '((guix build gnu-build-system)
1818 (guix build utils)
1819 (srfi srfi-1))
1820 #:parallel-build? #f ; for debugging
1821 #:configure-flags
1822 #~(let ((out (assoc-ref %outputs "out"))
1823 (libc (assoc-ref %build-inputs "libc"))
1824 (bash (assoc-ref %build-inputs "bash")))
1825 (list (string-append "--prefix=" out)
1826 (string-append "--with-build-sysroot=" libc "/include")
1827 (string-append "--with-native-system-header-dir=" libc "/include")
1828 (string-append "--build="
1829 #$(string-replace-substring
1830 (commencement-build-target)
1831 "-gnu" "-musl"))
1832 (string-append "--host="
1833 #$(string-replace-substring
1834 (commencement-build-target)
1835 "-gnu" "-musl"))
1836 "--disable-bootstrap"
1837 "--disable-decimal-float"
1838 "--disable-libatomic"
1839 "--disable-libcilkrts"
1840 "--disable-libgomp"
1841 "--disable-libitm"
1842 "--disable-libmudflap"
1843 "--disable-libquadmath"
1844 "--disable-libsanitizer"
1845 "--disable-libssp"
1846 "--disable-libvtv"
1847 "--disable-lto"
1848 "--disable-lto-plugin"
1849 "--disable-multilib"
1850 "--disable-plugin"
1851 "--disable-threads"
1852 "--enable-languages=c"
1853 "--enable-static"
1854 "--disable-shared"
1855 "--enable-threads=single"
1856 "--disable-libstdcxx-pch"
1857 "--disable-build-with-cxx"))
1858 #:phases
1859 #~(modify-phases %standard-phases
1860 (add-after 'unpack 'apply-riscv64-patch
1861 (lambda* (#:key inputs #:allow-other-keys)
1862 (let ((patch-file
1863 #$(local-file
1864 (search-patch "gcc-boot-4.6.4-riscv64-support.patch"))))
1865 (invoke "patch" "--force" "-p1" "-i" patch-file))))
1866 (add-after 'unpack 'fix-alloca
1867 (lambda* (#:key inputs #:allow-other-keys)
1868 (substitute* (list "libiberty/alloca.c"
1869 "include/libiberty.h")
1870 (("C_alloca") "alloca"))))
1871 (add-before 'configure 'fix-dynamic-linker-for-musl
1872 (lambda* (#:key inputs #:allow-other-keys)
1873 (let ((libc (assoc-ref inputs "libc")))
1874 ;; Fix the dynamic linker's file name.
1875 ;; This should work on gcc-13 for all architectures except loongarch.
1876 (substitute* (find-files "gcc/config"
1877 "^(aarch64-)?(linux|gnu|sysv4)(64|-elf|-eabi)?\\.h$")
1878 (("(#define MUSL_DYNAMIC_LINKER*).*$" _ dynamic-linker)
1879 ;; TODO: Make this use architecture specific ld-musl-*.so
1880 (string-append dynamic-linker " \"" libc "/lib/libc.so\"")))
1881 ;; We also need to adjust the references made for glibc
1882 ;; to point to the musl linker location
1883 (substitute* (find-files "gcc/config"
1884 "^(linux|gnu|sysv4)(64|-elf|-eabi)?\\.h$")
1885 (("#define (GLIBC|GNU_USER)_DYNAMIC_LINKER([^ \t]*).*$"
1886 _ gnu-user suffix)
1887 (format #f "#define ~a_DYNAMIC_LINKER~a \"~a\"~%"
1888 gnu-user suffix
1889 (string-append libc "/lib/libc.so")))))))
1890 (add-after 'apply-riscv64-patch 'patch-for-modern-libc
1891 (lambda _
1892 (for-each
1893 (lambda (dir)
1894 (substitute* (string-append "gcc/config/"
1895 dir "/linux-unwind.h")
1896 (("struct ucontext") "ucontext_t")))
1897 '("alpha" "bfin" "i386" "pa" "sh" "xtensa" "riscv"))))
1898 (add-before 'configure 'setenv
1899 (lambda _
1900 (setenv "CC" "tcc")
1901 (setenv "CFLAGS" "-D HAVE_ALLOCA_H"))))))
1902 (native-search-paths
1903 (list (search-path-specification
1904 (variable "C_INCLUDE_PATH")
1905 (files '("include")))
1906 (search-path-specification
1907 (variable "LIBRARY_PATH")
1908 (files '("lib")))))))
1798 1909
1799(define gcc-mesboot1 1910(define gcc-mesboot1
1800 (package 1911 (package
diff --git a/gnu/packages/patches/gcc-boot-4.6.4-riscv64-support.patch b/gnu/packages/patches/gcc-boot-4.6.4-riscv64-support.patch
new file mode 100644
index 00000000000..7489f22c861
--- /dev/null
+++ b/gnu/packages/patches/gcc-boot-4.6.4-riscv64-support.patch
@@ -0,0 +1,10974 @@
1This is the nearly¹ full diff between Ekaitz's branch² and upstream's releases/gcc-4.6.4 branch.
2After many months of work and funding from NLNet we are now able to build gcc-4.6.4
3on riscv64.
4
5¹ The hunks patching gcc/cp/cfns, libgfortran and libtstdc++-v3 needed to be removed so it could be applied
6² https://github.com/ekaitz-zarraga/gcc
7
8diff --git a/PREPARE_FOR_COMPILATION.sh b/PREPARE_FOR_COMPILATION.sh
9new file mode 100644
10index 00000000000..899db9983c5
11--- /dev/null
12+++ b/PREPARE_FOR_COMPILATION.sh
13@@ -0,0 +1,19 @@
14+echo "Preparing compilation toolchain for: $GUIX_ENVIRONMENT"
15+
16+triplet=$1
17+
18+if [ -z $triplet ]; then
19+ echo "-> ERROR Expecting triplet as argument"
20+ exit 1
21+fi
22+
23+binutils=$(guix build -e "(begin (use-modules (gnu packages cross-base)) (cross-binutils \"$triplet\"))")
24+echo " - binutils path is $binutils"
25+export PATH=$PATH:$binutils/$triplet/bin/
26+export LIBRARY_PATH=$LIBRARY_PATH:$GUIX_ENVIRONMENT/lib
27+export INCLUDE_PATH=$INCLUDE_PATH:$GUIX_ENVIRONMENT/include
28+
29+echo "NOTE: LIBRARY_PATH is kind of broken. Remember to add -L$GUIX_ENVIRONMENT/lib the gcc call"
30+echo "NOTE: crt1.o searching is broken for reasons beyond our understanding, add it by hand to the current dir"
31+
32+echo "NOTE: looks like it works with --sysroot=$GUIX_ENVIRONMENT, but that's only valid if you have an environment"
33diff --git a/channels.scm b/channels.scm
34new file mode 100644
35index 00000000000..c13ff2aa46e
36--- /dev/null
37+++ b/channels.scm
38@@ -0,0 +1,11 @@
39+(list (channel
40+ (name 'guix)
41+ (url "https://git.savannah.gnu.org/git/guix.git")
42+ (branch "master")
43+ (commit
44+ "0aa43117907581779cf3f343c6175d98369b7e07")
45+ (introduction
46+ (make-channel-introduction
47+ "9edb3f66fd807b096b48283debdcddccfea34bad"
48+ (openpgp-fingerprint
49+ "BBB0 2DDF 2CEA F6A8 0D1D E643 A2A0 6DF2 A33A 54FA")))))
50diff --git a/config.guess b/config.guess
51index 6eeea023eb9..be82274f67c 100755
52--- a/config.guess
53+++ b/config.guess
54@@ -956,6 +956,9 @@ EOF
55 ppc:Linux:*:*)
56 echo powerpc-unknown-linux-gnu
57 exit ;;
58+ riscv32:Linux:*:* | riscv64:Linux:*:*)
59+ echo ${UNAME_MACHINE}-unknown-linux
60+ exit ;;
61 s390:Linux:*:* | s390x:Linux:*:*)
62 echo ${UNAME_MACHINE}-ibm-linux
63 exit ;;
64diff --git a/config.sub b/config.sub
65index 204218c0738..6e75fe70b02 100755
66--- a/config.sub
67+++ b/config.sub
68@@ -125,7 +125,7 @@ esac
69 maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
70 case $maybe_os in
71 nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
72- linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
73+ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
74 knetbsd*-gnu* | netbsd*-gnu* | \
75 kopensolaris*-gnu* | \
76 storm-chaos* | os2-emx* | rtmk-nova*)
77@@ -154,7 +154,7 @@ case $os in
78 -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
79 -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
80 -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
81- -apple | -axis | -knuth | -cray | -microblaze)
82+ -apple | -axis | -knuth | -cray | -microblaze*)
83 os=
84 basic_machine=$1
85 ;;
86@@ -250,7 +250,10 @@ case $basic_machine in
87 | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
88 | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
89 | am33_2.0 \
90- | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
91+ | arc \
92+ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
93+ | avr | avr32 \
94+ | be32 | be64 \
95 | bfin \
96 | c4x | clipper \
97 | d10v | d30v | dlx | dsp16xx \
98@@ -260,7 +263,7 @@ case $basic_machine in
99 | ip2k | iq2000 \
100 | lm32 \
101 | m32c | m32r | m32rle | m68000 | m68k | m88k \
102- | maxq | mb | microblaze | mcore | mep | metag \
103+ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
104 | mips | mipsbe | mipseb | mipsel | mipsle \
105 | mips16 \
106 | mips64 | mips64el \
107@@ -290,6 +293,7 @@ case $basic_machine in
108 | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
109 | pyramid \
110 | rx \
111+ | riscv32 | riscv64 \
112 | score \
113 | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
114 | sh64 | sh64le \
115@@ -356,7 +360,8 @@ case $basic_machine in
116 | lm32-* \
117 | m32c-* | m32r-* | m32rle-* \
118 | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
119- | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
120+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
121+ | microblaze-* | microblazeel-* \
122 | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
123 | mips16-* \
124 | mips64-* | mips64el-* \
125@@ -753,9 +758,13 @@ case $basic_machine in
126 basic_machine=ns32k-utek
127 os=-sysv
128 ;;
129- microblaze)
130+ microblaze*)
131 basic_machine=microblaze-xilinx
132 ;;
133+ mingw64)
134+ basic_machine=x86_64-pc
135+ os=-mingw64
136+ ;;
137 mingw32)
138 basic_machine=i386-pc
139 os=-mingw32
140@@ -969,7 +978,11 @@ case $basic_machine in
141 basic_machine=i586-unknown
142 os=-pw32
143 ;;
144- rdos)
145+ rdos | rdos64)
146+ basic_machine=x86_64-pc
147+ os=-rdos
148+ ;;
149+ rdos32)
150 basic_machine=i386-pc
151 os=-rdos
152 ;;
153@@ -1301,15 +1314,15 @@ case $os in
154 | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
155 | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
156 | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
157- | -openbsd* | -solidbsd* \
158+ | -bitrig* | -openbsd* | -solidbsd* \
159 | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
160 | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
161 | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
162 | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
163 | -chorusos* | -chorusrdb* | -cegcc* \
164- | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
165- | -mingw32* | -linux-gnu* | -linux-android* \
166- | -linux-newlib* | -linux-uclibc* \
167+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
168+ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
169+ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
170 | -uxpv* | -beos* | -mpeix* | -udk* \
171 | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
172 | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
173@@ -1492,6 +1505,9 @@ case $basic_machine in
174 c4x-* | tic4x-*)
175 os=-coff
176 ;;
177+ hexagon-*)
178+ os=-elf
179+ ;;
180 tic54x-*)
181 os=-coff
182 ;;
183diff --git a/fixincludes/mkfixinc.sh b/fixincludes/mkfixinc.sh
184index b45f1795dcc..7f793a40d89 100755
185--- a/fixincludes/mkfixinc.sh
186+++ b/fixincludes/mkfixinc.sh
187@@ -23,7 +23,8 @@ case $machine in
188 powerpc-*-eabi* | \
189 powerpc-*-rtems* | \
190 powerpcle-*-eabisim* | \
191- powerpcle-*-eabi* )
192+ powerpcle-*-eabi* | \
193+ *-musl* )
194 # IF there is no include fixing,
195 # THEN create a no-op fixer and exit
196 (echo "#! /bin/sh" ; echo "exit 0" ) > ${target}
197diff --git a/gcc/ChangeLog b/gcc/ChangeLog
198index 8395ca76d0a..6cc433d9839 100644
199--- a/gcc/ChangeLog
200+++ b/gcc/ChangeLog
201@@ -1,3 +1,37 @@
202+2017-02-06 Palmer Dabbelt <palmer@dabbelt.com>
203+
204+ * config/riscv/riscv.c: New file.
205+ * gcc/common/config/riscv/riscv-common.c: Likewise.
206+ * config.gcc: Likewise.
207+ * config/riscv/constraints.md: Likewise.
208+ * config/riscv/elf.h: Likewise.
209+ * config/riscv/generic.md: Likewise.
210+ * config/riscv/linux.h: Likewise.
211+ * config/riscv/multilib-generator: Likewise.
212+ * config/riscv/peephole.md: Likewise.
213+ * config/riscv/pic.md: Likewise.
214+ * config/riscv/predicates.md: Likewise.
215+ * config/riscv/riscv-builtins.c: Likewise.
216+ * config/riscv/riscv-c.c: Likewise.
217+ * config/riscv/riscv-ftypes.def: Likewise.
218+ * config/riscv/riscv-modes.def: Likewise.
219+ * config/riscv/riscv-opts.h: Likewise.
220+ * config/riscv/riscv-protos.h: Likewise.
221+ * config/riscv/riscv.h: Likewise.
222+ * config/riscv/riscv.md: Likewise.
223+ * config/riscv/riscv.opt: Likewise.
224+ * config/riscv/sync.md: Likewise.
225+ * config/riscv/t-elf-multilib: Likewise.
226+ * config/riscv/t-linux: Likewise.
227+ * config/riscv/t-linux-multilib: Likewise.
228+ * config/riscv/t-riscv: Likewise.
229+ * configure.ac: Likewise.
230+ * doc/contrib.texi: Add Kito Cheng, Palmer Dabbelt, and Andrew
231+ Waterman as RISC-V maintainers.
232+ * doc/install.texi: Add RISC-V entries.
233+ * doc/invoke.texi: Add RISC-V options section.
234+ * doc/md.texi: Add RISC-V constraints section.
235+
236 2013-04-12 Release Manager
237
238 * GCC 4.6.4 released.
239diff --git a/gcc/Makefile.in b/gcc/Makefile.in
240index e0b952ffd99..852f35daac1 100644
241--- a/gcc/Makefile.in
242+++ b/gcc/Makefile.in
243@@ -440,7 +440,7 @@ LINKER_PLUGIN_API_H = $(srcdir)/../include/plugin-api.h
244 LTO_SYMTAB_H = $(srcdir)/../include/lto-symtab.h
245
246 # Default native SYSTEM_HEADER_DIR, to be overridden by targets.
247-NATIVE_SYSTEM_HEADER_DIR = /usr/include
248+# NATIVE_SYSTEM_HEADER_DIR = /usr/include
249 # Default cross SYSTEM_HEADER_DIR, to be overridden by targets.
250 CROSS_SYSTEM_HEADER_DIR = @CROSS_SYSTEM_HEADER_DIR@
251
252diff --git a/gcc/config.gcc b/gcc/config.gcc
253index 6dc2427bc7c..08537bc7f2c 100644
254--- a/gcc/config.gcc
255+++ b/gcc/config.gcc
256@@ -402,6 +402,16 @@ powerpc*-*-*)
257 esac
258 extra_options="${extra_options} g.opt fused-madd.opt"
259 ;;
260+riscv*)
261+ cpu_type=riscv
262+# need_64bit_hwint=yes
263+# case x$with_cpu in
264+# riscv64)
265+# cpu_is_64bit=yes
266+# ;;
267+# esac
268+# tmake_file="${tmake_file} riscv/t-riscv"
269+ ;;
270 rs6000*-*-*)
271 need_64bit_hwint=yes
272 extra_options="${extra_options} g.opt fused-madd.opt"
273@@ -478,7 +488,7 @@ case ${target} in
274 esac
275
276 # Common C libraries.
277-tm_defines="$tm_defines LIBC_GLIBC=1 LIBC_UCLIBC=2 LIBC_BIONIC=3"
278+tm_defines="$tm_defines LIBC_GLIBC=1 LIBC_UCLIBC=2 LIBC_BIONIC=3 LIBC_MUSL=4"
279
280 # Common parts for widely ported systems.
281 case ${target} in
282@@ -591,6 +601,9 @@ case ${target} in
283 *-*-*uclibc*)
284 tm_defines="$tm_defines DEFAULT_LIBC=LIBC_UCLIBC"
285 ;;
286+ *-*-*musl*)
287+ tm_defines="$tm_defines DEFAULT_LIBC=LIBC_MUSL"
288+ ;;
289 *)
290 tm_defines="$tm_defines DEFAULT_LIBC=LIBC_GLIBC"
291 ;;
292@@ -2051,6 +2064,49 @@ mn10300-*-*)
293 use_collect2=no
294 use_gcc_stdint=wrap
295 ;;
296+riscv*-*-linux*)
297+ tm_file="elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file} riscv/linux.h"
298+ case "x${enable_multilib}" in
299+ xno) ;;
300+ xyes) tmake_file="${tmake_file} riscv/t-linux-multilib" ;;
301+ *) echo "Unknown value for enable_multilib"; exit 1
302+ esac
303+ case ${target} in
304+ riscv64-*-linux*)
305+ tmake_file="${tmake_file} riscv/t-linux riscv/t-softfp64 soft-fp/t-softfp"
306+ ;;
307+ riscv32-*-linux*)
308+ tmake_file="${tmake_file} riscv/t-linux riscv/t-softfp32 soft-fp/t-softfp"
309+ ;;
310+ esac
311+
312+ gnu_ld=yes
313+ gas=yes
314+ # Force .init_array support. The configure script cannot always
315+ # automatically detect that GAS supports it, yet we require it.
316+ gcc_cv_initfini_array=yes
317+ ;;
318+riscv*-*-elf*)
319+ tm_file="elfos.h newlib-stdint.h ${tm_file} riscv/elf.h"
320+ case "x${enable_multilib}" in
321+ xno) ;;
322+ xyes) tmake_file="${tmake_file} riscv/t-elf-multilib" ;;
323+ *) echo "Unknown value for enable_multilib"; exit 1
324+ esac
325+ case ${target} in
326+ riscv64-*-elf*)
327+ tmake_file="${tmake_file} riscv/t-elf riscv/t-elf64 riscv/t-softfp64 soft-fp/t-softfp"
328+ ;;
329+ riscv32-*-elf*)
330+ tmake_file="${tmake_file} riscv/t-elf riscv/t-elf32 riscv/t-softfp32 soft-fp/t-softfp"
331+ ;;
332+ esac
333+ gnu_ld=yes
334+ gas=yes
335+ # Force .init_array support. The configure script cannot always
336+ # automatically detect that GAS supports it, yet we require it.
337+ gcc_cv_initfini_array=yes
338+ ;;
339 pdp11-*-*)
340 tm_file="${tm_file} newlib-stdint.h"
341 use_gcc_stdint=wrap
342@@ -3399,6 +3455,70 @@ case "${target}" in
343 done
344 ;;
345
346+ riscv*-*-*)
347+ supported_defaults="abi arch tune"
348+
349+ case "${target}" in
350+ riscv32*) xlen=32 ;;
351+ riscv64*) xlen=64 ;;
352+ *) echo "Unsupported RISC-V target ${target}" 1>&2; exit 1 ;;
353+ esac
354+
355+ # Infer arch from --with-arch, --target, and --with-abi.
356+ case "${with_arch}" in
357+ rv32i* | rv32g* | rv64i* | rv64g*)
358+ # OK.
359+ ;;
360+ "")
361+ # Infer XLEN, but otherwise assume GC.
362+ case "${with_abi}" in
363+ ilp32 | ilp32f | ilp32d) with_arch="rv32gc" ;;
364+ lp64 | lp64f | lp64d) with_arch="rv64gc" ;;
365+ *) with_arch="rv${xlen}gc" ;;
366+ esac
367+ ;;
368+ *)
369+ echo "--with-arch=${with_arch} is not supported. The argument must begin with rv32i, rv32g, rv64i, or rv64g." 1>&2
370+ exit 1
371+ ;;
372+ esac
373+
374+ # Make sure --with-abi is valid. If it was not specified,
375+ # pick a default based on the ISA, preferring soft-float
376+ # unless the D extension is present.
377+ case "${with_abi}" in
378+ ilp32 | ilp32f | ilp32d | lp64 | lp64f | lp64d)
379+ ;;
380+ "")
381+ case "${with_arch}" in
382+ rv32*d* | rv32g*) with_abi=ilp32d ;;
383+ rv32*) with_abi=ilp32 ;;
384+ rv64*d* | rv64g*) with_abi=lp64d ;;
385+ rv64*) with_abi=lp64 ;;
386+ esac
387+ ;;
388+ *)
389+ echo "--with-abi=${with_abi} is not supported" 1>&2
390+ exit 1
391+ ;;
392+ esac
393+
394+ # Make sure ABI and ISA are compatible.
395+ case "${with_abi},${with_arch}" in
396+ ilp32,rv32* \
397+ | ilp32f,rv32*f* | ilp32f,rv32g* \
398+ | ilp32d,rv32*d* | ilp32d,rv32g* \
399+ | lp64,rv64* \
400+ | lp64f,rv64*f* | lp64f,rv64g* \
401+ | lp64d,rv64*d* | lp64d,rv64g*)
402+ ;;
403+ *)
404+ echo "--with-abi=${with_abi} is not supported for ISA ${with_arch}" 1>&2
405+ exit 1
406+ ;;
407+ esac
408+ ;;
409+
410 mips*-*-*)
411 supported_defaults="abi arch arch_32 arch_64 float tune tune_32 tune_64 divide llsc mips-plt synci"
412
413diff --git a/gcc/config/alpha/linux.h b/gcc/config/alpha/linux.h
414index a1881c8168b..6e9a0189f63 100644
415--- a/gcc/config/alpha/linux.h
416+++ b/gcc/config/alpha/linux.h
417@@ -63,8 +63,16 @@ along with GCC; see the file COPYING3. If not see
418
419 #ifdef SINGLE_LIBC
420 #define OPTION_GLIBC (DEFAULT_LIBC == LIBC_GLIBC)
421+#define OPTION_UCLIBC (DEFAULT_LIBC == LIBC_UCLIBC)
422+#define OPTION_BIONIC (DEFAULT_LIBC == LIBC_BIONIC)
423+#undef OPTION_MUSL
424+#define OPTION_MUSL (DEFAULT_LIBC == LIBC_MUSL)
425 #else
426 #define OPTION_GLIBC (linux_libc == LIBC_GLIBC)
427+#define OPTION_UCLIBC (linux_libc == LIBC_UCLIBC)
428+#define OPTION_BIONIC (linux_libc == LIBC_BIONIC)
429+#undef OPTION_MUSL
430+#define OPTION_MUSL (linux_libc == LIBC_MUSL)
431 #endif
432
433 /* Determine whether the entire c99 runtime is present in the
434diff --git a/gcc/config/arm/linux-eabi.h b/gcc/config/arm/linux-eabi.h
435index 8330052844f..ed2ba04bdfc 100644
436--- a/gcc/config/arm/linux-eabi.h
437+++ b/gcc/config/arm/linux-eabi.h
438@@ -64,6 +64,23 @@
439 #undef GLIBC_DYNAMIC_LINKER
440 #define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.3"
441
442+/* For ARM musl currently supports four dynamic linkers:
443+ - ld-musl-arm.so.1 - for the EABI-derived soft-float ABI
444+ - ld-musl-armhf.so.1 - for the EABI-derived hard-float ABI
445+ - ld-musl-armeb.so.1 - for the EABI-derived soft-float ABI, EB
446+ - ld-musl-armebhf.so.1 - for the EABI-derived hard-float ABI, EB
447+ musl does not support the legacy OABI mode.
448+ All the dynamic linkers live in /lib.
449+ We default to soft-float, EL. */
450+#undef MUSL_DYNAMIC_LINKER
451+#if TARGET_BIG_ENDIAN_DEFAULT
452+#define MUSL_DYNAMIC_LINKER_E "%{mlittle-endian:;:eb}"
453+#else
454+#define MUSL_DYNAMIC_LINKER_E "%{mbig-endian:eb}"
455+#endif
456+#define MUSL_DYNAMIC_LINKER \
457+ "/lib/ld-musl-arm" MUSL_DYNAMIC_LINKER_E "%{mfloat-abi=hard:hf}.so.1"
458+
459 /* At this point, bpabi.h will have clobbered LINK_SPEC. We want to
460 use the GNU/Linux version, not the generic BPABI version. */
461 #undef LINK_SPEC
462diff --git a/gcc/config/glibc-stdint.h b/gcc/config/glibc-stdint.h
463index 4f8fe07a114..9c331237f07 100644
464--- a/gcc/config/glibc-stdint.h
465+++ b/gcc/config/glibc-stdint.h
466@@ -22,6 +22,12 @@ a copy of the GCC Runtime Library Exception along with this program;
467 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
468 <http://www.gnu.org/licenses/>. */
469
470+/* Systems using musl libc should use this header and make sure
471+ OPTION_MUSL is defined correctly before using the TYPE macros. */
472+#ifndef OPTION_MUSL
473+#define OPTION_MUSL 0
474+#endif
475+
476 #define SIG_ATOMIC_TYPE "int"
477
478 #define INT8_TYPE "signed char"
479@@ -43,12 +49,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
480 #define UINT_LEAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "long long unsigned int")
481
482 #define INT_FAST8_TYPE "signed char"
483-#define INT_FAST16_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "int")
484-#define INT_FAST32_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "int")
485+#define INT_FAST16_TYPE (LONG_TYPE_SIZE == 64 && !OPTION_MUSL ? "long int" : "int")
486+#define INT_FAST32_TYPE (LONG_TYPE_SIZE == 64 && !OPTION_MUSL ? "long int" : "int")
487 #define INT_FAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "long long int")
488 #define UINT_FAST8_TYPE "unsigned char"
489-#define UINT_FAST16_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "unsigned int")
490-#define UINT_FAST32_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "unsigned int")
491+#define UINT_FAST16_TYPE (LONG_TYPE_SIZE == 64 && !OPTION_MUSL ? "long unsigned int" : "unsigned int")
492+#define UINT_FAST32_TYPE (LONG_TYPE_SIZE == 64 && !OPTION_MUSL ? "long unsigned int" : "unsigned int")
493 #define UINT_FAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "long long unsigned int")
494
495 #define INTPTR_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "int")
496diff --git a/gcc/config/host-linux.c b/gcc/config/host-linux.c
497index ec6105577a6..61b4b3d1954 100644
498--- a/gcc/config/host-linux.c
499+++ b/gcc/config/host-linux.c
500@@ -22,6 +22,13 @@
501 #include "coretypes.h"
502 #include "hosthooks.h"
503 #include "hosthooks-def.h"
504+
505+// ../.././gcc/config/host-linux.c:213: `SSIZE_MAX' undeclared (first
506+// use in this function)
507+#include <limits.h>
508+#ifndef SSIZE_MAX
509+# define SSIZE_MAX LONG_MAX
510+#endif
511
512
513 /* Linux has a feature called exec-shield-randomize that perturbs the
514diff --git a/gcc/config/i386/linux.h b/gcc/config/i386/linux.h
515index 0084c8313f9..85c271d0619 100644
516--- a/gcc/config/i386/linux.h
517+++ b/gcc/config/i386/linux.h
518@@ -94,6 +94,9 @@ along with GCC; see the file COPYING3. If not see
519 #define LINK_EMULATION "elf_i386"
520 #define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2"
521
522+#undef MUSL_DYNAMIC_LINKER
523+#define MUSL_DYNAMIC_LINKER "/lib/ld-musl-i386.so.1"
524+
525 #undef ASM_SPEC
526 #define ASM_SPEC \
527 "--32 %{!mno-sse2avx:%{mavx:-msse2avx}} %{msse2avx:%{!mavx:-msse2avx}}"
528diff --git a/gcc/config/i386/linux64.h b/gcc/config/i386/linux64.h
529index 103ab0c99ca..a9cc98e09c8 100644
530--- a/gcc/config/i386/linux64.h
531+++ b/gcc/config/i386/linux64.h
532@@ -64,6 +64,14 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
533
534 #define GLIBC_DYNAMIC_LINKER32 "/lib/ld-linux.so.2"
535 #define GLIBC_DYNAMIC_LINKER64 "/lib64/ld-linux-x86-64.so.2"
536+#define GLIBC_DYNAMIC_LINKERX32 "/libx32/ld-linux-x32.so.2"
537+
538+#undef MUSL_DYNAMIC_LINKER32
539+#define MUSL_DYNAMIC_LINKER32 "/lib/ld-musl-i386.so.1"
540+#undef MUSL_DYNAMIC_LINKER64
541+#define MUSL_DYNAMIC_LINKER64 "/lib/ld-musl-x86_64.so.1"
542+#undef MUSL_DYNAMIC_LINKERX32
543+#define MUSL_DYNAMIC_LINKERX32 "/lib/ld-musl-x32.so.1"
544
545 #if TARGET_64BIT_DEFAULT
546 #define SPEC_32 "m32"
547diff --git a/gcc/config/linux.h b/gcc/config/linux.h
548index 00b4f1c1cd5..00744fde91d 100644
549--- a/gcc/config/linux.h
550+++ b/gcc/config/linux.h
551@@ -33,10 +33,14 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
552 #define OPTION_GLIBC (DEFAULT_LIBC == LIBC_GLIBC)
553 #define OPTION_UCLIBC (DEFAULT_LIBC == LIBC_UCLIBC)
554 #define OPTION_BIONIC (DEFAULT_LIBC == LIBC_BIONIC)
555+#undef OPTION_MUSL
556+#define OPTION_MUSL (DEFAULT_LIBC == LIBC_MUSL)
557 #else
558 #define OPTION_GLIBC (linux_libc == LIBC_GLIBC)
559 #define OPTION_UCLIBC (linux_libc == LIBC_UCLIBC)
560 #define OPTION_BIONIC (linux_libc == LIBC_BIONIC)
561+#undef OPTION_MUSL
562+#define OPTION_MUSL (linux_libc == LIBC_MUSL)
563 #endif
564
565 #define LINUX_TARGET_OS_CPP_BUILTINS() \
566@@ -51,21 +55,25 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
567 } while (0)
568
569 /* Determine which dynamic linker to use depending on whether GLIBC or
570- uClibc or Bionic is the default C library and whether
571- -muclibc or -mglibc or -mbionic has been passed to change the default. */
572+ uClibc or Bionic or musl is the default C library and whether
573+ -muclibc or -mglibc or -mbionic or -mmusl has been passed to change
574+ the default. */
575
576-#define CHOOSE_DYNAMIC_LINKER1(LIBC1, LIBC2, LIBC3, LD1, LD2, LD3) \
577- "%{" LIBC2 ":" LD2 ";:%{" LIBC3 ":" LD3 ";:" LD1 "}}"
578+#define CHOOSE_DYNAMIC_LINKER1(LIBC1, LIBC2, LIBC3, LIBC4, LD1, LD2, LD3, LD4) \
579+ "%{" LIBC2 ":" LD2 ";:%{" LIBC3 ":" LD3 ";:%{" LIBC4 ":" LD4 ";:" LD1 "}}}"
580
581 #if DEFAULT_LIBC == LIBC_GLIBC
582-#define CHOOSE_DYNAMIC_LINKER(G, U, B) \
583- CHOOSE_DYNAMIC_LINKER1 ("mglibc", "muclibc", "mbionic", G, U, B)
584+#define CHOOSE_DYNAMIC_LINKER(G, U, B, M) \
585+ CHOOSE_DYNAMIC_LINKER1 ("mglibc", "muclibc", "mbionic", "mmusl", G, U, B, M)
586 #elif DEFAULT_LIBC == LIBC_UCLIBC
587-#define CHOOSE_DYNAMIC_LINKER(G, U, B) \
588- CHOOSE_DYNAMIC_LINKER1 ("muclibc", "mglibc", "mbionic", U, G, B)
589+#define CHOOSE_DYNAMIC_LINKER(G, U, B, M) \
590+ CHOOSE_DYNAMIC_LINKER1 ("muclibc", "mglibc", "mbionic", "mmusl", U, G, B, M)
591 #elif DEFAULT_LIBC == LIBC_BIONIC
592-#define CHOOSE_DYNAMIC_LINKER(G, U, B) \
593- CHOOSE_DYNAMIC_LINKER1 ("mbionic", "mglibc", "muclibc", B, G, U)
594+#define CHOOSE_DYNAMIC_LINKER(G, U, B, M) \
595+ CHOOSE_DYNAMIC_LINKER1 ("mbionic", "mglibc", "muclibc", "mmusl", B, G, U, M)
596+#elif DEFAULT_LIBC == LIBC_MUSL
597+#define CHOOSE_DYNAMIC_LINKER(G, U, B, M) \
598+ CHOOSE_DYNAMIC_LINKER1 ("mmusl", "mglibc", "muclibc", "mbionic", M, G, U, B)
599 #else
600 #error "Unsupported DEFAULT_LIBC"
601 #endif /* DEFAULT_LIBC */
602@@ -80,20 +88,119 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
603 #define BIONIC_DYNAMIC_LINKER "/system/bin/linker"
604 #define BIONIC_DYNAMIC_LINKER32 "/system/bin/linker"
605 #define BIONIC_DYNAMIC_LINKER64 "/system/bin/linker64"
606+#define BIONIC_DYNAMIC_LINKERX32 "/system/bin/linkerx32"
607+/* Should be redefined for each target that supports musl. */
608+#define MUSL_DYNAMIC_LINKER "/dev/null"
609+#define MUSL_DYNAMIC_LINKER32 "/dev/null"
610+#define MUSL_DYNAMIC_LINKER64 "/dev/null"
611+#define MUSL_DYNAMIC_LINKERX32 "/dev/null"
612
613 #define LINUX_DYNAMIC_LINKER \
614 CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER, UCLIBC_DYNAMIC_LINKER, \
615- BIONIC_DYNAMIC_LINKER)
616-#define LINUX_DYNAMIC_LINKER32 \
617+ BIONIC_DYNAMIC_LINKER, MUSL_DYNAMIC_LINKER)
618+#define LINUX_DYNAMIC_LINKER32 \
619 CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER32, UCLIBC_DYNAMIC_LINKER32, \
620- BIONIC_DYNAMIC_LINKER32)
621-#define LINUX_DYNAMIC_LINKER64 \
622+ BIONIC_DYNAMIC_LINKER32, MUSL_DYNAMIC_LINKER32)
623+#define LINUX_DYNAMIC_LINKER64 \
624 CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER64, UCLIBC_DYNAMIC_LINKER64, \
625- BIONIC_DYNAMIC_LINKER64)
626+ BIONIC_DYNAMIC_LINKER64, MUSL_DYNAMIC_LINKER64)
627+#define LINUX_DYNAMIC_LINKERX32 \
628+ CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKERX32, UCLIBC_DYNAMIC_LINKERX32, \
629+ BIONIC_DYNAMIC_LINKERX32, MUSL_DYNAMIC_LINKERX32)
630
631 /* Determine whether the entire c99 runtime
632 is present in the runtime library. */
633 #define TARGET_C99_FUNCTIONS (OPTION_GLIBC)
634
635-/* Whether we have sincos that follows the GNU extension. */
636-#define TARGET_HAS_SINCOS (OPTION_GLIBC || OPTION_BIONIC)
637+/* musl avoids problematic includes by rearranging the include directories.
638+ * Unfortunately, this is mostly duplicated from cppdefault.c */
639+#if DEFAULT_LIBC == LIBC_MUSL
640+#define INCLUDE_DEFAULTS_MUSL_GPP \
641+ { GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1, 0, 0 }, \
642+ { GPLUSPLUS_TOOL_INCLUDE_DIR, "G++", 1, 1, 0, 1 }, \
643+ { GPLUSPLUS_BACKWARD_INCLUDE_DIR, "G++", 1, 1, 0, 0 },
644+
645+#ifdef LOCAL_INCLUDE_DIR
646+#define INCLUDE_DEFAULTS_MUSL_LOCAL \
647+ { LOCAL_INCLUDE_DIR, 0, 0, 1, 1, 2 }, \
648+ { LOCAL_INCLUDE_DIR, 0, 0, 1, 1, 0 },
649+#else
650+#define INCLUDE_DEFAULTS_MUSL_LOCAL
651+#endif
652+
653+#ifdef PREFIX_INCLUDE_DIR
654+#define INCLUDE_DEFAULTS_MUSL_PREFIX \
655+ { PREFIX_INCLUDE_DIR, 0, 0, 1, 0, 0},
656+#else
657+#define INCLUDE_DEFAULTS_MUSL_PREFIX
658+#endif
659+
660+#ifdef CROSS_INCLUDE_DIR
661+#define INCLUDE_DEFAULTS_MUSL_CROSS \
662+ { CROSS_INCLUDE_DIR, "GCC", 0, 0, 0, 0},
663+#else
664+#define INCLUDE_DEFAULTS_MUSL_CROSS
665+#endif
666+
667+#ifdef TOOL_INCLUDE_DIR
668+#define INCLUDE_DEFAULTS_MUSL_TOOL \
669+ { TOOL_INCLUDE_DIR, "BINUTILS", 0, 1, 0, 0},
670+#else
671+#define INCLUDE_DEFAULTS_MUSL_TOOL
672+#endif
673+
674+#ifdef NATIVE_SYSTEM_HEADER_DIR
675+#define INCLUDE_DEFAULTS_MUSL_NATIVE \
676+ { NATIVE_SYSTEM_HEADER_DIR, 0, 0, 0, 1, 2 }, \
677+ { NATIVE_SYSTEM_HEADER_DIR, 0, 0, 0, 1, 0 },
678+#else
679+#define INCLUDE_DEFAULTS_MUSL_NATIVE
680+#endif
681+
682+#if defined (CROSS_DIRECTORY_STRUCTURE) && !defined (TARGET_SYSTEM_ROOT)
683+# undef INCLUDE_DEFAULTS_MUSL_LOCAL
684+# define INCLUDE_DEFAULTS_MUSL_LOCAL
685+# undef INCLUDE_DEFAULTS_MUSL_NATIVE
686+# define INCLUDE_DEFAULTS_MUSL_NATIVE
687+#else
688+# undef INCLUDE_DEFAULTS_MUSL_CROSS
689+# define INCLUDE_DEFAULTS_MUSL_CROSS
690+#endif
691+
692+#undef INCLUDE_DEFAULTS
693+#define INCLUDE_DEFAULTS \
694+ { \
695+ INCLUDE_DEFAULTS_MUSL_GPP \
696+ INCLUDE_DEFAULTS_MUSL_PREFIX \
697+ INCLUDE_DEFAULTS_MUSL_CROSS \
698+ INCLUDE_DEFAULTS_MUSL_TOOL \
699+ INCLUDE_DEFAULTS_MUSL_NATIVE \
700+ { GCC_INCLUDE_DIR, "GCC", 0, 1, 0, 0 }, \
701+ { 0, 0, 0, 0, 0, 0 } \
702+ }
703+#endif
704+
705+#if (DEFAULT_LIBC == LIBC_UCLIBC) && defined (SINGLE_LIBC) /* uClinux */
706+/* This is a *uclinux* target. We don't define below macros to normal linux
707+ versions, because doing so would require *uclinux* targets to include
708+ linux.c, linux-protos.h, linux.opt, etc. We could, alternatively, add
709+ these files to *uclinux* targets, but that would only pollute option list
710+ (add -mglibc, etc.) without adding any useful support. */
711+
712+/* Define TARGET_LIBC_HAS_FUNCTION for *uclinux* targets to
713+ no_c99_libc_has_function, because uclibc does not, normally, have
714+ c99 runtime. If, in special cases, uclibc does have c99 runtime,
715+ this should be defined to a new hook. Also please note that for targets
716+ like *-linux-uclibc that similar check will also need to be added to
717+ linux_libc_has_function. */
718+# undef TARGET_LIBC_HAS_FUNCTION
719+# define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
720+
721+#else /* !uClinux, i.e., normal Linux */
722+
723+/* Determine what functions are present at the runtime;
724+ this includes full c99 runtime and sincos. */
725+# undef TARGET_LIBC_HAS_FUNCTION
726+# define TARGET_LIBC_HAS_FUNCTION linux_libc_has_function
727+
728+#endif
729diff --git a/gcc/config/linux.opt b/gcc/config/linux.opt
730index ba6b9f83e6d..f5e94a9b1db 100644
731--- a/gcc/config/linux.opt
732+++ b/gcc/config/linux.opt
733@@ -28,5 +28,9 @@ Target Report RejectNegative Var(linux_libc,LIBC_GLIBC) Negative(muclibc)
734 Use GNU C library
735
736 muclibc
737-Target Report RejectNegative Var(linux_libc,LIBC_UCLIBC) Negative(mbionic)
738+Target Report RejectNegative Var(linux_libc,LIBC_UCLIBC) Negative(mmusl)
739 Use uClibc C library
740+
741+mmusl
742+Target Report RejectNegative Var(linux_libc,LIBC_MUSL) Negative(mbionic)
743+Use musl C library
744diff --git a/gcc/config/microblaze/linux.h b/gcc/config/microblaze/linux.h
745index 3c13fabcb3b..50c44dc8580 100644
746--- a/gcc/config/microblaze/linux.h
747+++ b/gcc/config/microblaze/linux.h
748@@ -20,10 +20,20 @@
749 <http://www.gnu.org/licenses/>. */
750
751
752-#define DYNAMIC_LINKER "/lib/ld.so.1"
753+#define GLIBC_DYNAMIC_LINKER "/lib/ld.so.1"
754+
755+#if TARGET_BIG_ENDIAN_DEFAULT == 0 /* LE */
756+#define MUSL_DYNAMIC_LINKER_E "%{mbig-endian:;:el}"
757+#else
758+#define MUSL_DYNAMIC_LINKER_E "%{mlittle-endian:el}"
759+#endif
760+
761+#undef MUSL_DYNAMIC_LINKER
762+#define MUSL_DYNAMIC_LINKER "/lib/ld-musl-microblaze" MUSL_DYNAMIC_LINKER_E ".so.1"
763+
764 #undef SUBTARGET_EXTRA_SPECS
765 #define SUBTARGET_EXTRA_SPECS \
766- { "dynamic_linker", DYNAMIC_LINKER }
767+ { "dynamic_linker", GNU_USER_DYNAMIC_LINKER }
768
769 #undef LINK_SPEC
770 #define LINK_SPEC "%{shared:-shared} \
771diff --git a/gcc/config/mips/linux.h b/gcc/config/mips/linux.h
772index a78f6bcbbc5..cc05ddbd07c 100644
773--- a/gcc/config/mips/linux.h
774+++ b/gcc/config/mips/linux.h
775@@ -63,6 +63,17 @@ along with GCC; see the file COPYING3. If not see
776
777 #define GLIBC_DYNAMIC_LINKER "/lib/ld.so.1"
778
779+#undef MUSL_DYNAMIC_LINKER32
780+#define MUSL_DYNAMIC_LINKER32 "/lib/ld-musl-mips%{EL:el}%{msoft-float:-sf}.so.1"
781+#undef MUSL_DYNAMIC_LINKER64
782+#define MUSL_DYNAMIC_LINKER64 "/lib/ld-musl-mips64%{EL:el}%{msoft-float:-sf}.so.1"
783+#define MUSL_DYNAMIC_LINKERN32 "/lib/ld-musl-mipsn32%{EL:el}%{msoft-float:-sf}.so.1"
784+
785+#define BIONIC_DYNAMIC_LINKERN32 "/system/bin/linker32"
786+#define GNU_USER_DYNAMIC_LINKERN32 \
787+ CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKERN32, UCLIBC_DYNAMIC_LINKERN32, \
788+ BIONIC_DYNAMIC_LINKERN32, MUSL_DYNAMIC_LINKERN32)
789+
790 /* Borrowed from sparc/linux.h */
791 #undef LINK_SPEC
792 #define LINK_SPEC \
793diff --git a/gcc/config/riscv/atomic.c b/gcc/config/riscv/atomic.c
794new file mode 100644
795index 00000000000..448b0e55b5a
796--- /dev/null
797+++ b/gcc/config/riscv/atomic.c
798@@ -0,0 +1,111 @@
799+/* Legacy sub-word atomics for RISC-V.
800+
801+ Copyright (C) 2016-2017 Free Software Foundation, Inc.
802+
803+This file is part of GCC.
804+
805+GCC is free software; you can redistribute it and/or modify it under
806+the terms of the GNU General Public License as published by the Free
807+Software Foundation; either version 3, or (at your option) any later
808+version.
809+
810+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
811+WARRANTY; without even the implied warranty of MERCHANTABILITY or
812+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
813+for more details.
814+
815+Under Section 7 of GPL version 3, you are granted additional
816+permissions described in the GCC Runtime Library Exception, version
817+3.1, as published by the Free Software Foundation.
818+
819+You should have received a copy of the GNU General Public License and
820+a copy of the GCC Runtime Library Exception along with this program;
821+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
822+<http://www.gnu.org/licenses/>. */
823+
824+#ifdef __riscv_atomic
825+
826+#include <stdbool.h>
827+
828+#define INVERT "not %[tmp1], %[tmp1]\n\t"
829+#define DONT_INVERT ""
830+
831+#define GENERATE_FETCH_AND_OP(type, size, opname, insn, invert, cop) \
832+ type __sync_fetch_and_ ## opname ## _ ## size (type *p, type v) \
833+ { \
834+ unsigned long aligned_addr = ((unsigned long) p) & ~3UL; \
835+ int shift = (((unsigned long) p) & 3) * 8; \
836+ unsigned mask = ((1U << ((sizeof v) * 8)) - 1) << shift; \
837+ unsigned old, tmp1, tmp2; \
838+ \
839+ asm volatile ("1:\n\t" \
840+ "lr.w.aq %[old], %[mem]\n\t" \
841+ #insn " %[tmp1], %[old], %[value]\n\t" \
842+ invert \
843+ "and %[tmp1], %[tmp1], %[mask]\n\t" \
844+ "and %[tmp2], %[old], %[not_mask]\n\t" \
845+ "or %[tmp2], %[tmp2], %[tmp1]\n\t" \
846+ "sc.w.rl %[tmp1], %[tmp2], %[mem]\n\t" \
847+ "bnez %[tmp1], 1b" \
848+ : [old] "=&r" (old), \
849+ [mem] "+A" (*(volatile unsigned*) aligned_addr), \
850+ [tmp1] "=&r" (tmp1), \
851+ [tmp2] "=&r" (tmp2) \
852+ : [value] "r" (((unsigned) v) << shift), \
853+ [mask] "r" (mask), \
854+ [not_mask] "r" (~mask)); \
855+ \
856+ return (type) (old >> shift); \
857+ } \
858+ \
859+ type __sync_ ## opname ## _and_fetch_ ## size (type *p, type v) \
860+ { \
861+ type o = __sync_fetch_and_ ## opname ## _ ## size (p, v); \
862+ return cop; \
863+ }
864+
865+#define GENERATE_COMPARE_AND_SWAP(type, size) \
866+ type __sync_val_compare_and_swap_ ## size (type *p, type o, type n) \
867+ { \
868+ unsigned long aligned_addr = ((unsigned long) p) & ~3UL; \
869+ int shift = (((unsigned long) p) & 3) * 8; \
870+ unsigned mask = ((1U << ((sizeof o) * 8)) - 1) << shift; \
871+ unsigned old, tmp1; \
872+ \
873+ asm volatile ("1:\n\t" \
874+ "lr.w.aq %[old], %[mem]\n\t" \
875+ "and %[tmp1], %[old], %[mask]\n\t" \
876+ "bne %[tmp1], %[o], 1f\n\t" \
877+ "and %[tmp1], %[old], %[not_mask]\n\t" \
878+ "or %[tmp1], %[tmp1], %[n]\n\t" \
879+ "sc.w.rl %[tmp1], %[tmp1], %[mem]\n\t" \
880+ "bnez %[tmp1], 1b\n\t" \
881+ "1:" \
882+ : [old] "=&r" (old), \
883+ [mem] "+A" (*(volatile unsigned*) aligned_addr), \
884+ [tmp1] "=&r" (tmp1) \
885+ : [o] "r" ((((unsigned) o) << shift) & mask), \
886+ [n] "r" ((((unsigned) n) << shift) & mask), \
887+ [mask] "r" (mask), \
888+ [not_mask] "r" (~mask)); \
889+ \
890+ return (type) (old >> shift); \
891+ } \
892+ bool __sync_bool_compare_and_swap_ ## size (type *p, type o, type n) \
893+ { \
894+ return __sync_val_compare_and_swap(p, o, n) == o; \
895+ }
896+
897+#define GENERATE_ALL(type, size) \
898+ GENERATE_FETCH_AND_OP(type, size, add, add, DONT_INVERT, o + v) \
899+ GENERATE_FETCH_AND_OP(type, size, sub, sub, DONT_INVERT, o - v) \
900+ GENERATE_FETCH_AND_OP(type, size, and, and, DONT_INVERT, o & v) \
901+ GENERATE_FETCH_AND_OP(type, size, xor, xor, DONT_INVERT, o ^ v) \
902+ GENERATE_FETCH_AND_OP(type, size, or, or, DONT_INVERT, o | v) \
903+ GENERATE_FETCH_AND_OP(type, size, nand, and, INVERT, ~(o & v)) \
904+ GENERATE_COMPARE_AND_SWAP(type, size)
905+
906+GENERATE_ALL(unsigned char, 1)
907+GENERATE_ALL(unsigned short, 2)
908+
909+#endif
910diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md
911new file mode 100644
912index 00000000000..ae93788e44a
913--- /dev/null
914+++ b/gcc/config/riscv/constraints.md
915@@ -0,0 +1,78 @@
916+;; Constraint definitions for RISC-V target.
917+;; Copyright (C) 2011-2017 Free Software Foundation, Inc.
918+;; Contributed by Andrew Waterman (andrew@sifive.com).
919+;; Based on MIPS target for GNU compiler.
920+;;
921+;; This file is part of GCC.
922+;;
923+;; GCC is free software; you can redistribute it and/or modify
924+;; it under the terms of the GNU General Public License as published by
925+;; the Free Software Foundation; either version 3, or (at your option)
926+;; any later version.
927+;;
928+;; GCC is distributed in the hope that it will be useful,
929+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
930+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
931+;; GNU General Public License for more details.
932+;;
933+;; You should have received a copy of the GNU General Public License
934+;; along with GCC; see the file COPYING3. If not see
935+;; <http://www.gnu.org/licenses/>.
936+
937+;; Register constraints
938+
939+(define_register_constraint "f" "TARGET_HARD_FLOAT ? FP_REGS : NO_REGS"
940+ "A floating-point register (if available).")
941+
942+(define_register_constraint "j" "SIBCALL_REGS"
943+ "@internal")
944+
945+;; Avoid using register t0 for JALR's argument, because for some
946+;; microarchitectures that is a return-address stack hint.
947+(define_register_constraint "l" "JALR_REGS"
948+ "@internal")
949+
950+;; General constraints
951+
952+(define_constraint "I"
953+ "An I-type 12-bit signed immediate."
954+ (and (match_code "const_int")
955+ (match_test "SMALL_OPERAND (ival)")))
956+
957+(define_constraint "J"
958+ "Integer zero."
959+ (and (match_code "const_int")
960+ (match_test "ival == 0")))
961+
962+(define_constraint "K"
963+ "A 5-bit unsigned immediate for CSR access instructions."
964+ (and (match_code "const_int")
965+ (match_test "IN_RANGE (ival, 0, 31)")))
966+
967+;; Floating-point constant +0.0, used for FCVT-based moves when FMV is
968+;; not available in RV32.
969+(define_constraint "G"
970+ "@internal"
971+ (and (match_code "const_double")
972+ (match_test "op == CONST0_RTX (mode)")))
973+
974+(define_memory_constraint "A"
975+ "An address that is held in a general-purpose register."
976+ (and (match_code "mem")
977+ (match_test "GET_CODE(XEXP(op,0)) == REG")))
978+
979+(define_constraint "S"
980+ "@internal
981+ A constant call address."
982+ (match_operand 0 "absolute_symbolic_operand"))
983+
984+(define_constraint "U"
985+ "@internal
986+ A PLT-indirect call address."
987+ (match_operand 0 "plt_symbolic_operand"))
988+
989+(define_constraint "T"
990+ "@internal
991+ A constant @code{move_operand}."
992+ (and (match_operand 0 "move_operand")
993+ (match_test "CONSTANT_P (op)")))
994diff --git a/gcc/config/riscv/crti.S b/gcc/config/riscv/crti.S
995new file mode 100644
996index 00000000000..89bac706c63
997--- /dev/null
998+++ b/gcc/config/riscv/crti.S
999@@ -0,0 +1 @@
1000+/* crti.S is empty because .init_array/.fini_array are used exclusively. */
1001diff --git a/gcc/config/riscv/crtn.S b/gcc/config/riscv/crtn.S
1002new file mode 100644
1003index 00000000000..ca6ee7b6fba
1004--- /dev/null
1005+++ b/gcc/config/riscv/crtn.S
1006@@ -0,0 +1 @@
1007+/* crtn.S is empty because .init_array/.fini_array are used exclusively. */
1008diff --git a/gcc/config/riscv/elf.h b/gcc/config/riscv/elf.h
1009new file mode 100644
1010index 00000000000..391e59f49b9
1011--- /dev/null
1012+++ b/gcc/config/riscv/elf.h
1013@@ -0,0 +1,35 @@
1014+/* Target macros for riscv*-elf targets.
1015+ Copyright (C) 1994-2017 Free Software Foundation, Inc.
1016+
1017+This file is part of GCC.
1018+
1019+GCC is free software; you can redistribute it and/or modify
1020+it under the terms of the GNU General Public License as published by
1021+the Free Software Foundation; either version 3, or (at your option)
1022+any later version.
1023+
1024+GCC is distributed in the hope that it will be useful,
1025+but WITHOUT ANY WARRANTY; without even the implied warranty of
1026+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1027+GNU General Public License for more details.
1028+
1029+You should have received a copy of the GNU General Public License
1030+along with GCC; see the file COPYING3. If not see
1031+<http://www.gnu.org/licenses/>. */
1032+
1033+#define LINK_SPEC "\
1034+-melf" XLEN_SPEC "lriscv \
1035+%{shared}"
1036+
1037+/* Link against Newlib libraries, because the ELF backend assumes Newlib.
1038+ Handle the circular dependence between libc and libgloss. */
1039+#undef LIB_SPEC
1040+#define LIB_SPEC "--start-group -lc -lgloss --end-group"
1041+
1042+#undef STARTFILE_SPEC
1043+#define STARTFILE_SPEC "crt0%O%s crtbegin%O%s"
1044+
1045+#undef ENDFILE_SPEC
1046+#define ENDFILE_SPEC "crtend%O%s"
1047+
1048+#define NO_IMPLICIT_EXTERN_C 1
1049diff --git a/gcc/config/riscv/generic.md b/gcc/config/riscv/generic.md
1050new file mode 100644
1051index 00000000000..294c7ef729d
1052--- /dev/null
1053+++ b/gcc/config/riscv/generic.md
1054@@ -0,0 +1,78 @@
1055+;; Generic DFA-based pipeline description for RISC-V targets.
1056+;; Copyright (C) 2011-2017 Free Software Foundation, Inc.
1057+;; Contributed by Andrew Waterman (andrew@sifive.com).
1058+;; Based on MIPS target for GNU compiler.
1059+
1060+;; This file is part of GCC.
1061+
1062+;; GCC is free software; you can redistribute it and/or modify it
1063+;; under the terms of the GNU General Public License as published
1064+;; by the Free Software Foundation; either version 3, or (at your
1065+;; option) any later version.
1066+
1067+;; GCC is distributed in the hope that it will be useful, but WITHOUT
1068+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1069+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
1070+;; License for more details.
1071+
1072+;; You should have received a copy of the GNU General Public License
1073+;; along with GCC; see the file COPYING3. If not see
1074+;; <http://www.gnu.org/licenses/>.
1075+
1076+
1077+(define_automaton "pipe0")
1078+(define_cpu_unit "alu" "pipe0")
1079+(define_cpu_unit "imuldiv" "pipe0")
1080+(define_cpu_unit "fdivsqrt" "pipe0")
1081+
1082+(define_insn_reservation "generic_alu" 1
1083+ (eq_attr "type" "unknown,const,arith,shift,slt,multi,nop,logical,move")
1084+ "alu")
1085+
1086+(define_insn_reservation "generic_load" 3
1087+ (eq_attr "type" "load,fpload")
1088+ "alu")
1089+
1090+(define_insn_reservation "generic_store" 1
1091+ (eq_attr "type" "store,fpstore")
1092+ "alu")
1093+
1094+(define_insn_reservation "generic_xfer" 3
1095+ (eq_attr "type" "mfc,mtc,fcvt,fmove,fcmp")
1096+ "alu")
1097+
1098+(define_insn_reservation "generic_branch" 1
1099+ (eq_attr "type" "branch,jump,call")
1100+ "alu")
1101+
1102+(define_insn_reservation "generic_imul" 10
1103+ (eq_attr "type" "imul")
1104+ "imuldiv*10")
1105+
1106+(define_insn_reservation "generic_idivsi" 34
1107+ (and (eq_attr "type" "idiv")
1108+ (eq_attr "mode" "SI"))
1109+ "imuldiv*34")
1110+
1111+(define_insn_reservation "generic_idivdi" 66
1112+ (and (eq_attr "type" "idiv")
1113+ (eq_attr "mode" "DI"))
1114+ "imuldiv*66")
1115+
1116+(define_insn_reservation "generic_fmul_single" 5
1117+ (and (eq_attr "type" "fadd,fmul,fmadd")
1118+ (eq_attr "mode" "SF"))
1119+ "alu")
1120+
1121+(define_insn_reservation "generic_fmul_double" 7
1122+ (and (eq_attr "type" "fadd,fmul,fmadd")
1123+ (eq_attr "mode" "DF"))
1124+ "alu")
1125+
1126+(define_insn_reservation "generic_fdiv" 20
1127+ (eq_attr "type" "fdiv")
1128+ "fdivsqrt*20")
1129+
1130+(define_insn_reservation "generic_fsqrt" 25
1131+ (eq_attr "type" "fsqrt")
1132+ "fdivsqrt*25")
1133diff --git a/gcc/config/riscv/linux-unwind.h b/gcc/config/riscv/linux-unwind.h
1134new file mode 100644
1135index 00000000000..09ed48151f6
1136--- /dev/null
1137+++ b/gcc/config/riscv/linux-unwind.h
1138@@ -0,0 +1,89 @@
1139+/* Copyright (C) 2016-2017 Free Software Foundation, Inc.
1140+
1141+ This file is free software; you can redistribute it and/or modify it
1142+ under the terms of the GNU General Public License as published by the
1143+ Free Software Foundation; either version 3, or (at your option) any
1144+ later version.
1145+
1146+ This file is distributed in the hope that it will be useful, but
1147+ WITHOUT ANY WARRANTY; without even the implied warranty of
1148+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1149+ General Public License for more details.
1150+
1151+ Under Section 7 of GPL version 3, you are granted additional
1152+ permissions described in the GCC Runtime Library Exception, version
1153+ 3.1, as published by the Free Software Foundation.
1154+
1155+ You should have received a copy of the GNU General Public License and
1156+ a copy of the GCC Runtime Library Exception along with this program;
1157+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
1158+ <http://www.gnu.org/licenses/>. */
1159+
1160+#ifndef inhibit_libc
1161+
1162+#include <signal.h>
1163+#include <stdint.h>
1164+#include <sys/ucontext.h>
1165+
1166+#define LI_A7_8B 0x08b00893
1167+#define ECALL 0x00000073
1168+
1169+#define MD_FALLBACK_FRAME_STATE_FOR riscv_fallback_frame_state
1170+
1171+static _Unwind_Reason_Code
1172+riscv_fallback_frame_state (struct _Unwind_Context *context,
1173+ _Unwind_FrameState * fs)
1174+{
1175+ /* The kernel creates an rt_sigframe on the stack immediately prior
1176+ to delivering a signal.
1177+
1178+ This structure must have the same shape as the linux kernel
1179+ equivalent. */
1180+ struct rt_sigframe
1181+ {
1182+ siginfo_t info;
1183+ struct ucontext uc;
1184+ };
1185+
1186+ struct rt_sigframe *rt_;
1187+ _Unwind_Ptr new_cfa;
1188+ uint16_t *pc = context->ra;
1189+ struct sigcontext *sc;
1190+ int i;
1191+
1192+ /* A signal frame will have a return address pointing to
1193+ __default_sa_restorer. This code is hardwired as:
1194+
1195+ 0x08b00893 li a7,0x8b
1196+ 0x00000073 ecall
1197+
1198+ Note, the PC might only have 2-byte alignment.
1199+ */
1200+ if (pc[0] != (uint16_t)LI_A7_8B || pc[1] != (uint16_t)(LI_A7_8B >> 16)
1201+ || pc[2] != (uint16_t)ECALL || pc[3] != (uint16_t)(ECALL >> 16))
1202+ return _URC_END_OF_STACK;
1203+
1204+ rt_ = context->cfa;
1205+ sc = &rt_->uc.uc_mcontext;
1206+
1207+ new_cfa = (_Unwind_Ptr) sc;
1208+ fs->regs.cfa_how = CFA_REG_OFFSET;
1209+ fs->regs.cfa_reg = STACK_POINTER_REGNUM;
1210+ fs->regs.cfa_offset = new_cfa - (_Unwind_Ptr) context->cfa;
1211+
1212+ for (i = 0; i < 32; i++)
1213+ {
1214+ fs->regs.reg[i].how = REG_SAVED_OFFSET;
1215+ fs->regs.reg[i].loc.offset = (_Unwind_Ptr) &sc->gregs[i] - new_cfa;
1216+ }
1217+
1218+ fs->signal_frame = 1;
1219+ fs->retaddr_column = DWARF_ALT_FRAME_RETURN_COLUMN;
1220+ fs->regs.reg[fs->retaddr_column].how = REG_SAVED_VAL_OFFSET;
1221+ fs->regs.reg[fs->retaddr_column].loc.offset =
1222+ (_Unwind_Ptr) sc->gregs[0] - new_cfa;
1223+
1224+ return _URC_NO_REASON;
1225+}
1226+
1227+#endif
1228diff --git a/gcc/config/riscv/linux.h b/gcc/config/riscv/linux.h
1229new file mode 100644
1230index 00000000000..f55313c1de3
1231--- /dev/null
1232+++ b/gcc/config/riscv/linux.h
1233@@ -0,0 +1,58 @@
1234+/* Definitions for RISC-V GNU/Linux systems with ELF format.
1235+ Copyright (C) 1998-2017 Free Software Foundation, Inc.
1236+
1237+This file is part of GCC.
1238+
1239+GCC is free software; you can redistribute it and/or modify
1240+it under the terms of the GNU General Public License as published by
1241+the Free Software Foundation; either version 3, or (at your option)
1242+any later version.
1243+
1244+GCC is distributed in the hope that it will be useful,
1245+but WITHOUT ANY WARRANTY; without even the implied warranty of
1246+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1247+GNU General Public License for more details.
1248+
1249+You should have received a copy of the GNU General Public License
1250+along with GCC; see the file COPYING3. If not see
1251+<http://www.gnu.org/licenses/>. */
1252+
1253+#define TARGET_OS_CPP_BUILTINS() LINUX_TARGET_OS_CPP_BUILTINS()
1254+
1255+#define MD_UNWIND_SUPPORT "config/riscv/linux-unwind.h"
1256+
1257+#define GLIBC_DYNAMIC_LINKER "/lib/ld-linux-riscv" XLEN_SPEC "-" ABI_SPEC ".so.1"
1258+
1259+#define MUSL_ABI_SUFFIX \
1260+ "%{mabi=ilp32:-sf}" \
1261+ "%{mabi=ilp32f:-sp}" \
1262+ "%{mabi=ilp32d:}" \
1263+ "%{mabi=lp64:-sf}" \
1264+ "%{mabi=lp64f:-sp}" \
1265+ "%{mabi=lp64d:}" \
1266+
1267+#undef MUSL_DYNAMIC_LINKER
1268+#define MUSL_DYNAMIC_LINKER "/lib/ld-musl-riscv" XLEN_SPEC MUSL_ABI_SUFFIX ".so.1"
1269+
1270+/* Because RISC-V only has word-sized atomics, it requries libatomic where
1271+ others do not. So link libatomic by default, as needed. */
1272+/*
1273+ * REMOVED FOR BOOTSTRAPPING
1274+#undef LIB_SPEC
1275+#ifdef LD_AS_NEEDED_OPTION
1276+#define LIB_SPEC GNU_USER_TARGET_LIB_SPEC \
1277+ " %{pthread:" LD_AS_NEEDED_OPTION " -latomic " LD_NO_AS_NEEDED_OPTION "}"
1278+#else
1279+#define LIB_SPEC GNU_USER_TARGET_LIB_SPEC " -latomic "
1280+#endif
1281+*/
1282+
1283+#define LINK_SPEC "\
1284+-melf" XLEN_SPEC "lriscv \
1285+%{shared} \
1286+ %{!shared: \
1287+ %{!static: \
1288+ %{rdynamic:-export-dynamic} \
1289+ -dynamic-linker " LINUX_DYNAMIC_LINKER "} \
1290+ %{static:-static}}"
1291+
1292diff --git a/gcc/config/riscv/multilib-generator b/gcc/config/riscv/multilib-generator
1293new file mode 100755
1294index 00000000000..50687b41894
1295--- /dev/null
1296+++ b/gcc/config/riscv/multilib-generator
1297@@ -0,0 +1,65 @@
1298+#!/usr/bin/env python
1299+
1300+# RISC-V multilib list generator.
1301+# Copyright (C) 2011-2017 Free Software Foundation, Inc.
1302+# Contributed by Andrew Waterman (andrew@sifive.com).
1303+#
1304+# This file is part of GCC.
1305+#
1306+# GCC is free software; you can redistribute it and/or modify
1307+# it under the terms of the GNU General Public License as published by
1308+# the Free Software Foundation; either version 3, or (at your option)
1309+# any later version.
1310+#
1311+# GCC is distributed in the hope that it will be useful,
1312+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1313+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1314+# GNU General Public License for more details.
1315+#
1316+# You should have received a copy of the GNU General Public License
1317+# along with GCC; see the file COPYING3. If not see
1318+# <http://www.gnu.org/licenses/>.
1319+
1320+# Each argument to this script is of the form
1321+# <primary arch>-<abi>-<additional arches>-<extensions>
1322+# For example,
1323+# rv32imafd-ilp32d-rv32g-c,v
1324+# means that, in addition to rv32imafd, these configurations can also use the
1325+# rv32imafd-ilp32d libraries: rv32imafdc, rv32imafdv, rv32g, rv32gc, rv32gv
1326+
1327+from __future__ import print_function
1328+import sys
1329+import collections
1330+
1331+arches = collections.OrderedDict()
1332+abis = collections.OrderedDict()
1333+required = []
1334+reuse = []
1335+
1336+for cfg in sys.argv[1:]:
1337+ (arch, abi, extra, ext) = cfg.split('-')
1338+ arches[arch] = 1
1339+ abis[abi] = 1
1340+ extra = list(filter(None, extra.split(',')))
1341+ ext = list(filter(None, ext.split(',')))
1342+ alts = sum([[x] + [x + y for y in ext] for x in [arch] + extra], [])
1343+ alts = alts + [x.replace('imafd', 'g') for x in alts if 'imafd' in x]
1344+ for alt in alts[1:]:
1345+ arches[alt] = 1
1346+ reuse.append('march.%s/mabi.%s=march.%s/mabi.%s' % (arch, abi, alt, abi))
1347+ required.append('march=%s/mabi=%s' % (arch, abi))
1348+
1349+arch_options = '/'.join(['march=%s' % x for x in arches.keys()])
1350+arch_dirnames = ' \\\n'.join(arches.keys())
1351+
1352+abi_options = '/'.join(['mabi=%s' % x for x in abis.keys()])
1353+abi_dirnames = ' \\\n'.join(abis.keys())
1354+
1355+prog = sys.argv[0].split('/')[-1]
1356+print('# This file was generated by %s with the command:' % prog)
1357+print('# %s' % ' '.join(sys.argv))
1358+
1359+print('MULTILIB_OPTIONS = %s %s' % (arch_options, abi_options))
1360+print('MULTILIB_DIRNAMES = %s %s' % (arch_dirnames, abi_dirnames))
1361+print('MULTILIB_REQUIRED = %s' % ' \\\n'.join(required))
1362+print('MULTILIB_REUSE = %s' % ' \\\n'.join(reuse))
1363diff --git a/gcc/config/riscv/peephole.md b/gcc/config/riscv/peephole.md
1364new file mode 100644
1365index 00000000000..7e644e01759
1366--- /dev/null
1367+++ b/gcc/config/riscv/peephole.md
1368@@ -0,0 +1,40 @@
1369+;; Peephole optimizations for RISC-V for GNU compiler.
1370+;; Copyright (C) 2011-2017 Free Software Foundation, Inc.
1371+;; Contributed by Andrew Waterman (andrew@sifive.com).
1372+
1373+;; This file is part of GCC.
1374+
1375+;; GCC is free software; you can redistribute it and/or modify
1376+;; it under the terms of the GNU General Public License as published by
1377+;; the Free Software Foundation; either version 3, or (at your option)
1378+;; any later version.
1379+
1380+;; GCC is distributed in the hope that it will be useful,
1381+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
1382+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1383+;; GNU General Public License for more details.
1384+
1385+;; You should have received a copy of the GNU General Public License
1386+;; along with GCC; see the file COPYING3. If not see
1387+;; <http://www.gnu.org/licenses/>.
1388+
1389+;; Simplify (unsigned long)(unsigned int)a << const
1390+(define_peephole2
1391+ [(set (match_operand:DI 0 "register_operand")
1392+ (ashift:DI (match_operand:DI 1 "register_operand")
1393+ (match_operand 2 "const_int_operand")))
1394+ (set (match_operand:DI 3 "register_operand")
1395+ (lshiftrt:DI (match_dup 0) (match_dup 2)))
1396+ (set (match_operand:DI 4 "register_operand")
1397+ (ashift:DI (match_dup 3) (match_operand 5 "const_int_operand")))]
1398+ "TARGET_64BIT
1399+ && INTVAL (operands[5]) < INTVAL (operands[2])
1400+ && (REGNO (operands[3]) == REGNO (operands[4])
1401+ || peep2_reg_dead_p (3, operands[3]))"
1402+ [(set (match_dup 0)
1403+ (ashift:DI (match_dup 1) (match_dup 2)))
1404+ (set (match_dup 4)
1405+ (lshiftrt:DI (match_dup 0) (match_operand 5)))]
1406+{
1407+ operands[5] = GEN_INT (INTVAL (operands[2]) - INTVAL (operands[5]));
1408+})
1409diff --git a/gcc/config/riscv/pic.md b/gcc/config/riscv/pic.md
1410new file mode 100644
1411index 00000000000..6a29ead32d3
1412--- /dev/null
1413+++ b/gcc/config/riscv/pic.md
1414@@ -0,0 +1,85 @@
1415+;; PIC codegen for RISC-V for GNU compiler.
1416+;; Copyright (C) 2011-2017 Free Software Foundation, Inc.
1417+;; Contributed by Andrew Waterman (andrew@sifive.com).
1418+
1419+;; This file is part of GCC.
1420+
1421+;; GCC is free software; you can redistribute it and/or modify
1422+;; it under the terms of the GNU General Public License as published by
1423+;; the Free Software Foundation; either version 3, or (at your option)
1424+;; any later version.
1425+
1426+;; GCC is distributed in the hope that it will be useful,
1427+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
1428+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1429+;; GNU General Public License for more details.
1430+
1431+;; You should have received a copy of the GNU General Public License
1432+;; along with GCC; see the file COPYING3. If not see
1433+;; <http://www.gnu.org/licenses/>.
1434+
1435+
1436+;; Simplify PIC loads to static variables.
1437+;; These should go away once we figure out how to emit auipc discretely.
1438+
1439+(define_insn "*local_pic_load<mode>"
1440+ [(set (match_operand:ANYI 0 "register_operand" "=r")
1441+ (mem:ANYI (match_operand 1 "absolute_symbolic_operand" "")))]
1442+ "USE_LOAD_ADDRESS_MACRO (operands[1])"
1443+ "<load>\t%0,%1"
1444+ [(set (attr "length") (const_int 8))])
1445+
1446+(define_insn "*local_pic_load<mode>"
1447+ [(set (match_operand:ANYF 0 "register_operand" "=f")
1448+ (mem:ANYF (match_operand 1 "absolute_symbolic_operand" "")))
1449+ (clobber (match_scratch:DI 2 "=r"))]
1450+ "TARGET_HARD_FLOAT && TARGET_64BIT && USE_LOAD_ADDRESS_MACRO (operands[1])"
1451+ "<load>\t%0,%1,%2"
1452+ [(set (attr "length") (const_int 8))])
1453+
1454+(define_insn "*local_pic_load<mode>"
1455+ [(set (match_operand:ANYF 0 "register_operand" "=f")
1456+ (mem:ANYF (match_operand 1 "absolute_symbolic_operand" "")))
1457+ (clobber (match_scratch:SI 2 "=r"))]
1458+ "TARGET_HARD_FLOAT && !TARGET_64BIT && USE_LOAD_ADDRESS_MACRO (operands[1])"
1459+ "<load>\t%0,%1,%2"
1460+ [(set (attr "length") (const_int 8))])
1461+
1462+(define_insn "*local_pic_loadu<mode>"
1463+ [(set (match_operand:SUPERQI 0 "register_operand" "=r")
1464+ (zero_extend:SUPERQI (mem:SUBX (match_operand 1 "absolute_symbolic_operand" ""))))]
1465+ "USE_LOAD_ADDRESS_MACRO (operands[1])"
1466+ "<load>u\t%0,%1"
1467+ [(set (attr "length") (const_int 8))])
1468+
1469+(define_insn "*local_pic_storedi<mode>"
1470+ [(set (mem:ANYI (match_operand 0 "absolute_symbolic_operand" ""))
1471+ (match_operand:ANYI 1 "reg_or_0_operand" "rJ"))
1472+ (clobber (match_scratch:DI 2 "=&r"))]
1473+ "TARGET_64BIT && USE_LOAD_ADDRESS_MACRO (operands[0])"
1474+ "<store>\t%z1,%0,%2"
1475+ [(set (attr "length") (const_int 8))])
1476+
1477+(define_insn "*local_pic_storesi<mode>"
1478+ [(set (mem:ANYI (match_operand 0 "absolute_symbolic_operand" ""))
1479+ (match_operand:ANYI 1 "reg_or_0_operand" "rJ"))
1480+ (clobber (match_scratch:SI 2 "=&r"))]
1481+ "!TARGET_64BIT && USE_LOAD_ADDRESS_MACRO (operands[0])"
1482+ "<store>\t%z1,%0,%2"
1483+ [(set (attr "length") (const_int 8))])
1484+
1485+(define_insn "*local_pic_storedi<mode>"
1486+ [(set (mem:ANYF (match_operand 0 "absolute_symbolic_operand" ""))
1487+ (match_operand:ANYF 1 "register_operand" "f"))
1488+ (clobber (match_scratch:DI 2 "=r"))]
1489+ "TARGET_HARD_FLOAT && TARGET_64BIT && USE_LOAD_ADDRESS_MACRO (operands[0])"
1490+ "<store>\t%1,%0,%2"
1491+ [(set (attr "length") (const_int 8))])
1492+
1493+(define_insn "*local_pic_storesi<mode>"
1494+ [(set (mem:ANYF (match_operand 0 "absolute_symbolic_operand" ""))
1495+ (match_operand:ANYF 1 "register_operand" "f"))
1496+ (clobber (match_scratch:SI 2 "=r"))]
1497+ "TARGET_HARD_FLOAT && !TARGET_64BIT && USE_LOAD_ADDRESS_MACRO (operands[0])"
1498+ "<store>\t%1,%0,%2"
1499+ [(set (attr "length") (const_int 8))])
1500diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md
1501new file mode 100644
1502index 00000000000..2f5d3815b7c
1503--- /dev/null
1504+++ b/gcc/config/riscv/predicates.md
1505@@ -0,0 +1,180 @@
1506+;; Predicate description for RISC-V target.
1507+;; Copyright (C) 2011-2017 Free Software Foundation, Inc.
1508+;; Contributed by Andrew Waterman (andrew@sifive.com).
1509+;; Based on MIPS target for GNU compiler.
1510+;;
1511+;; This file is part of GCC.
1512+;;
1513+;; GCC is free software; you can redistribute it and/or modify
1514+;; it under the terms of the GNU General Public License as published by
1515+;; the Free Software Foundation; either version 3, or (at your option)
1516+;; any later version.
1517+;;
1518+;; GCC is distributed in the hope that it will be useful,
1519+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
1520+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1521+;; GNU General Public License for more details.
1522+;;
1523+;; You should have received a copy of the GNU General Public License
1524+;; along with GCC; see the file COPYING3. If not see
1525+;; <http://www.gnu.org/licenses/>.
1526+
1527+(define_predicate "const_arith_operand"
1528+ (and (match_code "const_int")
1529+ (match_test "SMALL_OPERAND (INTVAL (op))")))
1530+
1531+(define_predicate "arith_operand"
1532+ (ior (match_operand 0 "const_arith_operand")
1533+ (match_operand 0 "register_operand")))
1534+
1535+(define_predicate "const_csr_operand"
1536+ (and (match_code "const_int")
1537+ (match_test "IN_RANGE (INTVAL (op), 0, 31)")))
1538+
1539+(define_predicate "csr_operand"
1540+ (ior (match_operand 0 "const_csr_operand")
1541+ (match_operand 0 "register_operand")))
1542+
1543+(define_predicate "sle_operand"
1544+ (and (match_code "const_int")
1545+ (match_test "SMALL_OPERAND (INTVAL (op) + 1)")))
1546+
1547+(define_predicate "sleu_operand"
1548+ (and (match_operand 0 "sle_operand")
1549+ (match_test "INTVAL (op) + 1 != 0")))
1550+
1551+(define_predicate "const_0_operand"
1552+ (and (match_code "const_int,const_double,const_vector")
1553+ (match_test "op == CONST0_RTX (GET_MODE (op))")))
1554+
1555+(define_predicate "reg_or_0_operand"
1556+ (ior (match_operand 0 "const_0_operand")
1557+ (match_operand 0 "register_operand")))
1558+
1559+;; Only use branch-on-bit sequences when the mask is not an ANDI immediate.
1560+(define_predicate "branch_on_bit_operand"
1561+ (and (match_code "const_int")
1562+ (match_test "INTVAL (op) >= IMM_BITS - 1")))
1563+
1564+;; A legitimate CONST_INT operand that takes more than one instruction
1565+;; to load.
1566+(define_predicate "splittable_const_int_operand"
1567+ (match_code "const_int")
1568+{
1569+ /* Don't handle multi-word moves this way; we don't want to introduce
1570+ the individual word-mode moves until after reload. */
1571+ if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
1572+ return false;
1573+
1574+ /* Otherwise check whether the constant can be loaded in a single
1575+ instruction. */
1576+ return !LUI_OPERAND (INTVAL (op)) && !SMALL_OPERAND (INTVAL (op));
1577+})
1578+
1579+(define_predicate "move_operand"
1580+ (match_operand 0 "general_operand")
1581+{
1582+ enum riscv_symbol_type symbol_type;
1583+
1584+ /* The thinking here is as follows:
1585+
1586+ (1) The move expanders should split complex load sequences into
1587+ individual instructions. Those individual instructions can
1588+ then be optimized by all rtl passes.
1589+
1590+ (2) The target of pre-reload load sequences should not be used
1591+ to store temporary results. If the target register is only
1592+ assigned one value, reload can rematerialize that value
1593+ on demand, rather than spill it to the stack.
1594+
1595+ (3) If we allowed pre-reload passes like combine and cse to recreate
1596+ complex load sequences, we would want to be able to split the
1597+ sequences before reload as well, so that the pre-reload scheduler
1598+ can see the individual instructions. This falls foul of (2);
1599+ the splitter would be forced to reuse the target register for
1600+ intermediate results.
1601+
1602+ (4) We want to define complex load splitters for combine. These
1603+ splitters can request a temporary scratch register, which avoids
1604+ the problem in (2). They allow things like:
1605+
1606+ (set (reg T1) (high SYM))
1607+ (set (reg T2) (low (reg T1) SYM))
1608+ (set (reg X) (plus (reg T2) (const_int OFFSET)))
1609+
1610+ to be combined into:
1611+
1612+ (set (reg T3) (high SYM+OFFSET))
1613+ (set (reg X) (lo_sum (reg T3) SYM+OFFSET))
1614+
1615+ if T2 is only used this once. */
1616+ switch (GET_CODE (op))
1617+ {
1618+ case CONST_INT:
1619+ return !splittable_const_int_operand (op, mode);
1620+
1621+ case CONST:
1622+ case SYMBOL_REF:
1623+ case LABEL_REF:
1624+ return riscv_symbolic_constant_p (op, &symbol_type)
1625+ && !riscv_split_symbol_type (symbol_type);
1626+
1627+ case HIGH:
1628+ op = XEXP (op, 0);
1629+ return riscv_symbolic_constant_p (op, &symbol_type)
1630+ && riscv_split_symbol_type (symbol_type)
1631+ && symbol_type != SYMBOL_PCREL;
1632+
1633+ default:
1634+ return true;
1635+ }
1636+})
1637+
1638+(define_predicate "symbolic_operand"
1639+ (match_code "const,symbol_ref,label_ref")
1640+{
1641+ enum riscv_symbol_type type;
1642+ return riscv_symbolic_constant_p (op, &type);
1643+})
1644+
1645+(define_predicate "absolute_symbolic_operand"
1646+ (match_code "const,symbol_ref,label_ref")
1647+{
1648+ enum riscv_symbol_type type;
1649+ return (riscv_symbolic_constant_p (op, &type)
1650+ && (type == SYMBOL_ABSOLUTE || type == SYMBOL_PCREL));
1651+})
1652+
1653+(define_predicate "plt_symbolic_operand"
1654+ (match_code "const,symbol_ref,label_ref")
1655+{
1656+ enum riscv_symbol_type type;
1657+ return (riscv_symbolic_constant_p (op, &type)
1658+ && type == SYMBOL_GOT_DISP && !SYMBOL_REF_WEAK (op) && TARGET_PLT);
1659+})
1660+
1661+(define_predicate "call_insn_operand"
1662+ (ior (match_operand 0 "absolute_symbolic_operand")
1663+ (match_operand 0 "plt_symbolic_operand")
1664+ (match_operand 0 "register_operand")))
1665+
1666+(define_predicate "modular_operator"
1667+ (match_code "plus,minus,mult,ashift"))
1668+
1669+(define_predicate "equality_operator"
1670+ (match_code "eq,ne"))
1671+
1672+(define_predicate "order_operator"
1673+ (match_code "eq,ne,lt,ltu,le,leu,ge,geu,gt,gtu"))
1674+
1675+(define_predicate "signed_order_operator"
1676+ (match_code "eq,ne,lt,le,ge,gt"))
1677+
1678+(define_predicate "fp_native_comparison"
1679+ (match_code "eq,lt,le,gt,ge"))
1680+
1681+(define_predicate "fp_scc_comparison"
1682+ (match_code "unordered,ordered,unlt,unge,unle,ungt,ltgt,ne,eq,lt,le,gt,ge"))
1683+
1684+(define_predicate "fp_branch_comparison"
1685+ (match_code "unordered,ordered,unlt,unge,unle,ungt,uneq,ltgt,ne,eq,lt,le,gt,ge"))
1686diff --git a/gcc/config/riscv/riscv-builtins.c b/gcc/config/riscv/riscv-builtins.c
1687new file mode 100644
1688index 00000000000..626a6a33f99
1689--- /dev/null
1690+++ b/gcc/config/riscv/riscv-builtins.c
1691@@ -0,0 +1,287 @@
1692+/* Subroutines used for expanding RISC-V builtins.
1693+ Copyright (C) 2011-2017 Free Software Foundation, Inc.
1694+ Contributed by Andrew Waterman (andrew@sifive.com).
1695+
1696+This file is part of GCC.
1697+
1698+GCC is free software; you can redistribute it and/or modify
1699+it under the terms of the GNU General Public License as published by
1700+the Free Software Foundation; either version 3, or (at your option)
1701+any later version.
1702+
1703+GCC is distributed in the hope that it will be useful,
1704+but WITHOUT ANY WARRANTY; without even the implied warranty of
1705+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1706+GNU General Public License for more details.
1707+
1708+You should have received a copy of the GNU General Public License
1709+along with GCC; see the file COPYING3. If not see
1710+<http://www.gnu.org/licenses/>. */
1711+
1712+#include "config.h"
1713+#include "system.h"
1714+#include "coretypes.h"
1715+#include "tm.h"
1716+#include "rtl.h"
1717+#include "tree.h"
1718+#include "gimple-expr.h"
1719+#include "memmodel.h"
1720+#include "expmed.h"
1721+#include "optabs.h"
1722+#include "recog.h"
1723+#include "diagnostic-core.h"
1724+#include "stor-layout.h"
1725+#include "expr.h"
1726+#include "langhooks.h"
1727+
1728+/* Macros to create an enumeration identifier for a function prototype. */
1729+#define RISCV_FTYPE_NAME1(A, B) RISCV_##A##_FTYPE_##B
1730+
1731+/* Classifies the prototype of a built-in function. */
1732+enum riscv_function_type {
1733+#define DEF_RISCV_FTYPE(NARGS, LIST) RISCV_FTYPE_NAME##NARGS LIST,
1734+#include "config/riscv/riscv-ftypes.def"
1735+#undef DEF_RISCV_FTYPE
1736+ RISCV_MAX_FTYPE_MAX
1737+};
1738+
1739+/* Specifies how a built-in function should be converted into rtl. */
1740+enum riscv_builtin_type {
1741+ /* The function corresponds directly to an .md pattern. */
1742+ RISCV_BUILTIN_DIRECT,
1743+
1744+ /* Likewise, but with return type VOID. */
1745+ RISCV_BUILTIN_DIRECT_NO_TARGET
1746+};
1747+
1748+/* Declare an availability predicate for built-in functions. */
1749+#define AVAIL(NAME, COND) \
1750+ static unsigned int \
1751+ riscv_builtin_avail_##NAME (void) \
1752+ { \
1753+ return (COND); \
1754+ }
1755+
1756+/* This structure describes a single built-in function. */
1757+struct riscv_builtin_description {
1758+ /* The code of the main .md file instruction. See riscv_builtin_type
1759+ for more information. */
1760+ enum insn_code icode;
1761+
1762+ /* The name of the built-in function. */
1763+ const char *name;
1764+
1765+ /* Specifies how the function should be expanded. */
1766+ enum riscv_builtin_type builtin_type;
1767+
1768+ /* The function's prototype. */
1769+ enum riscv_function_type prototype;
1770+
1771+ /* Whether the function is available. */
1772+ unsigned int (*avail) (void);
1773+};
1774+
1775+AVAIL (hard_float, TARGET_HARD_FLOAT)
1776+
1777+/* Construct a riscv_builtin_description from the given arguments.
1778+
1779+ INSN is the name of the associated instruction pattern, without the
1780+ leading CODE_FOR_riscv_.
1781+
1782+ NAME is the name of the function itself, without the leading
1783+ "__builtin_riscv_".
1784+
1785+ BUILTIN_TYPE and FUNCTION_TYPE are riscv_builtin_description fields.
1786+
1787+ AVAIL is the name of the availability predicate, without the leading
1788+ riscv_builtin_avail_. */
1789+#define RISCV_BUILTIN(INSN, NAME, BUILTIN_TYPE, FUNCTION_TYPE, AVAIL) \
1790+ { CODE_FOR_riscv_ ## INSN, "__builtin_riscv_" NAME, \
1791+ BUILTIN_TYPE, FUNCTION_TYPE, riscv_builtin_avail_ ## AVAIL }
1792+
1793+/* Define __builtin_riscv_<INSN>, which is a RISCV_BUILTIN_DIRECT function
1794+ mapped to instruction CODE_FOR_riscv_<INSN>, FUNCTION_TYPE and AVAIL
1795+ are as for RISCV_BUILTIN. */
1796+#define DIRECT_BUILTIN(INSN, FUNCTION_TYPE, AVAIL) \
1797+ RISCV_BUILTIN (INSN, #INSN, RISCV_BUILTIN_DIRECT, FUNCTION_TYPE, AVAIL)
1798+
1799+/* Define __builtin_riscv_<INSN>, which is a RISCV_BUILTIN_DIRECT_NO_TARGET
1800+ function mapped to instruction CODE_FOR_riscv_<INSN>, FUNCTION_TYPE
1801+ and AVAIL are as for RISCV_BUILTIN. */
1802+#define DIRECT_NO_TARGET_BUILTIN(INSN, FUNCTION_TYPE, AVAIL) \
1803+ RISCV_BUILTIN (INSN, #INSN, RISCV_BUILTIN_DIRECT_NO_TARGET, \
1804+ FUNCTION_TYPE, AVAIL)
1805+
1806+/* Argument types. */
1807+#define RISCV_ATYPE_VOID void_type_node
1808+#define RISCV_ATYPE_USI unsigned_intSI_type_node
1809+
1810+/* RISCV_FTYPE_ATYPESN takes N RISCV_FTYPES-like type codes and lists
1811+ their associated RISCV_ATYPEs. */
1812+#define RISCV_FTYPE_ATYPES1(A, B) \
1813+ RISCV_ATYPE_##A, RISCV_ATYPE_##B
1814+
1815+static const struct riscv_builtin_description riscv_builtins[] = {
1816+ DIRECT_BUILTIN (frflags, RISCV_USI_FTYPE_VOID, hard_float),
1817+ DIRECT_NO_TARGET_BUILTIN (fsflags, RISCV_VOID_FTYPE_USI, hard_float)
1818+};
1819+
1820+/* Index I is the function declaration for riscv_builtins[I], or null if the
1821+ function isn't defined on this target. */
1822+static GTY(()) tree riscv_builtin_decls[ARRAY_SIZE (riscv_builtins)];
1823+
1824+/* Get the index I of the function declaration for riscv_builtin_decls[I]
1825+ using the instruction code or return null if not defined for the target. */
1826+static GTY(()) int riscv_builtin_decl_index[NUM_INSN_CODES];
1827+
1828+#define GET_BUILTIN_DECL(CODE) \
1829+ riscv_builtin_decls[riscv_builtin_decl_index[(CODE)]]
1830+
1831+/* Return the function type associated with function prototype TYPE. */
1832+
1833+static tree
1834+riscv_build_function_type (enum riscv_function_type type)
1835+{
1836+ static tree types[(int) RISCV_MAX_FTYPE_MAX];
1837+
1838+ if (types[(int) type] == NULL_TREE)
1839+ switch (type)
1840+ {
1841+#define DEF_RISCV_FTYPE(NUM, ARGS) \
1842+ case RISCV_FTYPE_NAME##NUM ARGS: \
1843+ types[(int) type] \
1844+ = build_function_type_list (RISCV_FTYPE_ATYPES##NUM ARGS, \
1845+ NULL_TREE); \
1846+ break;
1847+#include "config/riscv/riscv-ftypes.def"
1848+#undef DEF_RISCV_FTYPE
1849+ default:
1850+ gcc_unreachable ();
1851+ }
1852+
1853+ return types[(int) type];
1854+}
1855+
1856+/* Implement TARGET_INIT_BUILTINS. */
1857+
1858+void
1859+riscv_init_builtins (void)
1860+{
1861+ for (size_t i = 0; i < ARRAY_SIZE (riscv_builtins); i++)
1862+ {
1863+ const struct riscv_builtin_description *d = &riscv_builtins[i];
1864+ if (d->avail ())
1865+ {
1866+ tree type = riscv_build_function_type (d->prototype);
1867+ riscv_builtin_decls[i]
1868+ = add_builtin_function (d->name, type, i, BUILT_IN_MD, NULL, NULL);
1869+ riscv_builtin_decl_index[d->icode] = i;
1870+ }
1871+ }
1872+}
1873+
1874+/* Implement TARGET_BUILTIN_DECL. */
1875+
1876+tree
1877+riscv_builtin_decl (unsigned int code, bool initialize_p ATTRIBUTE_UNUSED)
1878+{
1879+ if (code >= ARRAY_SIZE (riscv_builtins))
1880+ return error_mark_node;
1881+ return riscv_builtin_decls[code];
1882+}
1883+
1884+/* Take argument ARGNO from EXP's argument list and convert it into
1885+ an expand operand. Store the operand in *OP. */
1886+
1887+static void
1888+riscv_prepare_builtin_arg (struct expand_operand *op, tree exp, unsigned argno)
1889+{
1890+ tree arg = CALL_EXPR_ARG (exp, argno);
1891+ create_input_operand (op, expand_normal (arg), TYPE_MODE (TREE_TYPE (arg)));
1892+}
1893+
1894+/* Expand instruction ICODE as part of a built-in function sequence.
1895+ Use the first NOPS elements of OPS as the instruction's operands.
1896+ HAS_TARGET_P is true if operand 0 is a target; it is false if the
1897+ instruction has no target.
1898+
1899+ Return the target rtx if HAS_TARGET_P, otherwise return const0_rtx. */
1900+
1901+static rtx
1902+riscv_expand_builtin_insn (enum insn_code icode, unsigned int n_ops,
1903+ struct expand_operand *ops, bool has_target_p)
1904+{
1905+ if (!maybe_expand_insn (icode, n_ops, ops))
1906+ {
1907+ error ("invalid argument to built-in function");
1908+ return has_target_p ? gen_reg_rtx (ops[0].mode) : const0_rtx;
1909+ }
1910+
1911+ return has_target_p ? ops[0].value : const0_rtx;
1912+}
1913+
1914+/* Expand a RISCV_BUILTIN_DIRECT or RISCV_BUILTIN_DIRECT_NO_TARGET function;
1915+ HAS_TARGET_P says which. EXP is the CALL_EXPR that calls the function
1916+ and ICODE is the code of the associated .md pattern. TARGET, if nonnull,
1917+ suggests a good place to put the result. */
1918+
1919+static rtx
1920+riscv_expand_builtin_direct (enum insn_code icode, rtx target, tree exp,
1921+ bool has_target_p)
1922+{
1923+ struct expand_operand ops[MAX_RECOG_OPERANDS];
1924+
1925+ /* Map any target to operand 0. */
1926+ int opno = 0;
1927+ if (has_target_p)
1928+ create_output_operand (&ops[opno++], target, TYPE_MODE (TREE_TYPE (exp)));
1929+
1930+ /* Map the arguments to the other operands. */
1931+ gcc_assert (opno + call_expr_nargs (exp)
1932+ == insn_data[icode].n_generator_args);
1933+ for (int argno = 0; argno < call_expr_nargs (exp); argno++)
1934+ riscv_prepare_builtin_arg (&ops[opno++], exp, argno);
1935+
1936+ return riscv_expand_builtin_insn (icode, opno, ops, has_target_p);
1937+}
1938+
1939+/* Implement TARGET_EXPAND_BUILTIN. */
1940+
1941+rtx
1942+riscv_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
1943+ machine_mode mode ATTRIBUTE_UNUSED,
1944+ int ignore ATTRIBUTE_UNUSED)
1945+{
1946+ tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
1947+ unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
1948+ const struct riscv_builtin_description *d = &riscv_builtins[fcode];
1949+
1950+ switch (d->builtin_type)
1951+ {
1952+ case RISCV_BUILTIN_DIRECT:
1953+ return riscv_expand_builtin_direct (d->icode, target, exp, true);
1954+
1955+ case RISCV_BUILTIN_DIRECT_NO_TARGET:
1956+ return riscv_expand_builtin_direct (d->icode, target, exp, false);
1957+ }
1958+
1959+ gcc_unreachable ();
1960+}
1961+
1962+/* Implement TARGET_ATOMIC_ASSIGN_EXPAND_FENV. */
1963+
1964+void
1965+riscv_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
1966+{
1967+ if (!TARGET_HARD_FLOAT)
1968+ return;
1969+
1970+ tree frflags = GET_BUILTIN_DECL (CODE_FOR_riscv_frflags);
1971+ tree fsflags = GET_BUILTIN_DECL (CODE_FOR_riscv_fsflags);
1972+ tree old_flags = create_tmp_var_raw (RISCV_ATYPE_USI);
1973+
1974+ *hold = build2 (MODIFY_EXPR, RISCV_ATYPE_USI, old_flags,
1975+ build_call_expr (frflags, 0));
1976+ *clear = build_call_expr (fsflags, 1, old_flags);
1977+ *update = NULL_TREE;
1978+}
1979diff --git a/gcc/config/riscv/riscv-c.c b/gcc/config/riscv/riscv-c.c
1980new file mode 100644
1981index 00000000000..7c737d01e4c
1982--- /dev/null
1983+++ b/gcc/config/riscv/riscv-c.c
1984@@ -0,0 +1,92 @@
1985+/* RISC-V-specific code for C family languages.
1986+ Copyright (C) 2011-2017 Free Software Foundation, Inc.
1987+ Contributed by Andrew Waterman (andrew@sifive.com).
1988+
1989+This file is part of GCC.
1990+
1991+GCC is free software; you can redistribute it and/or modify
1992+it under the terms of the GNU General Public License as published by
1993+the Free Software Foundation; either version 3, or (at your option)
1994+any later version.
1995+
1996+GCC is distributed in the hope that it will be useful,
1997+but WITHOUT ANY WARRANTY; without even the implied warranty of
1998+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1999+GNU General Public License for more details.
2000+
2001+You should have received a copy of the GNU General Public License
2002+along with GCC; see the file COPYING3. If not see
2003+<http://www.gnu.org/licenses/>. */
2004+
2005+#include "config.h"
2006+#include "c-family/c-common.h"
2007+#include "system.h"
2008+#include "coretypes.h"
2009+#include "tm.h"
2010+#include "cpplib.h"
2011+
2012+#define builtin_define(TXT) cpp_define (pfile, TXT)
2013+
2014+/* Implement TARGET_CPU_CPP_BUILTINS. */
2015+
2016+void
2017+riscv_cpu_cpp_builtins (struct cpp_reader *pfile)
2018+{
2019+ builtin_define ("__riscv");
2020+
2021+ if (TARGET_RVC)
2022+ builtin_define ("__riscv_compressed");
2023+
2024+ if (TARGET_ATOMIC)
2025+ builtin_define ("__riscv_atomic");
2026+
2027+ if (TARGET_MUL)
2028+ builtin_define ("__riscv_mul");
2029+ if (TARGET_DIV)
2030+ builtin_define ("__riscv_div");
2031+ if (TARGET_DIV && TARGET_MUL)
2032+ builtin_define ("__riscv_muldiv");
2033+
2034+ builtin_define_with_int_value ("__riscv_xlen", UNITS_PER_WORD * 8);
2035+ if (TARGET_HARD_FLOAT)
2036+ builtin_define_with_int_value ("__riscv_flen", UNITS_PER_FP_REG * 8);
2037+
2038+ if (TARGET_HARD_FLOAT && TARGET_FDIV)
2039+ {
2040+ builtin_define ("__riscv_fdiv");
2041+ builtin_define ("__riscv_fsqrt");
2042+ }
2043+
2044+ switch (riscv_abi)
2045+ {
2046+ case ABI_ILP32:
2047+ case ABI_LP64:
2048+ builtin_define ("__riscv_float_abi_soft");
2049+ break;
2050+
2051+ case ABI_ILP32F:
2052+ case ABI_LP64F:
2053+ builtin_define ("__riscv_float_abi_single");
2054+ break;
2055+
2056+ case ABI_ILP32D:
2057+ case ABI_LP64D:
2058+ builtin_define ("__riscv_float_abi_double");
2059+ break;
2060+ }
2061+
2062+ switch (riscv_cmodel)
2063+ {
2064+ case CM_MEDLOW:
2065+ builtin_define ("__riscv_cmodel_medlow");
2066+ break;
2067+
2068+ case CM_MEDANY:
2069+ builtin_define ("__riscv_cmodel_medany");
2070+ break;
2071+
2072+ case CM_PIC:
2073+ builtin_define ("__riscv_cmodel_pic");
2074+ break;
2075+ }
2076+}
2077diff --git a/gcc/config/riscv/riscv-ftypes.def b/gcc/config/riscv/riscv-ftypes.def
2078new file mode 100644
2079index 00000000000..eb69148368f
2080--- /dev/null
2081+++ b/gcc/config/riscv/riscv-ftypes.def
2082@@ -0,0 +1,30 @@
2083+/* Definitions of prototypes for RISC-V built-in functions. -*- C -*-
2084+ Copyright (C) 2011-2017 Free Software Foundation, Inc.
2085+ Contributed by Andrew Waterman (andrew@sifive.com).
2086+ Based on MIPS target for GNU compiler.
2087+
2088+This file is part of GCC.
2089+
2090+GCC is free software; you can redistribute it and/or modify
2091+it under the terms of the GNU General Public License as published by
2092+the Free Software Foundation; either version 3, or (at your option)
2093+any later version.
2094+
2095+GCC is distributed in the hope that it will be useful,
2096+but WITHOUT ANY WARRANTY; without even the implied warranty of
2097+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2098+GNU General Public License for more details.
2099+
2100+You should have received a copy of the GNU General Public License
2101+along with GCC; see the file COPYING3. If not see
2102+<http://www.gnu.org/licenses/>. */
2103+
2104+/* Invoke DEF_RISCV_FTYPE (NARGS, LIST) for each prototype used by
2105+ RISCV built-in functions, where:
2106+
2107+ NARGS is the number of arguments.
2108+ LIST contains the return-type code followed by the codes for each
2109+ argument type. */
2110+
2111+DEF_RISCV_FTYPE (1, (USI, VOID))
2112+DEF_RISCV_FTYPE (1, (VOID, USI))
2113diff --git a/gcc/config/riscv/riscv-modes.def b/gcc/config/riscv/riscv-modes.def
2114new file mode 100644
2115index 00000000000..5c65667da68
2116--- /dev/null
2117+++ b/gcc/config/riscv/riscv-modes.def
2118@@ -0,0 +1,22 @@
2119+/* Extra machine modes for RISC-V target.
2120+ Copyright (C) 2011-2017 Free Software Foundation, Inc.
2121+ Contributed by Andrew Waterman (andrew@sifive.com).
2122+ Based on MIPS target for GNU compiler.
2123+
2124+This file is part of GCC.
2125+
2126+GCC is free software; you can redistribute it and/or modify
2127+it under the terms of the GNU General Public License as published by
2128+the Free Software Foundation; either version 3, or (at your option)
2129+any later version.
2130+
2131+GCC is distributed in the hope that it will be useful,
2132+but WITHOUT ANY WARRANTY; without even the implied warranty of
2133+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2134+GNU General Public License for more details.
2135+
2136+You should have received a copy of the GNU General Public License
2137+along with GCC; see the file COPYING3. If not see
2138+<http://www.gnu.org/licenses/>. */
2139+
2140+FLOAT_MODE (TF, 16, ieee_quad_format);
2141diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
2142new file mode 100644
2143index 00000000000..2b19233379c
2144--- /dev/null
2145+++ b/gcc/config/riscv/riscv-opts.h
2146@@ -0,0 +1,41 @@
2147+/* Definition of RISC-V target for GNU compiler.
2148+ Copyright (C) 2016-2017 Free Software Foundation, Inc.
2149+ Contributed by Andrew Waterman (andrew@sifive.com).
2150+
2151+This file is part of GCC.
2152+
2153+GCC is free software; you can redistribute it and/or modify
2154+it under the terms of the GNU General Public License as published by
2155+the Free Software Foundation; either version 3, or (at your option)
2156+any later version.
2157+
2158+GCC is distributed in the hope that it will be useful,
2159+but WITHOUT ANY WARRANTY; without even the implied warranty of
2160+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2161+GNU General Public License for more details.
2162+
2163+You should have received a copy of the GNU General Public License
2164+along with GCC; see the file COPYING3. If not see
2165+<http://www.gnu.org/licenses/>. */
2166+
2167+#ifndef GCC_RISCV_OPTS_H
2168+#define GCC_RISCV_OPTS_H
2169+
2170+enum riscv_abi_type {
2171+ ABI_ILP32,
2172+ ABI_ILP32F,
2173+ ABI_ILP32D,
2174+ ABI_LP64,
2175+ ABI_LP64F,
2176+ ABI_LP64D
2177+};
2178+extern enum riscv_abi_type riscv_abi;
2179+
2180+enum riscv_code_model {
2181+ CM_MEDLOW,
2182+ CM_MEDANY,
2183+ CM_PIC
2184+};
2185+extern enum riscv_code_model riscv_cmodel;
2186+
2187+#endif /* ! GCC_RISCV_OPTS_H */
2188diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
2189new file mode 100644
2190index 00000000000..eef5fc090a4
2191--- /dev/null
2192+++ b/gcc/config/riscv/riscv-protos.h
2193@@ -0,0 +1,84 @@
2194+/* Definition of RISC-V target for GNU compiler.
2195+ Copyright (C) 2011-2017 Free Software Foundation, Inc.
2196+ Contributed by Andrew Waterman (andrew@sifive.com).
2197+ Based on MIPS target for GNU compiler.
2198+
2199+This file is part of GCC.
2200+
2201+GCC is free software; you can redistribute it and/or modify
2202+it under the terms of the GNU General Public License as published by
2203+the Free Software Foundation; either version 3, or (at your option)
2204+any later version.
2205+
2206+GCC is distributed in the hope that it will be useful,
2207+but WITHOUT ANY WARRANTY; without even the implied warranty of
2208+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2209+GNU General Public License for more details.
2210+
2211+You should have received a copy of the GNU General Public License
2212+along with GCC; see the file COPYING3. If not see
2213+<http://www.gnu.org/licenses/>. */
2214+
2215+#ifndef GCC_RISCV_PROTOS_H
2216+#define GCC_RISCV_PROTOS_H
2217+
2218+/* Symbol types we understand. The order of this list must match that of
2219+ the unspec enum in riscv.md, subsequent to UNSPEC_ADDRESS_FIRST. */
2220+enum riscv_symbol_type {
2221+ SYMBOL_ABSOLUTE,
2222+ SYMBOL_PCREL,
2223+ SYMBOL_GOT_DISP,
2224+ SYMBOL_TLS,
2225+ SYMBOL_TLS_LE,
2226+ SYMBOL_TLS_IE,
2227+ SYMBOL_TLS_GD
2228+};
2229+#define NUM_SYMBOL_TYPES (SYMBOL_TLS_GD + 1)
2230+
2231+/* Routines implemented in riscv.c. */
2232+extern enum riscv_symbol_type riscv_classify_symbolic_expression (rtx);
2233+extern bool riscv_symbolic_constant_p (rtx, enum riscv_symbol_type *);
2234+extern int riscv_regno_mode_ok_for_base_p (int, enum machine_mode, bool);
2235+extern bool riscv_hard_regno_mode_ok_p (unsigned int, enum machine_mode);
2236+extern int riscv_address_insns (rtx, enum machine_mode, bool);
2237+extern int riscv_const_insns (rtx);
2238+extern int riscv_split_const_insns (rtx);
2239+extern int riscv_load_store_insns (rtx, rtx);
2240+extern rtx riscv_emit_move (rtx, rtx);
2241+extern bool riscv_split_symbol (rtx, rtx, enum machine_mode, rtx *);
2242+extern bool riscv_split_symbol_type (enum riscv_symbol_type);
2243+extern rtx riscv_unspec_address (rtx, enum riscv_symbol_type);
2244+extern void riscv_move_integer (rtx, rtx, HOST_WIDE_INT);
2245+extern bool riscv_legitimize_move (enum machine_mode, rtx, rtx);
2246+extern rtx riscv_subword (rtx, bool);
2247+extern bool riscv_split_64bit_move_p (rtx, rtx);
2248+extern void riscv_split_doubleword_move (rtx, rtx);
2249+extern const char *riscv_output_move (rtx, rtx);
2250+extern const char *riscv_output_gpr_save (unsigned);
2251+#ifdef RTX_CODE
2252+extern void riscv_expand_int_scc (rtx, enum rtx_code, rtx, rtx);
2253+extern void riscv_expand_float_scc (rtx, enum rtx_code, rtx, rtx);
2254+extern void riscv_expand_conditional_branch (rtx, enum rtx_code, rtx, rtx);
2255+#endif
2256+extern rtx riscv_legitimize_call_address (rtx);
2257+extern void riscv_set_return_address (rtx, rtx);
2258+extern bool riscv_expand_block_move (rtx, rtx, rtx);
2259+extern rtx riscv_return_addr (int, rtx);
2260+extern HOST_WIDE_INT riscv_initial_elimination_offset (int, int);
2261+extern void riscv_expand_prologue (void);
2262+extern void riscv_expand_epilogue (bool);
2263+extern bool riscv_can_use_return_insn (void);
2264+extern rtx riscv_function_value (const_tree, const_tree, enum machine_mode);
2265+extern unsigned int riscv_hard_regno_nregs (int, enum machine_mode);
2266+extern unsigned char riscv_class_max_nregs (reg_class_t, enum machine_mode);
2267+
2268+/* Routines implemented in riscv-c.c. */
2269+void riscv_cpu_cpp_builtins (struct cpp_reader *);
2270+
2271+/* Routines implemented in riscv-builtins.c. */
2272+extern void riscv_atomic_assign_expand_fenv (tree *, tree *, tree *);
2273+extern rtx riscv_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
2274+extern tree riscv_builtin_decl (unsigned int, bool);
2275+extern void riscv_init_builtins (void);
2276+
2277+#endif /* ! GCC_RISCV_PROTOS_H */
2278diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c
2279new file mode 100644
2280index 00000000000..ae124055051
2281--- /dev/null
2282+++ b/gcc/config/riscv/riscv.c
2283@@ -0,0 +1,4150 @@
2284+/* Subroutines used for code generation for RISC-V.
2285+ Copyright (C) 2011-2017 Free Software Foundation, Inc.
2286+ Contributed by Andrew Waterman (andrew@sifive.com).
2287+ Based on MIPS target for GNU compiler.
2288+
2289+This file is part of GCC.
2290+
2291+GCC is free software; you can redistribute it and/or modify
2292+it under the terms of the GNU General Public License as published by
2293+the Free Software Foundation; either version 3, or (at your option)
2294+any later version.
2295+
2296+GCC is distributed in the hope that it will be useful,
2297+but WITHOUT ANY WARRANTY; without even the implied warranty of
2298+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2299+GNU General Public License for more details.
2300+
2301+You should have received a copy of the GNU General Public License
2302+along with GCC; see the file COPYING3. If not see
2303+<http://www.gnu.org/licenses/>. */
2304+
2305+#include "config.h"
2306+#include "system.h"
2307+#include "coretypes.h"
2308+#include "tm.h"
2309+#include "rtl.h"
2310+#include "regs.h"
2311+#include "hard-reg-set.h"
2312+#include "insn-config.h"
2313+#include "conditions.h"
2314+#include "insn-attr.h"
2315+#include "recog.h"
2316+#include "output.h"
2317+#include "tree.h"
2318+#include "function.h"
2319+#include "expr.h"
2320+#include "optabs.h"
2321+#include "libfuncs.h"
2322+#include "flags.h"
2323+#include "reload.h"
2324+#include "tm_p.h"
2325+#include "ggc.h"
2326+#include "gstab.h"
2327+#include "hashtab.h"
2328+#include "debug.h"
2329+#include "target.h"
2330+#include "target-def.h"
2331+#include "integrate.h"
2332+#include "langhooks.h"
2333+#include "cfglayout.h"
2334+#include "sched-int.h"
2335+#include "gimple.h"
2336+#include "bitmap.h"
2337+#include "diagnostic.h"
2338+#include "target-globals.h"
2339+
2340+
2341+/* True if X is an UNSPEC wrapper around a SYMBOL_REF or LABEL_REF. */
2342+#define UNSPEC_ADDRESS_P(X) \
2343+ (GET_CODE (X) == UNSPEC \
2344+ && XINT (X, 1) >= UNSPEC_ADDRESS_FIRST \
2345+ && XINT (X, 1) < UNSPEC_ADDRESS_FIRST + NUM_SYMBOL_TYPES)
2346+
2347+/* Extract the symbol or label from UNSPEC wrapper X. */
2348+#define UNSPEC_ADDRESS(X) \
2349+ XVECEXP (X, 0, 0)
2350+
2351+/* Extract the symbol type from UNSPEC wrapper X. */
2352+#define UNSPEC_ADDRESS_TYPE(X) \
2353+ ((enum riscv_symbol_type) (XINT (X, 1) - UNSPEC_ADDRESS_FIRST))
2354+
2355+/* True if bit BIT is set in VALUE. */
2356+#define BITSET_P(VALUE, BIT) (((VALUE) & (1ULL << (BIT))) != 0)
2357+
2358+/* Classifies an address.
2359+
2360+ ADDRESS_REG
2361+ A natural register + offset address. The register satisfies
2362+ riscv_valid_base_register_p and the offset is a const_arith_operand.
2363+
2364+ ADDRESS_LO_SUM
2365+ A LO_SUM rtx. The first operand is a valid base register and
2366+ the second operand is a symbolic address.
2367+
2368+ ADDRESS_CONST_INT
2369+ A signed 16-bit constant address.
2370+
2371+ ADDRESS_SYMBOLIC:
2372+ A constant symbolic address. */
2373+enum riscv_address_type {
2374+ ADDRESS_REG,
2375+ ADDRESS_LO_SUM,
2376+ ADDRESS_CONST_INT,
2377+ ADDRESS_SYMBOLIC
2378+};
2379+
2380+/* Information about a function's frame layout. */
2381+struct GTY(()) riscv_frame_info {
2382+ /* The size of the frame in bytes. */
2383+ HOST_WIDE_INT total_size;
2384+
2385+ /* Bit X is set if the function saves or restores GPR X. */
2386+ unsigned int mask;
2387+
2388+ /* Likewise FPR X. */
2389+ unsigned int fmask;
2390+
2391+ /* How much the GPR save/restore routines adjust sp (or 0 if unused). */
2392+ unsigned save_libcall_adjustment;
2393+
2394+ /* Offsets of fixed-point and floating-point save areas from frame bottom */
2395+ HOST_WIDE_INT gp_sp_offset;
2396+ HOST_WIDE_INT fp_sp_offset;
2397+
2398+ /* Offset of virtual frame pointer from stack pointer/frame bottom */
2399+ HOST_WIDE_INT frame_pointer_offset;
2400+
2401+ /* Offset of hard frame pointer from stack pointer/frame bottom */
2402+ HOST_WIDE_INT hard_frame_pointer_offset;
2403+
2404+ /* The offset of arg_pointer_rtx from the bottom of the frame. */
2405+ HOST_WIDE_INT arg_pointer_offset;
2406+};
2407+
2408+struct GTY(()) machine_function {
2409+ /* The number of extra stack bytes taken up by register varargs.
2410+ This area is allocated by the callee at the very top of the frame. */
2411+ int varargs_size;
2412+
2413+ /* Memoized return value of leaf_function_p. <0 if false, >0 if true. */
2414+ int is_leaf;
2415+
2416+ /* The current frame information, calculated by riscv_compute_frame_info. */
2417+ struct riscv_frame_info frame;
2418+};
2419+
2420+/* Information about a single argument. */
2421+struct riscv_arg_info {
2422+ /* True if the argument is at least partially passed on the stack. */
2423+ bool stack_p;
2424+
2425+ /* The number of integer registers allocated to this argument. */
2426+ unsigned int num_gprs;
2427+
2428+ /* The offset of the first register used, provided num_gprs is nonzero.
2429+ If passed entirely on the stack, the value is MAX_ARGS_IN_REGISTERS. */
2430+ unsigned int gpr_offset;
2431+
2432+ /* The number of floating-point registers allocated to this argument. */
2433+ unsigned int num_fprs;
2434+
2435+ /* The offset of the first register used, provided num_fprs is nonzero. */
2436+ unsigned int fpr_offset;
2437+};
2438+
2439+/* Information about an address described by riscv_address_type.
2440+
2441+ ADDRESS_CONST_INT
2442+ No fields are used.
2443+
2444+ ADDRESS_REG
2445+ REG is the base register and OFFSET is the constant offset.
2446+
2447+ ADDRESS_LO_SUM
2448+ REG and OFFSET are the operands to the LO_SUM and SYMBOL_TYPE
2449+ is the type of symbol it references.
2450+
2451+ ADDRESS_SYMBOLIC
2452+ SYMBOL_TYPE is the type of symbol that the address references. */
2453+struct riscv_address_info {
2454+ enum riscv_address_type type;
2455+ rtx reg;
2456+ rtx offset;
2457+ enum riscv_symbol_type symbol_type;
2458+};
2459+
2460+/* One stage in a constant building sequence. These sequences have
2461+ the form:
2462+
2463+ A = VALUE[0]
2464+ A = A CODE[1] VALUE[1]
2465+ A = A CODE[2] VALUE[2]
2466+ ...
2467+
2468+ where A is an accumulator, each CODE[i] is a binary rtl operation
2469+ and each VALUE[i] is a constant integer. CODE[0] is undefined. */
2470+struct riscv_integer_op {
2471+ enum rtx_code code;
2472+ unsigned HOST_WIDE_INT value;
2473+};
2474+
2475+/* The largest number of operations needed to load an integer constant.
2476+ The worst case is LUI, ADDI, SLLI, ADDI, SLLI, ADDI, SLLI, ADDI. */
2477+#define RISCV_MAX_INTEGER_OPS 8
2478+
2479+/* Costs of various operations on the different architectures. */
2480+
2481+struct riscv_tune_info
2482+{
2483+ unsigned short fp_add[2];
2484+ unsigned short fp_mul[2];
2485+ unsigned short fp_div[2];
2486+ unsigned short int_mul[2];
2487+ unsigned short int_div[2];
2488+ unsigned short issue_rate;
2489+ unsigned short branch_cost;
2490+ unsigned short memory_cost;
2491+};
2492+
2493+/* Information about one CPU we know about. */
2494+struct riscv_cpu_info {
2495+ /* This CPU's canonical name. */
2496+ const char *name;
2497+
2498+ /* Tuning parameters for this CPU. */
2499+ const struct riscv_tune_info *tune_info;
2500+};
2501+
2502+/* Global variables for machine-dependent things. */
2503+
2504+/* Which tuning parameters to use. */
2505+static const struct riscv_tune_info *tune_info;
2506+
2507+/* Index R is the smallest register class that contains register R. */
2508+const enum reg_class riscv_regno_to_class[FIRST_PSEUDO_REGISTER] = {
2509+ GR_REGS, GR_REGS, GR_REGS, GR_REGS,
2510+ GR_REGS, GR_REGS, SIBCALL_REGS, SIBCALL_REGS,
2511+ JALR_REGS, JALR_REGS, JALR_REGS, JALR_REGS,
2512+ JALR_REGS, JALR_REGS, JALR_REGS, JALR_REGS,
2513+ JALR_REGS, JALR_REGS, JALR_REGS, JALR_REGS,
2514+ JALR_REGS, JALR_REGS, JALR_REGS, JALR_REGS,
2515+ JALR_REGS, JALR_REGS, JALR_REGS, JALR_REGS,
2516+ SIBCALL_REGS, SIBCALL_REGS, SIBCALL_REGS, SIBCALL_REGS,
2517+ FP_REGS, FP_REGS, FP_REGS, FP_REGS,
2518+ FP_REGS, FP_REGS, FP_REGS, FP_REGS,
2519+ FP_REGS, FP_REGS, FP_REGS, FP_REGS,
2520+ FP_REGS, FP_REGS, FP_REGS, FP_REGS,
2521+ FP_REGS, FP_REGS, FP_REGS, FP_REGS,
2522+ FP_REGS, FP_REGS, FP_REGS, FP_REGS,
2523+ FP_REGS, FP_REGS, FP_REGS, FP_REGS,
2524+ FP_REGS, FP_REGS, FP_REGS, FP_REGS,
2525+ FRAME_REGS, FRAME_REGS,
2526+};
2527+
2528+/* Costs to use when optimizing for rocket. */
2529+static const struct riscv_tune_info rocket_tune_info = {
2530+ {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_add */
2531+ {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_mul */
2532+ {COSTS_N_INSNS (20), COSTS_N_INSNS (20)}, /* fp_div */
2533+ {COSTS_N_INSNS (4), COSTS_N_INSNS (4)}, /* int_mul */
2534+ {COSTS_N_INSNS (6), COSTS_N_INSNS (6)}, /* int_div */
2535+ 1, /* issue_rate */
2536+ 3, /* branch_cost */
2537+ 5 /* memory_cost */
2538+};
2539+
2540+/* Costs to use when optimizing for size. */
2541+static const struct riscv_tune_info optimize_size_tune_info = {
2542+ {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* fp_add */
2543+ {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* fp_mul */
2544+ {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* fp_div */
2545+ {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* int_mul */
2546+ {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* int_div */
2547+ 1, /* issue_rate */
2548+ 1, /* branch_cost */
2549+ 2 /* memory_cost */
2550+};
2551+
2552+/* A table describing all the processors GCC knows about. */
2553+static const struct riscv_cpu_info riscv_cpu_info_table[] = {
2554+ { "rocket", &rocket_tune_info },
2555+};
2556+
2557+/* Return the riscv_cpu_info entry for the given name string. */
2558+
2559+static const struct riscv_cpu_info *
2560+riscv_parse_cpu (const char *cpu_string)
2561+{
2562+ unsigned i;
2563+ for (i = 0; i < ARRAY_SIZE (riscv_cpu_info_table); i++)
2564+ if (strcmp (riscv_cpu_info_table[i].name, cpu_string) == 0)
2565+ return riscv_cpu_info_table + i;
2566+
2567+ error ("unknown cpu %qs for -mtune", cpu_string);
2568+ return riscv_cpu_info_table;
2569+}
2570+
2571+/* Helper function for riscv_build_integer; arguments are as for
2572+ riscv_build_integer. */
2573+
2574+static int
2575+riscv_build_integer_1 (struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS],
2576+ HOST_WIDE_INT value, enum machine_mode mode)
2577+{
2578+ HOST_WIDE_INT low_part = CONST_LOW_PART (value);
2579+ int cost = RISCV_MAX_INTEGER_OPS + 1, alt_cost;
2580+ struct riscv_integer_op alt_codes[RISCV_MAX_INTEGER_OPS];
2581+
2582+ if (SMALL_OPERAND (value) || LUI_OPERAND (value))
2583+ {
2584+ /* Simply ADDI or LUI. */
2585+ codes[0].code = UNKNOWN;
2586+ codes[0].value = value;
2587+ return 1;
2588+ }
2589+
2590+ /* End with ADDI. When constructing HImode constants, do not generate any
2591+ intermediate value that is not itself a valid HImode constant. The
2592+ XORI case below will handle those remaining HImode constants. */
2593+ if (low_part != 0 && (mode != HImode || value - low_part <= INT16_MAX))
2594+ {
2595+ alt_cost = 1 + riscv_build_integer_1 (alt_codes, value - low_part, mode);
2596+ if (alt_cost < cost)
2597+ {
2598+ alt_codes[alt_cost-1].code = PLUS;
2599+ alt_codes[alt_cost-1].value = low_part;
2600+ memcpy (codes, alt_codes, sizeof (alt_codes));
2601+ cost = alt_cost;
2602+ }
2603+ }
2604+
2605+ /* End with XORI. */
2606+ if (cost > 2 && (low_part < 0 || mode == HImode))
2607+ {
2608+ alt_cost = 1 + riscv_build_integer_1 (alt_codes, value ^ low_part, mode);
2609+ if (alt_cost < cost)
2610+ {
2611+ alt_codes[alt_cost-1].code = XOR;
2612+ alt_codes[alt_cost-1].value = low_part;
2613+ memcpy (codes, alt_codes, sizeof (alt_codes));
2614+ cost = alt_cost;
2615+ }
2616+ }
2617+
2618+ /* Eliminate trailing zeros and end with SLLI. */
2619+ if (cost > 2 && (value & 1) == 0)
2620+ {
2621+ int shift = ctz_hwi (value);
2622+ unsigned HOST_WIDE_INT x = value;
2623+ x = sext_hwi (x >> shift, HOST_BITS_PER_WIDE_INT - shift);
2624+
2625+ /* Don't eliminate the lower 12 bits if LUI might apply. */
2626+ if (shift > IMM_BITS && !SMALL_OPERAND (x) && LUI_OPERAND (x << IMM_BITS))
2627+ shift -= IMM_BITS, x <<= IMM_BITS;
2628+
2629+ alt_cost = 1 + riscv_build_integer_1 (alt_codes, x, mode);
2630+ if (alt_cost < cost)
2631+ {
2632+ alt_codes[alt_cost-1].code = ASHIFT;
2633+ alt_codes[alt_cost-1].value = shift;
2634+ memcpy (codes, alt_codes, sizeof (alt_codes));
2635+ cost = alt_cost;
2636+ }
2637+ }
2638+
2639+ gcc_assert (cost <= RISCV_MAX_INTEGER_OPS);
2640+ return cost;
2641+}
2642+
2643+/* Fill CODES with a sequence of rtl operations to load VALUE.
2644+ Return the number of operations needed. */
2645+
2646+static int
2647+riscv_build_integer (struct riscv_integer_op *codes, HOST_WIDE_INT value,
2648+ enum machine_mode mode)
2649+{
2650+ int cost = riscv_build_integer_1 (codes, value, mode);
2651+
2652+ /* Eliminate leading zeros and end with SRLI. */
2653+ if (value > 0 && cost > 2)
2654+ {
2655+ struct riscv_integer_op alt_codes[RISCV_MAX_INTEGER_OPS];
2656+ int alt_cost, shift = clz_hwi (value);
2657+ HOST_WIDE_INT shifted_val;
2658+
2659+ /* Try filling trailing bits with 1s. */
2660+ shifted_val = (value << shift) | ((((HOST_WIDE_INT) 1) << shift) - 1);
2661+ alt_cost = 1 + riscv_build_integer_1 (alt_codes, shifted_val, mode);
2662+ if (alt_cost < cost)
2663+ {
2664+ alt_codes[alt_cost-1].code = LSHIFTRT;
2665+ alt_codes[alt_cost-1].value = shift;
2666+ memcpy (codes, alt_codes, sizeof (alt_codes));
2667+ cost = alt_cost;
2668+ }
2669+
2670+ /* Try filling trailing bits with 0s. */
2671+ shifted_val = value << shift;
2672+ alt_cost = 1 + riscv_build_integer_1 (alt_codes, shifted_val, mode);
2673+ if (alt_cost < cost)
2674+ {
2675+ alt_codes[alt_cost-1].code = LSHIFTRT;
2676+ alt_codes[alt_cost-1].value = shift;
2677+ memcpy (codes, alt_codes, sizeof (alt_codes));
2678+ cost = alt_cost;
2679+ }
2680+ }
2681+
2682+ return cost;
2683+}
2684+
2685+/* Return the cost of constructing VAL in the event that a scratch
2686+ register is available. */
2687+
2688+static int
2689+riscv_split_integer_cost (HOST_WIDE_INT val)
2690+{
2691+ int cost;
2692+ unsigned HOST_WIDE_INT loval = sext_hwi (val, 32);
2693+ unsigned HOST_WIDE_INT hival = sext_hwi ((val - loval) >> 32, 32);
2694+ struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS];
2695+
2696+ cost = 2 + riscv_build_integer (codes, loval, VOIDmode);
2697+ if (loval != hival)
2698+ cost += riscv_build_integer (codes, hival, VOIDmode);
2699+
2700+ return cost;
2701+}
2702+
2703+/* Return the cost of constructing the integer constant VAL. */
2704+
2705+static int
2706+riscv_integer_cost (HOST_WIDE_INT val)
2707+{
2708+ struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS];
2709+ return MIN (riscv_build_integer (codes, val, VOIDmode),
2710+ riscv_split_integer_cost (val));
2711+}
2712+
2713+/* Try to split a 64b integer into 32b parts, then reassemble. */
2714+
2715+static rtx
2716+riscv_split_integer (HOST_WIDE_INT val, enum machine_mode mode)
2717+{
2718+ unsigned HOST_WIDE_INT loval = sext_hwi (val, 32);
2719+ unsigned HOST_WIDE_INT hival = sext_hwi ((val - loval) >> 32, 32);
2720+ rtx hi = gen_reg_rtx (mode), lo = gen_reg_rtx (mode);
2721+
2722+ riscv_move_integer (hi, hi, hival);
2723+ riscv_move_integer (lo, lo, loval);
2724+
2725+ hi = gen_rtx_fmt_ee (ASHIFT, mode, hi, GEN_INT (32));
2726+ hi = force_reg (mode, hi);
2727+
2728+ return gen_rtx_fmt_ee (PLUS, mode, hi, lo);
2729+}
2730+
2731+/* Return true if X is a thread-local symbol. */
2732+
2733+static bool
2734+riscv_tls_symbol_p (const_rtx x)
2735+{
2736+ return SYMBOL_REF_P (x) && SYMBOL_REF_TLS_MODEL (x) != 0;
2737+}
2738+
2739+static int
2740+riscv_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
2741+{
2742+ return riscv_tls_symbol_p (*x);
2743+}
2744+
2745+/* Return true if symbol X binds locally. */
2746+static bool
2747+riscv_symbol_binds_local_p (const_rtx x)
2748+{
2749+ if (SYMBOL_REF_P (x))
2750+ return (SYMBOL_REF_DECL (x)
2751+ ? targetm.binds_local_p (SYMBOL_REF_DECL (x))
2752+ : SYMBOL_REF_LOCAL_P (x));
2753+ else
2754+ return false;
2755+}
2756+
2757+/* Return the method that should be used to access SYMBOL_REF or
2758+ LABEL_REF X. */
2759+
2760+static enum riscv_symbol_type
2761+riscv_classify_symbol (const_rtx x)
2762+{
2763+ if (riscv_tls_symbol_p (x))
2764+ return SYMBOL_TLS;
2765+
2766+ if (GET_CODE (x) == SYMBOL_REF && flag_pic && !riscv_symbol_binds_local_p (x))
2767+ return SYMBOL_GOT_DISP;
2768+
2769+ return riscv_cmodel == CM_MEDLOW ? SYMBOL_ABSOLUTE : SYMBOL_PCREL;
2770+}
2771+
2772+/* Classify the base of symbolic expression X. */
2773+
2774+enum riscv_symbol_type
2775+riscv_classify_symbolic_expression (rtx x)
2776+{
2777+ rtx offset;
2778+
2779+ split_const (x, &x, &offset);
2780+ if (UNSPEC_ADDRESS_P (x))
2781+ return UNSPEC_ADDRESS_TYPE (x);
2782+
2783+ return riscv_classify_symbol (x);
2784+}
2785+
2786+/* Return true if X is a symbolic constant. If it is, store the type of
2787+ the symbol in *SYMBOL_TYPE. */
2788+
2789+bool
2790+riscv_symbolic_constant_p (rtx x, enum riscv_symbol_type *symbol_type)
2791+{
2792+ rtx offset;
2793+
2794+ split_const (x, &x, &offset);
2795+ if (UNSPEC_ADDRESS_P (x))
2796+ {
2797+ *symbol_type = UNSPEC_ADDRESS_TYPE (x);
2798+ x = UNSPEC_ADDRESS (x);
2799+ }
2800+ else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)
2801+ *symbol_type = riscv_classify_symbol (x);
2802+ else
2803+ return false;
2804+
2805+ if (offset == const0_rtx)
2806+ return true;
2807+
2808+ /* Nonzero offsets are only valid for references that don't use the GOT. */
2809+ switch (*symbol_type)
2810+ {
2811+ case SYMBOL_ABSOLUTE:
2812+ case SYMBOL_PCREL:
2813+ case SYMBOL_TLS_LE:
2814+ /* GAS rejects offsets outside the range [-2^31, 2^31-1]. */
2815+ return sext_hwi (INTVAL (offset), 32) == INTVAL (offset);
2816+
2817+ default:
2818+ return false;
2819+ }
2820+}
2821+
2822+/* Returns the number of instructions necessary to reference a symbol. */
2823+
2824+static int riscv_symbol_insns (enum riscv_symbol_type type)
2825+{
2826+ switch (type)
2827+ {
2828+ case SYMBOL_TLS: return 0; /* Depends on the TLS model. */
2829+ case SYMBOL_ABSOLUTE: return 2; /* LUI + the reference. */
2830+ case SYMBOL_PCREL: return 2; /* AUIPC + the reference. */
2831+ case SYMBOL_TLS_LE: return 3; /* LUI + ADD TP + the reference. */
2832+ case SYMBOL_GOT_DISP: return 3; /* AUIPC + LD GOT + the reference. */
2833+ default: gcc_unreachable ();
2834+ }
2835+}
2836+
2837+/* Implement TARGET_LEGITIMATE_CONSTANT_P. */
2838+
2839+static bool
2840+riscv_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
2841+{
2842+ return riscv_const_insns (x) > 0;
2843+}
2844+
2845+/* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
2846+
2847+static bool
2848+riscv_cannot_force_const_mem (rtx x)
2849+{
2850+ enum riscv_symbol_type type;
2851+ rtx base, offset;
2852+
2853+ /* There is no assembler syntax for expressing an address-sized
2854+ high part. */
2855+ if (GET_CODE (x) == HIGH)
2856+ return true;
2857+
2858+ split_const (x, &base, &offset);
2859+ if (riscv_symbolic_constant_p (base, &type))
2860+ {
2861+ /* As an optimization, don't spill symbolic constants that are as
2862+ cheap to rematerialize as to access in the constant pool. */
2863+ if (SMALL_OPERAND (INTVAL (offset)) && riscv_symbol_insns (type) > 0)
2864+ return true;
2865+
2866+ /* As an optimization, avoid needlessly generate dynamic relocations. */
2867+ if (flag_pic)
2868+ return true;
2869+ }
2870+
2871+ /* TLS symbols must be computed by riscv_legitimize_move. */
2872+ if (for_each_rtx (&x, &riscv_tls_symbol_ref_1, NULL))
2873+ return true;
2874+
2875+ return false;
2876+}
2877+
2878+/* Return true if register REGNO is a valid base register for mode MODE.
2879+ STRICT_P is true if REG_OK_STRICT is in effect. */
2880+
2881+int
2882+riscv_regno_mode_ok_for_base_p (int regno,
2883+ enum machine_mode mode ATTRIBUTE_UNUSED,
2884+ bool strict_p)
2885+{
2886+ if (!HARD_REGISTER_NUM_P (regno))
2887+ {
2888+ if (!strict_p)
2889+ return true;
2890+ regno = reg_renumber[regno];
2891+ }
2892+
2893+ /* These fake registers will be eliminated to either the stack or
2894+ hard frame pointer, both of which are usually valid base registers.
2895+ Reload deals with the cases where the eliminated form isn't valid. */
2896+ if (regno == ARG_POINTER_REGNUM || regno == FRAME_POINTER_REGNUM)
2897+ return true;
2898+
2899+ return GP_REG_P (regno);
2900+}
2901+
2902+/* Return true if X is a valid base register for mode MODE.
2903+ STRICT_P is true if REG_OK_STRICT is in effect. */
2904+
2905+static bool
2906+riscv_valid_base_register_p (rtx x, enum machine_mode mode, bool strict_p)
2907+{
2908+ if (!strict_p && GET_CODE (x) == SUBREG)
2909+ x = SUBREG_REG (x);
2910+
2911+ return (REG_P (x)
2912+ && riscv_regno_mode_ok_for_base_p (REGNO (x), mode, strict_p));
2913+}
2914+
2915+/* Return true if, for every base register BASE_REG, (plus BASE_REG X)
2916+ can address a value of mode MODE. */
2917+
2918+static bool
2919+riscv_valid_offset_p (rtx x, enum machine_mode mode)
2920+{
2921+ /* Check that X is a signed 12-bit number. */
2922+ if (!const_arith_operand (x, Pmode))
2923+ return false;
2924+
2925+ /* We may need to split multiword moves, so make sure that every word
2926+ is accessible. */
2927+ if (GET_MODE_SIZE (mode) > UNITS_PER_WORD
2928+ && !SMALL_OPERAND (INTVAL (x) + GET_MODE_SIZE (mode) - UNITS_PER_WORD))
2929+ return false;
2930+
2931+ return true;
2932+}
2933+
2934+/* Should a symbol of type SYMBOL_TYPE should be split in two? */
2935+
2936+bool
2937+riscv_split_symbol_type (enum riscv_symbol_type symbol_type)
2938+{
2939+ if (symbol_type == SYMBOL_TLS_LE)
2940+ return true;
2941+
2942+ if (!TARGET_EXPLICIT_RELOCS)
2943+ return false;
2944+
2945+ return symbol_type == SYMBOL_ABSOLUTE || symbol_type == SYMBOL_PCREL;
2946+}
2947+
2948+/* Return true if a LO_SUM can address a value of mode MODE when the
2949+ LO_SUM symbol has type SYM_TYPE. */
2950+
2951+static bool
2952+riscv_valid_lo_sum_p (enum riscv_symbol_type sym_type, enum machine_mode mode)
2953+{
2954+ /* Check that symbols of type SYMBOL_TYPE can be used to access values
2955+ of mode MODE. */
2956+ if (riscv_symbol_insns (sym_type) == 0)
2957+ return false;
2958+
2959+ /* Check that there is a known low-part relocation. */
2960+ if (!riscv_split_symbol_type (sym_type))
2961+ return false;
2962+
2963+ /* We may need to split multiword moves, so make sure that each word
2964+ can be accessed without inducing a carry. */
2965+ if (GET_MODE_SIZE (mode) > UNITS_PER_WORD
2966+ && GET_MODE_BITSIZE (mode) > GET_MODE_ALIGNMENT (mode))
2967+ return false;
2968+
2969+ return true;
2970+}
2971+
2972+/* Return true if X is a valid address for machine mode MODE. If it is,
2973+ fill in INFO appropriately. STRICT_P is true if REG_OK_STRICT is in
2974+ effect. */
2975+
2976+static bool
2977+riscv_classify_address (struct riscv_address_info *info, rtx x,
2978+ enum machine_mode mode, bool strict_p)
2979+{
2980+ switch (GET_CODE (x))
2981+ {
2982+ case REG:
2983+ case SUBREG:
2984+ info->type = ADDRESS_REG;
2985+ info->reg = x;
2986+ info->offset = const0_rtx;
2987+ return riscv_valid_base_register_p (info->reg, mode, strict_p);
2988+
2989+ case PLUS:
2990+ info->type = ADDRESS_REG;
2991+ info->reg = XEXP (x, 0);
2992+ info->offset = XEXP (x, 1);
2993+ return (riscv_valid_base_register_p (info->reg, mode, strict_p)
2994+ && riscv_valid_offset_p (info->offset, mode));
2995+
2996+ case LO_SUM:
2997+ info->type = ADDRESS_LO_SUM;
2998+ info->reg = XEXP (x, 0);
2999+ info->offset = XEXP (x, 1);
3000+ /* We have to trust the creator of the LO_SUM to do something vaguely
3001+ sane. Target-independent code that creates a LO_SUM should also
3002+ create and verify the matching HIGH. Target-independent code that
3003+ adds an offset to a LO_SUM must prove that the offset will not
3004+ induce a carry. Failure to do either of these things would be
3005+ a bug, and we are not required to check for it here. The RISC-V
3006+ backend itself should only create LO_SUMs for valid symbolic
3007+ constants, with the high part being either a HIGH or a copy
3008+ of _gp. */
3009+ info->symbol_type
3010+ = riscv_classify_symbolic_expression (info->offset);
3011+ return (riscv_valid_base_register_p (info->reg, mode, strict_p)
3012+ && riscv_valid_lo_sum_p (info->symbol_type, mode));
3013+
3014+ case CONST_INT:
3015+ /* Small-integer addresses don't occur very often, but they
3016+ are legitimate if x0 is a valid base register. */
3017+ info->type = ADDRESS_CONST_INT;
3018+ return SMALL_OPERAND (INTVAL (x));
3019+
3020+ default:
3021+ return false;
3022+ }
3023+}
3024+
3025+/* Implement TARGET_LEGITIMATE_ADDRESS_P. */
3026+
3027+static bool
3028+riscv_legitimate_address_p (enum machine_mode mode, rtx x, bool strict_p)
3029+{
3030+ struct riscv_address_info addr;
3031+
3032+ return riscv_classify_address (&addr, x, mode, strict_p);
3033+}
3034+
3035+/* Return the number of instructions needed to load or store a value
3036+ of mode MODE at address X. Return 0 if X isn't valid for MODE.
3037+ Assume that multiword moves may need to be split into word moves
3038+ if MIGHT_SPLIT_P, otherwise assume that a single load or store is
3039+ enough. */
3040+
3041+int
3042+riscv_address_insns (rtx x, enum machine_mode mode, bool might_split_p)
3043+{
3044+ struct riscv_address_info addr;
3045+ int n = 1;
3046+
3047+ if (!riscv_classify_address (&addr, x, mode, false))
3048+ return 0;
3049+
3050+ /* BLKmode is used for single unaligned loads and stores and should
3051+ not count as a multiword mode. */
3052+ if (mode != BLKmode && might_split_p)
3053+ n += (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
3054+
3055+ if (addr.type == ADDRESS_LO_SUM)
3056+ n += riscv_symbol_insns (addr.symbol_type) - 1;
3057+
3058+ return n;
3059+}
3060+
3061+/* Return the number of instructions needed to load constant X.
3062+ Return 0 if X isn't a valid constant. */
3063+
3064+int
3065+riscv_const_insns (rtx x)
3066+{
3067+ enum riscv_symbol_type symbol_type;
3068+ rtx offset;
3069+
3070+ switch (GET_CODE (x))
3071+ {
3072+ case HIGH:
3073+ if (!riscv_symbolic_constant_p (XEXP (x, 0), &symbol_type)
3074+ || !riscv_split_symbol_type (symbol_type))
3075+ return 0;
3076+
3077+ /* This is simply an LUI. */
3078+ return 1;
3079+
3080+ case CONST_INT:
3081+ {
3082+ int cost = riscv_integer_cost (INTVAL (x));
3083+ /* Force complicated constants to memory. */
3084+ return cost < 4 ? cost : 0;
3085+ }
3086+
3087+ case CONST_DOUBLE:
3088+ case CONST_VECTOR:
3089+ /* We can use x0 to load floating-point zero. */
3090+ return x == CONST0_RTX (GET_MODE (x)) ? 1 : 0;
3091+
3092+ case CONST:
3093+ /* See if we can refer to X directly. */
3094+ if (riscv_symbolic_constant_p (x, &symbol_type))
3095+ return riscv_symbol_insns (symbol_type);
3096+
3097+ /* Otherwise try splitting the constant into a base and offset. */
3098+ split_const (x, &x, &offset);
3099+ if (offset != 0)
3100+ {
3101+ int n = riscv_const_insns (x);
3102+ if (n != 0)
3103+ return n + riscv_integer_cost (INTVAL (offset));
3104+ }
3105+ return 0;
3106+
3107+ case SYMBOL_REF:
3108+ case LABEL_REF:
3109+ return riscv_symbol_insns (riscv_classify_symbol (x));
3110+
3111+ default:
3112+ return 0;
3113+ }
3114+}
3115+
3116+/* X is a doubleword constant that can be handled by splitting it into
3117+ two words and loading each word separately. Return the number of
3118+ instructions required to do this. */
3119+
3120+int
3121+riscv_split_const_insns (rtx x)
3122+{
3123+ unsigned int low, high;
3124+
3125+ low = riscv_const_insns (riscv_subword (x, false));
3126+ high = riscv_const_insns (riscv_subword (x, true));
3127+ gcc_assert (low > 0 && high > 0);
3128+ return low + high;
3129+}
3130+
3131+/* Return the number of instructions needed to implement INSN,
3132+ given that it loads from or stores to MEM. */
3133+
3134+int
3135+riscv_load_store_insns (rtx mem, rtx insn)
3136+{
3137+ enum machine_mode mode;
3138+ bool might_split_p;
3139+ rtx set;
3140+
3141+ gcc_assert (MEM_P (mem));
3142+ mode = GET_MODE (mem);
3143+
3144+ /* Try to prove that INSN does not need to be split. */
3145+ might_split_p = true;
3146+ if (GET_MODE_BITSIZE (mode) <= 32)
3147+ might_split_p = false;
3148+ else if (GET_MODE_BITSIZE (mode) == 64)
3149+ {
3150+ set = single_set (insn);
3151+ if (set && !riscv_split_64bit_move_p (SET_DEST (set), SET_SRC (set)))
3152+ might_split_p = false;
3153+ }
3154+
3155+ return riscv_address_insns (XEXP (mem, 0), mode, might_split_p);
3156+}
3157+
3158+/* Emit a move from SRC to DEST. Assume that the move expanders can
3159+ handle all moves if !can_create_pseudo_p (). The distinction is
3160+ important because, unlike emit_move_insn, the move expanders know
3161+ how to force Pmode objects into the constant pool even when the
3162+ constant pool address is not itself legitimate. */
3163+
3164+rtx
3165+riscv_emit_move (rtx dest, rtx src)
3166+{
3167+ return (can_create_pseudo_p ()
3168+ ? emit_move_insn (dest, src)
3169+ : emit_move_insn_1 (dest, src));
3170+}
3171+
3172+/* Emit an instruction of the form (set TARGET SRC). */
3173+
3174+static rtx
3175+riscv_emit_set (rtx target, rtx src)
3176+{
3177+ emit_insn (gen_rtx_SET (VOIDmode, target, src));
3178+ return target;
3179+}
3180+
3181+/* Emit an instruction of the form (set DEST (CODE X Y)). */
3182+
3183+static rtx
3184+riscv_emit_binary (enum rtx_code code, rtx dest, rtx x, rtx y)
3185+{
3186+ return riscv_emit_set (dest, gen_rtx_fmt_ee (code, GET_MODE (dest), x, y));
3187+}
3188+
3189+/* Compute (CODE X Y) and store the result in a new register
3190+ of mode MODE. Return that new register. */
3191+
3192+static rtx
3193+riscv_force_binary (enum machine_mode mode, enum rtx_code code, rtx x, rtx y)
3194+{
3195+ return riscv_emit_binary (code, gen_reg_rtx (mode), x, y);
3196+}
3197+
3198+/* Copy VALUE to a register and return that register. If new pseudos
3199+ are allowed, copy it into a new register, otherwise use DEST. */
3200+
3201+static rtx
3202+riscv_force_temporary (rtx dest, rtx value)
3203+{
3204+ if (can_create_pseudo_p ())
3205+ return force_reg (Pmode, value);
3206+ else
3207+ {
3208+ riscv_emit_move (dest, value);
3209+ return dest;
3210+ }
3211+}
3212+
3213+/* Wrap symbol or label BASE in an UNSPEC address of type SYMBOL_TYPE,
3214+ then add CONST_INT OFFSET to the result. */
3215+
3216+static rtx
3217+riscv_unspec_address_offset (rtx base, rtx offset,
3218+ enum riscv_symbol_type symbol_type)
3219+{
3220+ base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base),
3221+ UNSPEC_ADDRESS_FIRST + symbol_type);
3222+ if (offset != const0_rtx)
3223+ base = gen_rtx_PLUS (Pmode, base, offset);
3224+ return gen_rtx_CONST (Pmode, base);
3225+}
3226+
3227+/* Return an UNSPEC address with underlying address ADDRESS and symbol
3228+ type SYMBOL_TYPE. */
3229+
3230+rtx
3231+riscv_unspec_address (rtx address, enum riscv_symbol_type symbol_type)
3232+{
3233+ rtx base, offset;
3234+
3235+ split_const (address, &base, &offset);
3236+ return riscv_unspec_address_offset (base, offset, symbol_type);
3237+}
3238+
3239+/* If OP is an UNSPEC address, return the address to which it refers,
3240+ otherwise return OP itself. */
3241+
3242+static rtx
3243+riscv_strip_unspec_address (rtx op)
3244+{
3245+ rtx base, offset;
3246+
3247+ split_const (op, &base, &offset);
3248+ if (UNSPEC_ADDRESS_P (base))
3249+ op = plus_constant (UNSPEC_ADDRESS (base), INTVAL (offset));
3250+ return op;
3251+}
3252+
3253+/* If riscv_unspec_address (ADDR, SYMBOL_TYPE) is a 32-bit value, add the
3254+ high part to BASE and return the result. Just return BASE otherwise.
3255+ TEMP is as for riscv_force_temporary.
3256+
3257+ The returned expression can be used as the first operand to a LO_SUM. */
3258+
3259+static rtx
3260+riscv_unspec_offset_high (rtx temp, rtx addr, enum riscv_symbol_type symbol_type)
3261+{
3262+ addr = gen_rtx_HIGH (Pmode, riscv_unspec_address (addr, symbol_type));
3263+ return riscv_force_temporary (temp, addr);
3264+}
3265+
3266+/* Load an entry from the GOT for a TLS GD access. */
3267+
3268+static rtx riscv_got_load_tls_gd (rtx dest, rtx sym)
3269+{
3270+ if (Pmode == DImode)
3271+ return gen_got_load_tls_gddi (dest, sym);
3272+ else
3273+ return gen_got_load_tls_gdsi (dest, sym);
3274+}
3275+
3276+/* Load an entry from the GOT for a TLS IE access. */
3277+
3278+static rtx riscv_got_load_tls_ie (rtx dest, rtx sym)
3279+{
3280+ if (Pmode == DImode)
3281+ return gen_got_load_tls_iedi (dest, sym);
3282+ else
3283+ return gen_got_load_tls_iesi (dest, sym);
3284+}
3285+
3286+/* Add in the thread pointer for a TLS LE access. */
3287+
3288+static rtx riscv_tls_add_tp_le (rtx dest, rtx base, rtx sym)
3289+{
3290+ rtx tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
3291+ if (Pmode == DImode)
3292+ return gen_tls_add_tp_ledi (dest, base, tp, sym);
3293+ else
3294+ return gen_tls_add_tp_lesi (dest, base, tp, sym);
3295+}
3296+
3297+/* If MODE is MAX_MACHINE_MODE, ADDR appears as a move operand, otherwise
3298+ it appears in a MEM of that mode. Return true if ADDR is a legitimate
3299+ constant in that context and can be split into high and low parts.
3300+ If so, and if LOW_OUT is nonnull, emit the high part and store the
3301+ low part in *LOW_OUT. Leave *LOW_OUT unchanged otherwise.
3302+
3303+ TEMP is as for riscv_force_temporary and is used to load the high
3304+ part into a register.
3305+
3306+ When MODE is MAX_MACHINE_MODE, the low part is guaranteed to be
3307+ a legitimize SET_SRC for an .md pattern, otherwise the low part
3308+ is guaranteed to be a legitimate address for mode MODE. */
3309+
3310+bool
3311+riscv_split_symbol (rtx temp, rtx addr, enum machine_mode mode, rtx *low_out)
3312+{
3313+ enum riscv_symbol_type symbol_type;
3314+
3315+ if ((GET_CODE (addr) == HIGH && mode == MAX_MACHINE_MODE)
3316+ || !riscv_symbolic_constant_p (addr, &symbol_type)
3317+ || riscv_symbol_insns (symbol_type) == 0
3318+ || !riscv_split_symbol_type (symbol_type))
3319+ return false;
3320+
3321+ if (low_out)
3322+ switch (symbol_type)
3323+ {
3324+ case SYMBOL_ABSOLUTE:
3325+ {
3326+ rtx high = gen_rtx_HIGH (Pmode, copy_rtx (addr));
3327+ high = riscv_force_temporary (temp, high);
3328+ *low_out = gen_rtx_LO_SUM (Pmode, high, addr);
3329+ }
3330+ break;
3331+
3332+ case SYMBOL_PCREL:
3333+ {
3334+ static unsigned seqno;
3335+ char buf[32];
3336+ rtx label;
3337+
3338+ ssize_t bytes = snprintf (buf, sizeof (buf), ".LA%u", seqno);
3339+ gcc_assert ((size_t) bytes < sizeof (buf));
3340+
3341+ label = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
3342+ SYMBOL_REF_FLAGS (label) |= SYMBOL_FLAG_LOCAL;
3343+
3344+ if (temp == NULL)
3345+ temp = gen_reg_rtx (Pmode);
3346+
3347+ if (Pmode == DImode)
3348+ emit_insn (gen_auipcdi (temp, copy_rtx (addr), GEN_INT (seqno)));
3349+ else
3350+ emit_insn (gen_auipcsi (temp, copy_rtx (addr), GEN_INT (seqno)));
3351+
3352+ *low_out = gen_rtx_LO_SUM (Pmode, temp, label);
3353+
3354+ seqno++;
3355+ }
3356+ break;
3357+
3358+ default:
3359+ gcc_unreachable ();
3360+ }
3361+
3362+ return true;
3363+}
3364+
3365+/* Return a legitimate address for REG + OFFSET. TEMP is as for
3366+ riscv_force_temporary; it is only needed when OFFSET is not a
3367+ SMALL_OPERAND. */
3368+
3369+static rtx
3370+riscv_add_offset (rtx temp, rtx reg, HOST_WIDE_INT offset)
3371+{
3372+ if (!SMALL_OPERAND (offset))
3373+ {
3374+ rtx high;
3375+
3376+ /* Leave OFFSET as a 16-bit offset and put the excess in HIGH.
3377+ The addition inside the macro CONST_HIGH_PART may cause an
3378+ overflow, so we need to force a sign-extension check. */
3379+ high = gen_int_mode (CONST_HIGH_PART (offset), Pmode);
3380+ offset = CONST_LOW_PART (offset);
3381+ high = riscv_force_temporary (temp, high);
3382+ reg = riscv_force_temporary (temp, gen_rtx_PLUS (Pmode, high, reg));
3383+ }
3384+ return plus_constant (reg, offset);
3385+}
3386+
3387+/* The __tls_get_attr symbol. */
3388+static GTY(()) rtx riscv_tls_symbol;
3389+
3390+/* Return an instruction sequence that calls __tls_get_addr. SYM is
3391+ the TLS symbol we are referencing and TYPE is the symbol type to use
3392+ (either global dynamic or local dynamic). RESULT is an RTX for the
3393+ return value location. */
3394+
3395+static rtx
3396+riscv_call_tls_get_addr (rtx sym, rtx result)
3397+{
3398+ rtx a0 = gen_rtx_REG (Pmode, GP_ARG_FIRST), func;
3399+ rtx insn;
3400+
3401+ if (!riscv_tls_symbol)
3402+ riscv_tls_symbol = init_one_libfunc ("__tls_get_addr");
3403+ func = gen_rtx_MEM (FUNCTION_MODE, riscv_tls_symbol);
3404+
3405+ start_sequence ();
3406+
3407+ emit_insn (riscv_got_load_tls_gd (a0, sym));
3408+ insn = emit_call_insn (gen_call_value (result, func, const0_rtx, NULL));
3409+ RTL_CONST_CALL_P (insn) = 1;
3410+ use_reg (&CALL_INSN_FUNCTION_USAGE (insn), a0);
3411+ insn = get_insns ();
3412+
3413+ end_sequence ();
3414+
3415+ return insn;
3416+}
3417+
3418+/* Generate the code to access LOC, a thread-local SYMBOL_REF, and return
3419+ its address. The return value will be both a valid address and a valid
3420+ SET_SRC (either a REG or a LO_SUM). */
3421+
3422+static rtx
3423+riscv_legitimize_tls_address (rtx loc)
3424+{
3425+ rtx dest, tp, tmp;
3426+ enum tls_model model = SYMBOL_REF_TLS_MODEL (loc);
3427+
3428+ /* Since we support TLS copy relocs, non-PIC TLS accesses may all use LE. */
3429+ if (!flag_pic)
3430+ model = TLS_MODEL_LOCAL_EXEC;
3431+
3432+ switch (model)
3433+ {
3434+ case TLS_MODEL_LOCAL_DYNAMIC:
3435+ /* Rely on section anchors for the optimization that LDM TLS
3436+ provides. The anchor's address is loaded with GD TLS. */
3437+ case TLS_MODEL_GLOBAL_DYNAMIC:
3438+ tmp = gen_rtx_REG (Pmode, GP_RETURN);
3439+ dest = gen_reg_rtx (Pmode);
3440+ emit_libcall_block (riscv_call_tls_get_addr (loc, tmp), dest, tmp, loc);
3441+ break;
3442+
3443+ case TLS_MODEL_INITIAL_EXEC:
3444+ /* la.tls.ie; tp-relative add */
3445+ tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
3446+ tmp = gen_reg_rtx (Pmode);
3447+ emit_insn (riscv_got_load_tls_ie (tmp, loc));
3448+ dest = gen_reg_rtx (Pmode);
3449+ emit_insn (gen_add3_insn (dest, tmp, tp));
3450+ break;
3451+
3452+ case TLS_MODEL_LOCAL_EXEC:
3453+ tmp = riscv_unspec_offset_high (NULL, loc, SYMBOL_TLS_LE);
3454+ dest = gen_reg_rtx (Pmode);
3455+ emit_insn (riscv_tls_add_tp_le (dest, tmp, loc));
3456+ dest = gen_rtx_LO_SUM (Pmode, dest,
3457+ riscv_unspec_address (loc, SYMBOL_TLS_LE));
3458+ break;
3459+
3460+ default:
3461+ gcc_unreachable ();
3462+ }
3463+ return dest;
3464+}
3465+
3466+/* If X is not a valid address for mode MODE, force it into a register. */
3467+
3468+static rtx
3469+riscv_force_address (rtx x, enum machine_mode mode)
3470+{
3471+ if (!riscv_legitimate_address_p (mode, x, false))
3472+ x = force_reg (Pmode, x);
3473+ return x;
3474+}
3475+
3476+/* This function is used to implement LEGITIMIZE_ADDRESS. If X can
3477+ be legitimized in a way that the generic machinery might not expect,
3478+ return a new address, otherwise return NULL. MODE is the mode of
3479+ the memory being accessed. */
3480+
3481+static rtx
3482+riscv_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
3483+ enum machine_mode mode)
3484+{
3485+ rtx addr;
3486+
3487+ if (riscv_tls_symbol_p (x))
3488+ return riscv_legitimize_tls_address (x);
3489+
3490+ /* See if the address can split into a high part and a LO_SUM. */
3491+ if (riscv_split_symbol (NULL, x, mode, &addr))
3492+ return riscv_force_address (addr, mode);
3493+
3494+ /* Handle BASE + OFFSET using riscv_add_offset. */
3495+ if (GET_CODE (x) == PLUS && CONST_INT_P (XEXP (x, 1))
3496+ && INTVAL (XEXP (x, 1)) != 0)
3497+ {
3498+ rtx base = XEXP (x, 0);
3499+ HOST_WIDE_INT offset = INTVAL (XEXP (x, 1));
3500+
3501+ if (!riscv_valid_base_register_p (base, mode, false))
3502+ base = copy_to_mode_reg (Pmode, base);
3503+ addr = riscv_add_offset (NULL, base, offset);
3504+ return riscv_force_address (addr, mode);
3505+ }
3506+
3507+ return x;
3508+}
3509+
3510+/* Load VALUE into DEST. TEMP is as for riscv_force_temporary. */
3511+
3512+void
3513+riscv_move_integer (rtx temp, rtx dest, HOST_WIDE_INT value)
3514+{
3515+ struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS];
3516+ enum machine_mode mode;
3517+ int i, num_ops;
3518+ rtx x;
3519+
3520+ mode = GET_MODE (dest);
3521+ num_ops = riscv_build_integer (codes, value, mode);
3522+
3523+ if (can_create_pseudo_p () && num_ops > 2 /* not a simple constant */
3524+ && num_ops >= riscv_split_integer_cost (value))
3525+ x = riscv_split_integer (value, mode);
3526+ else
3527+ {
3528+ /* Apply each binary operation to X. */
3529+ x = GEN_INT (codes[0].value);
3530+
3531+ for (i = 1; i < num_ops; i++)
3532+ {
3533+ if (!can_create_pseudo_p ())
3534+ x = riscv_emit_set (temp, x);
3535+ else
3536+ x = force_reg (mode, x);
3537+
3538+ x = gen_rtx_fmt_ee (codes[i].code, mode, x, GEN_INT (codes[i].value));
3539+ }
3540+ }
3541+
3542+ riscv_emit_set (dest, x);
3543+}
3544+
3545+/* Subroutine of riscv_legitimize_move. Move constant SRC into register
3546+ DEST given that SRC satisfies immediate_operand but doesn't satisfy
3547+ move_operand. */
3548+
3549+static void
3550+riscv_legitimize_const_move (enum machine_mode mode, rtx dest, rtx src)
3551+{
3552+ rtx base, offset;
3553+
3554+ /* Split moves of big integers into smaller pieces. */
3555+ if (splittable_const_int_operand (src, mode))
3556+ {
3557+ riscv_move_integer (dest, dest, INTVAL (src));
3558+ return;
3559+ }
3560+
3561+ /* Split moves of symbolic constants into high/low pairs. */
3562+ if (riscv_split_symbol (dest, src, MAX_MACHINE_MODE, &src))
3563+ {
3564+ riscv_emit_set (dest, src);
3565+ return;
3566+ }
3567+
3568+ /* Generate the appropriate access sequences for TLS symbols. */
3569+ if (riscv_tls_symbol_p (src))
3570+ {
3571+ riscv_emit_move (dest, riscv_legitimize_tls_address (src));
3572+ return;
3573+ }
3574+
3575+ /* If we have (const (plus symbol offset)), and that expression cannot
3576+ be forced into memory, load the symbol first and add in the offset. Also
3577+ prefer to do this even if the constant _can_ be forced into memory, as it
3578+ usually produces better code. */
3579+ split_const (src, &base, &offset);
3580+ if (offset != const0_rtx
3581+ && (targetm.cannot_force_const_mem (src) || can_create_pseudo_p ()))
3582+ {
3583+ base = riscv_force_temporary (dest, base);
3584+ riscv_emit_move (dest, riscv_add_offset (NULL, base, INTVAL (offset)));
3585+ return;
3586+ }
3587+
3588+ src = force_const_mem (mode, src);
3589+
3590+ /* When using explicit relocs, constant pool references are sometimes
3591+ not legitimate addresses. */
3592+ riscv_split_symbol (dest, XEXP (src, 0), mode, &XEXP (src, 0));
3593+ riscv_emit_move (dest, src);
3594+}
3595+
3596+/* If (set DEST SRC) is not a valid move instruction, emit an equivalent
3597+ sequence that is valid. */
3598+
3599+bool
3600+riscv_legitimize_move (enum machine_mode mode, rtx dest, rtx src)
3601+{
3602+ if (!register_operand (dest, mode) && !reg_or_0_operand (src, mode))
3603+ {
3604+ riscv_emit_move (dest, force_reg (mode, src));
3605+ return true;
3606+ }
3607+
3608+ /* We need to deal with constants that would be legitimate
3609+ immediate_operands but aren't legitimate move_operands. */
3610+ if (CONSTANT_P (src) && !move_operand (src, mode))
3611+ {
3612+ riscv_legitimize_const_move (mode, dest, src);
3613+ set_unique_reg_note (get_last_insn (), REG_EQUAL, copy_rtx (src));
3614+ return true;
3615+ }
3616+
3617+ return false;
3618+}
3619+
3620+/* Return true if there is an instruction that implements CODE and accepts
3621+ X as an immediate operand. */
3622+
3623+static int
3624+riscv_immediate_operand_p (int code, HOST_WIDE_INT x)
3625+{
3626+ switch (code)
3627+ {
3628+ case ASHIFT:
3629+ case ASHIFTRT:
3630+ case LSHIFTRT:
3631+ /* All shift counts are truncated to a valid constant. */
3632+ return true;
3633+
3634+ case AND:
3635+ case IOR:
3636+ case XOR:
3637+ case PLUS:
3638+ case LT:
3639+ case LTU:
3640+ /* These instructions take 12-bit signed immediates. */
3641+ return SMALL_OPERAND (x);
3642+
3643+ case LE:
3644+ /* We add 1 to the immediate and use SLT. */
3645+ return SMALL_OPERAND (x + 1);
3646+
3647+ case LEU:
3648+ /* Likewise SLTU, but reject the always-true case. */
3649+ return SMALL_OPERAND (x + 1) && x + 1 != 0;
3650+
3651+ case GE:
3652+ case GEU:
3653+ /* We can emulate an immediate of 1 by using GT/GTU against x0. */
3654+ return x == 1;
3655+
3656+ default:
3657+ /* By default assume that x0 can be used for 0. */
3658+ return x == 0;
3659+ }
3660+}
3661+
3662+/* Return the cost of binary operation X, given that the instruction
3663+ sequence for a word-sized or smaller operation takes SIGNLE_INSNS
3664+ instructions and that the sequence of a double-word operation takes
3665+ DOUBLE_INSNS instructions. */
3666+
3667+static int
3668+riscv_binary_cost (rtx x, int single_insns, int double_insns)
3669+{
3670+ if (GET_MODE_SIZE (GET_MODE (x)) == UNITS_PER_WORD * 2)
3671+ return COSTS_N_INSNS (double_insns);
3672+ return COSTS_N_INSNS (single_insns);
3673+}
3674+
3675+/* Return the cost of sign- or zero-extending OP. */
3676+
3677+static int
3678+riscv_extend_cost (rtx op, bool unsigned_p)
3679+{
3680+ if (MEM_P (op))
3681+ return 0;
3682+
3683+ if (unsigned_p && GET_MODE (op) == QImode)
3684+ /* We can use ANDI. */
3685+ return COSTS_N_INSNS (1);
3686+
3687+ if (!unsigned_p && GET_MODE (op) == SImode)
3688+ /* We can use SEXT.W. */
3689+ return COSTS_N_INSNS (1);
3690+
3691+ /* We need to use a shift left and a shift right. */
3692+ return COSTS_N_INSNS (2);
3693+}
3694+
3695+/* Implement TARGET_RTX_COSTS. */
3696+
3697+static bool
3698+riscv_rtx_costs (rtx x, enum machine_mode mode, int outer_code, int *total, bool speed)
3699+{
3700+ bool float_mode_p = FLOAT_MODE_P (mode);
3701+ int cost;
3702+
3703+ switch (GET_CODE (x))
3704+ {
3705+ case CONST_INT:
3706+ if (riscv_immediate_operand_p (outer_code, INTVAL (x)))
3707+ {
3708+ *total = 0;
3709+ return true;
3710+ }
3711+ /* Fall through. */
3712+
3713+ case SYMBOL_REF:
3714+ case LABEL_REF:
3715+ case CONST_DOUBLE:
3716+ case CONST:
3717+ if ((cost = riscv_const_insns (x)) > 0)
3718+ {
3719+ /* If the constant is likely to be stored in a GPR, SETs of
3720+ single-insn constants are as cheap as register sets; we
3721+ never want to CSE them. */
3722+ if (cost == 1 && outer_code == SET)
3723+ *total = 0;
3724+ /* When we load a constant more than once, it usually is better
3725+ to duplicate the last operation in the sequence than to CSE
3726+ the constant itself. */
3727+ else if (outer_code == SET || GET_MODE (x) == VOIDmode)
3728+ *total = COSTS_N_INSNS (1);
3729+ }
3730+ else /* The instruction will be fetched from the constant pool. */
3731+ *total = COSTS_N_INSNS (riscv_symbol_insns (SYMBOL_ABSOLUTE));
3732+ return true;
3733+
3734+ case MEM:
3735+ /* If the address is legitimate, return the number of
3736+ instructions it needs. */
3737+ if ((cost = riscv_address_insns (XEXP (x, 0), mode, true)) > 0)
3738+ {
3739+ *total = COSTS_N_INSNS (cost + tune_info->memory_cost);
3740+ return true;
3741+ }
3742+ /* Otherwise use the default handling. */
3743+ return false;
3744+
3745+ case NOT:
3746+ *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) > UNITS_PER_WORD ? 2 : 1);
3747+ return false;
3748+
3749+ case AND:
3750+ case IOR:
3751+ case XOR:
3752+ /* Double-word operations use two single-word operations. */
3753+ *total = riscv_binary_cost (x, 1, 2);
3754+ return false;
3755+
3756+ case ASHIFT:
3757+ case ASHIFTRT:
3758+ case LSHIFTRT:
3759+ *total = riscv_binary_cost (x, 1, CONSTANT_P (XEXP (x, 1)) ? 4 : 9);
3760+ return false;
3761+
3762+ case ABS:
3763+ *total = COSTS_N_INSNS (float_mode_p ? 1 : 3);
3764+ return false;
3765+
3766+ case LO_SUM:
3767+ *total = rtx_cost (XEXP (x, 0), SET, speed);
3768+ return true;
3769+
3770+ case LT:
3771+ case LTU:
3772+ case LE:
3773+ case LEU:
3774+ case GT:
3775+ case GTU:
3776+ case GE:
3777+ case GEU:
3778+ case EQ:
3779+ case NE:
3780+ /* Branch comparisons have VOIDmode, so use the first operand's
3781+ mode instead. */
3782+ mode = GET_MODE (XEXP (x, 0));
3783+ if (float_mode_p)
3784+ *total = tune_info->fp_add[mode == DFmode];
3785+ else
3786+ *total = riscv_binary_cost (x, 1, 3);
3787+ return false;
3788+
3789+ case UNORDERED:
3790+ case ORDERED:
3791+ /* (FEQ(A, A) & FEQ(B, B)) compared against 0. */
3792+ mode = GET_MODE (XEXP (x, 0));
3793+ *total = tune_info->fp_add[mode == DFmode] + COSTS_N_INSNS (2);
3794+ return false;
3795+
3796+ case UNEQ:
3797+ case LTGT:
3798+ /* (FEQ(A, A) & FEQ(B, B)) compared against FEQ(A, B). */
3799+ mode = GET_MODE (XEXP (x, 0));
3800+ *total = tune_info->fp_add[mode == DFmode] + COSTS_N_INSNS (3);
3801+ return false;
3802+
3803+ case UNGE:
3804+ case UNGT:
3805+ case UNLE:
3806+ case UNLT:
3807+ /* FLT or FLE, but guarded by an FFLAGS read and write. */
3808+ mode = GET_MODE (XEXP (x, 0));
3809+ *total = tune_info->fp_add[mode == DFmode] + COSTS_N_INSNS (4);
3810+ return false;
3811+
3812+ case MINUS:
3813+ case PLUS:
3814+ if (float_mode_p)
3815+ *total = tune_info->fp_add[mode == DFmode];
3816+ else
3817+ *total = riscv_binary_cost (x, 1, 4);
3818+ return false;
3819+
3820+ case NEG:
3821+ {
3822+ rtx op = XEXP (x, 0);
3823+ if (GET_CODE (op) == FMA && !HONOR_SIGNED_ZEROS (mode))
3824+ {
3825+ *total = (tune_info->fp_mul[mode == DFmode]
3826+ + rtx_cost (XEXP (op, 0), SET, speed)
3827+ + rtx_cost (XEXP (op, 1), SET, speed)
3828+ + rtx_cost (XEXP (op, 2), SET, speed));
3829+ return true;
3830+ }
3831+ }
3832+
3833+ if (float_mode_p)
3834+ *total = tune_info->fp_add[mode == DFmode];
3835+ else
3836+ *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) > UNITS_PER_WORD ? 4 : 1);
3837+ return false;
3838+
3839+ case MULT:
3840+ if (float_mode_p)
3841+ *total = tune_info->fp_mul[mode == DFmode];
3842+ else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
3843+ *total = 3 * tune_info->int_mul[0] + COSTS_N_INSNS (2);
3844+ else if (!speed)
3845+ *total = COSTS_N_INSNS (1);
3846+ else
3847+ *total = tune_info->int_mul[mode == DImode];
3848+ return false;
3849+
3850+ case DIV:
3851+ case SQRT:
3852+ case MOD:
3853+ if (float_mode_p)
3854+ {
3855+ *total = tune_info->fp_div[mode == DFmode];
3856+ return false;
3857+ }
3858+ /* Fall through. */
3859+
3860+ case UDIV:
3861+ case UMOD:
3862+ if (speed)
3863+ *total = tune_info->int_div[mode == DImode];
3864+ else
3865+ *total = COSTS_N_INSNS (1);
3866+ return false;
3867+
3868+ case SIGN_EXTEND:
3869+ case ZERO_EXTEND:
3870+ *total = riscv_extend_cost (XEXP (x, 0), GET_CODE (x) == ZERO_EXTEND);
3871+ return false;
3872+
3873+ case FLOAT:
3874+ case UNSIGNED_FLOAT:
3875+ case FIX:
3876+ case FLOAT_EXTEND:
3877+ case FLOAT_TRUNCATE:
3878+ *total = tune_info->fp_add[mode == DFmode];
3879+ return false;
3880+
3881+ case FMA:
3882+ *total = (tune_info->fp_mul[mode == DFmode]
3883+ + rtx_cost (XEXP (x, 0), SET, speed)
3884+ + rtx_cost (XEXP (x, 1), SET, speed)
3885+ + rtx_cost (XEXP (x, 2), SET, speed));
3886+ return true;
3887+
3888+ case UNSPEC:
3889+ if (XINT (x, 1) == UNSPEC_AUIPC)
3890+ {
3891+ /* Make AUIPC cheap to avoid spilling its result to the stack. */
3892+ *total = 1;
3893+ return true;
3894+ }
3895+ return false;
3896+
3897+ default:
3898+ return false;
3899+ }
3900+}
3901+
3902+/* Implement TARGET_ADDRESS_COST. */
3903+
3904+static int
3905+riscv_address_cost (rtx addr, bool speed ATTRIBUTE_UNUSED)
3906+{
3907+ return riscv_address_insns (addr, SImode, false);
3908+}
3909+
3910+/* Return one word of double-word value OP. HIGH_P is true to select the
3911+ high part or false to select the low part. */
3912+
3913+rtx
3914+riscv_subword (rtx op, bool high_p)
3915+{
3916+ unsigned int byte = high_p ? UNITS_PER_WORD : 0;
3917+ enum machine_mode mode = GET_MODE (op);
3918+
3919+ if (mode == VOIDmode)
3920+ mode = TARGET_64BIT ? TImode : DImode;
3921+
3922+ if (MEM_P (op))
3923+ return adjust_address (op, word_mode, byte);
3924+
3925+ if (REG_P (op))
3926+ gcc_assert (!FP_REG_RTX_P (op));
3927+
3928+ return simplify_gen_subreg (word_mode, op, mode, byte);
3929+}
3930+
3931+/* Return true if a 64-bit move from SRC to DEST should be split into two. */
3932+
3933+bool
3934+riscv_split_64bit_move_p (rtx dest, rtx src)
3935+{
3936+ if (TARGET_64BIT)
3937+ return false;
3938+
3939+ /* Allow FPR <-> FPR and FPR <-> MEM moves, and permit the special case
3940+ of zeroing an FPR with FCVT.D.W. */
3941+ if (TARGET_DOUBLE_FLOAT
3942+ && ((FP_REG_RTX_P (src) && FP_REG_RTX_P (dest))
3943+ || (FP_REG_RTX_P (dest) && MEM_P (src))
3944+ || (FP_REG_RTX_P (src) && MEM_P (dest))
3945+ || (FP_REG_RTX_P (dest) && src == CONST0_RTX (GET_MODE (src)))))
3946+ return false;
3947+
3948+ return true;
3949+}
3950+
3951+/* Split a doubleword move from SRC to DEST. On 32-bit targets,
3952+ this function handles 64-bit moves for which riscv_split_64bit_move_p
3953+ holds. For 64-bit targets, this function handles 128-bit moves. */
3954+
3955+void
3956+riscv_split_doubleword_move (rtx dest, rtx src)
3957+{
3958+ rtx low_dest;
3959+
3960+ /* The operation can be split into two normal moves. Decide in
3961+ which order to do them. */
3962+ low_dest = riscv_subword (dest, false);
3963+ if (REG_P (low_dest) && reg_overlap_mentioned_p (low_dest, src))
3964+ {
3965+ riscv_emit_move (riscv_subword (dest, true), riscv_subword (src, true));
3966+ riscv_emit_move (low_dest, riscv_subword (src, false));
3967+ }
3968+ else
3969+ {
3970+ riscv_emit_move (low_dest, riscv_subword (src, false));
3971+ riscv_emit_move (riscv_subword (dest, true), riscv_subword (src, true));
3972+ }
3973+}
3974+
3975+/* Return the appropriate instructions to move SRC into DEST. Assume
3976+ that SRC is operand 1 and DEST is operand 0. */
3977+
3978+const char *
3979+riscv_output_move (rtx dest, rtx src)
3980+{
3981+ enum rtx_code dest_code, src_code;
3982+ enum machine_mode mode;
3983+ bool dbl_p;
3984+
3985+ dest_code = GET_CODE (dest);
3986+ src_code = GET_CODE (src);
3987+ mode = GET_MODE (dest);
3988+ dbl_p = (GET_MODE_SIZE (mode) == 8);
3989+
3990+ if (dbl_p && riscv_split_64bit_move_p (dest, src))
3991+ return "#";
3992+
3993+ if (dest_code == REG && GP_REG_P (REGNO (dest)))
3994+ {
3995+ if (src_code == REG && FP_REG_P (REGNO (src)))
3996+ return dbl_p ? "fmv.x.d\t%0,%1" : "fmv.x.s\t%0,%1";
3997+
3998+ if (src_code == MEM)
3999+ switch (GET_MODE_SIZE (mode))
4000+ {
4001+ case 1: return "lbu\t%0,%1";
4002+ case 2: return "lhu\t%0,%1";
4003+ case 4: return "lw\t%0,%1";
4004+ case 8: return "ld\t%0,%1";
4005+ }
4006+
4007+ if (src_code == CONST_INT)
4008+ return "li\t%0,%1";
4009+
4010+ if (src_code == HIGH)
4011+ return "lui\t%0,%h1";
4012+
4013+ if (symbolic_operand (src, VOIDmode))
4014+ switch (riscv_classify_symbolic_expression (src))
4015+ {
4016+ case SYMBOL_GOT_DISP: return "la\t%0,%1";
4017+ case SYMBOL_ABSOLUTE: return "lla\t%0,%1";
4018+ case SYMBOL_PCREL: return "lla\t%0,%1";
4019+ default: gcc_unreachable ();
4020+ }
4021+ }
4022+ if ((src_code == REG && GP_REG_P (REGNO (src)))
4023+ || (src == CONST0_RTX (mode)))
4024+ {
4025+ if (dest_code == REG)
4026+ {
4027+ if (GP_REG_P (REGNO (dest)))
4028+ return "mv\t%0,%z1";
4029+
4030+ if (FP_REG_P (REGNO (dest)))
4031+ {
4032+ if (!dbl_p)
4033+ return "fmv.s.x\t%0,%z1";
4034+ if (TARGET_64BIT)
4035+ return "fmv.d.x\t%0,%z1";
4036+ /* in RV32, we can emulate fmv.d.x %0, x0 using fcvt.d.w */
4037+ gcc_assert (src == CONST0_RTX (mode));
4038+ return "fcvt.d.w\t%0,x0";
4039+ }
4040+ }
4041+ if (dest_code == MEM)
4042+ switch (GET_MODE_SIZE (mode))
4043+ {
4044+ case 1: return "sb\t%z1,%0";
4045+ case 2: return "sh\t%z1,%0";
4046+ case 4: return "sw\t%z1,%0";
4047+ case 8: return "sd\t%z1,%0";
4048+ }
4049+ }
4050+ if (src_code == REG && FP_REG_P (REGNO (src)))
4051+ {
4052+ if (dest_code == REG && FP_REG_P (REGNO (dest)))
4053+ return dbl_p ? "fmv.d\t%0,%1" : "fmv.s\t%0,%1";
4054+
4055+ if (dest_code == MEM)
4056+ return dbl_p ? "fsd\t%1,%0" : "fsw\t%1,%0";
4057+ }
4058+ if (dest_code == REG && FP_REG_P (REGNO (dest)))
4059+ {
4060+ if (src_code == MEM)
4061+ return dbl_p ? "fld\t%0,%1" : "flw\t%0,%1";
4062+ }
4063+ gcc_unreachable ();
4064+}
4065+
4066+/* Return true if CMP1 is a suitable second operand for integer ordering
4067+ test CODE. See also the *sCC patterns in riscv.md. */
4068+
4069+static bool
4070+riscv_int_order_operand_ok_p (enum rtx_code code, rtx cmp1)
4071+{
4072+ switch (code)
4073+ {
4074+ case GT:
4075+ case GTU:
4076+ return reg_or_0_operand (cmp1, VOIDmode);
4077+
4078+ case GE:
4079+ case GEU:
4080+ return cmp1 == const1_rtx;
4081+
4082+ case LT:
4083+ case LTU:
4084+ return arith_operand (cmp1, VOIDmode);
4085+
4086+ case LE:
4087+ return sle_operand (cmp1, VOIDmode);
4088+
4089+ case LEU:
4090+ return sleu_operand (cmp1, VOIDmode);
4091+
4092+ default:
4093+ gcc_unreachable ();
4094+ }
4095+}
4096+
4097+/* Return true if *CMP1 (of mode MODE) is a valid second operand for
4098+ integer ordering test *CODE, or if an equivalent combination can
4099+ be formed by adjusting *CODE and *CMP1. When returning true, update
4100+ *CODE and *CMP1 with the chosen code and operand, otherwise leave
4101+ them alone. */
4102+
4103+static bool
4104+riscv_canonicalize_int_order_test (enum rtx_code *code, rtx *cmp1,
4105+ enum machine_mode mode)
4106+{
4107+ HOST_WIDE_INT plus_one;
4108+
4109+ if (riscv_int_order_operand_ok_p (*code, *cmp1))
4110+ return true;
4111+
4112+ if (CONST_INT_P (*cmp1))
4113+ switch (*code)
4114+ {
4115+ case LE:
4116+ plus_one = trunc_int_for_mode (UINTVAL (*cmp1) + 1, mode);
4117+ if (INTVAL (*cmp1) < plus_one)
4118+ {
4119+ *code = LT;
4120+ *cmp1 = force_reg (mode, GEN_INT (plus_one));
4121+ return true;
4122+ }
4123+ break;
4124+
4125+ case LEU:
4126+ plus_one = trunc_int_for_mode (UINTVAL (*cmp1) + 1, mode);
4127+ if (plus_one != 0)
4128+ {
4129+ *code = LTU;
4130+ *cmp1 = force_reg (mode, GEN_INT (plus_one));
4131+ return true;
4132+ }
4133+ break;
4134+
4135+ default:
4136+ break;
4137+ }
4138+ return false;
4139+}
4140+
4141+/* Compare CMP0 and CMP1 using ordering test CODE and store the result
4142+ in TARGET. CMP0 and TARGET are register_operands. If INVERT_PTR
4143+ is nonnull, it's OK to set TARGET to the inverse of the result and
4144+ flip *INVERT_PTR instead. */
4145+
4146+static void
4147+riscv_emit_int_order_test (enum rtx_code code, bool *invert_ptr,
4148+ rtx target, rtx cmp0, rtx cmp1)
4149+{
4150+ enum machine_mode mode;
4151+
4152+ /* First see if there is a RISCV instruction that can do this operation.
4153+ If not, try doing the same for the inverse operation. If that also
4154+ fails, force CMP1 into a register and try again. */
4155+ mode = GET_MODE (cmp0);
4156+ if (riscv_canonicalize_int_order_test (&code, &cmp1, mode))
4157+ riscv_emit_binary (code, target, cmp0, cmp1);
4158+ else
4159+ {
4160+ enum rtx_code inv_code = reverse_condition (code);
4161+ if (!riscv_canonicalize_int_order_test (&inv_code, &cmp1, mode))
4162+ {
4163+ cmp1 = force_reg (mode, cmp1);
4164+ riscv_emit_int_order_test (code, invert_ptr, target, cmp0, cmp1);
4165+ }
4166+ else if (invert_ptr == 0)
4167+ {
4168+ rtx inv_target = riscv_force_binary (GET_MODE (target),
4169+ inv_code, cmp0, cmp1);
4170+ riscv_emit_binary (XOR, target, inv_target, const1_rtx);
4171+ }
4172+ else
4173+ {
4174+ *invert_ptr = !*invert_ptr;
4175+ riscv_emit_binary (inv_code, target, cmp0, cmp1);
4176+ }
4177+ }
4178+}
4179+
4180+/* Return a register that is zero iff CMP0 and CMP1 are equal.
4181+ The register will have the same mode as CMP0. */
4182+
4183+static rtx
4184+riscv_zero_if_equal (rtx cmp0, rtx cmp1)
4185+{
4186+ if (cmp1 == const0_rtx)
4187+ return cmp0;
4188+
4189+ return expand_binop (GET_MODE (cmp0), sub_optab,
4190+ cmp0, cmp1, 0, 0, OPTAB_DIRECT);
4191+}
4192+
4193+/* Sign- or zero-extend OP0 and OP1 for integer comparisons. */
4194+
4195+static void
4196+riscv_extend_comparands (enum rtx_code code, rtx *op0, rtx *op1)
4197+{
4198+ /* Comparisons consider all XLEN bits, so extend sub-XLEN values. */
4199+ if (GET_MODE_SIZE (word_mode) > GET_MODE_SIZE (GET_MODE (*op0)))
4200+ {
4201+ /* It is more profitable to zero-extend QImode values. */
4202+ if (unsigned_condition (code) == code && GET_MODE (*op0) == QImode)
4203+ {
4204+ *op0 = gen_rtx_ZERO_EXTEND (word_mode, *op0);
4205+ if (CONST_INT_P (*op1))
4206+ *op1 = GEN_INT ((uint8_t) INTVAL (*op1));
4207+ else
4208+ *op1 = gen_rtx_ZERO_EXTEND (word_mode, *op1);
4209+ }
4210+ else
4211+ {
4212+ *op0 = gen_rtx_SIGN_EXTEND (word_mode, *op0);
4213+ if (*op1 != const0_rtx)
4214+ *op1 = gen_rtx_SIGN_EXTEND (word_mode, *op1);
4215+ }
4216+ }
4217+}
4218+
4219+/* Convert a comparison into something that can be used in a branch. On
4220+ entry, *OP0 and *OP1 are the values being compared and *CODE is the code
4221+ used to compare them. Update them to describe the final comparison. */
4222+
4223+static void
4224+riscv_emit_int_compare (enum rtx_code *code, rtx *op0, rtx *op1)
4225+{
4226+ size_t i;
4227+ if (splittable_const_int_operand (*op1, VOIDmode))
4228+ {
4229+ HOST_WIDE_INT rhs = INTVAL (*op1);
4230+
4231+ if (*code == EQ || *code == NE)
4232+ {
4233+ /* Convert e.g. OP0 == 2048 into OP0 - 2048 == 0. */
4234+ if (SMALL_OPERAND (-rhs))
4235+ {
4236+ *op0 = riscv_force_binary (GET_MODE (*op0), PLUS, *op0,
4237+ GEN_INT (-rhs));
4238+ *op1 = const0_rtx;
4239+ }
4240+ }
4241+ else
4242+ {
4243+ static const enum rtx_code mag_comparisons[][2] = {
4244+ {LEU, LTU}, {GTU, GEU}, {LE, LT}, {GT, GE}
4245+ };
4246+
4247+ /* Convert e.g. (OP0 <= 0xFFF) into (OP0 < 0x1000). */
4248+ for (i = 0; i < ARRAY_SIZE (mag_comparisons); i++)
4249+ {
4250+ HOST_WIDE_INT new_rhs;
4251+ bool increment = *code == mag_comparisons[i][0];
4252+ bool decrement = *code == mag_comparisons[i][1];
4253+ if (!increment && !decrement)
4254+ continue;
4255+
4256+ new_rhs = rhs + (increment ? 1 : -1);
4257+ if (riscv_integer_cost (new_rhs) < riscv_integer_cost (rhs)
4258+ && (rhs < 0) == (new_rhs < 0))
4259+ {
4260+ *op1 = GEN_INT (new_rhs);
4261+ *code = mag_comparisons[i][increment];
4262+ }
4263+ break;
4264+ }
4265+ }
4266+ }
4267+
4268+ riscv_extend_comparands (*code, op0, op1);
4269+
4270+ *op0 = force_reg (word_mode, *op0);
4271+ if (*op1 != const0_rtx)
4272+ *op1 = force_reg (word_mode, *op1);
4273+}
4274+
4275+/* Like riscv_emit_int_compare, but for floating-point comparisons. */
4276+
4277+static void
4278+riscv_emit_float_compare (enum rtx_code *code, rtx *op0, rtx *op1)
4279+{
4280+ rtx tmp0, tmp1, tmp2, cmp_op0 = *op0, cmp_op1 = *op1;
4281+ enum rtx_code fp_code = *code;
4282+ *code = NE;
4283+
4284+ switch (fp_code)
4285+ {
4286+ case UNORDERED:
4287+ *code = EQ;
4288+ /* Fall through. */
4289+
4290+ case ORDERED:
4291+ /* a == a && b == b */
4292+ tmp0 = riscv_force_binary (word_mode, EQ, cmp_op0, cmp_op0);
4293+ tmp1 = riscv_force_binary (word_mode, EQ, cmp_op1, cmp_op1);
4294+ *op0 = riscv_force_binary (word_mode, AND, tmp0, tmp1);
4295+ *op1 = const0_rtx;
4296+ break;
4297+
4298+ case UNEQ:
4299+ case LTGT:
4300+ /* ordered(a, b) > (a == b) */
4301+ *code = fp_code == LTGT ? GTU : EQ;
4302+ tmp0 = riscv_force_binary (word_mode, EQ, cmp_op0, cmp_op0);
4303+ tmp1 = riscv_force_binary (word_mode, EQ, cmp_op1, cmp_op1);
4304+ *op0 = riscv_force_binary (word_mode, AND, tmp0, tmp1);
4305+ *op1 = riscv_force_binary (word_mode, EQ, cmp_op0, cmp_op1);
4306+ break;
4307+
4308+#define UNORDERED_COMPARISON(CODE, CMP) \
4309+ case CODE: \
4310+ *code = EQ; \
4311+ *op0 = gen_reg_rtx (word_mode); \
4312+ if (GET_MODE (cmp_op0) == SFmode && TARGET_64BIT) \
4313+ emit_insn (gen_f##CMP##_quietsfdi4 (*op0, cmp_op0, cmp_op1)); \
4314+ else if (GET_MODE (cmp_op0) == SFmode) \
4315+ emit_insn (gen_f##CMP##_quietsfsi4 (*op0, cmp_op0, cmp_op1)); \
4316+ else if (GET_MODE (cmp_op0) == DFmode && TARGET_64BIT) \
4317+ emit_insn (gen_f##CMP##_quietdfdi4 (*op0, cmp_op0, cmp_op1)); \
4318+ else if (GET_MODE (cmp_op0) == DFmode) \
4319+ emit_insn (gen_f##CMP##_quietdfsi4 (*op0, cmp_op0, cmp_op1)); \
4320+ else \
4321+ gcc_unreachable (); \
4322+ *op1 = const0_rtx; \
4323+ break;
4324+
4325+ case UNLT:
4326+ tmp2 = cmp_op0;
4327+ cmp_op0 = cmp_op1;
4328+ cmp_op1 = tmp2;
4329+ /* Fall through. */
4330+
4331+ UNORDERED_COMPARISON(UNGT, le)
4332+
4333+ case UNLE:
4334+ tmp2 = cmp_op0;
4335+ cmp_op0 = cmp_op1;
4336+ cmp_op1 = tmp2;
4337+ /* Fall through. */
4338+
4339+ UNORDERED_COMPARISON(UNGE, lt)
4340+#undef UNORDERED_COMPARISON
4341+
4342+ case NE:
4343+ fp_code = EQ;
4344+ *code = EQ;
4345+ /* Fall through. */
4346+
4347+ case EQ:
4348+ case LE:
4349+ case LT:
4350+ case GE:
4351+ case GT:
4352+ /* We have instructions for these cases. */
4353+ *op0 = riscv_force_binary (word_mode, fp_code, cmp_op0, cmp_op1);
4354+ *op1 = const0_rtx;
4355+ break;
4356+
4357+ default:
4358+ gcc_unreachable ();
4359+ }
4360+}
4361+
4362+/* CODE-compare OP0 and OP1. Store the result in TARGET. */
4363+
4364+void
4365+riscv_expand_int_scc (rtx target, enum rtx_code code, rtx op0, rtx op1)
4366+{
4367+ riscv_extend_comparands (code, &op0, &op1);
4368+ op0 = force_reg (word_mode, op0);
4369+
4370+ if (code == EQ || code == NE)
4371+ {
4372+ rtx zie = riscv_zero_if_equal (op0, op1);
4373+ riscv_emit_binary (code, target, zie, const0_rtx);
4374+ }
4375+ else
4376+ riscv_emit_int_order_test (code, 0, target, op0, op1);
4377+}
4378+
4379+/* Like riscv_expand_int_scc, but for floating-point comparisons. */
4380+
4381+void
4382+riscv_expand_float_scc (rtx target, enum rtx_code code, rtx op0, rtx op1)
4383+{
4384+ riscv_emit_float_compare (&code, &op0, &op1);
4385+
4386+ rtx cmp = riscv_force_binary (word_mode, code, op0, op1);
4387+ riscv_emit_set (target, lowpart_subreg (SImode, cmp, word_mode));
4388+}
4389+
4390+/* Jump to LABEL if (CODE OP0 OP1) holds. */
4391+
4392+void
4393+riscv_expand_conditional_branch (rtx label, enum rtx_code code, rtx op0, rtx op1)
4394+{
4395+ if (FLOAT_MODE_P (GET_MODE (op1)))
4396+ riscv_emit_float_compare (&code, &op0, &op1);
4397+ else
4398+ riscv_emit_int_compare (&code, &op0, &op1);
4399+
4400+ rtx condition = gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
4401+ emit_jump_insn (gen_condjump (condition, label));
4402+}
4403+
4404+/* Implement TARGET_FUNCTION_ARG_BOUNDARY. Every parameter gets at
4405+ least PARM_BOUNDARY bits of alignment, but will be given anything up
4406+ to STACK_BOUNDARY bits if the type requires it. */
4407+
4408+static unsigned int
4409+riscv_function_arg_boundary (enum machine_mode mode, const_tree type)
4410+{
4411+ unsigned int alignment;
4412+
4413+ /* Use natural alignment if the type is not aggregate data. */
4414+ if (type && !AGGREGATE_TYPE_P (type))
4415+ alignment = TYPE_ALIGN (TYPE_MAIN_VARIANT (type));
4416+ else
4417+ alignment = type ? TYPE_ALIGN (type) : GET_MODE_ALIGNMENT (mode);
4418+
4419+ return MIN (STACK_BOUNDARY, MAX (PARM_BOUNDARY, alignment));
4420+}
4421+
4422+/* If MODE represents an argument that can be passed or returned in
4423+ floating-point registers, return the number of registers, else 0. */
4424+
4425+static unsigned
4426+riscv_pass_mode_in_fpr_p (enum machine_mode mode)
4427+{
4428+ if (GET_MODE_UNIT_SIZE (mode) <= UNITS_PER_FP_ARG)
4429+ {
4430+ if (GET_MODE_CLASS (mode) == MODE_FLOAT)
4431+ return 1;
4432+
4433+ if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
4434+ return 2;
4435+ }
4436+
4437+ return 0;
4438+}
4439+
4440+typedef struct {
4441+ const_tree type;
4442+ HOST_WIDE_INT offset;
4443+} riscv_aggregate_field;
4444+
4445+/* Identify subfields of aggregates that are candidates for passing in
4446+ floating-point registers. */
4447+
4448+static int
4449+riscv_flatten_aggregate_field (const_tree type,
4450+ riscv_aggregate_field fields[2],
4451+ int n, HOST_WIDE_INT offset)
4452+{
4453+ tree f;
4454+ HOST_WIDE_INT pos;
4455+ HOST_WIDE_INT n_elts, i;
4456+ int j, n_subfields;
4457+ riscv_aggregate_field subfields[2];
4458+ tree index, elt_size;
4459+
4460+ switch (TREE_CODE (type))
4461+ {
4462+ case RECORD_TYPE:
4463+ /* Can't handle incomplete types nor sizes that are not fixed. */
4464+ if (!COMPLETE_TYPE_P (type)
4465+ || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
4466+ || !host_integerp (TYPE_SIZE (type), 0))
4467+ return -1;
4468+
4469+ for (f = TYPE_FIELDS (type); f; f = DECL_CHAIN (f))
4470+ if (TREE_CODE (f) == FIELD_DECL)
4471+ {
4472+ if (!TYPE_P (TREE_TYPE (f)))
4473+ return -1;
4474+
4475+ pos = offset + int_byte_position (f);
4476+ n = riscv_flatten_aggregate_field (TREE_TYPE (f), fields, n, pos);
4477+ if (n < 0)
4478+ return -1;
4479+ }
4480+ return n;
4481+
4482+ case ARRAY_TYPE:
4483+ {
4484+ index = TYPE_DOMAIN (type);
4485+ elt_size = TYPE_SIZE_UNIT (TREE_TYPE (type));
4486+ n_subfields = riscv_flatten_aggregate_field (TREE_TYPE (type),
4487+ subfields, 0, offset);
4488+
4489+ /* Can't handle incomplete types nor sizes that are not fixed. */
4490+ if (n_subfields <= 0
4491+ || !COMPLETE_TYPE_P (type)
4492+ || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
4493+ || !index
4494+ || !TYPE_MAX_VALUE (index)
4495+ || !host_integerp(TYPE_MAX_VALUE (index),0)
4496+ || !TYPE_MIN_VALUE (index)
4497+ || !host_integerp(TYPE_MIN_VALUE (index),0)
4498+ || !host_integerp(elt_size,0))
4499+ return -1;
4500+
4501+ n_elts = 1 + TREE_INT_CST_LOW(TYPE_MAX_VALUE (index))
4502+ - TREE_INT_CST_LOW (TYPE_MIN_VALUE (index));
4503+ gcc_assert (n_elts >= 0);
4504+
4505+ for (i = 0; i < n_elts; i++)
4506+ for (j = 0; j < n_subfields; j++)
4507+ {
4508+ if (n >= 2)
4509+ return -1;
4510+
4511+ fields[n] = subfields[j];
4512+ fields[n++].offset += i * TREE_INT_CST_LOW (elt_size);
4513+ }
4514+
4515+ return n;
4516+ }
4517+
4518+ case COMPLEX_TYPE:
4519+ {
4520+ /* Complex type need consume 2 field, so n must be 0. */
4521+ if (n != 0)
4522+ return -1;
4523+
4524+ elt_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (type)));
4525+
4526+ if (elt_size <= UNITS_PER_FP_ARG)
4527+ {
4528+ fields[0].type = TREE_TYPE (type);
4529+ fields[0].offset = offset;
4530+ fields[1].type = TREE_TYPE (type);
4531+ fields[1].offset = offset + elt_size;
4532+
4533+ return 2;
4534+ }
4535+
4536+ return -1;
4537+ }
4538+
4539+ default:
4540+ if (n < 2
4541+ && ((SCALAR_FLOAT_TYPE_P (type)
4542+ && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_FP_ARG)
4543+ || (INTEGRAL_TYPE_P (type)
4544+ && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_WORD)))
4545+ {
4546+ fields[n].type = type;
4547+ fields[n].offset = offset;
4548+ return n + 1;
4549+ }
4550+ else
4551+ return -1;
4552+ }
4553+}
4554+
4555+/* Identify candidate aggregates for passing in floating-point registers.
4556+ Candidates have at most two fields after flattening. */
4557+
4558+static int
4559+riscv_flatten_aggregate_argument (const_tree type,
4560+ riscv_aggregate_field fields[2])
4561+{
4562+ if (!type || TREE_CODE (type) != RECORD_TYPE)
4563+ return -1;
4564+
4565+ return riscv_flatten_aggregate_field (type, fields, 0, 0);
4566+}
4567+
4568+/* See whether TYPE is a record whose fields should be returned in one or
4569+ two floating-point registers. If so, populate FIELDS accordingly. */
4570+
4571+static unsigned
4572+riscv_pass_aggregate_in_fpr_pair_p (const_tree type,
4573+ riscv_aggregate_field fields[2])
4574+{
4575+ int i;
4576+ int n = riscv_flatten_aggregate_argument (type, fields);
4577+
4578+ for (i = 0; i < n; i++)
4579+ if (!SCALAR_FLOAT_TYPE_P (fields[i].type))
4580+ return 0;
4581+
4582+ return n > 0 ? n : 0;
4583+}
4584+
4585+/* See whether TYPE is a record whose fields should be returned in one or
4586+ floating-point register and one integer register. If so, populate
4587+ FIELDS accordingly. */
4588+
4589+static bool
4590+riscv_pass_aggregate_in_fpr_and_gpr_p (const_tree type,
4591+ riscv_aggregate_field fields[2])
4592+{
4593+ unsigned num_int = 0, num_float = 0;
4594+ int n = riscv_flatten_aggregate_argument (type, fields);
4595+ int i;
4596+
4597+ for (i = 0; i < n; i++)
4598+ {
4599+ num_float += SCALAR_FLOAT_TYPE_P (fields[i].type);
4600+ num_int += INTEGRAL_TYPE_P (fields[i].type);
4601+ }
4602+
4603+ return num_int == 1 && num_float == 1;
4604+}
4605+
4606+/* Return the representation of an argument passed or returned in an FPR
4607+ when the value has mode VALUE_MODE and the type has TYPE_MODE. The
4608+ two modes may be different for structures like:
4609+
4610+ struct __attribute__((packed)) foo { float f; }
4611+
4612+ where the SFmode value "f" is passed in REGNO but the struct itself
4613+ has mode BLKmode. */
4614+
4615+static rtx
4616+riscv_pass_fpr_single (enum machine_mode type_mode, unsigned regno,
4617+ enum machine_mode value_mode)
4618+{
4619+ rtx x = gen_rtx_REG (value_mode, regno);
4620+
4621+ if (type_mode != value_mode)
4622+ {
4623+ x = gen_rtx_EXPR_LIST (VOIDmode, x, const0_rtx);
4624+ x = gen_rtx_PARALLEL (type_mode, gen_rtvec (1, x));
4625+ }
4626+ return x;
4627+}
4628+
4629+/* Pass or return a composite value in the FPR pair REGNO and REGNO + 1.
4630+ MODE is the mode of the composite. MODE1 and OFFSET1 are the mode and
4631+ byte offset for the first value, likewise MODE2 and OFFSET2 for the
4632+ second value. */
4633+
4634+static rtx
4635+riscv_pass_fpr_pair (enum machine_mode mode, unsigned regno1,
4636+ enum machine_mode mode1, HOST_WIDE_INT offset1,
4637+ unsigned regno2, enum machine_mode mode2,
4638+ HOST_WIDE_INT offset2)
4639+{
4640+ return gen_rtx_PARALLEL
4641+ (mode,
4642+ gen_rtvec (2,
4643+ gen_rtx_EXPR_LIST (VOIDmode,
4644+ gen_rtx_REG (mode1, regno1),
4645+ GEN_INT (offset1)),
4646+ gen_rtx_EXPR_LIST (VOIDmode,
4647+ gen_rtx_REG (mode2, regno2),
4648+ GEN_INT (offset2))));
4649+}
4650+
4651+/* Fill INFO with information about a single argument, and return an
4652+ RTL pattern to pass or return the argument. CUM is the cumulative
4653+ state for earlier arguments. MODE is the mode of this argument and
4654+ TYPE is its type (if known). NAMED is true if this is a named
4655+ (fixed) argument rather than a variable one. RETURN_P is true if
4656+ returning the argument, or false if passing the argument. */
4657+
4658+static rtx
4659+riscv_get_arg_info (struct riscv_arg_info *info, const CUMULATIVE_ARGS *cum,
4660+ enum machine_mode mode, const_tree type, bool named,
4661+ bool return_p)
4662+{
4663+ unsigned num_bytes, num_words;
4664+ unsigned fpr_base = return_p ? FP_RETURN : FP_ARG_FIRST;
4665+ unsigned gpr_base = return_p ? GP_RETURN : GP_ARG_FIRST;
4666+ unsigned alignment = riscv_function_arg_boundary (mode, type);
4667+
4668+ memset (info, 0, sizeof (*info));
4669+ info->gpr_offset = cum->num_gprs;
4670+ info->fpr_offset = cum->num_fprs;
4671+
4672+ if (named)
4673+ {
4674+ riscv_aggregate_field fields[2];
4675+ unsigned tmp;
4676+ unsigned fregno = fpr_base + info->fpr_offset;
4677+ unsigned gregno = gpr_base + info->gpr_offset;
4678+
4679+ /* Pass one- or two-element floating-point aggregates in FPRs. */
4680+ if ((info->num_fprs = riscv_pass_aggregate_in_fpr_pair_p (type, fields))
4681+ && info->fpr_offset + info->num_fprs <= MAX_ARGS_IN_REGISTERS)
4682+ switch (info->num_fprs)
4683+ {
4684+ case 1:
4685+ return riscv_pass_fpr_single (mode, fregno,
4686+ TYPE_MODE (fields[0].type));
4687+
4688+ case 2:
4689+ return riscv_pass_fpr_pair (mode, fregno,
4690+ TYPE_MODE (fields[0].type),
4691+ fields[0].offset,
4692+ fregno + 1,
4693+ TYPE_MODE (fields[1].type),
4694+ fields[1].offset);
4695+
4696+ default:
4697+ gcc_unreachable ();
4698+ }
4699+
4700+ /* Pass real and complex floating-point numbers in FPRs. */
4701+ if ((info->num_fprs = riscv_pass_mode_in_fpr_p (mode))
4702+ && info->fpr_offset + info->num_fprs <= MAX_ARGS_IN_REGISTERS)
4703+ switch (GET_MODE_CLASS (mode))
4704+ {
4705+ case MODE_FLOAT:
4706+ return gen_rtx_REG (mode, fregno);
4707+
4708+ case MODE_COMPLEX_FLOAT:
4709+ return riscv_pass_fpr_pair (mode, fregno, GET_MODE_INNER (mode), 0,
4710+ fregno + 1, GET_MODE_INNER (mode),
4711+ GET_MODE_UNIT_SIZE (mode));
4712+
4713+ default:
4714+ gcc_unreachable ();
4715+ }
4716+
4717+ /* Pass structs with one float and one integer in an FPR and a GPR. */
4718+ if (riscv_pass_aggregate_in_fpr_and_gpr_p (type, fields)
4719+ && info->gpr_offset < MAX_ARGS_IN_REGISTERS
4720+ && info->fpr_offset < MAX_ARGS_IN_REGISTERS)
4721+ {
4722+ info->num_gprs = 1;
4723+ info->num_fprs = 1;
4724+
4725+ if (!SCALAR_FLOAT_TYPE_P (fields[0].type)){
4726+ tmp = fregno;
4727+ fregno = gregno;
4728+ gregno = tmp;
4729+ }
4730+
4731+ return riscv_pass_fpr_pair (mode, fregno, TYPE_MODE (fields[0].type),
4732+ fields[0].offset,
4733+ gregno, TYPE_MODE (fields[1].type),
4734+ fields[1].offset);
4735+ }
4736+ }
4737+
4738+ /* Work out the size of the argument. */
4739+ num_bytes = type ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
4740+ num_words = (num_bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
4741+
4742+ /* Doubleword-aligned varargs start on an even register boundary. */
4743+ if (!named && num_bytes != 0 && alignment > BITS_PER_WORD)
4744+ info->gpr_offset += info->gpr_offset & 1;
4745+
4746+ /* Partition the argument between registers and stack. */
4747+ info->num_fprs = 0;
4748+ info->num_gprs = MIN (num_words, MAX_ARGS_IN_REGISTERS - info->gpr_offset);
4749+ info->stack_p = (num_words - info->num_gprs) != 0;
4750+
4751+ if (info->num_gprs || return_p)
4752+ return gen_rtx_REG (mode, gpr_base + info->gpr_offset);
4753+
4754+ return NULL_RTX;
4755+}
4756+
4757+/* Implement TARGET_FUNCTION_ARG. */
4758+
4759+static rtx
4760+riscv_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
4761+ const_tree type, bool named)
4762+{
4763+ struct riscv_arg_info info;
4764+
4765+ if (mode == VOIDmode)
4766+ return NULL;
4767+
4768+ return riscv_get_arg_info (&info, cum, mode, type, named, false);
4769+}
4770+
4771+/* Implement TARGET_FUNCTION_ARG_ADVANCE. */
4772+static void
4773+riscv_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
4774+ const_tree type, bool named)
4775+{
4776+ struct riscv_arg_info info;
4777+
4778+ riscv_get_arg_info (&info, cum, mode, type, named, false);
4779+
4780+ /* Advance the register count. This has the effect of setting
4781+ num_gprs to MAX_ARGS_IN_REGISTERS if a doubleword-aligned
4782+ argument required us to skip the final GPR and pass the whole
4783+ argument on the stack. */
4784+ cum->num_fprs = info.fpr_offset + info.num_fprs;
4785+ cum->num_gprs = info.gpr_offset + info.num_gprs;
4786+}
4787+
4788+/* Implement TARGET_ARG_PARTIAL_BYTES. */
4789+
4790+static int
4791+riscv_arg_partial_bytes (CUMULATIVE_ARGS *cum,
4792+ enum machine_mode mode, tree type, bool named)
4793+{
4794+ struct riscv_arg_info arg;
4795+
4796+ riscv_get_arg_info (&arg, cum, mode, type, named, false);
4797+ return arg.stack_p ? arg.num_gprs * UNITS_PER_WORD : 0;
4798+}
4799+
4800+/* Implement FUNCTION_VALUE and LIBCALL_VALUE. For normal calls,
4801+ VALTYPE is the return type and MODE is VOIDmode. For libcalls,
4802+ VALTYPE is null and MODE is the mode of the return value. */
4803+
4804+rtx
4805+riscv_function_value (const_tree type, const_tree func, enum machine_mode mode)
4806+{
4807+ struct riscv_arg_info info;
4808+ CUMULATIVE_ARGS args;
4809+
4810+ if (type)
4811+ {
4812+ int unsigned_p = TYPE_UNSIGNED (type);
4813+
4814+ mode = TYPE_MODE (type);
4815+
4816+ /* Since TARGET_PROMOTE_FUNCTION_MODE unconditionally promotes,
4817+ return values, promote the mode here too. */
4818+ mode = promote_function_mode (type, mode, &unsigned_p, func, 1);
4819+ }
4820+
4821+ memset (&args, 0, sizeof args);
4822+ return riscv_get_arg_info (&info, &args, mode, type, true, true);
4823+}
4824+
4825+/* Implement TARGET_PASS_BY_REFERENCE. */
4826+static bool
4827+riscv_pass_by_reference (CUMULATIVE_ARGS *cum, enum machine_mode mode,
4828+ const_tree type, bool named)
4829+{
4830+ HOST_WIDE_INT size = type ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
4831+ struct riscv_arg_info info;
4832+
4833+ /* ??? std_gimplify_va_arg_expr passes NULL for cum. Fortunately, we
4834+ never pass variadic arguments in floating-point registers, so we can
4835+ avoid the call to riscv_get_arg_info in this case. */
4836+ if (cum != NULL)
4837+ {
4838+ /* Don't pass by reference if we can use a floating-point register. */
4839+ riscv_get_arg_info (&info, cum, mode, type, named, false);
4840+ if (info.num_fprs)
4841+ return false;
4842+ }
4843+
4844+ /* Pass by reference if the data do not fit in two integer registers. */
4845+ return !IN_RANGE (size, 0, 2 * UNITS_PER_WORD);
4846+}
4847+
4848+/* Implement TARGET_RETURN_IN_MEMORY. */
4849+static bool
4850+riscv_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED)
4851+{
4852+ CUMULATIVE_ARGS cum;
4853+
4854+ /* The rules for returning in memory are the same as for passing the
4855+ first named argument by reference. */
4856+ memset (&cum, 0, sizeof cum);
4857+ return riscv_pass_by_reference (&cum, TYPE_MODE (type), type, true);
4858+}
4859+
4860+/* Implement TARGET_SETUP_INCOMING_VARARGS. */
4861+
4862+static void
4863+riscv_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
4864+ tree type, int *pretend_size ATTRIBUTE_UNUSED,
4865+ int no_rtl)
4866+{
4867+ CUMULATIVE_ARGS local_cum;
4868+ int gp_saved;
4869+
4870+ /* The caller has advanced CUM up to, but not beyond, the last named
4871+ argument. Advance a local copy of CUM past the last "real" named
4872+ argument, to find out how many registers are left over. */
4873+ local_cum = *cum;
4874+ riscv_function_arg_advance (&local_cum, mode, type, 1);
4875+
4876+ /* Found out how many registers we need to save. */
4877+ gp_saved = MAX_ARGS_IN_REGISTERS - local_cum.num_gprs;
4878+
4879+ if (!no_rtl && gp_saved > 0)
4880+ {
4881+ rtx ptr = plus_constant (virtual_incoming_args_rtx,
4882+ REG_PARM_STACK_SPACE (cfun->decl)
4883+ - gp_saved * UNITS_PER_WORD);
4884+ rtx mem = gen_frame_mem (BLKmode, ptr);
4885+ set_mem_alias_set (mem, get_varargs_alias_set ());
4886+
4887+ move_block_from_reg (local_cum.num_gprs + GP_ARG_FIRST,
4888+ mem, gp_saved);
4889+ }
4890+ if (REG_PARM_STACK_SPACE (cfun->decl) == 0)
4891+ cfun->machine->varargs_size = gp_saved * UNITS_PER_WORD;
4892+}
4893+
4894+/* Implement TARGET_EXPAND_BUILTIN_VA_START. */
4895+
4896+static void
4897+riscv_va_start (tree valist, rtx nextarg)
4898+{
4899+ nextarg = plus_constant (nextarg, -cfun->machine->varargs_size);
4900+ std_expand_builtin_va_start (valist, nextarg);
4901+}
4902+
4903+/* Make ADDR suitable for use as a call or sibcall target. */
4904+
4905+rtx
4906+riscv_legitimize_call_address (rtx addr)
4907+{
4908+ if (!call_insn_operand (addr, VOIDmode))
4909+ {
4910+ rtx reg = RISCV_PROLOGUE_TEMP (Pmode);
4911+ riscv_emit_move (reg, addr);
4912+ return reg;
4913+ }
4914+ return addr;
4915+}
4916+
4917+/* Print symbolic operand OP, which is part of a HIGH or LO_SUM
4918+ in context CONTEXT. HI_RELOC indicates a high-part reloc. */
4919+
4920+static void
4921+riscv_print_operand_reloc (FILE *file, rtx op, bool hi_reloc)
4922+{
4923+ const char *reloc;
4924+
4925+ switch (riscv_classify_symbolic_expression (op))
4926+ {
4927+ case SYMBOL_ABSOLUTE:
4928+ reloc = hi_reloc ? "%hi" : "%lo";
4929+ break;
4930+
4931+ case SYMBOL_PCREL:
4932+ reloc = hi_reloc ? "%pcrel_hi" : "%pcrel_lo";
4933+ break;
4934+
4935+ case SYMBOL_TLS_LE:
4936+ reloc = hi_reloc ? "%tprel_hi" : "%tprel_lo";
4937+ break;
4938+
4939+ default:
4940+ gcc_unreachable ();
4941+ }
4942+
4943+ fprintf (file, "%s(", reloc);
4944+ output_addr_const (file, riscv_strip_unspec_address (op));
4945+ fputc (')', file);
4946+}
4947+
4948+/* Implement TARGET_PRINT_OPERAND. The RISCV-specific operand codes are:
4949+
4950+ 'h' Print the high-part relocation associated with OP, after stripping
4951+ any outermost HIGH.
4952+ 'R' Print the low-part relocation associated with OP.
4953+ 'C' Print the integer branch condition for comparison OP.
4954+ 'A' Print the atomic operation suffix for memory model OP.
4955+ 'F' Print a FENCE if the memory model requires a release.
4956+ 'z' Print x0 if OP is zero, otherwise print OP normally. */
4957+
4958+static void
4959+riscv_print_operand (FILE *file, rtx op, int letter)
4960+{
4961+ /*enum machine_mode mode = GET_MODE (op);*/
4962+ enum rtx_code code = GET_CODE (op);
4963+
4964+ switch (letter)
4965+ {
4966+ case 'h':
4967+ if (code == HIGH)
4968+ op = XEXP (op, 0);
4969+ riscv_print_operand_reloc (file, op, true);
4970+ break;
4971+
4972+ case 'R':
4973+ riscv_print_operand_reloc (file, op, false);
4974+ break;
4975+
4976+ case 'C':
4977+ /* The RTL names match the instruction names. */
4978+ fputs (GET_RTX_NAME (code), file);
4979+ break;
4980+
4981+ case 'A':
4982+ /* Always add the .aq suffix, we don't want to check the memory model*/
4983+ fputs (".aq", file);
4984+ break;
4985+
4986+ case 'F':
4987+ /* Always add the fence, we don't want to check the memory model*/
4988+ fputs ("fence rw,w; ", file);
4989+ break;
4990+
4991+ default:
4992+ switch (code)
4993+ {
4994+ case REG:
4995+ if (letter && letter != 'z')
4996+ output_operand_lossage ("invalid use of '%%%c'", letter);
4997+ fprintf (file, "%s", reg_names[REGNO (op)]);
4998+ break;
4999+
5000+ case MEM:
5001+ if (letter && letter != 'z')
5002+ output_operand_lossage ("invalid use of '%%%c'", letter);
5003+ else
5004+ output_address (XEXP (op, 0));
5005+ break;
5006+
5007+ default:
5008+ if (letter == 'z' && op == CONST0_RTX (GET_MODE (op)))
5009+ fputs (reg_names[GP_REG_FIRST], file);
5010+ else if (letter && letter != 'z')
5011+ output_operand_lossage ("invalid use of '%%%c'", letter);
5012+ else
5013+ output_addr_const (file, riscv_strip_unspec_address (op));
5014+ break;
5015+ }
5016+ }
5017+}
5018+
5019+/* Implement TARGET_PRINT_OPERAND_ADDRESS. */
5020+
5021+static void
5022+riscv_print_operand_address (FILE *file, rtx x)
5023+{
5024+ struct riscv_address_info addr;
5025+
5026+ if (riscv_classify_address (&addr, x, word_mode, true))
5027+ switch (addr.type)
5028+ {
5029+ case ADDRESS_REG:
5030+ riscv_print_operand (file, addr.offset, 0);
5031+ fprintf (file, "(%s)", reg_names[REGNO (addr.reg)]);
5032+ return;
5033+
5034+ case ADDRESS_LO_SUM:
5035+ riscv_print_operand_reloc (file, addr.offset, false);
5036+ fprintf (file, "(%s)", reg_names[REGNO (addr.reg)]);
5037+ return;
5038+
5039+ case ADDRESS_CONST_INT:
5040+ output_addr_const (file, x);
5041+ fprintf (file, "(%s)", reg_names[GP_REG_FIRST]);
5042+ return;
5043+
5044+ case ADDRESS_SYMBOLIC:
5045+ output_addr_const (file, riscv_strip_unspec_address (x));
5046+ return;
5047+ }
5048+ gcc_unreachable ();
5049+}
5050+
5051+static bool
5052+riscv_size_ok_for_small_data_p (int size)
5053+{
5054+ return g_switch_value && IN_RANGE (size, 1, g_switch_value);
5055+}
5056+
5057+/* Return true if EXP should be placed in the small data section. */
5058+
5059+static bool
5060+riscv_in_small_data_p (const_tree x)
5061+{
5062+ if (TREE_CODE (x) == STRING_CST || TREE_CODE (x) == FUNCTION_DECL)
5063+ return false;
5064+
5065+ if (TREE_CODE (x) == VAR_DECL && DECL_SECTION_NAME (x))
5066+ {
5067+ const char *sec = DECL_SECTION_NAME (x);
5068+ return strcmp (sec, ".sdata") == 0 || strcmp (sec, ".sbss") == 0;
5069+ }
5070+
5071+ return riscv_size_ok_for_small_data_p (int_size_in_bytes (TREE_TYPE (x)));
5072+}
5073+
5074+/* Return a section for X, handling small data. */
5075+
5076+static section *
5077+riscv_elf_select_rtx_section (enum machine_mode mode, rtx x,
5078+ unsigned HOST_WIDE_INT align)
5079+{
5080+ section *s = default_elf_select_rtx_section (mode, x, align);
5081+
5082+ if (riscv_size_ok_for_small_data_p (GET_MODE_SIZE (mode)))
5083+ {
5084+ if (strncmp (s->named.name, ".rodata.cst", strlen (".rodata.cst")) == 0)
5085+ {
5086+ /* Rename .rodata.cst* to .srodata.cst*. */
5087+ char *name = (char *) alloca (strlen (s->named.name) + 2);
5088+ sprintf (name, ".s%s", s->named.name + 1);
5089+ return get_section (name, s->named.common.flags, NULL);
5090+ }
5091+
5092+ if (s == data_section)
5093+ return sdata_section;
5094+ }
5095+
5096+ return s;
5097+}
5098+
5099+/* Make the last instruction frame-related and note that it performs
5100+ the operation described by FRAME_PATTERN. */
5101+
5102+static void
5103+riscv_set_frame_expr (rtx frame_pattern)
5104+{
5105+ rtx insn;
5106+
5107+ insn = get_last_insn ();
5108+ RTX_FRAME_RELATED_P (insn) = 1;
5109+ REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
5110+ frame_pattern,
5111+ REG_NOTES (insn));
5112+}
5113+
5114+/* Return a frame-related rtx that stores REG at MEM.
5115+ REG must be a single register. */
5116+
5117+static rtx
5118+riscv_frame_set (rtx mem, rtx reg)
5119+{
5120+ rtx set = gen_rtx_SET (VOIDmode, mem, reg);
5121+ RTX_FRAME_RELATED_P (set) = 1;
5122+ return set;
5123+}
5124+
5125+/* Return true if the current function must save register REGNO. */
5126+
5127+static bool
5128+riscv_save_reg_p (unsigned int regno)
5129+{
5130+ bool call_saved = !global_regs[regno] && !call_used_regs[regno];
5131+ bool might_clobber = crtl->saves_all_registers
5132+ || df_regs_ever_live_p (regno);
5133+
5134+ if (call_saved && might_clobber)
5135+ return true;
5136+
5137+ if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
5138+ return true;
5139+
5140+ if (regno == RETURN_ADDR_REGNUM && crtl->calls_eh_return)
5141+ return true;
5142+
5143+ return false;
5144+}
5145+
5146+/* Determine whether to call GPR save/restore routines. */
5147+
5148+static bool
5149+riscv_use_save_libcall (const struct riscv_frame_info *frame)
5150+{
5151+ if (!TARGET_SAVE_RESTORE || crtl->calls_eh_return || frame_pointer_needed)
5152+ return false;
5153+
5154+ return frame->save_libcall_adjustment != 0;
5155+}
5156+
5157+/* Determine which GPR save/restore routine to call. */
5158+
5159+static unsigned
5160+riscv_save_libcall_count (unsigned mask)
5161+{
5162+ unsigned n;
5163+ for (n = GP_REG_LAST; n > GP_REG_FIRST; n--)
5164+ if (BITSET_P (mask, n))
5165+ return CALLEE_SAVED_REG_NUMBER (n) + 1;
5166+ abort ();
5167+}
5168+
5169+/* Populate the current function's riscv_frame_info structure.
5170+
5171+ RISC-V stack frames grown downward. High addresses are at the top.
5172+
5173+ +-------------------------------+
5174+ | |
5175+ | incoming stack arguments |
5176+ | |
5177+ +-------------------------------+ <-- incoming stack pointer
5178+ | |
5179+ | callee-allocated save area |
5180+ | for arguments that are |
5181+ | split between registers and |
5182+ | the stack |
5183+ | |
5184+ +-------------------------------+ <-- arg_pointer_rtx
5185+ | |
5186+ | callee-allocated save area |
5187+ | for register varargs |
5188+ | |
5189+ +-------------------------------+ <-- hard_frame_pointer_rtx;
5190+ | | stack_pointer_rtx + gp_sp_offset
5191+ | GPR save area | + UNITS_PER_WORD
5192+ | |
5193+ +-------------------------------+ <-- stack_pointer_rtx + fp_sp_offset
5194+ | | + UNITS_PER_HWVALUE
5195+ | FPR save area |
5196+ | |
5197+ +-------------------------------+ <-- frame_pointer_rtx (virtual)
5198+ | |
5199+ | local variables |
5200+ | |
5201+ P +-------------------------------+
5202+ | |
5203+ | outgoing stack arguments |
5204+ | |
5205+ +-------------------------------+ <-- stack_pointer_rtx
5206+
5207+ Dynamic stack allocations such as alloca insert data at point P.
5208+ They decrease stack_pointer_rtx but leave frame_pointer_rtx and
5209+ hard_frame_pointer_rtx unchanged. */
5210+
5211+static void
5212+riscv_compute_frame_info (void)
5213+{
5214+ struct riscv_frame_info *frame;
5215+ HOST_WIDE_INT offset;
5216+ unsigned int regno, i, num_x_saved = 0, num_f_saved = 0;
5217+
5218+ frame = &cfun->machine->frame;
5219+ memset (frame, 0, sizeof (*frame));
5220+
5221+ /* Find out which GPRs we need to save. */
5222+ for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
5223+ if (riscv_save_reg_p (regno))
5224+ frame->mask |= 1 << (regno - GP_REG_FIRST), num_x_saved++;
5225+
5226+ /* If this function calls eh_return, we must also save and restore the
5227+ EH data registers. */
5228+ if (crtl->calls_eh_return)
5229+ for (i = 0; (regno = EH_RETURN_DATA_REGNO (i)) != INVALID_REGNUM; i++)
5230+ frame->mask |= 1 << (regno - GP_REG_FIRST), num_x_saved++;
5231+
5232+ /* Find out which FPRs we need to save. This loop must iterate over
5233+ the same space as its companion in riscv_for_each_saved_reg. */
5234+ if (TARGET_HARD_FLOAT)
5235+ for (regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
5236+ if (riscv_save_reg_p (regno))
5237+ frame->fmask |= 1 << (regno - FP_REG_FIRST), num_f_saved++;
5238+
5239+ /* At the bottom of the frame are any outgoing stack arguments. */
5240+ offset = crtl->outgoing_args_size;
5241+ /* Next are local stack variables. */
5242+ offset += RISCV_STACK_ALIGN (get_frame_size ());
5243+ /* The virtual frame pointer points above the local variables. */
5244+ frame->frame_pointer_offset = offset;
5245+ /* Next are the callee-saved FPRs. */
5246+ if (frame->fmask)
5247+ offset += RISCV_STACK_ALIGN (num_f_saved * UNITS_PER_FP_REG);
5248+ frame->fp_sp_offset = offset - UNITS_PER_FP_REG;
5249+ /* Next are the callee-saved GPRs. */
5250+ if (frame->mask)
5251+ {
5252+ unsigned x_save_size = RISCV_STACK_ALIGN (num_x_saved * UNITS_PER_WORD);
5253+ unsigned num_save_restore = 1 + riscv_save_libcall_count (frame->mask);
5254+
5255+ /* Only use save/restore routines if they don't alter the stack size. */
5256+ if (RISCV_STACK_ALIGN (num_save_restore * UNITS_PER_WORD) == x_save_size)
5257+ frame->save_libcall_adjustment = x_save_size;
5258+
5259+ offset += x_save_size;
5260+ }
5261+ frame->gp_sp_offset = offset - UNITS_PER_WORD;
5262+ /* The hard frame pointer points above the callee-saved GPRs. */
5263+ frame->hard_frame_pointer_offset = offset;
5264+ /* Above the hard frame pointer is the callee-allocated varags save area. */
5265+ offset += RISCV_STACK_ALIGN (cfun->machine->varargs_size);
5266+ frame->arg_pointer_offset = offset;
5267+ /* Next is the callee-allocated area for pretend stack arguments. */
5268+ offset += crtl->args.pretend_args_size;
5269+ frame->total_size = offset;
5270+ /* Next points the incoming stack pointer and any incoming arguments. */
5271+
5272+ /* Only use save/restore routines when the GPRs are atop the frame. */
5273+ if (frame->hard_frame_pointer_offset != frame->total_size)
5274+ frame->save_libcall_adjustment = 0;
5275+}
5276+
5277+/* Make sure that we're not trying to eliminate to the wrong hard frame
5278+ pointer. */
5279+
5280+static bool
5281+riscv_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
5282+{
5283+ return (to == HARD_FRAME_POINTER_REGNUM || to == STACK_POINTER_REGNUM);
5284+}
5285+
5286+/* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame pointer
5287+ or argument pointer. TO is either the stack pointer or hard frame
5288+ pointer. */
5289+
5290+HOST_WIDE_INT
5291+riscv_initial_elimination_offset (int from, int to)
5292+{
5293+ HOST_WIDE_INT src, dest;
5294+
5295+ riscv_compute_frame_info ();
5296+
5297+ if (to == HARD_FRAME_POINTER_REGNUM)
5298+ dest = cfun->machine->frame.hard_frame_pointer_offset;
5299+ else if (to == STACK_POINTER_REGNUM)
5300+ dest = 0; /* The stack pointer is the base of all offsets, hence 0. */
5301+ else
5302+ gcc_unreachable ();
5303+
5304+ if (from == FRAME_POINTER_REGNUM)
5305+ src = cfun->machine->frame.frame_pointer_offset;
5306+ else if (from == ARG_POINTER_REGNUM)
5307+ src = cfun->machine->frame.arg_pointer_offset;
5308+ else
5309+ gcc_unreachable ();
5310+
5311+ return src - dest;
5312+}
5313+
5314+/* Implement RETURN_ADDR_RTX. We do not support moving back to a
5315+ previous frame. */
5316+
5317+rtx
5318+riscv_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
5319+{
5320+ if (count != 0)
5321+ return const0_rtx;
5322+
5323+ return get_hard_reg_initial_val (Pmode, RETURN_ADDR_REGNUM);
5324+}
5325+
5326+/* Emit code to change the current function's return address to
5327+ ADDRESS. SCRATCH is available as a scratch register, if needed.
5328+ ADDRESS and SCRATCH are both word-mode GPRs. */
5329+
5330+void
5331+riscv_set_return_address (rtx address, rtx scratch)
5332+{
5333+ rtx slot_address;
5334+
5335+ gcc_assert (BITSET_P (cfun->machine->frame.mask, RETURN_ADDR_REGNUM));
5336+ slot_address = riscv_add_offset (scratch, stack_pointer_rtx,
5337+ cfun->machine->frame.gp_sp_offset);
5338+ riscv_emit_move (gen_frame_mem (GET_MODE (address), slot_address), address);
5339+}
5340+
5341+/* A function to save or store a register. The first argument is the
5342+ register and the second is the stack slot. */
5343+typedef void (*riscv_save_restore_fn) (rtx, rtx);
5344+
5345+/* Use FN to save or restore register REGNO. MODE is the register's
5346+ mode and OFFSET is the offset of its save slot from the current
5347+ stack pointer. */
5348+
5349+static void
5350+riscv_save_restore_reg (enum machine_mode mode, int regno,
5351+ HOST_WIDE_INT offset, riscv_save_restore_fn fn)
5352+{
5353+ rtx mem;
5354+
5355+ mem = gen_frame_mem (mode, plus_constant (stack_pointer_rtx, offset));
5356+ fn (gen_rtx_REG (mode, regno), mem);
5357+}
5358+
5359+/* Call FN for each register that is saved by the current function.
5360+ SP_OFFSET is the offset of the current stack pointer from the start
5361+ of the frame. */
5362+
5363+static void
5364+riscv_for_each_saved_reg (HOST_WIDE_INT sp_offset, riscv_save_restore_fn fn)
5365+{
5366+ HOST_WIDE_INT offset;
5367+ int regno;
5368+ /* Save the link register and s-registers. */
5369+ offset = cfun->machine->frame.gp_sp_offset - sp_offset;
5370+ for (regno = GP_REG_FIRST; regno <= GP_REG_LAST-1; regno++)
5371+ if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST))
5372+ {
5373+ riscv_save_restore_reg (word_mode, regno, offset, fn);
5374+ offset -= UNITS_PER_WORD;
5375+ }
5376+
5377+ /* This loop must iterate over the same space as its companion in
5378+ riscv_compute_frame_info. */
5379+ offset = cfun->machine->frame.fp_sp_offset - sp_offset;
5380+ for (regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
5381+ if (BITSET_P (cfun->machine->frame.fmask, regno - FP_REG_FIRST))
5382+ {
5383+ enum machine_mode mode = TARGET_DOUBLE_FLOAT ? DFmode : SFmode;
5384+
5385+ riscv_save_restore_reg (mode, regno, offset, fn);
5386+ offset -= GET_MODE_SIZE (mode);
5387+ }
5388+}
5389+
5390+/* Save register REG to MEM. Make the instruction frame-related. */
5391+
5392+static void
5393+riscv_save_reg (rtx reg, rtx mem)
5394+{
5395+ riscv_emit_move (mem, reg);
5396+ riscv_set_frame_expr (riscv_frame_set (mem, reg));
5397+}
5398+
5399+/* Restore register REG from MEM. */
5400+
5401+static void
5402+riscv_restore_reg (rtx reg, rtx mem)
5403+{
5404+ rtx insn = riscv_emit_move (reg, mem);
5405+ rtx dwarf = NULL_RTX;
5406+ dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
5407+ REG_NOTES (insn) = dwarf;
5408+
5409+ RTX_FRAME_RELATED_P (insn) = 1;
5410+}
5411+
5412+/* Return the code to invoke the GPR save routine. */
5413+
5414+const char *
5415+riscv_output_gpr_save (unsigned mask)
5416+{
5417+ static char s[32];
5418+ unsigned n = riscv_save_libcall_count (mask);
5419+
5420+ ssize_t bytes = snprintf (s, sizeof (s), "call\tt0,__riscv_save_%u", n);
5421+ gcc_assert ((size_t) bytes < sizeof (s));
5422+
5423+ return s;
5424+}
5425+
5426+/* For stack frames that can't be allocated with a single ADDI instruction,
5427+ compute the best value to initially allocate. It must at a minimum
5428+ allocate enough space to spill the callee-saved registers. */
5429+
5430+static HOST_WIDE_INT
5431+riscv_first_stack_step (struct riscv_frame_info *frame)
5432+{
5433+ HOST_WIDE_INT min_first_step = frame->total_size - frame->fp_sp_offset;
5434+ HOST_WIDE_INT max_first_step = IMM_REACH / 2 - STACK_BOUNDARY / 8;
5435+
5436+ if (SMALL_OPERAND (frame->total_size))
5437+ return frame->total_size;
5438+
5439+ /* As an optimization, use the least-significant bits of the total frame
5440+ size, so that the second adjustment step is just LUI + ADD. */
5441+ if (!SMALL_OPERAND (frame->total_size - max_first_step)
5442+ && frame->total_size % IMM_REACH < IMM_REACH / 2
5443+ && frame->total_size % IMM_REACH >= min_first_step)
5444+ return frame->total_size % IMM_REACH;
5445+
5446+ gcc_assert (min_first_step <= max_first_step);
5447+ return max_first_step;
5448+}
5449+
5450+static rtx
5451+riscv_adjust_libcall_cfi_prologue ()
5452+{
5453+ rtx dwarf = NULL_RTX;
5454+ rtx adjust_sp_rtx, reg, mem, insn;
5455+ int saved_size = cfun->machine->frame.save_libcall_adjustment;
5456+ int offset;
5457+ int regno;
5458+
5459+ for (regno = GP_REG_FIRST; regno <= GP_REG_LAST-1; regno++)
5460+ if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST))
5461+ {
5462+ /* The save order is ra, s0, s1, s2 to s11. */
5463+ if (regno == RETURN_ADDR_REGNUM)
5464+ offset = saved_size - UNITS_PER_WORD;
5465+ else if (regno == S0_REGNUM)
5466+ offset = saved_size - UNITS_PER_WORD * 2;
5467+ else if (regno == S1_REGNUM)
5468+ offset = saved_size - UNITS_PER_WORD * 3;
5469+ else
5470+ offset = saved_size - ((regno - S2_REGNUM + 4) * UNITS_PER_WORD);
5471+
5472+ reg = gen_rtx_REG (SImode, regno);
5473+ mem = gen_frame_mem (SImode, plus_constant (stack_pointer_rtx, offset));
5474+
5475+ insn = gen_rtx_SET (VOIDmode, mem, reg);
5476+ dwarf = alloc_reg_note (REG_CFA_OFFSET, insn, dwarf);
5477+ }
5478+
5479+ /* Debug info for adjust sp. */
5480+ adjust_sp_rtx = gen_add3_insn (stack_pointer_rtx,
5481+ stack_pointer_rtx, GEN_INT (-saved_size));
5482+ dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, adjust_sp_rtx,
5483+ dwarf);
5484+ return dwarf;
5485+}
5486+
5487+static void
5488+riscv_emit_stack_tie (void)
5489+{
5490+ if (Pmode == SImode)
5491+ emit_insn (gen_stack_tiesi (stack_pointer_rtx, hard_frame_pointer_rtx));
5492+ else
5493+ emit_insn (gen_stack_tiedi (stack_pointer_rtx, hard_frame_pointer_rtx));
5494+}
5495+
5496+/* Expand the "prologue" pattern. */
5497+
5498+void
5499+riscv_expand_prologue (void)
5500+{
5501+ struct riscv_frame_info *frame = &cfun->machine->frame;
5502+ HOST_WIDE_INT size = frame->total_size;
5503+ unsigned mask = frame->mask;
5504+ rtx insn;
5505+
5506+ if (flag_stack_usage)
5507+ current_function_static_stack_size = size;
5508+
5509+ /* When optimizing for size, call a subroutine to save the registers. */
5510+ if (riscv_use_save_libcall (frame))
5511+ {
5512+ rtx dwarf = NULL_RTX;
5513+ dwarf = riscv_adjust_libcall_cfi_prologue ();
5514+
5515+ frame->mask = 0; /* Temporarily fib that we need not save GPRs. */
5516+ size -= frame->save_libcall_adjustment;
5517+ insn = emit_insn (gen_gpr_save (GEN_INT (mask)));
5518+
5519+ RTX_FRAME_RELATED_P (insn) = 1;
5520+ REG_NOTES (insn) = dwarf;
5521+ }
5522+
5523+ /* Save the registers. */
5524+ if ((frame->mask | frame->fmask) != 0)
5525+ {
5526+ HOST_WIDE_INT step1 = MIN (size, riscv_first_stack_step (frame));
5527+
5528+ insn = gen_add3_insn (stack_pointer_rtx,
5529+ stack_pointer_rtx,
5530+ GEN_INT (-step1));
5531+ RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
5532+ size -= step1;
5533+ riscv_for_each_saved_reg (size, riscv_save_reg);
5534+ }
5535+
5536+ frame->mask = mask; /* Undo the above fib. */
5537+
5538+ /* Set up the frame pointer, if we're using one. */
5539+ if (frame_pointer_needed)
5540+ {
5541+ insn = gen_add3_insn (hard_frame_pointer_rtx, stack_pointer_rtx,
5542+ GEN_INT (frame->hard_frame_pointer_offset - size));
5543+ RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
5544+
5545+ riscv_emit_stack_tie ();
5546+ }
5547+
5548+ /* Allocate the rest of the frame. */
5549+ if (size > 0)
5550+ {
5551+ if (SMALL_OPERAND (-size))
5552+ {
5553+ insn = gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
5554+ GEN_INT (-size));
5555+ RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
5556+ }
5557+ else
5558+ {
5559+ riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode), GEN_INT (-size));
5560+ emit_insn (gen_add3_insn (stack_pointer_rtx,
5561+ stack_pointer_rtx,
5562+ RISCV_PROLOGUE_TEMP (Pmode)));
5563+
5564+ /* Describe the effect of the previous instructions. */
5565+ insn = plus_constant (stack_pointer_rtx, -size);
5566+ insn = gen_rtx_SET (VOIDmode, stack_pointer_rtx, insn);
5567+ riscv_set_frame_expr (insn);
5568+ }
5569+ }
5570+}
5571+
5572+static rtx
5573+riscv_adjust_libcall_cfi_epilogue ()
5574+{
5575+ rtx dwarf = NULL_RTX;
5576+ rtx adjust_sp_rtx, reg;
5577+ int regno;
5578+ int saved_size = cfun->machine->frame.save_libcall_adjustment;
5579+
5580+ /* Debug info for adjust sp. */
5581+ adjust_sp_rtx = gen_add3_insn (stack_pointer_rtx,
5582+ stack_pointer_rtx, GEN_INT (saved_size));
5583+ dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, adjust_sp_rtx,
5584+ dwarf);
5585+
5586+ for (regno = GP_REG_FIRST; regno <= GP_REG_LAST-1; regno++)
5587+ if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST))
5588+ {
5589+ reg = gen_rtx_REG (SImode, regno);
5590+ dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
5591+ }
5592+
5593+ return dwarf;
5594+}
5595+
5596+/* Expand an "epilogue" or "sibcall_epilogue" pattern; SIBCALL_P
5597+ says which. */
5598+
5599+void
5600+riscv_expand_epilogue (bool sibcall_p)
5601+{
5602+ /* Split the frame into two. STEP1 is the amount of stack we should
5603+ deallocate before restoring the registers. STEP2 is the amount we
5604+ should deallocate afterwards.
5605+
5606+ Start off by assuming that no registers need to be restored. */
5607+ struct riscv_frame_info *frame = &cfun->machine->frame;
5608+ unsigned mask = frame->mask;
5609+ HOST_WIDE_INT step1 = frame->total_size;
5610+ HOST_WIDE_INT step2 = 0;
5611+ bool use_restore_libcall = !sibcall_p && riscv_use_save_libcall (frame);
5612+ rtx ra = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
5613+ rtx insn, dwarf, cfa_adjust_rtx, cfa_adjust_value, adjust;
5614+
5615+ /* We need to add memory barrier to prevent read from deallocated stack. */
5616+ bool need_barrier_p = (get_frame_size ()
5617+ + cfun->machine->frame.arg_pointer_offset) != 0;
5618+
5619+ if (!sibcall_p && riscv_can_use_return_insn ())
5620+ {
5621+ emit_jump_insn (gen_return ());
5622+ return;
5623+ }
5624+
5625+ /* Move past any dynamic stack allocations. */
5626+ if (cfun->calls_alloca)
5627+ {
5628+ /* Emit a barrier to prevent loads from a deallocated stack. */
5629+ riscv_emit_stack_tie ();
5630+ need_barrier_p = false;
5631+
5632+ rtx adjust = GEN_INT (-frame->hard_frame_pointer_offset);
5633+ if (!SMALL_OPERAND (INTVAL (adjust)))
5634+ {
5635+ riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode), adjust);
5636+ adjust = RISCV_PROLOGUE_TEMP (Pmode);
5637+ }
5638+
5639+ insn = emit_insn (
5640+ gen_add3_insn (stack_pointer_rtx, hard_frame_pointer_rtx,
5641+ adjust));
5642+
5643+ dwarf = NULL_RTX;
5644+ cfa_adjust_value = gen_rtx_PLUS (
5645+ Pmode, hard_frame_pointer_rtx,
5646+ GEN_INT (-frame->hard_frame_pointer_offset));
5647+ cfa_adjust_rtx = gen_rtx_SET (VOIDmode, stack_pointer_rtx, cfa_adjust_value);
5648+ dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, cfa_adjust_rtx, dwarf);
5649+ RTX_FRAME_RELATED_P (insn) = 1;
5650+
5651+ REG_NOTES (insn) = dwarf;
5652+ }
5653+
5654+ /* If we need to restore registers, deallocate as much stack as
5655+ possible in the second step without going out of range. */
5656+ if ((frame->mask | frame->fmask) != 0)
5657+ {
5658+ step2 = riscv_first_stack_step (frame);
5659+ step1 -= step2;
5660+ }
5661+
5662+ /* Set TARGET to BASE + STEP1. */
5663+ if (step1 > 0)
5664+ {
5665+ /* Emit a barrier to prevent loads from a deallocated stack. */
5666+ riscv_emit_stack_tie ();
5667+ need_barrier_p = false;
5668+
5669+ /* Get an rtx for STEP1 that we can add to BASE. */
5670+ adjust = GEN_INT (step1);
5671+ if (!SMALL_OPERAND (step1))
5672+ {
5673+ riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode), adjust);
5674+ adjust = RISCV_PROLOGUE_TEMP (Pmode);
5675+ }
5676+
5677+ insn = emit_insn (
5678+ gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx, adjust));
5679+
5680+ dwarf = NULL_RTX;
5681+ cfa_adjust_rtx = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
5682+ GEN_INT (step2));
5683+
5684+ dwarf = alloc_reg_note (REG_CFA_DEF_CFA, cfa_adjust_rtx, dwarf);
5685+ RTX_FRAME_RELATED_P (insn) = 1;
5686+
5687+ REG_NOTES (insn) = dwarf;
5688+ }
5689+
5690+ if (use_restore_libcall)
5691+ frame->mask = 0; /* Temporarily fib that we need not save GPRs. */
5692+
5693+ /* Restore the registers. */
5694+ riscv_for_each_saved_reg (frame->total_size - step2, riscv_restore_reg);
5695+
5696+ if (use_restore_libcall)
5697+ {
5698+ frame->mask = mask; /* Undo the above fib. */
5699+ gcc_assert (step2 >= frame->save_libcall_adjustment);
5700+ step2 -= frame->save_libcall_adjustment;
5701+ }
5702+
5703+ if (need_barrier_p)
5704+ riscv_emit_stack_tie ();
5705+
5706+ /* Deallocate the final bit of the frame. */
5707+ if (step2 > 0)
5708+ {
5709+ insn = emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
5710+ GEN_INT (step2)));
5711+
5712+ dwarf = NULL_RTX;
5713+ cfa_adjust_rtx = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
5714+ const0_rtx);
5715+ dwarf = alloc_reg_note (REG_CFA_DEF_CFA, cfa_adjust_rtx, dwarf);
5716+ RTX_FRAME_RELATED_P (insn) = 1;
5717+
5718+ REG_NOTES (insn) = dwarf;
5719+ }
5720+
5721+ if (use_restore_libcall)
5722+ {
5723+ dwarf = riscv_adjust_libcall_cfi_epilogue ();
5724+ insn = emit_insn (gen_gpr_restore (GEN_INT (riscv_save_libcall_count (mask))));
5725+ RTX_FRAME_RELATED_P (insn) = 1;
5726+ REG_NOTES (insn) = dwarf;
5727+
5728+ emit_jump_insn (gen_gpr_restore_return (ra));
5729+ return;
5730+ }
5731+
5732+ /* Add in the __builtin_eh_return stack adjustment. */
5733+ if (crtl->calls_eh_return)
5734+ emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
5735+ EH_RETURN_STACKADJ_RTX));
5736+
5737+ if (!sibcall_p)
5738+ emit_jump_insn (gen_simple_return_internal (ra));
5739+}
5740+
5741+/* Return nonzero if this function is known to have a null epilogue.
5742+ This allows the optimizer to omit jumps to jumps if no stack
5743+ was created. */
5744+
5745+bool
5746+riscv_can_use_return_insn (void)
5747+{
5748+ return reload_completed && cfun->machine->frame.total_size == 0;
5749+}
5750+
5751+/* Implement TARGET_REGISTER_MOVE_COST. */
5752+
5753+static int
5754+riscv_register_move_cost (enum machine_mode mode,
5755+ reg_class_t from, reg_class_t to)
5756+{
5757+ return SECONDARY_MEMORY_NEEDED (from, to, mode) ? 8 : 2;
5758+}
5759+
5760+/* Return true if register REGNO can store a value of mode MODE. */
5761+
5762+bool
5763+riscv_hard_regno_mode_ok_p (unsigned int regno, enum machine_mode mode)
5764+{
5765+ unsigned int nregs = riscv_hard_regno_nregs (regno, mode);
5766+ unsigned i;
5767+
5768+ if (GP_REG_P (regno))
5769+ {
5770+ if (!GP_REG_P (regno + nregs - 1))
5771+ return false;
5772+ }
5773+ else if (FP_REG_P (regno))
5774+ {
5775+ if (!FP_REG_P (regno + nregs - 1))
5776+ return false;
5777+
5778+ if (GET_MODE_CLASS (mode) != MODE_FLOAT
5779+ && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
5780+ return false;
5781+
5782+ /* Only use callee-saved registers if a potential callee is guaranteed
5783+ to spill the requisite width. */
5784+ if (GET_MODE_UNIT_SIZE (mode) > UNITS_PER_FP_REG
5785+ || (!call_used_regs[regno]
5786+ && GET_MODE_UNIT_SIZE (mode) > UNITS_PER_FP_ARG))
5787+ return false;
5788+ }
5789+ else
5790+ return false;
5791+
5792+ /* Require same callee-savedness for all registers. */
5793+ for (i = 1; i < nregs; i++)
5794+ if (call_used_regs[regno] != call_used_regs[regno + i])
5795+ return false;
5796+
5797+ return true;
5798+}
5799+
5800+/* Implement HARD_REGNO_NREGS. */
5801+
5802+unsigned int
5803+riscv_hard_regno_nregs (int regno, enum machine_mode mode)
5804+{
5805+ if (FP_REG_P (regno))
5806+ return (GET_MODE_SIZE (mode) + UNITS_PER_FP_REG - 1) / UNITS_PER_FP_REG;
5807+
5808+ /* All other registers are word-sized. */
5809+ return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
5810+}
5811+
5812+/* Implement CLASS_MAX_NREGS. */
5813+unsigned char
5814+riscv_class_max_nregs (reg_class_t rclass, enum machine_mode mode)
5815+{
5816+ if (reg_class_subset_p (FP_REGS, rclass))
5817+ return riscv_hard_regno_nregs (FP_REG_FIRST, mode);
5818+
5819+ if (reg_class_subset_p (GR_REGS, rclass))
5820+ return riscv_hard_regno_nregs (GP_REG_FIRST, mode);
5821+
5822+ return 0;
5823+}
5824+
5825+/* Implement TARGET_PREFERRED_RELOAD_CLASS. */
5826+
5827+static reg_class_t
5828+riscv_preferred_reload_class (rtx x ATTRIBUTE_UNUSED, reg_class_t rclass)
5829+{
5830+ return reg_class_subset_p (FP_REGS, rclass) ? FP_REGS :
5831+ reg_class_subset_p (GR_REGS, rclass) ? GR_REGS :
5832+ rclass;
5833+}
5834+
5835+/* Implement TARGET_MEMORY_MOVE_COST. */
5836+
5837+static int
5838+riscv_memory_move_cost (enum machine_mode mode, reg_class_t rclass, bool in)
5839+{
5840+ return (tune_info->memory_cost
5841+ + memory_move_secondary_cost (mode, rclass, in));
5842+}
5843+
5844+/* Return the number of instructions that can be issued per cycle. */
5845+
5846+static int
5847+riscv_issue_rate (void)
5848+{
5849+ return tune_info->issue_rate;
5850+}
5851+
5852+/* Implement TARGET_ASM_FILE_START. */
5853+
5854+static void
5855+riscv_file_start (void)
5856+{
5857+ default_file_start ();
5858+
5859+ /* Instruct GAS to generate position-[in]dependent code. */
5860+ fprintf (asm_out_file, "\t.option %spic\n", (flag_pic ? "" : "no"));
5861+}
5862+
5863+/* Implement TARGET_ASM_OUTPUT_MI_THUNK. Generate rtl rather than asm text
5864+ in order to avoid duplicating too much logic from elsewhere. */
5865+
5866+static void
5867+riscv_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
5868+ HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
5869+ tree function)
5870+{
5871+ rtx this_rtx, temp1, temp2, fnaddr;
5872+ rtx insn;
5873+
5874+ /* Pretend to be a post-reload pass while generating rtl. */
5875+ reload_completed = 1;
5876+
5877+ /* Mark the end of the (empty) prologue. */
5878+ emit_note (NOTE_INSN_PROLOGUE_END);
5879+
5880+ /* Determine if we can use a sibcall to call FUNCTION directly. */
5881+ fnaddr = gen_rtx_MEM (FUNCTION_MODE, XEXP (DECL_RTL (function), 0));
5882+
5883+ /* We need two temporary registers in some cases. */
5884+ temp1 = gen_rtx_REG (Pmode, RISCV_PROLOGUE_TEMP_REGNUM);
5885+ temp2 = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM);
5886+
5887+ /* Find out which register contains the "this" pointer. */
5888+ if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
5889+ this_rtx = gen_rtx_REG (Pmode, GP_ARG_FIRST + 1);
5890+ else
5891+ this_rtx = gen_rtx_REG (Pmode, GP_ARG_FIRST);
5892+
5893+ /* Add DELTA to THIS_RTX. */
5894+ if (delta != 0)
5895+ {
5896+ rtx offset = GEN_INT (delta);
5897+ if (!SMALL_OPERAND (delta))
5898+ {
5899+ riscv_emit_move (temp1, offset);
5900+ offset = temp1;
5901+ }
5902+ emit_insn (gen_add3_insn (this_rtx, this_rtx, offset));
5903+ }
5904+
5905+ /* If needed, add *(*THIS_RTX + VCALL_OFFSET) to THIS_RTX. */
5906+ if (vcall_offset != 0)
5907+ {
5908+ rtx addr;
5909+
5910+ /* Set TEMP1 to *THIS_RTX. */
5911+ riscv_emit_move (temp1, gen_rtx_MEM (Pmode, this_rtx));
5912+
5913+ /* Set ADDR to a legitimate address for *THIS_RTX + VCALL_OFFSET. */
5914+ addr = riscv_add_offset (temp2, temp1, vcall_offset);
5915+
5916+ /* Load the offset and add it to THIS_RTX. */
5917+ riscv_emit_move (temp1, gen_rtx_MEM (Pmode, addr));
5918+ emit_insn (gen_add3_insn (this_rtx, this_rtx, temp1));
5919+ }
5920+
5921+ /* Jump to the target function. */
5922+ insn = emit_call_insn (gen_sibcall (fnaddr, const0_rtx, NULL, const0_rtx));
5923+ SIBLING_CALL_P (insn) = 1;
5924+
5925+ /* Run just enough of rest_of_compilation. This sequence was
5926+ "borrowed" from alpha.c. */
5927+ insn = get_insns ();
5928+ split_all_insns_noflow ();
5929+ shorten_branches (insn);
5930+ final_start_function (insn, file, 1);
5931+ final (insn, file, 1);
5932+ final_end_function ();
5933+
5934+ /* Clean up the vars set above. Note that final_end_function resets
5935+ the global pointer for us. */
5936+ reload_completed = 0;
5937+}
5938+
5939+/* Allocate a chunk of memory for per-function machine-dependent data. */
5940+
5941+static struct machine_function *
5942+riscv_init_machine_status (void)
5943+{
5944+ return ggc_alloc_cleared_machine_function ();
5945+}
5946+
5947+/* Implement TARGET_OPTION_OVERRIDE. */
5948+
5949+static void
5950+riscv_option_override (void)
5951+{
5952+ const struct riscv_cpu_info *cpu;
5953+
5954+#ifdef SUBTARGET_OVERRIDE_OPTIONS
5955+ SUBTARGET_OVERRIDE_OPTIONS;
5956+#endif
5957+
5958+ flag_pcc_struct_return = 0;
5959+
5960+ if (flag_pic)
5961+ g_switch_value = 0;
5962+
5963+ /* The presence of the M extension implies that division instructions
5964+ are present, so include them unless explicitly disabled. */
5965+ if (TARGET_MUL && (target_flags_explicit & MASK_DIV) == 0)
5966+ target_flags |= MASK_DIV;
5967+ else if (!TARGET_MUL && TARGET_DIV)
5968+ error ("-mdiv requires -march to subsume the %<M%> extension");
5969+
5970+ /* Likewise floating-point division and square root. */
5971+ if (TARGET_HARD_FLOAT && (target_flags_explicit & MASK_FDIV) == 0)
5972+ target_flags |= MASK_FDIV;
5973+
5974+ /* Handle -mtune. */
5975+ cpu = riscv_parse_cpu (riscv_tune_string ? riscv_tune_string :
5976+ RISCV_TUNE_STRING_DEFAULT);
5977+ tune_info = optimize_size ? &optimize_size_tune_info : cpu->tune_info;
5978+
5979+ /* If the user hasn't specified a branch cost, use the processor's
5980+ default. */
5981+ if (riscv_branch_cost == 0)
5982+ riscv_branch_cost = tune_info->branch_cost;
5983+
5984+ /* Function to allocate machine-dependent function status. */
5985+ init_machine_status = &riscv_init_machine_status;
5986+
5987+ if (flag_pic)
5988+ riscv_cmodel = CM_PIC;
5989+
5990+ /* We get better code with explicit relocs for CM_MEDLOW, but
5991+ worse code for the others (for now). Pick the best default. */
5992+ if ((target_flags_explicit & MASK_EXPLICIT_RELOCS) == 0)
5993+ if (riscv_cmodel == CM_MEDLOW)
5994+ target_flags |= MASK_EXPLICIT_RELOCS;
5995+
5996+ /* Require that the ISA supports the requested floating-point ABI. */
5997+ if (UNITS_PER_FP_ARG > (TARGET_HARD_FLOAT ? UNITS_PER_FP_REG : 0))
5998+ error ("requested ABI requires -march to subsume the %qc extension",
5999+ UNITS_PER_FP_ARG > 8 ? 'Q' : (UNITS_PER_FP_ARG > 4 ? 'D' : 'F'));
6000+
6001+ /* We do not yet support ILP32 on RV64. */
6002+ if (BITS_PER_WORD != POINTER_SIZE)
6003+ error ("ABI requires -march=rv%d", POINTER_SIZE);
6004+}
6005+
6006+/* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */
6007+
6008+static void
6009+riscv_conditional_register_usage (void)
6010+{
6011+ int regno;
6012+ if (!TARGET_HARD_FLOAT)
6013+ {
6014+ for (regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
6015+ fixed_regs[regno] = call_used_regs[regno] = 1;
6016+ }
6017+}
6018+
6019+/* Return a register priority for hard reg REGNO. */
6020+
6021+static int
6022+riscv_register_priority (int regno)
6023+{
6024+ /* Favor x8-x15/f8-f15 to improve the odds of RVC instruction selection. */
6025+ if (TARGET_RVC && (IN_RANGE (regno, GP_REG_FIRST + 8, GP_REG_FIRST + 15)
6026+ || IN_RANGE (regno, FP_REG_FIRST + 8, FP_REG_FIRST + 15)))
6027+ return 1;
6028+
6029+ return 0;
6030+}
6031+
6032+/* Implement TARGET_TRAMPOLINE_INIT. */
6033+
6034+static void
6035+riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
6036+{
6037+ rtx addr, end_addr, mem, target_function, uimm_mask, imm12_mask, fixup_value,
6038+ hi_chain, lui_hi_chain, hi_func, lui_hi_func, lo_chain,
6039+ addi_lo_chain, lo_func, jr_lo_func;
6040+ uint32_t trampoline[4];
6041+ unsigned int i;
6042+ HOST_WIDE_INT static_chain_offset, target_function_offset;
6043+
6044+ unsigned HOST_WIDE_INT lui_hi_chain_code, lui_hi_func_code;
6045+ unsigned HOST_WIDE_INT lo_chain_code, lo_func_code;
6046+
6047+
6048+ /* Work out the offsets of the pointers from the start of the
6049+ trampoline code. */
6050+ gcc_assert (ARRAY_SIZE (trampoline) * 4 == TRAMPOLINE_CODE_SIZE);
6051+
6052+ /* Get pointers to the beginning and end of the code block. */
6053+ addr = force_reg (Pmode, XEXP (m_tramp, 0));
6054+ end_addr = riscv_force_binary (Pmode, PLUS, addr,
6055+ GEN_INT (TRAMPOLINE_CODE_SIZE));
6056+
6057+
6058+ if (Pmode == SImode)
6059+ {
6060+ chain_value = force_reg (Pmode, chain_value);
6061+
6062+ target_function = force_reg (Pmode, XEXP (DECL_RTL (fndecl), 0));
6063+ /* lui t2, hi(chain)
6064+ lui t1, hi(func)
6065+ addi t2, t2, lo(chain)
6066+ jr r1, lo(func)
6067+ */
6068+ uimm_mask = force_reg (SImode, gen_int_mode (-IMM_REACH, SImode));
6069+
6070+ /* 0xfff. */
6071+ imm12_mask = gen_reg_rtx (SImode);
6072+ emit_insn (gen_one_cmplsi2 (imm12_mask, uimm_mask));
6073+
6074+ fixup_value = force_reg (SImode, gen_int_mode (IMM_REACH/2, SImode));
6075+
6076+ /* Gen lui t2, hi(chain). */
6077+ hi_chain = riscv_force_binary (SImode, PLUS, chain_value,
6078+ fixup_value);
6079+ hi_chain = riscv_force_binary (SImode, AND, hi_chain,
6080+ uimm_mask);
6081+ lui_hi_chain_code = OPCODE_LUI | (STATIC_CHAIN_REGNUM << SHIFT_RD);
6082+ lui_hi_chain = riscv_force_binary (SImode, IOR, hi_chain,
6083+ gen_int_mode (lui_hi_chain_code, SImode));
6084+
6085+ mem = adjust_address (m_tramp, SImode, 0);
6086+ riscv_emit_move (mem, lui_hi_chain);
6087+
6088+ /* Gen lui t1, hi(func). */
6089+ hi_func = riscv_force_binary (SImode, PLUS, target_function,
6090+ fixup_value);
6091+ hi_func = riscv_force_binary (SImode, AND, hi_func,
6092+ uimm_mask);
6093+ lui_hi_func_code = OPCODE_LUI | (RISCV_PROLOGUE_TEMP_REGNUM << SHIFT_RD);
6094+ lui_hi_func = riscv_force_binary (SImode, IOR, hi_func,
6095+ gen_int_mode (lui_hi_func_code, SImode));
6096+
6097+ mem = adjust_address (m_tramp, SImode, 1 * GET_MODE_SIZE (SImode));
6098+ riscv_emit_move (mem, lui_hi_func);
6099+
6100+ /* Gen addi t2, t2, lo(chain). */
6101+ lo_chain = riscv_force_binary (SImode, AND, chain_value,
6102+ imm12_mask);
6103+ lo_chain = riscv_force_binary (SImode, ASHIFT, lo_chain, GEN_INT (20));
6104+
6105+ lo_chain_code = OPCODE_ADDI
6106+ | (STATIC_CHAIN_REGNUM << SHIFT_RD)
6107+ | (STATIC_CHAIN_REGNUM << SHIFT_RS1);
6108+
6109+ addi_lo_chain = riscv_force_binary (SImode, IOR, lo_chain,
6110+ force_reg (SImode, GEN_INT (lo_chain_code)));
6111+
6112+ mem = adjust_address (m_tramp, SImode, 2 * GET_MODE_SIZE (SImode));
6113+ riscv_emit_move (mem, addi_lo_chain);
6114+
6115+ /* Gen jr r1, lo(func). */
6116+ lo_func = riscv_force_binary (SImode, AND, target_function,
6117+ imm12_mask);
6118+ lo_func = riscv_force_binary (SImode, ASHIFT, lo_func, GEN_INT (20));
6119+
6120+ lo_func_code = OPCODE_JALR | (RISCV_PROLOGUE_TEMP_REGNUM << SHIFT_RS1);
6121+
6122+ jr_lo_func = riscv_force_binary (SImode, IOR, lo_func,
6123+ force_reg (SImode, GEN_INT (lo_func_code)));
6124+
6125+ mem = adjust_address (m_tramp, SImode, 3 * GET_MODE_SIZE (SImode));
6126+ riscv_emit_move (mem, jr_lo_func);
6127+ }
6128+ else
6129+ {
6130+ static_chain_offset = TRAMPOLINE_CODE_SIZE;
6131+ target_function_offset = static_chain_offset + GET_MODE_SIZE (ptr_mode);
6132+
6133+ /* auipc t2, 0
6134+ l[wd] t1, target_function_offset(t2)
6135+ l[wd] t2, static_chain_offset(t2)
6136+ jr t1
6137+ */
6138+ trampoline[0] = OPCODE_AUIPC | (STATIC_CHAIN_REGNUM << SHIFT_RD);
6139+ trampoline[1] = (Pmode == DImode ? OPCODE_LD : OPCODE_LW)
6140+ | (RISCV_PROLOGUE_TEMP_REGNUM << SHIFT_RD)
6141+ | (STATIC_CHAIN_REGNUM << SHIFT_RS1)
6142+ | (target_function_offset << SHIFT_IMM);
6143+ trampoline[2] = (Pmode == DImode ? OPCODE_LD : OPCODE_LW)
6144+ | (STATIC_CHAIN_REGNUM << SHIFT_RD)
6145+ | (STATIC_CHAIN_REGNUM << SHIFT_RS1)
6146+ | (static_chain_offset << SHIFT_IMM);
6147+ trampoline[3] = OPCODE_JALR | (RISCV_PROLOGUE_TEMP_REGNUM << SHIFT_RS1);
6148+
6149+ /* Copy the trampoline code. */
6150+ for (i = 0; i < ARRAY_SIZE (trampoline); i++)
6151+ {
6152+ mem = adjust_address (m_tramp, SImode, i * GET_MODE_SIZE (SImode));
6153+ riscv_emit_move (mem, gen_int_mode (trampoline[i], SImode));
6154+ }
6155+
6156+ /* Set up the static chain pointer field. */
6157+ mem = adjust_address (m_tramp, ptr_mode, static_chain_offset);
6158+ riscv_emit_move (mem, chain_value);
6159+
6160+ /* Set up the target function field. */
6161+ mem = adjust_address (m_tramp, ptr_mode, target_function_offset);
6162+ riscv_emit_move (mem, XEXP (DECL_RTL (fndecl), 0));
6163+ }
6164+
6165+ /* Flush the code part of the trampoline. */
6166+ emit_insn (gen_add3_insn (end_addr, addr, GEN_INT (TRAMPOLINE_SIZE)));
6167+ emit_insn (gen_clear_cache (addr, end_addr));
6168+}
6169+
6170+/* Return leaf_function_p () and memoize the result. */
6171+
6172+static bool
6173+riscv_leaf_function_p (void)
6174+{
6175+ if (cfun->machine->is_leaf == 0)
6176+ cfun->machine->is_leaf = leaf_function_p () ? 1 : -1;
6177+
6178+ return cfun->machine->is_leaf > 0;
6179+}
6180+
6181+/* Implement TARGET_FUNCTION_OK_FOR_SIBCALL. */
6182+
6183+static bool
6184+riscv_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
6185+ tree exp ATTRIBUTE_UNUSED)
6186+{
6187+ /* When optimzing for size, don't use sibcalls in non-leaf routines */
6188+ if (TARGET_SAVE_RESTORE)
6189+ return riscv_leaf_function_p ();
6190+
6191+ return true;
6192+}
6193+
6194+/* Implement TARGET_CANNOT_COPY_INSN_P. */
6195+static bool
6196+riscv_cannot_copy_insn_p (rtx insn)
6197+{
6198+ return recog_memoized (insn) >= 0 && get_attr_cannot_copy (insn);
6199+}
6200+
6201+/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
6202+static const struct default_options riscv_option_optimization_table[] =
6203+ {
6204+ { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
6205+ { OPT_LEVELS_NONE, 0, NULL, 0 }
6206+ };
6207+
6208+/* Parse a RISC-V ISA string into an option mask. */
6209+
6210+static void
6211+riscv_parse_arch_string (const char *isa)
6212+{
6213+ const char *p = isa;
6214+
6215+ if (strncmp (p, "rv32", 4) == 0)
6216+ target_flags &= ~MASK_64BIT, p += 4;
6217+ else if (strncmp (p, "rv64", 4) == 0)
6218+ target_flags |= MASK_64BIT, p += 4;
6219+ else
6220+ {
6221+ error("-march=%s: ISA string must begin with rv32 or rv64", isa);
6222+ return;
6223+ }
6224+
6225+ if (*p == 'g')
6226+ {
6227+ p++;
6228+
6229+ target_flags |= MASK_MUL;
6230+ target_flags |= MASK_ATOMIC;
6231+ target_flags |= MASK_HARD_FLOAT;
6232+ target_flags |= MASK_DOUBLE_FLOAT;
6233+ }
6234+ else if (*p == 'i')
6235+ {
6236+ p++;
6237+
6238+ target_flags &= ~MASK_MUL;
6239+ if (*p == 'm')
6240+ target_flags |= MASK_MUL, p++;
6241+
6242+ target_flags &= ~MASK_ATOMIC;
6243+ if (*p == 'a')
6244+ target_flags |= MASK_ATOMIC, p++;
6245+
6246+ target_flags &= ~(MASK_HARD_FLOAT | MASK_DOUBLE_FLOAT);
6247+ if (*p == 'f')
6248+ {
6249+ target_flags |= MASK_HARD_FLOAT, p++;
6250+
6251+ if (*p == 'd')
6252+ {
6253+ target_flags |= MASK_DOUBLE_FLOAT;
6254+ p++;
6255+ }
6256+ }
6257+ }
6258+ else
6259+ {
6260+ error ("-march=%s: invalid ISA string", isa);
6261+ return;
6262+ }
6263+
6264+ target_flags &= ~MASK_RVC;
6265+ if (*p == 'c')
6266+ target_flags |= MASK_RVC, p++;
6267+
6268+ if (*p)
6269+ {
6270+ error ("-march=%s: unsupported ISA substring %qs", isa, p);
6271+ return;
6272+ }
6273+}
6274+
6275+/* Implement TARGET_HANDLE_OPTION. */
6276+
6277+static bool
6278+riscv_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
6279+{
6280+ switch (code)
6281+ {
6282+ case OPT_march_:
6283+ riscv_parse_arch_string (arg);
6284+ return true;
6285+
6286+ default:
6287+ return true;
6288+ }
6289+}
6290+
6291+
6292+/* Initialize the GCC target structure. */
6293+#undef TARGET_ASM_ALIGNED_HI_OP
6294+#define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
6295+#undef TARGET_ASM_ALIGNED_SI_OP
6296+#define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
6297+#undef TARGET_ASM_ALIGNED_DI_OP
6298+#define TARGET_ASM_ALIGNED_DI_OP "\t.dword\t"
6299+
6300+#undef TARGET_OPTION_OVERRIDE
6301+#define TARGET_OPTION_OVERRIDE riscv_option_override
6302+
6303+#undef TARGET_OPTION_OPTIMIZATION_TABLE
6304+#define TARGET_OPTION_OPTIMIZATION_TABLE riscv_option_optimization_table
6305+
6306+#undef TARGET_HANDLE_OPTION
6307+#define TARGET_HANDLE_OPTION riscv_handle_option
6308+
6309+#undef TARGET_LEGITIMIZE_ADDRESS
6310+#define TARGET_LEGITIMIZE_ADDRESS riscv_legitimize_address
6311+
6312+#undef TARGET_SCHED_ISSUE_RATE
6313+#define TARGET_SCHED_ISSUE_RATE riscv_issue_rate
6314+
6315+#undef TARGET_FUNCTION_OK_FOR_SIBCALL
6316+#define TARGET_FUNCTION_OK_FOR_SIBCALL riscv_function_ok_for_sibcall
6317+
6318+#undef TARGET_REGISTER_MOVE_COST
6319+#define TARGET_REGISTER_MOVE_COST riscv_register_move_cost
6320+#undef TARGET_MEMORY_MOVE_COST
6321+#define TARGET_MEMORY_MOVE_COST riscv_memory_move_cost
6322+#undef TARGET_RTX_COSTS
6323+#define TARGET_RTX_COSTS riscv_rtx_costs
6324+#undef TARGET_ADDRESS_COST
6325+#define TARGET_ADDRESS_COST riscv_address_cost
6326+
6327+#undef TARGET_PREFERRED_RELOAD_CLASS
6328+#define TARGET_PREFERRED_RELOAD_CLASS riscv_preferred_reload_class
6329+
6330+#undef TARGET_ASM_FILE_START
6331+#define TARGET_ASM_FILE_START riscv_file_start
6332+#undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
6333+#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
6334+#undef TARGET_PROMOTE_FUNCTION_MODE
6335+#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
6336+
6337+#undef TARGET_RETURN_IN_MEMORY
6338+#define TARGET_RETURN_IN_MEMORY riscv_return_in_memory
6339+
6340+#undef TARGET_ASM_OUTPUT_MI_THUNK
6341+#define TARGET_ASM_OUTPUT_MI_THUNK riscv_output_mi_thunk
6342+#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
6343+#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
6344+
6345+#undef TARGET_PRINT_OPERAND
6346+#define TARGET_PRINT_OPERAND riscv_print_operand
6347+#undef TARGET_PRINT_OPERAND_ADDRESS
6348+#define TARGET_PRINT_OPERAND_ADDRESS riscv_print_operand_address
6349+
6350+#undef TARGET_SETUP_INCOMING_VARARGS
6351+#define TARGET_SETUP_INCOMING_VARARGS riscv_setup_incoming_varargs
6352+#undef TARGET_STRICT_ARGUMENT_NAMING
6353+#define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
6354+#undef TARGET_MUST_PASS_IN_STACK
6355+#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
6356+#undef TARGET_PASS_BY_REFERENCE
6357+#define TARGET_PASS_BY_REFERENCE riscv_pass_by_reference
6358+#undef TARGET_ARG_PARTIAL_BYTES
6359+#define TARGET_ARG_PARTIAL_BYTES riscv_arg_partial_bytes
6360+#undef TARGET_FUNCTION_ARG
6361+#define TARGET_FUNCTION_ARG riscv_function_arg
6362+#undef TARGET_FUNCTION_ARG_ADVANCE
6363+#define TARGET_FUNCTION_ARG_ADVANCE riscv_function_arg_advance
6364+#undef TARGET_FUNCTION_ARG_BOUNDARY
6365+#define TARGET_FUNCTION_ARG_BOUNDARY riscv_function_arg_boundary
6366+
6367+/* The generic ELF target does not always have TLS support. */
6368+#ifdef HAVE_AS_TLS
6369+#undef TARGET_HAVE_TLS
6370+#define TARGET_HAVE_TLS true
6371+#endif
6372+
6373+#undef TARGET_CANNOT_FORCE_CONST_MEM
6374+#define TARGET_CANNOT_FORCE_CONST_MEM riscv_cannot_force_const_mem
6375+
6376+#undef TARGET_LEGITIMATE_CONSTANT_P
6377+#define TARGET_LEGITIMATE_CONSTANT_P riscv_legitimate_constant_p
6378+
6379+#undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
6380+#define TARGET_USE_BLOCKS_FOR_CONSTANT_P hook_bool_mode_const_rtx_true
6381+
6382+#undef TARGET_LEGITIMATE_ADDRESS_P
6383+#define TARGET_LEGITIMATE_ADDRESS_P riscv_legitimate_address_p
6384+
6385+#undef TARGET_CAN_ELIMINATE
6386+#define TARGET_CAN_ELIMINATE riscv_can_eliminate
6387+
6388+#undef TARGET_CONDITIONAL_REGISTER_USAGE
6389+#define TARGET_CONDITIONAL_REGISTER_USAGE riscv_conditional_register_usage
6390+
6391+#undef TARGET_CLASS_MAX_NREGS
6392+#define TARGET_CLASS_MAX_NREGS riscv_class_max_nregs
6393+
6394+#undef TARGET_TRAMPOLINE_INIT
6395+#define TARGET_TRAMPOLINE_INIT riscv_trampoline_init
6396+
6397+#undef TARGET_IN_SMALL_DATA_P
6398+#define TARGET_IN_SMALL_DATA_P riscv_in_small_data_p
6399+
6400+#undef TARGET_ASM_SELECT_RTX_SECTION
6401+#define TARGET_ASM_SELECT_RTX_SECTION riscv_elf_select_rtx_section
6402+
6403+#undef TARGET_MIN_ANCHOR_OFFSET
6404+#define TARGET_MIN_ANCHOR_OFFSET (-IMM_REACH/2)
6405+
6406+#undef TARGET_MAX_ANCHOR_OFFSET
6407+#define TARGET_MAX_ANCHOR_OFFSET (IMM_REACH/2-1)
6408+
6409+#undef TARGET_REGISTER_PRIORITY
6410+#define TARGET_REGISTER_PRIORITY riscv_register_priority
6411+
6412+#undef TARGET_CANNOT_COPY_INSN_P
6413+#define TARGET_CANNOT_COPY_INSN_P riscv_cannot_copy_insn_p
6414+
6415+#undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
6416+#define TARGET_ATOMIC_ASSIGN_EXPAND_FENV riscv_atomic_assign_expand_fenv
6417+
6418+#undef TARGET_EXPAND_BUILTIN_VA_START
6419+#define TARGET_EXPAND_BUILTIN_VA_START riscv_va_start
6420+
6421+/* TODO I think we don't need this */
6422+/* #undef TARGET_INIT_BUILTINS */
6423+/* #define TARGET_INIT_BUILTINS riscv_init_builtins */
6424+
6425+/* #undef TARGET_BUILTIN_DECL */
6426+/* #define TARGET_BUILTIN_DECL riscv_builtin_decl */
6427+
6428+/* #undef TARGET_EXPAND_BUILTIN */
6429+/* #define TARGET_EXPAND_BUILTIN riscv_expand_builtin */
6430+
6431+struct gcc_target targetm = TARGET_INITIALIZER;
6432+
6433+#include "gt-riscv.h"
6434diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
6435new file mode 100644
6436index 00000000000..586843f9d9f
6437--- /dev/null
6438+++ b/gcc/config/riscv/riscv.h
6439@@ -0,0 +1,969 @@
6440+/* Definition of RISC-V target for GNU compiler.
6441+ Copyright (C) 2011-2017 Free Software Foundation, Inc.
6442+ Contributed by Andrew Waterman (andrew@sifive.com).
6443+ Based on MIPS target for GNU compiler.
6444+
6445+This file is part of GCC.
6446+
6447+GCC is free software; you can redistribute it and/or modify
6448+it under the terms of the GNU General Public License as published by
6449+the Free Software Foundation; either version 3, or (at your option)
6450+any later version.
6451+
6452+GCC is distributed in the hope that it will be useful,
6453+but WITHOUT ANY WARRANTY; without even the implied warranty of
6454+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6455+GNU General Public License for more details.
6456+
6457+You should have received a copy of the GNU General Public License
6458+along with GCC; see the file COPYING3. If not see
6459+<http://www.gnu.org/licenses/>. */
6460+
6461+#ifndef GCC_RISCV_H
6462+#define GCC_RISCV_H
6463+
6464+#include "config/riscv/riscv-opts.h"
6465+
6466+/* Target CPU builtins. */
6467+#define TARGET_CPU_CPP_BUILTINS() \
6468+do { \
6469+ builtin_define ("__riscv"); \
6470+ \
6471+ if (TARGET_RVC) \
6472+ builtin_define ("__riscv_compressed"); \
6473+ \
6474+ if (TARGET_ATOMIC) \
6475+ builtin_define ("__riscv_atomic"); \
6476+ \
6477+ if (TARGET_MUL) \
6478+ builtin_define ("__riscv_mul"); \
6479+ if (TARGET_DIV) \
6480+ builtin_define ("__riscv_div"); \
6481+ if (TARGET_DIV && TARGET_MUL) \
6482+ builtin_define ("__riscv_muldiv"); \
6483+ \
6484+ builtin_define_with_int_value ("__riscv_xlen", UNITS_PER_WORD * 8); \
6485+ if (TARGET_HARD_FLOAT) \
6486+ builtin_define_with_int_value ("__riscv_flen", UNITS_PER_FP_REG * 8); \
6487+ \
6488+ if (TARGET_HARD_FLOAT && TARGET_FDIV) \
6489+ { \
6490+ builtin_define ("__riscv_fdiv"); \
6491+ builtin_define ("__riscv_fsqrt"); \
6492+ } \
6493+ \
6494+ switch (riscv_abi) \
6495+ { \
6496+ case ABI_ILP32: \
6497+ case ABI_LP64: \
6498+ builtin_define ("__riscv_float_abi_soft"); \
6499+ break; \
6500+ \
6501+ case ABI_ILP32F: \
6502+ case ABI_LP64F: \
6503+ builtin_define ("__riscv_float_abi_single"); \
6504+ break; \
6505+ \
6506+ case ABI_ILP32D: \
6507+ case ABI_LP64D: \
6508+ builtin_define ("__riscv_float_abi_double"); \
6509+ break; \
6510+ } \
6511+ \
6512+ switch (riscv_cmodel) \
6513+ { \
6514+ case CM_MEDLOW: \
6515+ builtin_define ("__riscv_cmodel_medlow"); \
6516+ break; \
6517+ \
6518+ case CM_MEDANY: \
6519+ builtin_define ("__riscv_cmodel_medany"); \
6520+ break; \
6521+ \
6522+ case CM_PIC: \
6523+ builtin_define ("__riscv_cmodel_pic"); \
6524+ break; \
6525+ } \
6526+} while (0);
6527+
6528+/* Default target_flags if no switches are specified */
6529+
6530+#ifndef TARGET_DEFAULT
6531+#define TARGET_DEFAULT 0
6532+#endif
6533+
6534+#ifndef RISCV_TUNE_STRING_DEFAULT
6535+#define RISCV_TUNE_STRING_DEFAULT "rocket"
6536+#endif
6537+
6538+/* Support for a compile-time default CPU, et cetera. The rules are:
6539+ --with-arch is ignored if -march is specified.
6540+ --with-abi is ignored if -mabi is specified.
6541+ --with-tune is ignored if -mtune is specified. */
6542+#define OPTION_DEFAULT_SPECS \
6543+ {"tune", "%{!mtune=*:-mtune=%(VALUE)}" }, \
6544+ {"arch", "%{!march=*:-march=%(VALUE)}" }, \
6545+ {"abi", "%{!mabi=*:-mabi=%(VALUE)}" }, \
6546+
6547+#ifdef IN_LIBGCC2
6548+#undef TARGET_64BIT
6549+/* Make this compile time constant for libgcc2 */
6550+#define TARGET_64BIT (__riscv_xlen == 64)
6551+#endif /* IN_LIBGCC2 */
6552+
6553+#undef ASM_SPEC
6554+#define ASM_SPEC "\
6555+%(subtarget_asm_debugging_spec) \
6556+%{fpic|fpie:-fpic} %{fPIC|fPIE:-fpic} \
6557+%{march=*} \
6558+%{mabi=*} \
6559+%(subtarget_asm_spec)"
6560+
6561+#define TARGET_DEFAULT_CMODEL CM_MEDLOW
6562+
6563+#define LOCAL_LABEL_PREFIX "."
6564+#define USER_LABEL_PREFIX ""
6565+
6566+/* Offsets recorded in opcodes are a multiple of this alignment factor.
6567+ The default for this in 64-bit mode is 8, which causes problems with
6568+ SFmode register saves. */
6569+#define DWARF_CIE_DATA_ALIGNMENT -4
6570+
6571+/* The mapping from gcc register number to DWARF 2 CFA column number. */
6572+#define DWARF_FRAME_REGNUM(REGNO) \
6573+ (GP_REG_P (REGNO) || FP_REG_P (REGNO) ? REGNO : INVALID_REGNUM)
6574+
6575+/* The DWARF 2 CFA column which tracks the return address. */
6576+#define DWARF_FRAME_RETURN_COLUMN RETURN_ADDR_REGNUM
6577+#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (VOIDmode, RETURN_ADDR_REGNUM)
6578+
6579+/* Describe how we implement __builtin_eh_return. */
6580+#define EH_RETURN_DATA_REGNO(N) \
6581+ ((N) < 4 ? (N) + GP_ARG_FIRST : INVALID_REGNUM)
6582+
6583+#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, GP_ARG_FIRST + 4)
6584+
6585+/* Target machine storage layout */
6586+
6587+#define BITS_BIG_ENDIAN 0
6588+#define BYTES_BIG_ENDIAN 0
6589+#define WORDS_BIG_ENDIAN 0
6590+
6591+#define MAX_BITS_PER_WORD 64
6592+
6593+/* Width of a word, in units (bytes). */
6594+#define UNITS_PER_WORD (TARGET_64BIT ? 8 : 4)
6595+#ifndef IN_LIBGCC2
6596+#define MIN_UNITS_PER_WORD 4
6597+#endif
6598+
6599+/* The `Q' extension is not yet supported. */
6600+#define UNITS_PER_FP_REG (TARGET_DOUBLE_FLOAT ? 8 : 4)
6601+
6602+/* The largest type that can be passed in floating-point registers. */
6603+#define UNITS_PER_FP_ARG \
6604+ (riscv_abi == ABI_ILP32 || riscv_abi == ABI_LP64 ? 0 : \
6605+ riscv_abi == ABI_ILP32F || riscv_abi == ABI_LP64F ? 4 : 8) \
6606+
6607+/* Set the sizes of the core types. */
6608+#define SHORT_TYPE_SIZE 16
6609+#define INT_TYPE_SIZE 32
6610+#define LONG_LONG_TYPE_SIZE 64
6611+#define POINTER_SIZE (riscv_abi >= ABI_LP64 ? 64 : 32)
6612+#define LONG_TYPE_SIZE POINTER_SIZE
6613+
6614+#define FLOAT_TYPE_SIZE 32
6615+#define DOUBLE_TYPE_SIZE 64
6616+#define LONG_DOUBLE_TYPE_SIZE 128
6617+
6618+/* Allocation boundary (in *bits*) for storing arguments in argument list. */
6619+#define PARM_BOUNDARY BITS_PER_WORD
6620+
6621+/* Allocation boundary (in *bits*) for the code of a function. */
6622+#define FUNCTION_BOUNDARY (TARGET_RVC ? 16 : 32)
6623+
6624+/* There is no point aligning anything to a rounder boundary than this. */
6625+#define BIGGEST_ALIGNMENT 128
6626+
6627+/* The user-level ISA permits misaligned accesses, but they may execute
6628+ extremely slowly and non-atomically. Some privileged architectures
6629+ do not permit them at all. It is best to enforce strict alignment. */
6630+#define STRICT_ALIGNMENT 1
6631+
6632+/* Define this if you wish to imitate the way many other C compilers
6633+ handle alignment of bitfields and the structures that contain
6634+ them.
6635+
6636+ The behavior is that the type written for a bit-field (`int',
6637+ `short', or other integer type) imposes an alignment for the
6638+ entire structure, as if the structure really did contain an
6639+ ordinary field of that type. In addition, the bit-field is placed
6640+ within the structure so that it would fit within such a field,
6641+ not crossing a boundary for it.
6642+
6643+ Thus, on most machines, a bit-field whose type is written as `int'
6644+ would not cross a four-byte boundary, and would force four-byte
6645+ alignment for the whole structure. (The alignment used may not
6646+ be four bytes; it is controlled by the other alignment
6647+ parameters.)
6648+
6649+ If the macro is defined, its definition should be a C expression;
6650+ a nonzero value for the expression enables this behavior. */
6651+
6652+#define PCC_BITFIELD_TYPE_MATTERS 1
6653+
6654+/* If defined, a C expression to compute the alignment given to a
6655+ constant that is being placed in memory. CONSTANT is the constant
6656+ and ALIGN is the alignment that the object would ordinarily have.
6657+ The value of this macro is used instead of that alignment to align
6658+ the object.
6659+
6660+ If this macro is not defined, then ALIGN is used.
6661+
6662+ The typical use of this macro is to increase alignment for string
6663+ constants to be word aligned so that `strcpy' calls that copy
6664+ constants can be done inline. */
6665+
6666+#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
6667+ ((TREE_CODE (EXP) == STRING_CST || TREE_CODE (EXP) == CONSTRUCTOR) \
6668+ && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
6669+
6670+/* If defined, a C expression to compute the alignment for a static
6671+ variable. TYPE is the data type, and ALIGN is the alignment that
6672+ the object would ordinarily have. The value of this macro is used
6673+ instead of that alignment to align the object.
6674+
6675+ If this macro is not defined, then ALIGN is used.
6676+
6677+ One use of this macro is to increase alignment of medium-size
6678+ data to make it all fit in fewer cache lines. Another is to
6679+ cause character arrays to be word-aligned so that `strcpy' calls
6680+ that copy constants to character arrays can be done inline. */
6681+
6682+#define DATA_ALIGNMENT(TYPE, ALIGN) \
6683+ ((((ALIGN) < BITS_PER_WORD) \
6684+ && (TREE_CODE (TYPE) == ARRAY_TYPE \
6685+ || TREE_CODE (TYPE) == UNION_TYPE \
6686+ || TREE_CODE (TYPE) == RECORD_TYPE)) ? BITS_PER_WORD : (ALIGN))
6687+
6688+/* We need this for the same reason as DATA_ALIGNMENT, namely to cause
6689+ character arrays to be word-aligned so that `strcpy' calls that copy
6690+ constants to character arrays can be done inline, and 'strcmp' can be
6691+ optimised to use word loads. */
6692+#define LOCAL_ALIGNMENT(TYPE, ALIGN) \
6693+ DATA_ALIGNMENT (TYPE, ALIGN)
6694+
6695+/* Define if operations between registers always perform the operation
6696+ on the full register even if a narrower mode is specified. */
6697+#define WORD_REGISTER_OPERATIONS 1
6698+
6699+/* When in 64-bit mode, move insns will sign extend SImode and CCmode
6700+ moves. All other references are zero extended. */
6701+#define LOAD_EXTEND_OP(MODE) \
6702+ (TARGET_64BIT && (MODE) == SImode ? SIGN_EXTEND : ZERO_EXTEND)
6703+
6704+/* Define this macro if it is advisable to hold scalars in registers
6705+ in a wider mode than that declared by the program. In such cases,
6706+ the value is constrained to be within the bounds of the declared
6707+ type, but kept valid in the wider mode. The signedness of the
6708+ extension may differ from that of the type. */
6709+
6710+#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \
6711+ if (GET_MODE_CLASS (MODE) == MODE_INT \
6712+ && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \
6713+ { \
6714+ if ((MODE) == SImode) \
6715+ (UNSIGNEDP) = 0; \
6716+ (MODE) = word_mode; \
6717+ }
6718+
6719+/* Pmode is always the same as ptr_mode, but not always the same as word_mode.
6720+ Extensions of pointers to word_mode must be signed. */
6721+#define POINTERS_EXTEND_UNSIGNED false
6722+
6723+/* When floating-point registers are wider than integer ones, moves between
6724+ them must go through memory. */
6725+#define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \
6726+ (GET_MODE_SIZE (MODE) > UNITS_PER_WORD \
6727+ && ((CLASS1) == FP_REGS) != ((CLASS2) == FP_REGS))
6728+
6729+/* Define if loading short immediate values into registers sign extends. */
6730+#define SHORT_IMMEDIATES_SIGN_EXTEND 1
6731+
6732+/* Standard register usage. */
6733+
6734+/* Number of hardware registers. We have:
6735+
6736+ - 32 integer registers
6737+ - 32 floating point registers
6738+ - 2 fake registers:
6739+ - ARG_POINTER_REGNUM
6740+ - FRAME_POINTER_REGNUM */
6741+
6742+#define FIRST_PSEUDO_REGISTER 66
6743+
6744+/* x0, sp, gp, and tp are fixed. */
6745+
6746+#define FIXED_REGISTERS \
6747+{ /* General registers. */ \
6748+ 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
6749+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
6750+ /* Floating-point registers. */ \
6751+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
6752+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
6753+ /* Others. */ \
6754+ 1, 1 \
6755+}
6756+
6757+/* a0-a7, t0-a6, fa0-fa7, and ft0-ft11 are volatile across calls.
6758+ The call RTLs themselves clobber ra. */
6759+
6760+#define CALL_USED_REGISTERS \
6761+{ /* General registers. */ \
6762+ 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, \
6763+ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, \
6764+ /* Floating-point registers. */ \
6765+ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, \
6766+ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, \
6767+ /* Others. */ \
6768+ 1, 1 \
6769+}
6770+
6771+/* Internal macros to classify an ISA register's type. */
6772+
6773+#define GP_REG_FIRST 0
6774+#define GP_REG_LAST 31
6775+#define GP_REG_NUM (GP_REG_LAST - GP_REG_FIRST + 1)
6776+
6777+#define FP_REG_FIRST 32
6778+#define FP_REG_LAST 63
6779+#define FP_REG_NUM (FP_REG_LAST - FP_REG_FIRST + 1)
6780+
6781+/* The DWARF 2 CFA column which tracks the return address from a
6782+ signal handler context. This means that to maintain backwards
6783+ compatibility, no hard register can be assigned this column if it
6784+ would need to be handled by the DWARF unwinder. */
6785+#define DWARF_ALT_FRAME_RETURN_COLUMN 64
6786+
6787+#define GP_REG_P(REGNO) \
6788+ ((unsigned int) ((int) (REGNO) - GP_REG_FIRST) < GP_REG_NUM)
6789+#define FP_REG_P(REGNO) \
6790+ ((unsigned int) ((int) (REGNO) - FP_REG_FIRST) < FP_REG_NUM)
6791+
6792+#define FP_REG_RTX_P(X) (REG_P (X) && FP_REG_P (REGNO (X)))
6793+
6794+#define HARD_REGNO_NREGS(REGNO, MODE) riscv_hard_regno_nregs (REGNO, MODE)
6795+
6796+#define HARD_REGNO_MODE_OK(REGNO, MODE) \
6797+ riscv_hard_regno_mode_ok_p (REGNO, MODE)
6798+
6799+/* Don't allow floating-point modes to be tied, since type punning of
6800+ single-precision and double-precision is implementation defined. */
6801+#define MODES_TIEABLE_P(MODE1, MODE2) \
6802+ ((MODE1) == (MODE2) \
6803+ || !(GET_MODE_CLASS (MODE1) == MODE_FLOAT \
6804+ && GET_MODE_CLASS (MODE2) == MODE_FLOAT))
6805+
6806+/* Use s0 as the frame pointer if it is so requested. */
6807+#define HARD_FRAME_POINTER_REGNUM 8
6808+#define STACK_POINTER_REGNUM 2
6809+#define THREAD_POINTER_REGNUM 4
6810+
6811+/* These two registers don't really exist: they get eliminated to either
6812+ the stack or hard frame pointer. */
6813+#define ARG_POINTER_REGNUM 64
6814+#define FRAME_POINTER_REGNUM 65
6815+
6816+/* Register in which static-chain is passed to a function. */
6817+#define STATIC_CHAIN_REGNUM (GP_TEMP_FIRST + 2)
6818+
6819+/* Registers used as temporaries in prologue/epilogue code.
6820+
6821+ The prologue registers mustn't conflict with any
6822+ incoming arguments, the static chain pointer, or the frame pointer.
6823+ The epilogue temporary mustn't conflict with the return registers,
6824+ the frame pointer, the EH stack adjustment, or the EH data registers. */
6825+
6826+#define RISCV_PROLOGUE_TEMP_REGNUM (GP_TEMP_FIRST + 1)
6827+#define RISCV_PROLOGUE_TEMP(MODE) gen_rtx_REG (MODE, RISCV_PROLOGUE_TEMP_REGNUM)
6828+
6829+#define MCOUNT_NAME "_mcount"
6830+
6831+#define NO_PROFILE_COUNTERS 1
6832+
6833+/* Emit rtl for profiling. Output assembler code to FILE
6834+ to call "_mcount" for profiling a function entry. */
6835+#define PROFILE_HOOK(LABEL) \
6836+ { \
6837+ rtx fun, ra; \
6838+ ra = get_hard_reg_initial_val (Pmode, RETURN_ADDR_REGNUM); \
6839+ fun = gen_rtx_SYMBOL_REF (Pmode, MCOUNT_NAME); \
6840+ emit_library_call (fun, LCT_NORMAL, VOIDmode, 1, ra, Pmode); \
6841+ }
6842+
6843+/* All the work done in PROFILE_HOOK, but still required. */
6844+#define FUNCTION_PROFILER(STREAM, LABELNO) do { } while (0)
6845+
6846+/* Define this macro if it is as good or better to call a constant
6847+ function address than to call an address kept in a register. */
6848+#define NO_FUNCTION_CSE 1
6849+
6850+/* Define the classes of registers for register constraints in the
6851+ machine description. Also define ranges of constants.
6852+
6853+ One of the classes must always be named ALL_REGS and include all hard regs.
6854+ If there is more than one class, another class must be named NO_REGS
6855+ and contain no registers.
6856+
6857+ The name GENERAL_REGS must be the name of a class (or an alias for
6858+ another name such as ALL_REGS). This is the class of registers
6859+ that is allowed by "g" or "r" in a register constraint.
6860+ Also, registers outside this class are allocated only when
6861+ instructions express preferences for them.
6862+
6863+ The classes must be numbered in nondecreasing order; that is,
6864+ a larger-numbered class must never be contained completely
6865+ in a smaller-numbered class.
6866+
6867+ For any two classes, it is very desirable that there be another
6868+ class that represents their union. */
6869+
6870+enum reg_class
6871+{
6872+ NO_REGS, /* no registers in set */
6873+ SIBCALL_REGS, /* registers used by indirect sibcalls */
6874+ JALR_REGS, /* registers used by indirect calls */
6875+ GR_REGS, /* integer registers */
6876+ FP_REGS, /* floating-point registers */
6877+ FRAME_REGS, /* arg pointer and frame pointer */
6878+ ALL_REGS, /* all registers */
6879+ LIM_REG_CLASSES /* max value + 1 */
6880+};
6881+
6882+#define N_REG_CLASSES (int) LIM_REG_CLASSES
6883+
6884+#define GENERAL_REGS GR_REGS
6885+
6886+/* An initializer containing the names of the register classes as C
6887+ string constants. These names are used in writing some of the
6888+ debugging dumps. */
6889+
6890+#define REG_CLASS_NAMES \
6891+{ \
6892+ "NO_REGS", \
6893+ "SIBCALL_REGS", \
6894+ "JALR_REGS", \
6895+ "GR_REGS", \
6896+ "FP_REGS", \
6897+ "FRAME_REGS", \
6898+ "ALL_REGS" \
6899+}
6900+
6901+/* An initializer containing the contents of the register classes,
6902+ as integers which are bit masks. The Nth integer specifies the
6903+ contents of class N. The way the integer MASK is interpreted is
6904+ that register R is in the class if `MASK & (1 << R)' is 1.
6905+
6906+ When the machine has more than 32 registers, an integer does not
6907+ suffice. Then the integers are replaced by sub-initializers,
6908+ braced groupings containing several integers. Each
6909+ sub-initializer must be suitable as an initializer for the type
6910+ `HARD_REG_SET' which is defined in `hard-reg-set.h'. */
6911+
6912+#define REG_CLASS_CONTENTS \
6913+{ \
6914+ { 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */ \
6915+ { 0xf00000c0, 0x00000000, 0x00000000 }, /* SIBCALL_REGS */ \
6916+ { 0xffffffc0, 0x00000000, 0x00000000 }, /* JALR_REGS */ \
6917+ { 0xffffffff, 0x00000000, 0x00000000 }, /* GR_REGS */ \
6918+ { 0x00000000, 0xffffffff, 0x00000000 }, /* FP_REGS */ \
6919+ { 0x00000000, 0x00000000, 0x00000003 }, /* FRAME_REGS */ \
6920+ { 0xffffffff, 0xffffffff, 0x00000003 } /* ALL_REGS */ \
6921+}
6922+
6923+/* A C expression whose value is a register class containing hard
6924+ register REGNO. In general there is more that one such class;
6925+ choose a class which is "minimal", meaning that no smaller class
6926+ also contains the register. */
6927+
6928+#define REGNO_REG_CLASS(REGNO) riscv_regno_to_class[ (REGNO) ]
6929+
6930+/* A macro whose definition is the name of the class to which a
6931+ valid base register must belong. A base register is one used in
6932+ an address which is the register value plus a displacement. */
6933+
6934+#define BASE_REG_CLASS GR_REGS
6935+
6936+/* A macro whose definition is the name of the class to which a
6937+ valid index register must belong. An index register is one used
6938+ in an address where its value is either multiplied by a scale
6939+ factor or added to another register (as well as added to a
6940+ displacement). */
6941+
6942+#define INDEX_REG_CLASS NO_REGS
6943+
6944+/* We generally want to put call-clobbered registers ahead of
6945+ call-saved ones. (IRA expects this.) */
6946+
6947+#define REG_ALLOC_ORDER \
6948+{ \
6949+ /* Call-clobbered GPRs. */ \
6950+ 15, 14, 13, 12, 11, 10, 16, 17, 6, 28, 29, 30, 31, 5, 7, 1, \
6951+ /* Call-saved GPRs. */ \
6952+ 8, 9, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, \
6953+ /* GPRs that can never be exposed to the register allocator. */ \
6954+ 0, 2, 3, 4, \
6955+ /* Call-clobbered FPRs. */ \
6956+ 47, 46, 45, 44, 43, 42, 32, 33, 34, 35, 36, 37, 38, 39, 48, 49, \
6957+ 60, 61, 62, 63, \
6958+ /* Call-saved FPRs. */ \
6959+ 40, 41, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, \
6960+ /* None of the remaining classes have defined call-saved \
6961+ registers. */ \
6962+ 64, 65 \
6963+}
6964+
6965+/* True if VALUE is a signed 12-bit number. */
6966+
6967+#define SMALL_OPERAND(VALUE) \
6968+ ((unsigned HOST_WIDE_INT) (VALUE) + IMM_REACH/2 < IMM_REACH)
6969+
6970+/* True if VALUE can be loaded into a register using LUI. */
6971+
6972+#define LUI_OPERAND(VALUE) \
6973+ (((VALUE) | ((1UL<<31) - IMM_REACH)) == ((1UL<<31) - IMM_REACH) \
6974+ || ((VALUE) | ((1UL<<31) - IMM_REACH)) + IMM_REACH == 0)
6975+
6976+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
6977+ reg_classes_intersect_p (FP_REGS, CLASS)
6978+
6979+/* Stack layout; function entry, exit and calling. */
6980+
6981+#define STACK_GROWS_DOWNWARD 1
6982+
6983+#define FRAME_GROWS_DOWNWARD 1
6984+
6985+#define STARTING_FRAME_OFFSET 0
6986+
6987+#define RETURN_ADDR_RTX riscv_return_addr
6988+
6989+#define ELIMINABLE_REGS \
6990+{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
6991+ { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
6992+ { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
6993+ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}} \
6994+
6995+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
6996+ (OFFSET) = riscv_initial_elimination_offset (FROM, TO)
6997+
6998+/* Allocate stack space for arguments at the beginning of each function. */
6999+#define ACCUMULATE_OUTGOING_ARGS 1
7000+
7001+/* The argument pointer always points to the first argument. */
7002+#define FIRST_PARM_OFFSET(FNDECL) 0
7003+
7004+#define REG_PARM_STACK_SPACE(FNDECL) 0
7005+
7006+/* Define this if it is the responsibility of the caller to
7007+ allocate the area reserved for arguments passed in registers.
7008+ If `ACCUMULATE_OUTGOING_ARGS' is also defined, the only effect
7009+ of this macro is to determine whether the space is included in
7010+ `crtl->outgoing_args_size'. */
7011+#define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1
7012+
7013+#define STACK_BOUNDARY 128
7014+
7015+/* Symbolic macros for the registers used to return integer and floating
7016+ point values. */
7017+
7018+#define GP_RETURN GP_ARG_FIRST
7019+#define FP_RETURN (UNITS_PER_FP_ARG == 0 ? GP_RETURN : FP_ARG_FIRST)
7020+
7021+#define MAX_ARGS_IN_REGISTERS 8
7022+
7023+/* Symbolic macros for the first/last argument registers. */
7024+
7025+#define GP_ARG_FIRST (GP_REG_FIRST + 10)
7026+#define GP_ARG_LAST (GP_ARG_FIRST + MAX_ARGS_IN_REGISTERS - 1)
7027+#define GP_TEMP_FIRST (GP_REG_FIRST + 5)
7028+#define FP_ARG_FIRST (FP_REG_FIRST + 10)
7029+#define FP_ARG_LAST (FP_ARG_FIRST + MAX_ARGS_IN_REGISTERS - 1)
7030+
7031+#define CALLEE_SAVED_REG_NUMBER(REGNO) \
7032+ ((REGNO) >= 8 && (REGNO) <= 9 ? (REGNO) - 8 : \
7033+ (REGNO) >= 18 && (REGNO) <= 27 ? (REGNO) - 16 : -1)
7034+
7035+#define LIBCALL_VALUE(MODE) \
7036+ riscv_function_value (NULL_TREE, NULL_TREE, MODE)
7037+
7038+#define FUNCTION_VALUE(VALTYPE, FUNC) \
7039+ riscv_function_value (VALTYPE, FUNC, VOIDmode)
7040+
7041+#define FUNCTION_VALUE_REGNO_P(N) ((N) == GP_RETURN || (N) == FP_RETURN)
7042+
7043+/* 1 if N is a possible register number for function argument passing.
7044+ We have no FP argument registers when soft-float. When FP registers
7045+ are 32 bits, we can't directly reference the odd numbered ones. */
7046+
7047+/* Accept arguments in a0-a7, and in fa0-fa7 if permitted by the ABI. */
7048+#define FUNCTION_ARG_REGNO_P(N) \
7049+ (IN_RANGE ((N), GP_ARG_FIRST, GP_ARG_LAST) \
7050+ || (UNITS_PER_FP_ARG && IN_RANGE ((N), FP_ARG_FIRST, FP_ARG_LAST)))
7051+
7052+typedef struct {
7053+ /* Number of integer registers used so far, up to MAX_ARGS_IN_REGISTERS. */
7054+ unsigned int num_gprs;
7055+
7056+ /* Number of floating-point registers used so far, likewise. */
7057+ unsigned int num_fprs;
7058+} CUMULATIVE_ARGS;
7059+
7060+/* Initialize a variable CUM of type CUMULATIVE_ARGS
7061+ for a call to a function whose data type is FNTYPE.
7062+ For a library call, FNTYPE is 0. */
7063+
7064+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
7065+ memset (&(CUM), 0, sizeof (CUM))
7066+
7067+#define EPILOGUE_USES(REGNO) ((REGNO) == RETURN_ADDR_REGNUM)
7068+
7069+/* ABI requires 16-byte alignment, even on RV32. */
7070+#define RISCV_STACK_ALIGN(LOC) (((LOC) + 15) & -16)
7071+
7072+/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
7073+ the stack pointer does not matter. The value is tested only in
7074+ functions that have frame pointers.
7075+ No definition is equivalent to always zero. */
7076+
7077+#define EXIT_IGNORE_STACK 1
7078+
7079+
7080+/* Trampolines are a block of code followed by two pointers. */
7081+
7082+#define TRAMPOLINE_CODE_SIZE 16
7083+#define TRAMPOLINE_SIZE \
7084+ ((Pmode == SImode) \
7085+ ? TRAMPOLINE_CODE_SIZE \
7086+ : (TRAMPOLINE_CODE_SIZE + POINTER_SIZE * 2))
7087+#define TRAMPOLINE_ALIGNMENT POINTER_SIZE
7088+
7089+/* Addressing modes, and classification of registers for them. */
7090+
7091+#define REGNO_OK_FOR_INDEX_P(REGNO) 0
7092+#define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) \
7093+ riscv_regno_mode_ok_for_base_p (REGNO, MODE, 1)
7094+
7095+/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
7096+ and check its validity for a certain class.
7097+ We have two alternate definitions for each of them.
7098+ The usual definition accepts all pseudo regs; the other rejects them all.
7099+ The symbol REG_OK_STRICT causes the latter definition to be used.
7100+
7101+ Most source files want to accept pseudo regs in the hope that
7102+ they will get allocated to the class that the insn wants them to be in.
7103+ Some source files that are used after register allocation
7104+ need to be strict. */
7105+
7106+#ifndef REG_OK_STRICT
7107+#define REG_MODE_OK_FOR_BASE_P(X, MODE) \
7108+ riscv_regno_mode_ok_for_base_p (REGNO (X), MODE, 0)
7109+#else
7110+#define REG_MODE_OK_FOR_BASE_P(X, MODE) \
7111+ riscv_regno_mode_ok_for_base_p (REGNO (X), MODE, 1)
7112+#endif
7113+
7114+#define REG_OK_FOR_INDEX_P(X) 0
7115+
7116+/* Maximum number of registers that can appear in a valid memory address. */
7117+
7118+#define MAX_REGS_PER_ADDRESS 1
7119+
7120+#define CONSTANT_ADDRESS_P(X) \
7121+ (CONSTANT_P (X) && memory_address_p (SImode, X))
7122+
7123+/* This handles the magic '..CURRENT_FUNCTION' symbol, which means
7124+ 'the start of the function that this code is output in'. */
7125+
7126+#define ASM_OUTPUT_LABELREF(FILE,NAME) \
7127+ if (strcmp (NAME, "..CURRENT_FUNCTION") == 0) \
7128+ asm_fprintf ((FILE), "%U%s", \
7129+ XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); \
7130+ else \
7131+ asm_fprintf ((FILE), "%U%s", (NAME))
7132+
7133+#define JUMP_TABLES_IN_TEXT_SECTION 0
7134+#define CASE_VECTOR_MODE SImode
7135+#define CASE_VECTOR_PC_RELATIVE (riscv_cmodel != CM_MEDLOW)
7136+
7137+/* The load-address macro is used for PC-relative addressing of symbols
7138+ that bind locally. Don't use it for symbols that should be addressed
7139+ via the GOT. Also, avoid it for CM_MEDLOW, where LUI addressing
7140+ currently results in more opportunities for linker relaxation. */
7141+#define USE_LOAD_ADDRESS_MACRO(sym) \
7142+ (!TARGET_EXPLICIT_RELOCS && \
7143+ ((flag_pic \
7144+ && ((SYMBOL_REF_P (sym) && SYMBOL_REF_LOCAL_P (sym)) \
7145+ || ((GET_CODE (sym) == CONST) \
7146+ && SYMBOL_REF_P (XEXP (XEXP (sym, 0),0)) \
7147+ && SYMBOL_REF_LOCAL_P (XEXP (XEXP (sym, 0),0))))) \
7148+ || riscv_cmodel == CM_MEDANY))
7149+
7150+/* Define this as 1 if `char' should by default be signed; else as 0. */
7151+#define DEFAULT_SIGNED_CHAR 0
7152+
7153+#define MOVE_MAX UNITS_PER_WORD
7154+#define MAX_MOVE_MAX 8
7155+
7156+#define SLOW_BYTE_ACCESS 0
7157+
7158+#define SHIFT_COUNT_TRUNCATED 1
7159+
7160+#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
7161+
7162+/* Specify the machine mode that pointers have.
7163+ After generation of rtl, the compiler makes no further distinction
7164+ between pointers and any other objects of this machine mode. */
7165+
7166+#define Pmode word_mode
7167+
7168+/* Give call MEMs SImode since it is the "most permissive" mode
7169+ for both 32-bit and 64-bit targets. */
7170+
7171+#define FUNCTION_MODE SImode
7172+
7173+/* A C expression for the cost of a branch instruction. A value of 2
7174+ seems to minimize code size. */
7175+
7176+#define BRANCH_COST(speed_p, predictable_p) \
7177+ ((!(speed_p) || (predictable_p)) ? 2 : riscv_branch_cost)
7178+
7179+#define LOGICAL_OP_NON_SHORT_CIRCUIT 0
7180+
7181+/* Control the assembler format that we output. */
7182+
7183+/* Output to assembler file text saying following lines
7184+ may contain character constants, extra white space, comments, etc. */
7185+
7186+#ifndef ASM_APP_ON
7187+#define ASM_APP_ON " #APP\n"
7188+#endif
7189+
7190+/* Output to assembler file text saying following lines
7191+ no longer contain unusual constructs. */
7192+
7193+#ifndef ASM_APP_OFF
7194+#define ASM_APP_OFF " #NO_APP\n"
7195+#endif
7196+
7197+#define REGISTER_NAMES \
7198+{ "zero","ra", "sp", "gp", "tp", "t0", "t1", "t2", \
7199+ "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", \
7200+ "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", \
7201+ "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6", \
7202+ "ft0", "ft1", "ft2", "ft3", "ft4", "ft5", "ft6", "ft7", \
7203+ "fs0", "fs1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5", \
7204+ "fa6", "fa7", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7", \
7205+ "fs8", "fs9", "fs10","fs11","ft8", "ft9", "ft10","ft11", \
7206+ "arg", "frame", }
7207+
7208+#define ADDITIONAL_REGISTER_NAMES \
7209+{ \
7210+ { "x0", 0 + GP_REG_FIRST }, \
7211+ { "x1", 1 + GP_REG_FIRST }, \
7212+ { "x2", 2 + GP_REG_FIRST }, \
7213+ { "x3", 3 + GP_REG_FIRST }, \
7214+ { "x4", 4 + GP_REG_FIRST }, \
7215+ { "x5", 5 + GP_REG_FIRST }, \
7216+ { "x6", 6 + GP_REG_FIRST }, \
7217+ { "x7", 7 + GP_REG_FIRST }, \
7218+ { "x8", 8 + GP_REG_FIRST }, \
7219+ { "x9", 9 + GP_REG_FIRST }, \
7220+ { "x10", 10 + GP_REG_FIRST }, \
7221+ { "x11", 11 + GP_REG_FIRST }, \
7222+ { "x12", 12 + GP_REG_FIRST }, \
7223+ { "x13", 13 + GP_REG_FIRST }, \
7224+ { "x14", 14 + GP_REG_FIRST }, \
7225+ { "x15", 15 + GP_REG_FIRST }, \
7226+ { "x16", 16 + GP_REG_FIRST }, \
7227+ { "x17", 17 + GP_REG_FIRST }, \
7228+ { "x18", 18 + GP_REG_FIRST }, \
7229+ { "x19", 19 + GP_REG_FIRST }, \
7230+ { "x20", 20 + GP_REG_FIRST }, \
7231+ { "x21", 21 + GP_REG_FIRST }, \
7232+ { "x22", 22 + GP_REG_FIRST }, \
7233+ { "x23", 23 + GP_REG_FIRST }, \
7234+ { "x24", 24 + GP_REG_FIRST }, \
7235+ { "x25", 25 + GP_REG_FIRST }, \
7236+ { "x26", 26 + GP_REG_FIRST }, \
7237+ { "x27", 27 + GP_REG_FIRST }, \
7238+ { "x28", 28 + GP_REG_FIRST }, \
7239+ { "x29", 29 + GP_REG_FIRST }, \
7240+ { "x30", 30 + GP_REG_FIRST }, \
7241+ { "x31", 31 + GP_REG_FIRST }, \
7242+ { "f0", 0 + FP_REG_FIRST }, \
7243+ { "f1", 1 + FP_REG_FIRST }, \
7244+ { "f2", 2 + FP_REG_FIRST }, \
7245+ { "f3", 3 + FP_REG_FIRST }, \
7246+ { "f4", 4 + FP_REG_FIRST }, \
7247+ { "f5", 5 + FP_REG_FIRST }, \
7248+ { "f6", 6 + FP_REG_FIRST }, \
7249+ { "f7", 7 + FP_REG_FIRST }, \
7250+ { "f8", 8 + FP_REG_FIRST }, \
7251+ { "f9", 9 + FP_REG_FIRST }, \
7252+ { "f10", 10 + FP_REG_FIRST }, \
7253+ { "f11", 11 + FP_REG_FIRST }, \
7254+ { "f12", 12 + FP_REG_FIRST }, \
7255+ { "f13", 13 + FP_REG_FIRST }, \
7256+ { "f14", 14 + FP_REG_FIRST }, \
7257+ { "f15", 15 + FP_REG_FIRST }, \
7258+ { "f16", 16 + FP_REG_FIRST }, \
7259+ { "f17", 17 + FP_REG_FIRST }, \
7260+ { "f18", 18 + FP_REG_FIRST }, \
7261+ { "f19", 19 + FP_REG_FIRST }, \
7262+ { "f20", 20 + FP_REG_FIRST }, \
7263+ { "f21", 21 + FP_REG_FIRST }, \
7264+ { "f22", 22 + FP_REG_FIRST }, \
7265+ { "f23", 23 + FP_REG_FIRST }, \
7266+ { "f24", 24 + FP_REG_FIRST }, \
7267+ { "f25", 25 + FP_REG_FIRST }, \
7268+ { "f26", 26 + FP_REG_FIRST }, \
7269+ { "f27", 27 + FP_REG_FIRST }, \
7270+ { "f28", 28 + FP_REG_FIRST }, \
7271+ { "f29", 29 + FP_REG_FIRST }, \
7272+ { "f30", 30 + FP_REG_FIRST }, \
7273+ { "f31", 31 + FP_REG_FIRST }, \
7274+}
7275+
7276+/* Globalizing directive for a label. */
7277+#define GLOBAL_ASM_OP "\t.globl\t"
7278+
7279+/* This is how to store into the string LABEL
7280+ the symbol_ref name of an internal numbered label where
7281+ PREFIX is the class of label and NUM is the number within the class.
7282+ This is suitable for output with `assemble_name'. */
7283+
7284+#undef ASM_GENERATE_INTERNAL_LABEL
7285+#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \
7286+ sprintf ((LABEL), "*%s%s%ld", (LOCAL_LABEL_PREFIX), (PREFIX), (long)(NUM))
7287+
7288+/* This is how to output an element of a case-vector that is absolute. */
7289+
7290+#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \
7291+ fprintf (STREAM, "\t.word\t%sL%d\n", LOCAL_LABEL_PREFIX, VALUE)
7292+
7293+/* This is how to output an element of a PIC case-vector. */
7294+
7295+#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL) \
7296+ fprintf (STREAM, "\t.word\t%sL%d-%sL%d\n", \
7297+ LOCAL_LABEL_PREFIX, VALUE, LOCAL_LABEL_PREFIX, REL)
7298+
7299+/* This is how to output an assembler line
7300+ that says to advance the location counter
7301+ to a multiple of 2**LOG bytes. */
7302+
7303+#define ASM_OUTPUT_ALIGN(STREAM,LOG) \
7304+ fprintf (STREAM, "\t.align\t%d\n", (LOG))
7305+
7306+/* Define the strings to put out for each section in the object file. */
7307+#define TEXT_SECTION_ASM_OP "\t.text" /* instructions */
7308+#define DATA_SECTION_ASM_OP "\t.data" /* large data */
7309+#define READONLY_DATA_SECTION_ASM_OP "\t.section\t.rodata"
7310+#define BSS_SECTION_ASM_OP "\t.bss"
7311+#define SBSS_SECTION_ASM_OP "\t.section\t.sbss,\"aw\",@nobits"
7312+#define SDATA_SECTION_ASM_OP "\t.section\t.sdata,\"aw\",@progbits"
7313+
7314+#define ASM_OUTPUT_REG_PUSH(STREAM,REGNO) \
7315+do \
7316+ { \
7317+ fprintf (STREAM, "\taddi\t%s,%s,-8\n\t%s\t%s,0(%s)\n", \
7318+ reg_names[STACK_POINTER_REGNUM], \
7319+ reg_names[STACK_POINTER_REGNUM], \
7320+ TARGET_64BIT ? "sd" : "sw", \
7321+ reg_names[REGNO], \
7322+ reg_names[STACK_POINTER_REGNUM]); \
7323+ } \
7324+while (0)
7325+
7326+#define ASM_OUTPUT_REG_POP(STREAM,REGNO) \
7327+do \
7328+ { \
7329+ fprintf (STREAM, "\t%s\t%s,0(%s)\n\taddi\t%s,%s,8\n", \
7330+ TARGET_64BIT ? "ld" : "lw", \
7331+ reg_names[REGNO], \
7332+ reg_names[STACK_POINTER_REGNUM], \
7333+ reg_names[STACK_POINTER_REGNUM], \
7334+ reg_names[STACK_POINTER_REGNUM]); \
7335+ } \
7336+while (0)
7337+
7338+#define ASM_COMMENT_START "#"
7339+
7340+#undef SIZE_TYPE
7341+#define SIZE_TYPE (POINTER_SIZE == 64 ? "long unsigned int" : "unsigned int")
7342+
7343+#undef PTRDIFF_TYPE
7344+#define PTRDIFF_TYPE (POINTER_SIZE == 64 ? "long int" : "int")
7345+
7346+/* If a memory-to-memory move would take MOVE_RATIO or more simple
7347+ move-instruction pairs, we will do a movmem or libcall instead. */
7348+
7349+#define MOVE_RATIO(speed) (CLEAR_RATIO (speed) / 2)
7350+
7351+/* For CLEAR_RATIO, when optimizing for size, give a better estimate
7352+ of the length of a memset call, but use the default otherwise. */
7353+
7354+#define CLEAR_RATIO(speed) ((speed) ? 16 : 6)
7355+
7356+/* This is similar to CLEAR_RATIO, but for a non-zero constant, so when
7357+ optimizing for size adjust the ratio to account for the overhead of
7358+ loading the constant and replicating it across the word. */
7359+
7360+#define SET_RATIO(speed) (CLEAR_RATIO (speed) - ((speed) ? 0 : 2))
7361+
7362+#ifndef USED_FOR_TARGET
7363+extern const enum reg_class riscv_regno_to_class[];
7364+extern bool riscv_hard_regno_mode_ok[][FIRST_PSEUDO_REGISTER];
7365+#endif
7366+
7367+#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \
7368+ (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4)
7369+
7370+#define XLEN_SPEC \
7371+ "%{march=rv32*:32}" \
7372+ "%{march=rv64*:64}" \
7373+
7374+#define ABI_SPEC \
7375+ "%{mabi=ilp32:ilp32}" \
7376+ "%{mabi=ilp32f:ilp32f}" \
7377+ "%{mabi=ilp32d:ilp32d}" \
7378+ "%{mabi=lp64:lp64}" \
7379+ "%{mabi=lp64f:lp64f}" \
7380+ "%{mabi=lp64d:lp64d}" \
7381+
7382+#define STARTFILE_PREFIX_SPEC \
7383+ "/lib" XLEN_SPEC "/" ABI_SPEC "/ " \
7384+ "/usr/lib" XLEN_SPEC "/" ABI_SPEC "/ " \
7385+ "/lib/ " \
7386+ "/usr/lib/ "
7387+
7388+/* ISA constants needed for code generation. */
7389+#define OPCODE_LW 0x2003
7390+#define OPCODE_LD 0x3003
7391+#define OPCODE_AUIPC 0x17
7392+#define OPCODE_JALR 0x67
7393+#define OPCODE_LUI 0x37
7394+#define OPCODE_ADDI 0x13
7395+#define SHIFT_RD 7
7396+#define SHIFT_RS1 15
7397+#define SHIFT_IMM 20
7398+#define IMM_BITS 12
7399+
7400+#define IMM_REACH (1LL << IMM_BITS)
7401+#define CONST_HIGH_PART(VALUE) (((VALUE) + (IMM_REACH/2)) & ~(IMM_REACH-1))
7402+#define CONST_LOW_PART(VALUE) ((VALUE) - CONST_HIGH_PART (VALUE))
7403+
7404+#define SYMBOL_REF_P(RTX) (GET_CODE (RTX) == SYMBOL_REF)
7405+#define CLASS_MAX_NREGS(CLASS, MODE) riscv_class_max_nregs (CLASS, MODE)
7406+#define LEGITIMATE_CONSTANT_P(X) (riscv_const_insns (X) > 0)
7407+
7408+#endif /* ! GCC_RISCV_H */
7409diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
7410new file mode 100644
7411index 00000000000..cfb0e45862e
7412--- /dev/null
7413+++ b/gcc/config/riscv/riscv.md
7414@@ -0,0 +1,2091 @@
7415+;; Machine description for RISC-V for GNU compiler.
7416+;; Copyright (C) 2011-2017 Free Software Foundation, Inc.
7417+;; Contributed by Andrew Waterman (andrew@sifive.com).
7418+;; Based on MIPS target for GNU compiler.
7419+
7420+;; This file is part of GCC.
7421+
7422+;; GCC is free software; you can redistribute it and/or modify
7423+;; it under the terms of the GNU General Public License as published by
7424+;; the Free Software Foundation; either version 3, or (at your option)
7425+;; any later version.
7426+
7427+;; GCC is distributed in the hope that it will be useful,
7428+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
7429+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7430+;; GNU General Public License for more details.
7431+
7432+;; You should have received a copy of the GNU General Public License
7433+;; along with GCC; see the file COPYING3. If not see
7434+;; <http://www.gnu.org/licenses/>.
7435+
7436+(define_c_enum "unspec" [
7437+ ;; Override return address for exception handling.
7438+ UNSPEC_EH_RETURN
7439+
7440+ ;; Symbolic accesses. The order of this list must match that of
7441+ ;; enum riscv_symbol_type in riscv-protos.h.
7442+ UNSPEC_ADDRESS_FIRST
7443+ UNSPEC_PCREL
7444+ UNSPEC_LOAD_GOT
7445+ UNSPEC_TLS
7446+ UNSPEC_TLS_LE
7447+ UNSPEC_TLS_IE
7448+ UNSPEC_TLS_GD
7449+
7450+ ;; High part of PC-relative address.
7451+ UNSPEC_AUIPC
7452+
7453+ ;; Floating-point unspecs.
7454+ UNSPEC_FLT_QUIET
7455+ UNSPEC_FLE_QUIET
7456+ UNSPEC_COPYSIGN
7457+ UNSPEC_LRINT
7458+ UNSPEC_LROUND
7459+
7460+ ;; Stack tie
7461+ UNSPEC_TIE
7462+])
7463+
7464+(define_c_enum "unspecv" [
7465+ ;; Register save and restore.
7466+ UNSPECV_GPR_SAVE
7467+ UNSPECV_GPR_RESTORE
7468+
7469+ ;; Floating-point unspecs.
7470+ UNSPECV_FRFLAGS
7471+ UNSPECV_FSFLAGS
7472+
7473+ ;; Blockage and synchronization.
7474+ UNSPECV_BLOCKAGE
7475+ UNSPECV_FENCE
7476+ UNSPECV_FENCE_I
7477+])
7478+
7479+(define_constants
7480+ [(RETURN_ADDR_REGNUM 1)
7481+ (T0_REGNUM 5)
7482+ (T1_REGNUM 6)
7483+ (S0_REGNUM 8)
7484+ (S1_REGNUM 9)
7485+ (S2_REGNUM 18)
7486+])
7487+
7488+(include "predicates.md")
7489+(include "constraints.md")
7490+
7491+;; ....................
7492+;;
7493+;; Attributes
7494+;;
7495+;; ....................
7496+
7497+(define_attr "got" "unset,xgot_high,load"
7498+ (const_string "unset"))
7499+
7500+;; Classification of moves, extensions and truncations. Most values
7501+;; are as for "type" (see below) but there are also the following
7502+;; move-specific values:
7503+;;
7504+;; andi a single ANDI instruction
7505+;; shift_shift a shift left followed by a shift right
7506+;;
7507+;; This attribute is used to determine the instruction's length and
7508+;; scheduling type. For doubleword moves, the attribute always describes
7509+;; the split instructions; in some cases, it is more appropriate for the
7510+;; scheduling type to be "multi" instead.
7511+(define_attr "move_type"
7512+ "unknown,load,fpload,store,fpstore,mtc,mfc,move,fmove,
7513+ const,logical,arith,andi,shift_shift"
7514+ (const_string "unknown"))
7515+
7516+;; Main data type used by the insn
7517+(define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF"
7518+ (const_string "unknown"))
7519+
7520+;; True if the main data type is twice the size of a word.
7521+(define_attr "dword_mode" "no,yes"
7522+ (cond [(and (eq_attr "mode" "DI,DF")
7523+ (eq (symbol_ref "TARGET_64BIT") (const_int 0)))
7524+ (const_string "yes")
7525+
7526+ (and (eq_attr "mode" "TI,TF")
7527+ (ne (symbol_ref "TARGET_64BIT") (const_int 0)))
7528+ (const_string "yes")]
7529+ (const_string "no")))
7530+
7531+;; Classification of each insn.
7532+;; branch conditional branch
7533+;; jump unconditional jump
7534+;; call unconditional call
7535+;; load load instruction(s)
7536+;; fpload floating point load
7537+;; store store instruction(s)
7538+;; fpstore floating point store
7539+;; mtc transfer to coprocessor
7540+;; mfc transfer from coprocessor
7541+;; const load constant
7542+;; arith integer arithmetic instructions
7543+;; logical integer logical instructions
7544+;; shift integer shift instructions
7545+;; slt set less than instructions
7546+;; imul integer multiply
7547+;; idiv integer divide
7548+;; move integer register move (addi rd, rs1, 0)
7549+;; fmove floating point register move
7550+;; fadd floating point add/subtract
7551+;; fmul floating point multiply
7552+;; fmadd floating point multiply-add
7553+;; fdiv floating point divide
7554+;; fcmp floating point compare
7555+;; fcvt floating point convert
7556+;; fsqrt floating point square root
7557+;; multi multiword sequence (or user asm statements)
7558+;; nop no operation
7559+;; ghost an instruction that produces no real code
7560+(define_attr "type"
7561+ "unknown,branch,jump,call,load,fpload,store,fpstore,
7562+ mtc,mfc,const,arith,logical,shift,slt,imul,idiv,move,fmove,fadd,fmul,
7563+ fmadd,fdiv,fcmp,fcvt,fsqrt,multi,nop,ghost"
7564+ (cond [(eq_attr "got" "load") (const_string "load")
7565+
7566+ ;; If a doubleword move uses these expensive instructions,
7567+ ;; it is usually better to schedule them in the same way
7568+ ;; as the singleword form, rather than as "multi".
7569+ (eq_attr "move_type" "load") (const_string "load")
7570+ (eq_attr "move_type" "fpload") (const_string "fpload")
7571+ (eq_attr "move_type" "store") (const_string "store")
7572+ (eq_attr "move_type" "fpstore") (const_string "fpstore")
7573+ (eq_attr "move_type" "mtc") (const_string "mtc")
7574+ (eq_attr "move_type" "mfc") (const_string "mfc")
7575+
7576+ ;; These types of move are always single insns.
7577+ (eq_attr "move_type" "fmove") (const_string "fmove")
7578+ (eq_attr "move_type" "arith") (const_string "arith")
7579+ (eq_attr "move_type" "logical") (const_string "logical")
7580+ (eq_attr "move_type" "andi") (const_string "logical")
7581+
7582+ ;; These types of move are always split.
7583+ (eq_attr "move_type" "shift_shift")
7584+ (const_string "multi")
7585+
7586+ ;; These types of move are split for doubleword modes only.
7587+ (and (eq_attr "move_type" "move,const")
7588+ (eq_attr "dword_mode" "yes"))
7589+ (const_string "multi")
7590+ (eq_attr "move_type" "move") (const_string "move")
7591+ (eq_attr "move_type" "const") (const_string "const")]
7592+ (const_string "unknown")))
7593+
7594+;; Length of instruction in bytes.
7595+(define_attr "length" ""
7596+ (cond [
7597+ ;; Branches further than +/- 4 KiB require two instructions.
7598+ (eq_attr "type" "branch")
7599+ (if_then_else (and (le (minus (match_dup 0) (pc)) (const_int 4088))
7600+ (le (minus (pc) (match_dup 0)) (const_int 4092)))
7601+ (const_int 4)
7602+ (const_int 8))
7603+
7604+ ;; Conservatively assume calls take two instructions (AUIPC + JALR).
7605+ ;; The linker will opportunistically relax the sequence to JAL.
7606+ (eq_attr "type" "call") (const_int 8)
7607+
7608+ ;; "Ghost" instructions occupy no space.
7609+ (eq_attr "type" "ghost") (const_int 0)
7610+
7611+ (eq_attr "got" "load") (const_int 8)
7612+
7613+ (eq_attr "type" "fcmp") (const_int 8)
7614+
7615+ ;; SHIFT_SHIFTs are decomposed into two separate instructions.
7616+ (eq_attr "move_type" "shift_shift")
7617+ (const_int 8)
7618+
7619+ ;; Check for doubleword moves that are decomposed into two
7620+ ;; instructions.
7621+ (and (eq_attr "move_type" "mtc,mfc,move")
7622+ (eq_attr "dword_mode" "yes"))
7623+ (const_int 8)
7624+
7625+ ;; Doubleword CONST{,N} moves are split into two word
7626+ ;; CONST{,N} moves.
7627+ (and (eq_attr "move_type" "const")
7628+ (eq_attr "dword_mode" "yes"))
7629+ (symbol_ref "riscv_split_const_insns (operands[1]) * 4")
7630+
7631+ ;; Otherwise, constants, loads and stores are handled by external
7632+ ;; routines.
7633+ (eq_attr "move_type" "load,fpload")
7634+ (symbol_ref "riscv_load_store_insns (operands[1], insn) * 4")
7635+ (eq_attr "move_type" "store,fpstore")
7636+ (symbol_ref "riscv_load_store_insns (operands[0], insn) * 4")
7637+ ] (const_int 4)))
7638+
7639+;; Is copying of this instruction disallowed?
7640+(define_attr "cannot_copy" "no,yes" (const_string "no"))
7641+
7642+;; Describe a user's asm statement.
7643+(define_asm_attributes
7644+ [(set_attr "type" "multi")])
7645+
7646+;; This mode iterator allows 32-bit and 64-bit GPR patterns to be generated
7647+;; from the same template.
7648+(define_mode_iterator GPR [SI (DI "TARGET_64BIT")])
7649+
7650+;; This mode iterator allows :P to be used for patterns that operate on
7651+;; pointer-sized quantities. Exactly one of the two alternatives will match.
7652+(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
7653+
7654+;; Likewise, but for XLEN-sized quantities.
7655+(define_mode_iterator X [(SI "!TARGET_64BIT") (DI "TARGET_64BIT")])
7656+
7657+;; Branches operate on XLEN-sized quantities, but for RV64 we accept
7658+;; QImode values so we can force zero-extension.
7659+(define_mode_iterator BR [(QI "TARGET_64BIT") SI (DI "TARGET_64BIT")])
7660+
7661+;; 32-bit moves for which we provide move patterns.
7662+(define_mode_iterator MOVE32 [SI])
7663+
7664+;; 64-bit modes for which we provide move patterns.
7665+(define_mode_iterator MOVE64 [DI DF])
7666+
7667+;; Iterator for sub-32-bit integer modes.
7668+(define_mode_iterator SHORT [QI HI])
7669+
7670+;; Iterator for HImode constant generation.
7671+(define_mode_iterator HISI [HI SI])
7672+
7673+;; Iterator for QImode extension patterns.
7674+(define_mode_iterator SUPERQI [HI SI (DI "TARGET_64BIT")])
7675+
7676+;; Iterator for hardware integer modes narrower than XLEN.
7677+(define_mode_iterator SUBX [QI HI (SI "TARGET_64BIT")])
7678+
7679+;; Iterator for hardware-supported integer modes.
7680+(define_mode_iterator ANYI [QI HI SI (DI "TARGET_64BIT")])
7681+
7682+;; Iterator for hardware-supported floating-point modes.
7683+(define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT")
7684+ (DF "TARGET_DOUBLE_FLOAT")])
7685+
7686+;; This attribute gives the length suffix for a sign- or zero-extension
7687+;; instruction.
7688+(define_mode_attr size [(QI "b") (HI "h")])
7689+
7690+;; Mode attributes for loads.
7691+(define_mode_attr load [(QI "lb") (HI "lh") (SI "lw") (DI "ld") (SF "flw") (DF "fld")])
7692+
7693+;; Instruction names for stores.
7694+(define_mode_attr store [(QI "sb") (HI "sh") (SI "sw") (DI "sd") (SF "fsw") (DF "fsd")])
7695+
7696+;; This attribute gives the best constraint to use for registers of
7697+;; a given mode.
7698+(define_mode_attr reg [(SI "d") (DI "d") (CC "d")])
7699+
7700+;; This attribute gives the format suffix for floating-point operations.
7701+(define_mode_attr fmt [(SF "s") (DF "d")])
7702+
7703+;; This attribute gives the integer suffix for floating-point conversions.
7704+(define_mode_attr ifmt [(SI "w") (DI "l")])
7705+
7706+;; This attribute gives the format suffix for atomic memory operations.
7707+(define_mode_attr amo [(SI "w") (DI "d")])
7708+
7709+;; This attribute gives the upper-case mode name for one unit of a
7710+;; floating-point mode.
7711+(define_mode_attr UNITMODE [(SF "SF") (DF "DF")])
7712+
7713+;; This attribute gives the integer mode that has half the size of
7714+;; the controlling mode.
7715+(define_mode_attr HALFMODE [(DF "SI") (DI "SI") (TF "DI")])
7716+
7717+;; This code iterator allows signed and unsigned widening multiplications
7718+;; to use the same template.
7719+(define_code_iterator any_extend [sign_extend zero_extend])
7720+
7721+;; This code iterator allows the two right shift instructions to be
7722+;; generated from the same template.
7723+(define_code_iterator any_shiftrt [ashiftrt lshiftrt])
7724+
7725+;; This code iterator allows the three shift instructions to be generated
7726+;; from the same template.
7727+(define_code_iterator any_shift [ashift ashiftrt lshiftrt])
7728+
7729+;; This code iterator allows the three bitwise instructions to be generated
7730+;; from the same template.
7731+(define_code_iterator any_bitwise [and ior xor])
7732+
7733+;; This code iterator allows unsigned and signed division to be generated
7734+;; from the same template.
7735+(define_code_iterator any_div [div udiv mod umod])
7736+
7737+;; This code iterator allows unsigned and signed modulus to be generated
7738+;; from the same template.
7739+(define_code_iterator any_mod [mod umod])
7740+
7741+;; These code iterators allow the signed and unsigned scc operations to use
7742+;; the same template.
7743+(define_code_iterator any_gt [gt gtu])
7744+(define_code_iterator any_ge [ge geu])
7745+(define_code_iterator any_lt [lt ltu])
7746+(define_code_iterator any_le [le leu])
7747+
7748+;; <u> expands to an empty string when doing a signed operation and
7749+;; "u" when doing an unsigned operation.
7750+(define_code_attr u [(sign_extend "") (zero_extend "u")
7751+ (gt "") (gtu "u")
7752+ (ge "") (geu "u")
7753+ (lt "") (ltu "u")
7754+ (le "") (leu "u")])
7755+
7756+;; <su> is like <u>, but the signed form expands to "s" rather than "".
7757+(define_code_attr su [(sign_extend "s") (zero_extend "u")])
7758+
7759+;; <optab> expands to the name of the optab for a particular code.
7760+(define_code_attr optab [(ashift "ashl")
7761+ (ashiftrt "ashr")
7762+ (lshiftrt "lshr")
7763+ (div "div")
7764+ (mod "mod")
7765+ (udiv "udiv")
7766+ (umod "umod")
7767+ (ge "ge")
7768+ (le "le")
7769+ (gt "gt")
7770+ (lt "lt")
7771+ (ior "ior")
7772+ (xor "xor")
7773+ (and "and")
7774+ (plus "add")
7775+ (minus "sub")])
7776+
7777+;; <insn> expands to the name of the insn that implements a particular code.
7778+(define_code_attr insn [(ashift "sll")
7779+ (ashiftrt "sra")
7780+ (lshiftrt "srl")
7781+ (div "div")
7782+ (mod "rem")
7783+ (udiv "divu")
7784+ (umod "remu")
7785+ (ior "or")
7786+ (xor "xor")
7787+ (and "and")
7788+ (plus "add")
7789+ (minus "sub")])
7790+
7791+;; Ghost instructions produce no real code and introduce no hazards.
7792+;; They exist purely to express an effect on dataflow.
7793+(define_insn_reservation "ghost" 0
7794+ (eq_attr "type" "ghost")
7795+ "nothing")
7796+
7797+;;
7798+;; ....................
7799+;;
7800+;; ADDITION
7801+;;
7802+;; ....................
7803+;;
7804+
7805+(define_insn "add<mode>3"
7806+ [(set (match_operand:ANYF 0 "register_operand" "=f")
7807+ (plus:ANYF (match_operand:ANYF 1 "register_operand" "f")
7808+ (match_operand:ANYF 2 "register_operand" "f")))]
7809+ "TARGET_HARD_FLOAT"
7810+ "fadd.<fmt>\t%0,%1,%2"
7811+ [(set_attr "type" "fadd")
7812+ (set_attr "mode" "<UNITMODE>")])
7813+
7814+(define_insn "addsi3"
7815+ [(set (match_operand:SI 0 "register_operand" "=r,r")
7816+ (plus:SI (match_operand:SI 1 "register_operand" "r,r")
7817+ (match_operand:SI 2 "arith_operand" "r,I")))]
7818+ ""
7819+ { return TARGET_64BIT ? "addw\t%0,%1,%2" : "add\t%0,%1,%2"; }
7820+ [(set_attr "type" "arith")
7821+ (set_attr "mode" "SI")])
7822+
7823+(define_insn "adddi3"
7824+ [(set (match_operand:DI 0 "register_operand" "=r,r")
7825+ (plus:DI (match_operand:DI 1 "register_operand" "r,r")
7826+ (match_operand:DI 2 "arith_operand" "r,I")))]
7827+ "TARGET_64BIT"
7828+ "add\t%0,%1,%2"
7829+ [(set_attr "type" "arith")
7830+ (set_attr "mode" "DI")])
7831+
7832+(define_insn "*addsi3_extended"
7833+ [(set (match_operand:DI 0 "register_operand" "=r,r")
7834+ (sign_extend:DI
7835+ (plus:SI (match_operand:SI 1 "register_operand" "r,r")
7836+ (match_operand:SI 2 "arith_operand" "r,I"))))]
7837+ "TARGET_64BIT"
7838+ "addw\t%0,%1,%2"
7839+ [(set_attr "type" "arith")
7840+ (set_attr "mode" "SI")])
7841+
7842+(define_insn "*addsi3_extended2"
7843+ [(set (match_operand:DI 0 "register_operand" "=r,r")
7844+ (sign_extend:DI
7845+ (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "r,r")
7846+ (match_operand:DI 2 "arith_operand" "r,I"))
7847+ 0)))]
7848+ "TARGET_64BIT"
7849+ "addw\t%0,%1,%2"
7850+ [(set_attr "type" "arith")
7851+ (set_attr "mode" "SI")])
7852+
7853+;;
7854+;; ....................
7855+;;
7856+;; SUBTRACTION
7857+;;
7858+;; ....................
7859+;;
7860+
7861+(define_insn "sub<mode>3"
7862+ [(set (match_operand:ANYF 0 "register_operand" "=f")
7863+ (minus:ANYF (match_operand:ANYF 1 "register_operand" "f")
7864+ (match_operand:ANYF 2 "register_operand" "f")))]
7865+ "TARGET_HARD_FLOAT"
7866+ "fsub.<fmt>\t%0,%1,%2"
7867+ [(set_attr "type" "fadd")
7868+ (set_attr "mode" "<UNITMODE>")])
7869+
7870+(define_insn "subdi3"
7871+ [(set (match_operand:DI 0 "register_operand" "=r")
7872+ (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
7873+ (match_operand:DI 2 "register_operand" "r")))]
7874+ "TARGET_64BIT"
7875+ "sub\t%0,%z1,%2"
7876+ [(set_attr "type" "arith")
7877+ (set_attr "mode" "DI")])
7878+
7879+(define_insn "subsi3"
7880+ [(set (match_operand:SI 0 "register_operand" "=r")
7881+ (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
7882+ (match_operand:SI 2 "register_operand" "r")))]
7883+ ""
7884+ { return TARGET_64BIT ? "subw\t%0,%z1,%2" : "sub\t%0,%z1,%2"; }
7885+ [(set_attr "type" "arith")
7886+ (set_attr "mode" "SI")])
7887+
7888+(define_insn "*subsi3_extended"
7889+ [(set (match_operand:DI 0 "register_operand" "=r")
7890+ (sign_extend:DI
7891+ (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
7892+ (match_operand:SI 2 "register_operand" "r"))))]
7893+ "TARGET_64BIT"
7894+ "subw\t%0,%z1,%2"
7895+ [(set_attr "type" "arith")
7896+ (set_attr "mode" "SI")])
7897+
7898+(define_insn "*subsi3_extended2"
7899+ [(set (match_operand:DI 0 "register_operand" "=r")
7900+ (sign_extend:DI
7901+ (subreg:SI (minus:DI (match_operand:DI 1 "reg_or_0_operand" "r")
7902+ (match_operand:DI 2 "register_operand" "r"))
7903+ 0)))]
7904+ "TARGET_64BIT"
7905+ "subw\t%0,%z1,%2"
7906+ [(set_attr "type" "arith")
7907+ (set_attr "mode" "SI")])
7908+
7909+;;
7910+;; ....................
7911+;;
7912+;; MULTIPLICATION
7913+;;
7914+;; ....................
7915+;;
7916+
7917+(define_insn "mul<mode>3"
7918+ [(set (match_operand:ANYF 0 "register_operand" "=f")
7919+ (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
7920+ (match_operand:ANYF 2 "register_operand" "f")))]
7921+ "TARGET_HARD_FLOAT"
7922+ "fmul.<fmt>\t%0,%1,%2"
7923+ [(set_attr "type" "fmul")
7924+ (set_attr "mode" "<UNITMODE>")])
7925+
7926+(define_insn "mulsi3"
7927+ [(set (match_operand:SI 0 "register_operand" "=r")
7928+ (mult:SI (match_operand:SI 1 "register_operand" "r")
7929+ (match_operand:SI 2 "register_operand" "r")))]
7930+ "TARGET_MUL"
7931+ { return TARGET_64BIT ? "mulw\t%0,%1,%2" : "mul\t%0,%1,%2"; }
7932+ [(set_attr "type" "imul")
7933+ (set_attr "mode" "SI")])
7934+
7935+(define_insn "muldi3"
7936+ [(set (match_operand:DI 0 "register_operand" "=r")
7937+ (mult:DI (match_operand:DI 1 "register_operand" "r")
7938+ (match_operand:DI 2 "register_operand" "r")))]
7939+ "TARGET_MUL && TARGET_64BIT"
7940+ "mul\t%0,%1,%2"
7941+ [(set_attr "type" "imul")
7942+ (set_attr "mode" "DI")])
7943+
7944+(define_insn "*mulsi3_extended"
7945+ [(set (match_operand:DI 0 "register_operand" "=r")
7946+ (sign_extend:DI
7947+ (mult:SI (match_operand:SI 1 "register_operand" "r")
7948+ (match_operand:SI 2 "register_operand" "r"))))]
7949+ "TARGET_MUL && TARGET_64BIT"
7950+ "mulw\t%0,%1,%2"
7951+ [(set_attr "type" "imul")
7952+ (set_attr "mode" "SI")])
7953+
7954+(define_insn "*mulsi3_extended2"
7955+ [(set (match_operand:DI 0 "register_operand" "=r")
7956+ (sign_extend:DI
7957+ (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "r")
7958+ (match_operand:DI 2 "register_operand" "r"))
7959+ 0)))]
7960+ "TARGET_MUL && TARGET_64BIT"
7961+ "mulw\t%0,%1,%2"
7962+ [(set_attr "type" "imul")
7963+ (set_attr "mode" "SI")])
7964+
7965+;;
7966+;; ........................
7967+;;
7968+;; MULTIPLICATION HIGH-PART
7969+;;
7970+;; ........................
7971+;;
7972+
7973+
7974+(define_expand "<u>mulditi3"
7975+ [(set (match_operand:TI 0 "register_operand")
7976+ (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
7977+ (any_extend:TI (match_operand:DI 2 "register_operand"))))]
7978+ "TARGET_MUL && TARGET_64BIT"
7979+{
7980+ rtx low = gen_reg_rtx (DImode);
7981+ emit_insn (gen_muldi3 (low, operands[1], operands[2]));
7982+
7983+ rtx high = gen_reg_rtx (DImode);
7984+ emit_insn (gen_<u>muldi3_highpart (high, operands[1], operands[2]));
7985+
7986+ emit_move_insn (gen_lowpart (DImode, operands[0]), low);
7987+ emit_move_insn (gen_highpart (DImode, operands[0]), high);
7988+ DONE;
7989+})
7990+
7991+(define_insn "<u>muldi3_highpart"
7992+ [(set (match_operand:DI 0 "register_operand" "=r")
7993+ (truncate:DI
7994+ (lshiftrt:TI
7995+ (mult:TI (any_extend:TI
7996+ (match_operand:DI 1 "register_operand" "r"))
7997+ (any_extend:TI
7998+ (match_operand:DI 2 "register_operand" "r")))
7999+ (const_int 64))))]
8000+ "TARGET_MUL && TARGET_64BIT"
8001+ "mulh<u>\t%0,%1,%2"
8002+ [(set_attr "type" "imul")
8003+ (set_attr "mode" "DI")])
8004+
8005+(define_expand "usmulditi3"
8006+ [(set (match_operand:TI 0 "register_operand")
8007+ (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand"))
8008+ (sign_extend:TI (match_operand:DI 2 "register_operand"))))]
8009+ "TARGET_MUL && TARGET_64BIT"
8010+{
8011+ rtx low = gen_reg_rtx (DImode);
8012+ emit_insn (gen_muldi3 (low, operands[1], operands[2]));
8013+
8014+ rtx high = gen_reg_rtx (DImode);
8015+ emit_insn (gen_usmuldi3_highpart (high, operands[1], operands[2]));
8016+
8017+ emit_move_insn (gen_lowpart (DImode, operands[0]), low);
8018+ emit_move_insn (gen_highpart (DImode, operands[0]), high);
8019+ DONE;
8020+})
8021+
8022+(define_insn "usmuldi3_highpart"
8023+ [(set (match_operand:DI 0 "register_operand" "=r")
8024+ (truncate:DI
8025+ (lshiftrt:TI
8026+ (mult:TI (zero_extend:TI
8027+ (match_operand:DI 1 "register_operand" "r"))
8028+ (sign_extend:TI
8029+ (match_operand:DI 2 "register_operand" "r")))
8030+ (const_int 64))))]
8031+ "TARGET_MUL && TARGET_64BIT"
8032+ "mulhsu\t%0,%2,%1"
8033+ [(set_attr "type" "imul")
8034+ (set_attr "mode" "DI")])
8035+
8036+(define_expand "<u>mulsidi3"
8037+ [(set (match_operand:DI 0 "register_operand" "=r")
8038+ (mult:DI (any_extend:DI
8039+ (match_operand:SI 1 "register_operand" "r"))
8040+ (any_extend:DI
8041+ (match_operand:SI 2 "register_operand" "r"))))]
8042+ "TARGET_MUL && !TARGET_64BIT"
8043+{
8044+ rtx temp = gen_reg_rtx (SImode);
8045+ emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
8046+ emit_insn (gen_<u>mulsi3_highpart (riscv_subword (operands[0], true),
8047+ operands[1], operands[2]));
8048+ emit_insn (gen_movsi (riscv_subword (operands[0], false), temp));
8049+ DONE;
8050+})
8051+
8052+(define_insn "<u>mulsi3_highpart"
8053+ [(set (match_operand:SI 0 "register_operand" "=r")
8054+ (truncate:SI
8055+ (lshiftrt:DI
8056+ (mult:DI (any_extend:DI
8057+ (match_operand:SI 1 "register_operand" "r"))
8058+ (any_extend:DI
8059+ (match_operand:SI 2 "register_operand" "r")))
8060+ (const_int 32))))]
8061+ "TARGET_MUL && !TARGET_64BIT"
8062+ "mulh<u>\t%0,%1,%2"
8063+ [(set_attr "type" "imul")
8064+ (set_attr "mode" "SI")])
8065+
8066+
8067+(define_expand "usmulsidi3"
8068+ [(set (match_operand:DI 0 "register_operand" "=r")
8069+ (mult:DI (zero_extend:DI
8070+ (match_operand:SI 1 "register_operand" "r"))
8071+ (sign_extend:DI
8072+ (match_operand:SI 2 "register_operand" "r"))))]
8073+ "TARGET_MUL && !TARGET_64BIT"
8074+{
8075+ rtx temp = gen_reg_rtx (SImode);
8076+ emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
8077+ emit_insn (gen_usmulsi3_highpart (riscv_subword (operands[0], true),
8078+ operands[1], operands[2]));
8079+ emit_insn (gen_movsi (riscv_subword (operands[0], false), temp));
8080+ DONE;
8081+})
8082+
8083+(define_insn "usmulsi3_highpart"
8084+ [(set (match_operand:SI 0 "register_operand" "=r")
8085+ (truncate:SI
8086+ (lshiftrt:DI
8087+ (mult:DI (zero_extend:DI
8088+ (match_operand:SI 1 "register_operand" "r"))
8089+ (sign_extend:DI
8090+ (match_operand:SI 2 "register_operand" "r")))
8091+ (const_int 32))))]
8092+ "TARGET_MUL && !TARGET_64BIT"
8093+ "mulhsu\t%0,%2,%1"
8094+ [(set_attr "type" "imul")
8095+ (set_attr "mode" "SI")])
8096+
8097+;;
8098+;; ....................
8099+;;
8100+;; DIVISION and REMAINDER
8101+;;
8102+;; ....................
8103+;;
8104+
8105+(define_insn "<optab>si3"
8106+ [(set (match_operand:SI 0 "register_operand" "=r")
8107+ (any_div:SI (match_operand:SI 1 "register_operand" "r")
8108+ (match_operand:SI 2 "register_operand" "r")))]
8109+ "TARGET_DIV"
8110+ { return TARGET_64BIT ? "<insn>w\t%0,%1,%2" : "<insn>\t%0,%1,%2"; }
8111+ [(set_attr "type" "idiv")
8112+ (set_attr "mode" "SI")])
8113+
8114+(define_insn "<optab>di3"
8115+ [(set (match_operand:DI 0 "register_operand" "=r")
8116+ (any_div:DI (match_operand:DI 1 "register_operand" "r")
8117+ (match_operand:DI 2 "register_operand" "r")))]
8118+ "TARGET_DIV && TARGET_64BIT"
8119+ "<insn>\t%0,%1,%2"
8120+ [(set_attr "type" "idiv")
8121+ (set_attr "mode" "DI")])
8122+
8123+(define_insn "*<optab>si3_extended"
8124+ [(set (match_operand:DI 0 "register_operand" "=r")
8125+ (sign_extend:DI
8126+ (any_div:SI (match_operand:SI 1 "register_operand" "r")
8127+ (match_operand:SI 2 "register_operand" "r"))))]
8128+ "TARGET_DIV && TARGET_64BIT"
8129+ "<insn>w\t%0,%1,%2"
8130+ [(set_attr "type" "idiv")
8131+ (set_attr "mode" "DI")])
8132+
8133+(define_insn "div<mode>3"
8134+ [(set (match_operand:ANYF 0 "register_operand" "=f")
8135+ (div:ANYF (match_operand:ANYF 1 "register_operand" "f")
8136+ (match_operand:ANYF 2 "register_operand" "f")))]
8137+ "TARGET_HARD_FLOAT && TARGET_FDIV"
8138+ "fdiv.<fmt>\t%0,%1,%2"
8139+ [(set_attr "type" "fdiv")
8140+ (set_attr "mode" "<UNITMODE>")])
8141+
8142+;;
8143+;; ....................
8144+;;
8145+;; SQUARE ROOT
8146+;;
8147+;; ....................
8148+
8149+(define_insn "sqrt<mode>2"
8150+ [(set (match_operand:ANYF 0 "register_operand" "=f")
8151+ (sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
8152+ "TARGET_HARD_FLOAT && TARGET_FDIV"
8153+{
8154+ return "fsqrt.<fmt>\t%0,%1";
8155+}
8156+ [(set_attr "type" "fsqrt")
8157+ (set_attr "mode" "<UNITMODE>")])
8158+
8159+;; Floating point multiply accumulate instructions.
8160+
8161+;; a * b + c
8162+(define_insn "fma<mode>4"
8163+ [(set (match_operand:ANYF 0 "register_operand" "=f")
8164+ (fma:ANYF
8165+ (match_operand:ANYF 1 "register_operand" "f")
8166+ (match_operand:ANYF 2 "register_operand" "f")
8167+ (match_operand:ANYF 3 "register_operand" "f")))]
8168+ "TARGET_HARD_FLOAT"
8169+ "fmadd.<fmt>\t%0,%1,%2,%3"
8170+ [(set_attr "type" "fmadd")
8171+ (set_attr "mode" "<UNITMODE>")])
8172+
8173+;; a * b - c
8174+(define_insn "fms<mode>4"
8175+ [(set (match_operand:ANYF 0 "register_operand" "=f")
8176+ (fma:ANYF
8177+ (match_operand:ANYF 1 "register_operand" "f")
8178+ (match_operand:ANYF 2 "register_operand" "f")
8179+ (neg:ANYF (match_operand:ANYF 3 "register_operand" "f"))))]
8180+ "TARGET_HARD_FLOAT"
8181+ "fmsub.<fmt>\t%0,%1,%2,%3"
8182+ [(set_attr "type" "fmadd")
8183+ (set_attr "mode" "<UNITMODE>")])
8184+
8185+;; -a * b - c
8186+(define_insn "fnms<mode>4"
8187+ [(set (match_operand:ANYF 0 "register_operand" "=f")
8188+ (fma:ANYF
8189+ (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
8190+ (match_operand:ANYF 2 "register_operand" "f")
8191+ (neg:ANYF (match_operand:ANYF 3 "register_operand" "f"))))]
8192+ "TARGET_HARD_FLOAT"
8193+ "fnmadd.<fmt>\t%0,%1,%2,%3"
8194+ [(set_attr "type" "fmadd")
8195+ (set_attr "mode" "<UNITMODE>")])
8196+
8197+;; -a * b + c
8198+(define_insn "fnma<mode>4"
8199+ [(set (match_operand:ANYF 0 "register_operand" "=f")
8200+ (fma:ANYF
8201+ (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
8202+ (match_operand:ANYF 2 "register_operand" "f")
8203+ (match_operand:ANYF 3 "register_operand" "f")))]
8204+ "TARGET_HARD_FLOAT"
8205+ "fnmsub.<fmt>\t%0,%1,%2,%3"
8206+ [(set_attr "type" "fmadd")
8207+ (set_attr "mode" "<UNITMODE>")])
8208+
8209+;; -(-a * b - c), modulo signed zeros
8210+(define_insn "*fma<mode>4"
8211+ [(set (match_operand:ANYF 0 "register_operand" "=f")
8212+ (neg:ANYF
8213+ (fma:ANYF
8214+ (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
8215+ (match_operand:ANYF 2 "register_operand" "f")
8216+ (neg:ANYF (match_operand:ANYF 3 "register_operand" "f")))))]
8217+ "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
8218+ "fmadd.<fmt>\t%0,%1,%2,%3"
8219+ [(set_attr "type" "fmadd")
8220+ (set_attr "mode" "<UNITMODE>")])
8221+
8222+;; -(-a * b + c), modulo signed zeros
8223+(define_insn "*fms<mode>4"
8224+ [(set (match_operand:ANYF 0 "register_operand" "=f")
8225+ (neg:ANYF
8226+ (fma:ANYF
8227+ (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
8228+ (match_operand:ANYF 2 "register_operand" "f")
8229+ (match_operand:ANYF 3 "register_operand" "f"))))]
8230+ "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
8231+ "fmsub.<fmt>\t%0,%1,%2,%3"
8232+ [(set_attr "type" "fmadd")
8233+ (set_attr "mode" "<UNITMODE>")])
8234+
8235+;; -(a * b + c), modulo signed zeros
8236+(define_insn "*fnms<mode>4"
8237+ [(set (match_operand:ANYF 0 "register_operand" "=f")
8238+ (neg:ANYF
8239+ (fma:ANYF
8240+ (match_operand:ANYF 1 "register_operand" "f")
8241+ (match_operand:ANYF 2 "register_operand" "f")
8242+ (match_operand:ANYF 3 "register_operand" "f"))))]
8243+ "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
8244+ "fnmadd.<fmt>\t%0,%1,%2,%3"
8245+ [(set_attr "type" "fmadd")
8246+ (set_attr "mode" "<UNITMODE>")])
8247+
8248+;; -(a * b - c), modulo signed zeros
8249+(define_insn "*fnma<mode>4"
8250+ [(set (match_operand:ANYF 0 "register_operand" "=f")
8251+ (neg:ANYF
8252+ (fma:ANYF
8253+ (match_operand:ANYF 1 "register_operand" "f")
8254+ (match_operand:ANYF 2 "register_operand" "f")
8255+ (neg:ANYF (match_operand:ANYF 3 "register_operand" "f")))))]
8256+ "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (<MODE>mode)"
8257+ "fnmsub.<fmt>\t%0,%1,%2,%3"
8258+ [(set_attr "type" "fmadd")
8259+ (set_attr "mode" "<UNITMODE>")])
8260+
8261+;;
8262+;; ....................
8263+;;
8264+;; SIGN INJECTION
8265+;;
8266+;; ....................
8267+
8268+(define_insn "abs<mode>2"
8269+ [(set (match_operand:ANYF 0 "register_operand" "=f")
8270+ (abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
8271+ "TARGET_HARD_FLOAT"
8272+ "fabs.<fmt>\t%0,%1"
8273+ [(set_attr "type" "fmove")
8274+ (set_attr "mode" "<UNITMODE>")])
8275+
8276+(define_insn "copysign<mode>3"
8277+ [(set (match_operand:ANYF 0 "register_operand" "=f")
8278+ (unspec:ANYF [(match_operand:ANYF 1 "register_operand" "f")
8279+ (match_operand:ANYF 2 "register_operand" "f")]
8280+ UNSPEC_COPYSIGN))]
8281+ "TARGET_HARD_FLOAT"
8282+ "fsgnj.<fmt>\t%0,%1,%2"
8283+ [(set_attr "type" "fmove")
8284+ (set_attr "mode" "<UNITMODE>")])
8285+
8286+(define_insn "neg<mode>2"
8287+ [(set (match_operand:ANYF 0 "register_operand" "=f")
8288+ (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
8289+ "TARGET_HARD_FLOAT"
8290+ "fneg.<fmt>\t%0,%1"
8291+ [(set_attr "type" "fmove")
8292+ (set_attr "mode" "<UNITMODE>")])
8293+
8294+;;
8295+;; ....................
8296+;;
8297+;; MIN/MAX
8298+;;
8299+;; ....................
8300+
8301+(define_insn "smin<mode>3"
8302+ [(set (match_operand:ANYF 0 "register_operand" "=f")
8303+ (smin:ANYF (match_operand:ANYF 1 "register_operand" "f")
8304+ (match_operand:ANYF 2 "register_operand" "f")))]
8305+ "TARGET_HARD_FLOAT"
8306+ "fmin.<fmt>\t%0,%1,%2"
8307+ [(set_attr "type" "fmove")
8308+ (set_attr "mode" "<UNITMODE>")])
8309+
8310+(define_insn "smax<mode>3"
8311+ [(set (match_operand:ANYF 0 "register_operand" "=f")
8312+ (smax:ANYF (match_operand:ANYF 1 "register_operand" "f")
8313+ (match_operand:ANYF 2 "register_operand" "f")))]
8314+ "TARGET_HARD_FLOAT"
8315+ "fmax.<fmt>\t%0,%1,%2"
8316+ [(set_attr "type" "fmove")
8317+ (set_attr "mode" "<UNITMODE>")])
8318+
8319+;;
8320+;; ....................
8321+;;
8322+;; LOGICAL
8323+;;
8324+;; ....................
8325+;;
8326+
8327+;; For RV64, we don't expose the SImode operations to the rtl expanders,
8328+;; but SImode versions exist for combine.
8329+
8330+(define_insn "<optab><mode>3"
8331+ [(set (match_operand:X 0 "register_operand" "=r,r")
8332+ (any_bitwise:X (match_operand:X 1 "register_operand" "%r,r")
8333+ (match_operand:X 2 "arith_operand" "r,I")))]
8334+ ""
8335+ "<insn>\t%0,%1,%2"
8336+ [(set_attr "type" "logical")
8337+ (set_attr "mode" "<MODE>")])
8338+
8339+(define_insn "*<optab>si3_internal"
8340+ [(set (match_operand:SI 0 "register_operand" "=r,r")
8341+ (any_bitwise:SI (match_operand:SI 1 "register_operand" "%r,r")
8342+ (match_operand:SI 2 "arith_operand" "r,I")))]
8343+ "TARGET_64BIT"
8344+ "<insn>\t%0,%1,%2"
8345+ [(set_attr "type" "logical")
8346+ (set_attr "mode" "SI")])
8347+
8348+(define_insn "one_cmpl<mode>2"
8349+ [(set (match_operand:X 0 "register_operand" "=r")
8350+ (not:X (match_operand:X 1 "register_operand" "r")))]
8351+ ""
8352+ "not\t%0,%1"
8353+ [(set_attr "type" "logical")
8354+ (set_attr "mode" "<MODE>")])
8355+
8356+(define_insn "*one_cmplsi2_internal"
8357+ [(set (match_operand:SI 0 "register_operand" "=r")
8358+ (not:SI (match_operand:SI 1 "register_operand" "r")))]
8359+ "TARGET_64BIT"
8360+ "not\t%0,%1"
8361+ [(set_attr "type" "logical")
8362+ (set_attr "mode" "SI")])
8363+
8364+;;
8365+;; ....................
8366+;;
8367+;; TRUNCATION
8368+;;
8369+;; ....................
8370+
8371+(define_insn "truncdfsf2"
8372+ [(set (match_operand:SF 0 "register_operand" "=f")
8373+ (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
8374+ "TARGET_DOUBLE_FLOAT"
8375+ "fcvt.s.d\t%0,%1"
8376+ [(set_attr "type" "fcvt")
8377+ (set_attr "mode" "SF")])
8378+
8379+;;
8380+;; ....................
8381+;;
8382+;; ZERO EXTENSION
8383+;;
8384+;; ....................
8385+
8386+;; Extension insns.
8387+
8388+(define_insn_and_split "zero_extendsidi2"
8389+ [(set (match_operand:DI 0 "register_operand" "=r,r")
8390+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
8391+ "TARGET_64BIT"
8392+ "@
8393+ #
8394+ lwu\t%0,%1"
8395+ "&& reload_completed && REG_P (operands[1])"
8396+ [(set (match_dup 0)
8397+ (ashift:DI (match_dup 1) (const_int 32)))
8398+ (set (match_dup 0)
8399+ (lshiftrt:DI (match_dup 0) (const_int 32)))]
8400+ { operands[1] = gen_lowpart (DImode, operands[1]); }
8401+ [(set_attr "move_type" "shift_shift,load")
8402+ (set_attr "mode" "DI")])
8403+
8404+(define_insn_and_split "zero_extendhi<GPR:mode>2"
8405+ [(set (match_operand:GPR 0 "register_operand" "=r,r")
8406+ (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
8407+ ""
8408+ "@
8409+ #
8410+ lhu\t%0,%1"
8411+ "&& reload_completed && REG_P (operands[1])"
8412+ [(set (match_dup 0)
8413+ (ashift:GPR (match_dup 1) (match_dup 2)))
8414+ (set (match_dup 0)
8415+ (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
8416+ {
8417+ operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]);
8418+ operands[2] = GEN_INT(GET_MODE_BITSIZE(<GPR:MODE>mode) - 16);
8419+ }
8420+ [(set_attr "move_type" "shift_shift,load")
8421+ (set_attr "mode" "<GPR:MODE>")])
8422+
8423+(define_insn "zero_extendqi<SUPERQI:mode>2"
8424+ [(set (match_operand:SUPERQI 0 "register_operand" "=r,r")
8425+ (zero_extend:SUPERQI
8426+ (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
8427+ ""
8428+ "@
8429+ and\t%0,%1,0xff
8430+ lbu\t%0,%1"
8431+ [(set_attr "move_type" "andi,load")
8432+ (set_attr "mode" "<SUPERQI:MODE>")])
8433+
8434+;;
8435+;; ....................
8436+;;
8437+;; SIGN EXTENSION
8438+;;
8439+;; ....................
8440+
8441+(define_insn "extendsidi2"
8442+ [(set (match_operand:DI 0 "register_operand" "=r,r")
8443+ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
8444+ "TARGET_64BIT"
8445+ "@
8446+ sext.w\t%0,%1
8447+ lw\t%0,%1"
8448+ [(set_attr "move_type" "move,load")
8449+ (set_attr "mode" "DI")])
8450+
8451+(define_insn_and_split "extend<SHORT:mode><SUPERQI:mode>2"
8452+ [(set (match_operand:SUPERQI 0 "register_operand" "=r,r")
8453+ (sign_extend:SUPERQI
8454+ (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
8455+ ""
8456+ "@
8457+ #
8458+ l<SHORT:size>\t%0,%1"
8459+ "&& reload_completed && REG_P (operands[1])"
8460+ [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
8461+ (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
8462+{
8463+ operands[0] = gen_lowpart (SImode, operands[0]);
8464+ operands[1] = gen_lowpart (SImode, operands[1]);
8465+ operands[2] = GEN_INT (GET_MODE_BITSIZE (SImode)
8466+ - GET_MODE_BITSIZE (<SHORT:MODE>mode));
8467+}
8468+ [(set_attr "move_type" "shift_shift,load")
8469+ (set_attr "mode" "SI")])
8470+
8471+(define_insn "extendsfdf2"
8472+ [(set (match_operand:DF 0 "register_operand" "=f")
8473+ (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
8474+ "TARGET_DOUBLE_FLOAT"
8475+ "fcvt.d.s\t%0,%1"
8476+ [(set_attr "type" "fcvt")
8477+ (set_attr "mode" "DF")])
8478+
8479+;;
8480+;; ....................
8481+;;
8482+;; CONVERSIONS
8483+;;
8484+;; ....................
8485+
8486+(define_insn "fix_trunc<ANYF:mode><GPR:mode>2"
8487+ [(set (match_operand:GPR 0 "register_operand" "=r")
8488+ (fix:GPR (match_operand:ANYF 1 "register_operand" "f")))]
8489+ "TARGET_HARD_FLOAT"
8490+ "fcvt.<GPR:ifmt>.<ANYF:fmt> %0,%1,rtz"
8491+ [(set_attr "type" "fcvt")
8492+ (set_attr "mode" "<ANYF:MODE>")])
8493+
8494+(define_insn "fixuns_trunc<ANYF:mode><GPR:mode>2"
8495+ [(set (match_operand:GPR 0 "register_operand" "=r")
8496+ (unsigned_fix:GPR (match_operand:ANYF 1 "register_operand" "f")))]
8497+ "TARGET_HARD_FLOAT"
8498+ "fcvt.<GPR:ifmt>u.<ANYF:fmt> %0,%1,rtz"
8499+ [(set_attr "type" "fcvt")
8500+ (set_attr "mode" "<ANYF:MODE>")])
8501+
8502+(define_insn "float<GPR:mode><ANYF:mode>2"
8503+ [(set (match_operand:ANYF 0 "register_operand" "=f")
8504+ (float:ANYF (match_operand:GPR 1 "reg_or_0_operand" "rJ")))]
8505+ "TARGET_HARD_FLOAT"
8506+ "fcvt.<ANYF:fmt>.<GPR:ifmt>\t%0,%z1"
8507+ [(set_attr "type" "fcvt")
8508+ (set_attr "mode" "<ANYF:MODE>")])
8509+
8510+(define_insn "floatuns<GPR:mode><ANYF:mode>2"
8511+ [(set (match_operand:ANYF 0 "register_operand" "=f")
8512+ (unsigned_float:ANYF (match_operand:GPR 1 "reg_or_0_operand" "rJ")))]
8513+ "TARGET_HARD_FLOAT"
8514+ "fcvt.<ANYF:fmt>.<GPR:ifmt>u\t%0,%z1"
8515+ [(set_attr "type" "fcvt")
8516+ (set_attr "mode" "<ANYF:MODE>")])
8517+
8518+(define_insn "lrint<ANYF:mode><GPR:mode>2"
8519+ [(set (match_operand:GPR 0 "register_operand" "=r")
8520+ (unspec:GPR [(match_operand:ANYF 1 "register_operand" "f")]
8521+ UNSPEC_LRINT))]
8522+ "TARGET_HARD_FLOAT"
8523+ "fcvt.<GPR:ifmt>.<ANYF:fmt> %0,%1,dyn"
8524+ [(set_attr "type" "fcvt")
8525+ (set_attr "mode" "<ANYF:MODE>")])
8526+
8527+(define_insn "lround<ANYF:mode><GPR:mode>2"
8528+ [(set (match_operand:GPR 0 "register_operand" "=r")
8529+ (unspec:GPR [(match_operand:ANYF 1 "register_operand" "f")]
8530+ UNSPEC_LROUND))]
8531+ "TARGET_HARD_FLOAT"
8532+ "fcvt.<GPR:ifmt>.<ANYF:fmt> %0,%1,rmm"
8533+ [(set_attr "type" "fcvt")
8534+ (set_attr "mode" "<ANYF:MODE>")])
8535+;;
8536+;; ....................
8537+;;
8538+;; DATA MOVEMENT
8539+;;
8540+;; ....................
8541+
8542+;; Lower-level instructions for loading an address from the GOT.
8543+;; We could use MEMs, but an unspec gives more optimization
8544+;; opportunities.
8545+
8546+(define_insn "got_load<mode>"
8547+ [(set (match_operand:P 0 "register_operand" "=r")
8548+ (unspec:P [(match_operand:P 1 "symbolic_operand" "")]
8549+ UNSPEC_LOAD_GOT))]
8550+ ""
8551+ "la\t%0,%1"
8552+ [(set_attr "got" "load")
8553+ (set_attr "mode" "<MODE>")])
8554+
8555+(define_insn "tls_add_tp_le<mode>"
8556+ [(set (match_operand:P 0 "register_operand" "=r")
8557+ (unspec:P [(match_operand:P 1 "register_operand" "r")
8558+ (match_operand:P 2 "register_operand" "r")
8559+ (match_operand:P 3 "symbolic_operand" "")]
8560+ UNSPEC_TLS_LE))]
8561+ ""
8562+ "add\t%0,%1,%2,%%tprel_add(%3)"
8563+ [(set_attr "type" "arith")
8564+ (set_attr "mode" "<MODE>")])
8565+
8566+(define_insn "got_load_tls_gd<mode>"
8567+ [(set (match_operand:P 0 "register_operand" "=r")
8568+ (unspec:P [(match_operand:P 1 "symbolic_operand" "")]
8569+ UNSPEC_TLS_GD))]
8570+ ""
8571+ "la.tls.gd\t%0,%1"
8572+ [(set_attr "got" "load")
8573+ (set_attr "mode" "<MODE>")])
8574+
8575+(define_insn "got_load_tls_ie<mode>"
8576+ [(set (match_operand:P 0 "register_operand" "=r")
8577+ (unspec:P [(match_operand:P 1 "symbolic_operand" "")]
8578+ UNSPEC_TLS_IE))]
8579+ ""
8580+ "la.tls.ie\t%0,%1"
8581+ [(set_attr "got" "load")
8582+ (set_attr "mode" "<MODE>")])
8583+
8584+(define_insn "auipc<mode>"
8585+ [(set (match_operand:P 0 "register_operand" "=r")
8586+ (unspec:P [(match_operand:P 1 "symbolic_operand" "")
8587+ (match_operand:P 2 "const_int_operand")
8588+ (pc)]
8589+ UNSPEC_AUIPC))]
8590+ ""
8591+ ".LA%2: auipc\t%0,%h1"
8592+ [(set_attr "type" "arith")
8593+ (set_attr "cannot_copy" "yes")])
8594+
8595+;; Instructions for adding the low 12 bits of an address to a register.
8596+;; Operand 2 is the address: riscv_print_operand works out which relocation
8597+;; should be applied.
8598+
8599+(define_insn "*low<mode>"
8600+ [(set (match_operand:P 0 "register_operand" "=r")
8601+ (lo_sum:P (match_operand:P 1 "register_operand" "r")
8602+ (match_operand:P 2 "symbolic_operand" "")))]
8603+ ""
8604+ "addi\t%0,%1,%R2"
8605+ [(set_attr "type" "arith")
8606+ (set_attr "mode" "<MODE>")])
8607+
8608+;; Allow combine to split complex const_int load sequences, using operand 2
8609+;; to store the intermediate results. See move_operand for details.
8610+(define_split
8611+ [(set (match_operand:GPR 0 "register_operand")
8612+ (match_operand:GPR 1 "splittable_const_int_operand"))
8613+ (clobber (match_operand:GPR 2 "register_operand"))]
8614+ ""
8615+ [(const_int 0)]
8616+{
8617+ riscv_move_integer (operands[2], operands[0], INTVAL (operands[1]));
8618+ DONE;
8619+})
8620+
8621+;; Likewise, for symbolic operands.
8622+(define_split
8623+ [(set (match_operand:P 0 "register_operand")
8624+ (match_operand:P 1))
8625+ (clobber (match_operand:P 2 "register_operand"))]
8626+ "riscv_split_symbol (operands[2], operands[1], MAX_MACHINE_MODE, NULL)"
8627+ [(set (match_dup 0) (match_dup 3))]
8628+{
8629+ riscv_split_symbol (operands[2], operands[1],
8630+ MAX_MACHINE_MODE, &operands[3]);
8631+})
8632+
8633+;; 64-bit integer moves
8634+
8635+(define_expand "movdi"
8636+ [(set (match_operand:DI 0 "")
8637+ (match_operand:DI 1 ""))]
8638+ ""
8639+{
8640+ if (riscv_legitimize_move (DImode, operands[0], operands[1]))
8641+ DONE;
8642+})
8643+
8644+(define_insn "*movdi_32bit"
8645+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m, *f,*f,*r,*f,*m")
8646+ (match_operand:DI 1 "move_operand" " r,i,m,r,*J*r,*m,*f,*f,*f"))]
8647+ "!TARGET_64BIT
8648+ && (register_operand (operands[0], DImode)
8649+ || reg_or_0_operand (operands[1], DImode))"
8650+ { return riscv_output_move (operands[0], operands[1]); }
8651+ [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fmove,fpstore")
8652+ (set_attr "mode" "DI")])
8653+
8654+(define_insn "*movdi_64bit"
8655+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m,*f,*f,*r,*f,*m")
8656+ (match_operand:DI 1 "move_operand" " r,T,m,rJ,*r*J,*m,*f,*f,*f"))]
8657+ "TARGET_64BIT
8658+ && (register_operand (operands[0], DImode)
8659+ || reg_or_0_operand (operands[1], DImode))"
8660+ { return riscv_output_move (operands[0], operands[1]); }
8661+ [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fmove,fpstore")
8662+ (set_attr "mode" "DI")])
8663+
8664+;; 32-bit Integer moves
8665+
8666+(define_expand "mov<mode>"
8667+ [(set (match_operand:MOVE32 0 "")
8668+ (match_operand:MOVE32 1 ""))]
8669+ ""
8670+{
8671+ if (riscv_legitimize_move (<MODE>mode, operands[0], operands[1]))
8672+ DONE;
8673+})
8674+
8675+(define_insn "*movsi_internal"
8676+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,*f,*f,*r,*m")
8677+ (match_operand:SI 1 "move_operand" "r,T,m,rJ,*r*J,*m,*f,*f"))]
8678+ "(register_operand (operands[0], SImode)
8679+ || reg_or_0_operand (operands[1], SImode))"
8680+ { return riscv_output_move (operands[0], operands[1]); }
8681+ [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fpstore")
8682+ (set_attr "mode" "SI")])
8683+
8684+;; 16-bit Integer moves
8685+
8686+;; Unlike most other insns, the move insns can't be split with
8687+;; different predicates, because register spilling and other parts of
8688+;; the compiler, have memoized the insn number already.
8689+;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
8690+
8691+(define_expand "movhi"
8692+ [(set (match_operand:HI 0 "")
8693+ (match_operand:HI 1 ""))]
8694+ ""
8695+{
8696+ if (riscv_legitimize_move (HImode, operands[0], operands[1]))
8697+ DONE;
8698+})
8699+
8700+(define_insn "*movhi_internal"
8701+ [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,*f,*r")
8702+ (match_operand:HI 1 "move_operand" "r,T,m,rJ,*r*J,*f"))]
8703+ "(register_operand (operands[0], HImode)
8704+ || reg_or_0_operand (operands[1], HImode))"
8705+ { return riscv_output_move (operands[0], operands[1]); }
8706+ [(set_attr "move_type" "move,const,load,store,mtc,mfc")
8707+ (set_attr "mode" "HI")])
8708+
8709+;; HImode constant generation; see riscv_move_integer for details.
8710+;; si+si->hi without truncation is legal because of TRULY_NOOP_TRUNCATION.
8711+
8712+(define_insn "*add<mode>hi3"
8713+ [(set (match_operand:HI 0 "register_operand" "=r,r")
8714+ (plus:HI (match_operand:HISI 1 "register_operand" "r,r")
8715+ (match_operand:HISI 2 "arith_operand" "r,I")))]
8716+ ""
8717+ { return TARGET_64BIT ? "addw\t%0,%1,%2" : "add\t%0,%1,%2"; }
8718+ [(set_attr "type" "arith")
8719+ (set_attr "mode" "HI")])
8720+
8721+(define_insn "*xor<mode>hi3"
8722+ [(set (match_operand:HI 0 "register_operand" "=r,r")
8723+ (xor:HI (match_operand:HISI 1 "register_operand" "r,r")
8724+ (match_operand:HISI 2 "arith_operand" "r,I")))]
8725+ ""
8726+ "xor\t%0,%1,%2"
8727+ [(set_attr "type" "logical")
8728+ (set_attr "mode" "HI")])
8729+
8730+;; 8-bit Integer moves
8731+
8732+(define_expand "movqi"
8733+ [(set (match_operand:QI 0 "")
8734+ (match_operand:QI 1 ""))]
8735+ ""
8736+{
8737+ if (riscv_legitimize_move (QImode, operands[0], operands[1]))
8738+ DONE;
8739+})
8740+
8741+(define_insn "*movqi_internal"
8742+ [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m,*f,*r")
8743+ (match_operand:QI 1 "move_operand" "r,I,m,rJ,*r*J,*f"))]
8744+ "(register_operand (operands[0], QImode)
8745+ || reg_or_0_operand (operands[1], QImode))"
8746+ { return riscv_output_move (operands[0], operands[1]); }
8747+ [(set_attr "move_type" "move,const,load,store,mtc,mfc")
8748+ (set_attr "mode" "QI")])
8749+
8750+;; 32-bit floating point moves
8751+
8752+(define_expand "movsf"
8753+ [(set (match_operand:SF 0 "")
8754+ (match_operand:SF 1 ""))]
8755+ ""
8756+{
8757+ if (riscv_legitimize_move (SFmode, operands[0], operands[1]))
8758+ DONE;
8759+})
8760+
8761+(define_insn "*movsf_hardfloat"
8762+ [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r,*r,*r,*m")
8763+ (match_operand:SF 1 "move_operand" "f,G,m,f,G,*r,*f,*G*r,*m,*r"))]
8764+ "TARGET_HARD_FLOAT
8765+ && (register_operand (operands[0], SFmode)
8766+ || reg_or_0_operand (operands[1], SFmode))"
8767+ { return riscv_output_move (operands[0], operands[1]); }
8768+ [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
8769+ (set_attr "mode" "SF")])
8770+
8771+(define_insn "*movsf_softfloat"
8772+ [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
8773+ (match_operand:SF 1 "move_operand" "Gr,m,r"))]
8774+ "!TARGET_HARD_FLOAT
8775+ && (register_operand (operands[0], SFmode)
8776+ || reg_or_0_operand (operands[1], SFmode))"
8777+ { return riscv_output_move (operands[0], operands[1]); }
8778+ [(set_attr "move_type" "move,load,store")
8779+ (set_attr "mode" "SF")])
8780+
8781+;; 64-bit floating point moves
8782+
8783+(define_expand "movdf"
8784+ [(set (match_operand:DF 0 "")
8785+ (match_operand:DF 1 ""))]
8786+ ""
8787+{
8788+ if (riscv_legitimize_move (DFmode, operands[0], operands[1]))
8789+ DONE;
8790+})
8791+
8792+;; In RV32, we lack fmv.x.d and fmv.d.x. Go through memory instead.
8793+;; (However, we can still use fcvt.d.w to zero a floating-point register.)
8794+(define_insn "*movdf_hardfloat_rv32"
8795+ [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*r,*r,*m")
8796+ (match_operand:DF 1 "move_operand" "f,G,m,f,G,*r*G,*m,*r"))]
8797+ "!TARGET_64BIT && TARGET_DOUBLE_FLOAT
8798+ && (register_operand (operands[0], DFmode)
8799+ || reg_or_0_operand (operands[1], DFmode))"
8800+ { return riscv_output_move (operands[0], operands[1]); }
8801+ [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,move,load,store")
8802+ (set_attr "mode" "DF")])
8803+
8804+(define_insn "*movdf_hardfloat_rv64"
8805+ [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r,*r,*r,*m")
8806+ (match_operand:DF 1 "move_operand" "f,G,m,f,G,*r,*f,*r*G,*m,*r"))]
8807+ "TARGET_64BIT && TARGET_DOUBLE_FLOAT
8808+ && (register_operand (operands[0], DFmode)
8809+ || reg_or_0_operand (operands[1], DFmode))"
8810+ { return riscv_output_move (operands[0], operands[1]); }
8811+ [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
8812+ (set_attr "mode" "DF")])
8813+
8814+(define_insn "*movdf_softfloat"
8815+ [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
8816+ (match_operand:DF 1 "move_operand" "rG,m,rG"))]
8817+ "!TARGET_DOUBLE_FLOAT
8818+ && (register_operand (operands[0], DFmode)
8819+ || reg_or_0_operand (operands[1], DFmode))"
8820+ { return riscv_output_move (operands[0], operands[1]); }
8821+ [(set_attr "move_type" "move,load,store")
8822+ (set_attr "mode" "DF")])
8823+
8824+(define_split
8825+ [(set (match_operand:MOVE64 0 "nonimmediate_operand")
8826+ (match_operand:MOVE64 1 "move_operand"))]
8827+ "reload_completed
8828+ && riscv_split_64bit_move_p (operands[0], operands[1])"
8829+ [(const_int 0)]
8830+{
8831+ riscv_split_doubleword_move (operands[0], operands[1]);
8832+ DONE;
8833+})
8834+
8835+;; Expand in-line code to clear the instruction cache between operand[0] and
8836+;; operand[1].
8837+(define_expand "clear_cache"
8838+ [(match_operand 0 "pmode_register_operand")
8839+ (match_operand 1 "pmode_register_operand")]
8840+ ""
8841+{
8842+ emit_insn (gen_fence_i ());
8843+ DONE;
8844+})
8845+
8846+(define_insn "fence"
8847+ [(unspec_volatile [(const_int 0)] UNSPECV_FENCE)]
8848+ ""
8849+ "%|fence%-")
8850+
8851+(define_insn "fence_i"
8852+ [(unspec_volatile [(const_int 0)] UNSPECV_FENCE_I)]
8853+ ""
8854+ "fence.i")
8855+
8856+;;
8857+;; ....................
8858+;;
8859+;; SHIFTS
8860+;;
8861+;; ....................
8862+
8863+(define_insn "<optab>si3"
8864+ [(set (match_operand:SI 0 "register_operand" "=r")
8865+ (any_shift:SI (match_operand:SI 1 "register_operand" "r")
8866+ (match_operand:SI 2 "arith_operand" "rI")))]
8867+ ""
8868+{
8869+ if (GET_CODE (operands[2]) == CONST_INT)
8870+ operands[2] = GEN_INT (INTVAL (operands[2])
8871+ & (GET_MODE_BITSIZE (SImode) - 1));
8872+
8873+ return TARGET_64BIT ? "<insn>w\t%0,%1,%2" : "<insn>\t%0,%1,%2";
8874+}
8875+ [(set_attr "type" "shift")
8876+ (set_attr "mode" "SI")])
8877+
8878+(define_insn "<optab>di3"
8879+ [(set (match_operand:DI 0 "register_operand" "=r")
8880+ (any_shift:DI (match_operand:DI 1 "register_operand" "r")
8881+ (match_operand:DI 2 "arith_operand" "rI")))]
8882+ "TARGET_64BIT"
8883+{
8884+ if (GET_CODE (operands[2]) == CONST_INT)
8885+ operands[2] = GEN_INT (INTVAL (operands[2])
8886+ & (GET_MODE_BITSIZE (DImode) - 1));
8887+
8888+ return "<insn>\t%0,%1,%2";
8889+}
8890+ [(set_attr "type" "shift")
8891+ (set_attr "mode" "DI")])
8892+
8893+(define_insn "*<optab>si3_extend"
8894+ [(set (match_operand:DI 0 "register_operand" "=r")
8895+ (sign_extend:DI
8896+ (any_shift:SI (match_operand:SI 1 "register_operand" "r")
8897+ (match_operand:SI 2 "arith_operand" "rI"))))]
8898+ "TARGET_64BIT"
8899+{
8900+ if (GET_CODE (operands[2]) == CONST_INT)
8901+ operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8902+
8903+ return "<insn>w\t%0,%1,%2";
8904+}
8905+ [(set_attr "type" "shift")
8906+ (set_attr "mode" "SI")])
8907+
8908+;;
8909+;; ....................
8910+;;
8911+;; CONDITIONAL BRANCHES
8912+;;
8913+;; ....................
8914+
8915+;; Conditional branches
8916+
8917+(define_insn "*branch_order<mode>"
8918+ [(set (pc)
8919+ (if_then_else
8920+ (match_operator 1 "order_operator"
8921+ [(match_operand:X 2 "register_operand" "r")
8922+ (match_operand:X 3 "register_operand" "r")])
8923+ (label_ref (match_operand 0 "" ""))
8924+ (pc)))]
8925+ ""
8926+ "b%C1\t%2,%3,%0"
8927+ [(set_attr "type" "branch")
8928+ (set_attr "mode" "none")])
8929+
8930+(define_insn "*branch_zero<mode>"
8931+ [(set (pc)
8932+ (if_then_else
8933+ (match_operator 1 "signed_order_operator"
8934+ [(match_operand:X 2 "register_operand" "r")
8935+ (const_int 0)])
8936+ (label_ref (match_operand 0 "" ""))
8937+ (pc)))]
8938+ ""
8939+ "b%C1z\t%2,%0"
8940+ [(set_attr "type" "branch")
8941+ (set_attr "mode" "none")])
8942+
8943+;; Used to implement built-in functions.
8944+(define_expand "condjump"
8945+ [(set (pc)
8946+ (if_then_else (match_operand 0)
8947+ (label_ref (match_operand 1))
8948+ (pc)))])
8949+
8950+(define_expand "cbranch<mode>4"
8951+ [(set (pc)
8952+ (if_then_else (match_operator 0 "comparison_operator"
8953+ [(match_operand:BR 1 "register_operand")
8954+ (match_operand:BR 2 "nonmemory_operand")])
8955+ (label_ref (match_operand 3 ""))
8956+ (pc)))]
8957+ ""
8958+{
8959+ riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]),
8960+ operands[1], operands[2]);
8961+ DONE;
8962+})
8963+
8964+(define_expand "cbranch<mode>4"
8965+ [(set (pc)
8966+ (if_then_else (match_operator 0 "fp_branch_comparison"
8967+ [(match_operand:ANYF 1 "register_operand")
8968+ (match_operand:ANYF 2 "register_operand")])
8969+ (label_ref (match_operand 3 ""))
8970+ (pc)))]
8971+ "TARGET_HARD_FLOAT"
8972+{
8973+ riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]),
8974+ operands[1], operands[2]);
8975+ DONE;
8976+})
8977+
8978+(define_insn_and_split "*branch_on_bit<X:mode>"
8979+ [(set (pc)
8980+ (if_then_else
8981+ (match_operator 0 "equality_operator"
8982+ [(zero_extract:X (match_operand:X 2 "register_operand" "r")
8983+ (const_int 1)
8984+ (match_operand 3 "branch_on_bit_operand"))
8985+ (const_int 0)])
8986+ (label_ref (match_operand 1))
8987+ (pc)))
8988+ (clobber (match_scratch:X 4 "=&r"))]
8989+ ""
8990+ "#"
8991+ "reload_completed"
8992+ [(set (match_dup 4)
8993+ (ashift:X (match_dup 2) (match_dup 3)))
8994+ (set (pc)
8995+ (if_then_else
8996+ (match_op_dup 0 [(match_dup 4) (const_int 0)])
8997+ (label_ref (match_operand 1))
8998+ (pc)))]
8999+{
9000+ int shift = GET_MODE_BITSIZE (<MODE>mode) - 1 - INTVAL (operands[3]);
9001+ operands[3] = GEN_INT (shift);
9002+
9003+ if (GET_CODE (operands[0]) == EQ)
9004+ operands[0] = gen_rtx_GE (<MODE>mode, operands[4], const0_rtx);
9005+ else
9006+ operands[0] = gen_rtx_LT (<MODE>mode, operands[4], const0_rtx);
9007+})
9008+
9009+(define_insn_and_split "*branch_on_bit_range<X:mode>"
9010+ [(set (pc)
9011+ (if_then_else
9012+ (match_operator 0 "equality_operator"
9013+ [(zero_extract:X (match_operand:X 2 "register_operand" "r")
9014+ (match_operand 3 "branch_on_bit_operand")
9015+ (const_int 0))
9016+ (const_int 0)])
9017+ (label_ref (match_operand 1))
9018+ (pc)))
9019+ (clobber (match_scratch:X 4 "=&r"))]
9020+ ""
9021+ "#"
9022+ "reload_completed"
9023+ [(set (match_dup 4)
9024+ (ashift:X (match_dup 2) (match_dup 3)))
9025+ (set (pc)
9026+ (if_then_else
9027+ (match_op_dup 0 [(match_dup 4) (const_int 0)])
9028+ (label_ref (match_operand 1))
9029+ (pc)))]
9030+{
9031+ operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[3]));
9032+})
9033+
9034+;;
9035+;; ....................
9036+;;
9037+;; SETTING A REGISTER FROM A COMPARISON
9038+;;
9039+;; ....................
9040+
9041+;; Destination is always set in SI mode.
9042+
9043+(define_expand "cstore<mode>4"
9044+ [(set (match_operand:SI 0 "register_operand")
9045+ (match_operator:SI 1 "order_operator"
9046+ [(match_operand:GPR 2 "register_operand")
9047+ (match_operand:GPR 3 "nonmemory_operand")]))]
9048+ ""
9049+{
9050+ riscv_expand_int_scc (operands[0], GET_CODE (operands[1]), operands[2],
9051+ operands[3]);
9052+ DONE;
9053+})
9054+
9055+(define_expand "cstore<mode>4"
9056+ [(set (match_operand:SI 0 "register_operand")
9057+ (match_operator:SI 1 "fp_scc_comparison"
9058+ [(match_operand:ANYF 2 "register_operand")
9059+ (match_operand:ANYF 3 "register_operand")]))]
9060+ "TARGET_HARD_FLOAT"
9061+{
9062+ riscv_expand_float_scc (operands[0], GET_CODE (operands[1]), operands[2],
9063+ operands[3]);
9064+ DONE;
9065+})
9066+
9067+(define_insn "*cstore<ANYF:mode><X:mode>4"
9068+ [(set (match_operand:X 0 "register_operand" "=r")
9069+ (match_operator:X 1 "fp_native_comparison"
9070+ [(match_operand:ANYF 2 "register_operand" "f")
9071+ (match_operand:ANYF 3 "register_operand" "f")]))]
9072+ "TARGET_HARD_FLOAT"
9073+ "f%C1.<fmt>\t%0,%2,%3"
9074+ [(set_attr "type" "fcmp")
9075+ (set_attr "mode" "<UNITMODE>")])
9076+
9077+(define_insn "fle_quiet<ANYF:mode><X:mode>4"
9078+ [(set (match_operand:X 0 "register_operand" "=r")
9079+ (unspec:X
9080+ [(match_operand:ANYF 1 "register_operand" "f")
9081+ (match_operand:ANYF 2 "register_operand" "f")]
9082+ UNSPEC_FLE_QUIET))
9083+ (clobber (match_scratch:X 3 "=&r"))]
9084+ "TARGET_HARD_FLOAT"
9085+ "frflags\t%3\n\tfle.<fmt>\t%0,%1,%2\n\tfsflags %3"
9086+ [(set_attr "type" "fcmp")
9087+ (set_attr "mode" "<UNITMODE>")
9088+ (set (attr "length") (const_int 12))])
9089+
9090+(define_insn "flt_quiet<ANYF:mode><X:mode>4"
9091+ [(set (match_operand:X 0 "register_operand" "=r")
9092+ (unspec:X
9093+ [(match_operand:ANYF 1 "register_operand" "f")
9094+ (match_operand:ANYF 2 "register_operand" "f")]
9095+ UNSPEC_FLT_QUIET))
9096+ (clobber (match_scratch:X 3 "=&r"))]
9097+ "TARGET_HARD_FLOAT"
9098+ "frflags\t%3\n\tflt.<fmt>\t%0,%1,%2\n\tfsflags %3"
9099+ [(set_attr "type" "fcmp")
9100+ (set_attr "mode" "<UNITMODE>")
9101+ (set (attr "length") (const_int 12))])
9102+
9103+(define_insn "*seq_zero_<X:mode><GPR:mode>"
9104+ [(set (match_operand:GPR 0 "register_operand" "=r")
9105+ (eq:GPR (match_operand:X 1 "register_operand" "r")
9106+ (const_int 0)))]
9107+ ""
9108+ "seqz\t%0,%1"
9109+ [(set_attr "type" "slt")
9110+ (set_attr "mode" "<X:MODE>")])
9111+
9112+(define_insn "*sne_zero_<X:mode><GPR:mode>"
9113+ [(set (match_operand:GPR 0 "register_operand" "=r")
9114+ (ne:GPR (match_operand:X 1 "register_operand" "r")
9115+ (const_int 0)))]
9116+ ""
9117+ "snez\t%0,%1"
9118+ [(set_attr "type" "slt")
9119+ (set_attr "mode" "<X:MODE>")])
9120+
9121+(define_insn "*sgt<u>_<X:mode><GPR:mode>"
9122+ [(set (match_operand:GPR 0 "register_operand" "=r")
9123+ (any_gt:GPR (match_operand:X 1 "register_operand" "r")
9124+ (match_operand:X 2 "reg_or_0_operand" "rJ")))]
9125+ ""
9126+ "sgt<u>\t%0,%1,%z2"
9127+ [(set_attr "type" "slt")
9128+ (set_attr "mode" "<X:MODE>")])
9129+
9130+(define_insn "*sge<u>_<X:mode><GPR:mode>"
9131+ [(set (match_operand:GPR 0 "register_operand" "=r")
9132+ (any_ge:GPR (match_operand:X 1 "register_operand" "r")
9133+ (const_int 1)))]
9134+ ""
9135+ "slt<u>\t%0,zero,%1"
9136+ [(set_attr "type" "slt")
9137+ (set_attr "mode" "<MODE>")])
9138+
9139+(define_insn "*slt<u>_<X:mode><GPR:mode>"
9140+ [(set (match_operand:GPR 0 "register_operand" "=r")
9141+ (any_lt:GPR (match_operand:X 1 "register_operand" "r")
9142+ (match_operand:X 2 "arith_operand" "rI")))]
9143+ ""
9144+ "slt<u>\t%0,%1,%2"
9145+ [(set_attr "type" "slt")
9146+ (set_attr "mode" "<MODE>")])
9147+
9148+(define_insn "*sle<u>_<X:mode><GPR:mode>"
9149+ [(set (match_operand:GPR 0 "register_operand" "=r")
9150+ (any_le:GPR (match_operand:X 1 "register_operand" "r")
9151+ (match_operand:X 2 "sle_operand" "")))]
9152+ ""
9153+{
9154+ operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
9155+ return "slt<u>\t%0,%1,%2";
9156+}
9157+ [(set_attr "type" "slt")
9158+ (set_attr "mode" "<MODE>")])
9159+
9160+;;
9161+;; ....................
9162+;;
9163+;; UNCONDITIONAL BRANCHES
9164+;;
9165+;; ....................
9166+
9167+;; Unconditional branches.
9168+
9169+(define_insn "jump"
9170+ [(set (pc)
9171+ (label_ref (match_operand 0 "" "")))]
9172+ ""
9173+ "j\t%l0"
9174+ [(set_attr "type" "jump")
9175+ (set_attr "mode" "none")])
9176+
9177+(define_expand "indirect_jump"
9178+ [(set (pc) (match_operand 0 "register_operand"))]
9179+ ""
9180+{
9181+ operands[0] = force_reg (Pmode, operands[0]);
9182+ if (Pmode == SImode)
9183+ emit_jump_insn (gen_indirect_jumpsi (operands[0]));
9184+ else
9185+ emit_jump_insn (gen_indirect_jumpdi (operands[0]));
9186+ DONE;
9187+})
9188+
9189+(define_insn "indirect_jump<mode>"
9190+ [(set (pc) (match_operand:P 0 "register_operand" "l"))]
9191+ ""
9192+ "jr\t%0"
9193+ [(set_attr "type" "jump")
9194+ (set_attr "mode" "none")])
9195+
9196+(define_expand "tablejump"
9197+ [(set (pc) (match_operand 0 "register_operand" ""))
9198+ (use (label_ref (match_operand 1 "" "")))]
9199+ ""
9200+{
9201+ if (CASE_VECTOR_PC_RELATIVE)
9202+ operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
9203+ gen_rtx_LABEL_REF (Pmode, operands[1]),
9204+ NULL_RTX, 0, OPTAB_DIRECT);
9205+
9206+ if (CASE_VECTOR_PC_RELATIVE && Pmode == DImode)
9207+ emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
9208+ else
9209+ emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
9210+ DONE;
9211+})
9212+
9213+(define_insn "tablejump<mode>"
9214+ [(set (pc) (match_operand:GPR 0 "register_operand" "l"))
9215+ (use (label_ref (match_operand 1 "" "")))]
9216+ ""
9217+ "jr\t%0"
9218+ [(set_attr "type" "jump")
9219+ (set_attr "mode" "none")])
9220+
9221+;;
9222+;; ....................
9223+;;
9224+;; Function prologue/epilogue
9225+;;
9226+;; ....................
9227+;;
9228+
9229+(define_expand "prologue"
9230+ [(const_int 1)]
9231+ ""
9232+{
9233+ riscv_expand_prologue ();
9234+ DONE;
9235+})
9236+
9237+;; Block any insns from being moved before this point, since the
9238+;; profiling call to mcount can use various registers that aren't
9239+;; saved or used to pass arguments.
9240+
9241+(define_insn "blockage"
9242+ [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9243+ ""
9244+ ""
9245+ [(set_attr "type" "ghost")
9246+ (set_attr "mode" "none")])
9247+
9248+(define_expand "epilogue"
9249+ [(const_int 2)]
9250+ ""
9251+{
9252+ riscv_expand_epilogue (false);
9253+ DONE;
9254+})
9255+
9256+(define_expand "sibcall_epilogue"
9257+ [(const_int 2)]
9258+ ""
9259+{
9260+ riscv_expand_epilogue (true);
9261+ DONE;
9262+})
9263+
9264+;; Trivial return. Make it look like a normal return insn as that
9265+;; allows jump optimizations to work better.
9266+
9267+(define_expand "return"
9268+ [(return)]
9269+ "riscv_can_use_return_insn ()"
9270+ "")
9271+
9272+(define_insn "simple_return"
9273+ [(return)]
9274+ ""
9275+ "ret"
9276+ [(set_attr "type" "jump")
9277+ (set_attr "mode" "none")])
9278+
9279+;; Normal return.
9280+
9281+(define_insn "simple_return_internal"
9282+ [(return)
9283+ (use (match_operand 0 "pmode_register_operand" ""))]
9284+ ""
9285+ "jr\t%0"
9286+ [(set_attr "type" "jump")
9287+ (set_attr "mode" "none")])
9288+
9289+;; This is used in compiling the unwind routines.
9290+(define_expand "eh_return"
9291+ [(use (match_operand 0 "general_operand"))]
9292+ ""
9293+{
9294+ if (GET_MODE (operands[0]) != word_mode)
9295+ operands[0] = convert_to_mode (word_mode, operands[0], 0);
9296+ if (TARGET_64BIT)
9297+ emit_insn (gen_eh_set_lr_di (operands[0]));
9298+ else
9299+ emit_insn (gen_eh_set_lr_si (operands[0]));
9300+ DONE;
9301+})
9302+
9303+;; Clobber the return address on the stack. We can't expand this
9304+;; until we know where it will be put in the stack frame.
9305+
9306+(define_insn "eh_set_lr_si"
9307+ [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
9308+ (clobber (match_scratch:SI 1 "=&r"))]
9309+ "! TARGET_64BIT"
9310+ "#")
9311+
9312+(define_insn "eh_set_lr_di"
9313+ [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
9314+ (clobber (match_scratch:DI 1 "=&r"))]
9315+ "TARGET_64BIT"
9316+ "#")
9317+
9318+(define_split
9319+ [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
9320+ (clobber (match_scratch 1))]
9321+ "reload_completed"
9322+ [(const_int 0)]
9323+{
9324+ riscv_set_return_address (operands[0], operands[1]);
9325+ DONE;
9326+})
9327+
9328+;;
9329+;; ....................
9330+;;
9331+;; FUNCTION CALLS
9332+;;
9333+;; ....................
9334+
9335+(define_expand "sibcall"
9336+ [(parallel [(call (match_operand 0 "")
9337+ (match_operand 1 ""))
9338+ (use (match_operand 2 "")) ;; next_arg_reg
9339+ (use (match_operand 3 ""))])] ;; struct_value_size_rtx
9340+ ""
9341+{
9342+ rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
9343+ emit_call_insn (gen_sibcall_internal (target, operands[1]));
9344+ DONE;
9345+})
9346+
9347+(define_insn "sibcall_internal"
9348+ [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S,U"))
9349+ (match_operand 1 "" ""))]
9350+ "SIBLING_CALL_P (insn)"
9351+ "@
9352+ jr\t%0
9353+ tail\t%0
9354+ tail\t%0@plt"
9355+ [(set_attr "type" "call")])
9356+
9357+(define_expand "sibcall_value"
9358+ [(parallel [(set (match_operand 0 "")
9359+ (call (match_operand 1 "")
9360+ (match_operand 2 "")))
9361+ (use (match_operand 3 ""))])] ;; next_arg_reg
9362+ ""
9363+{
9364+ rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
9365+ emit_call_insn (gen_sibcall_value_internal (operands[0], target, operands[2]));
9366+ DONE;
9367+})
9368+
9369+(define_insn "sibcall_value_internal"
9370+ [(set (match_operand 0 "" "")
9371+ (call (mem:SI (match_operand 1 "call_insn_operand" "j,S,U"))
9372+ (match_operand 2 "" "")))]
9373+ "SIBLING_CALL_P (insn)"
9374+ "@
9375+ jr\t%1
9376+ tail\t%1
9377+ tail\t%1@plt"
9378+ [(set_attr "type" "call")])
9379+
9380+(define_expand "call"
9381+ [(parallel [(call (match_operand 0 "")
9382+ (match_operand 1 ""))
9383+ (use (match_operand 2 "")) ;; next_arg_reg
9384+ (use (match_operand 3 ""))])] ;; struct_value_size_rtx
9385+ ""
9386+{
9387+ rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
9388+ emit_call_insn (gen_call_internal (target, operands[1]));
9389+ DONE;
9390+})
9391+
9392+(define_insn "call_internal"
9393+ [(call (mem:SI (match_operand 0 "call_insn_operand" "l,S,U"))
9394+ (match_operand 1 "" ""))
9395+ (clobber (reg:SI RETURN_ADDR_REGNUM))]
9396+ ""
9397+ "@
9398+ jalr\t%0
9399+ call\t%0
9400+ call\t%0@plt"
9401+ [(set_attr "type" "call")])
9402+
9403+(define_expand "call_value"
9404+ [(parallel [(set (match_operand 0 "")
9405+ (call (match_operand 1 "")
9406+ (match_operand 2 "")))
9407+ (use (match_operand 3 ""))])] ;; next_arg_reg
9408+ ""
9409+{
9410+ rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
9411+ emit_call_insn (gen_call_value_internal (operands[0], target, operands[2]));
9412+ DONE;
9413+})
9414+
9415+(define_insn "call_value_internal"
9416+ [(set (match_operand 0 "" "")
9417+ (call (mem:SI (match_operand 1 "call_insn_operand" "l,S,U"))
9418+ (match_operand 2 "" "")))
9419+ (clobber (reg:SI RETURN_ADDR_REGNUM))]
9420+ ""
9421+ "@
9422+ jalr\t%1
9423+ call\t%1
9424+ call\t%1@plt"
9425+ [(set_attr "type" "call")])
9426+
9427+;; Call subroutine returning any type.
9428+
9429+(define_expand "untyped_call"
9430+ [(parallel [(call (match_operand 0 "")
9431+ (const_int 0))
9432+ (match_operand 1 "")
9433+ (match_operand 2 "")])]
9434+ ""
9435+{
9436+ int i;
9437+
9438+ emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
9439+
9440+ for (i = 0; i < XVECLEN (operands[2], 0); i++)
9441+ {
9442+ rtx set = XVECEXP (operands[2], 0, i);
9443+ riscv_emit_move (SET_DEST (set), SET_SRC (set));
9444+ }
9445+
9446+ emit_insn (gen_blockage ());
9447+ DONE;
9448+})
9449+
9450+(define_insn "nop"
9451+ [(const_int 0)]
9452+ ""
9453+ "nop"
9454+ [(set_attr "type" "nop")
9455+ (set_attr "mode" "none")])
9456+
9457+(define_insn "trap"
9458+ [(trap_if (const_int 1) (const_int 0))]
9459+ ""
9460+ "ebreak")
9461+
9462+(define_insn "gpr_save"
9463+ [(unspec_volatile [(match_operand 0 "const_int_operand")] UNSPECV_GPR_SAVE)
9464+ (clobber (reg:SI T0_REGNUM))
9465+ (clobber (reg:SI T1_REGNUM))]
9466+ ""
9467+ { return riscv_output_gpr_save (INTVAL (operands[0])); })
9468+
9469+(define_insn "gpr_restore"
9470+ [(unspec_volatile [(match_operand 0 "const_int_operand")] UNSPECV_GPR_RESTORE)]
9471+ ""
9472+ "tail\t__riscv_restore_%0")
9473+
9474+(define_insn "gpr_restore_return"
9475+ [(return)
9476+ (use (match_operand 0 "pmode_register_operand" ""))
9477+ (const_int 0)]
9478+ ""
9479+ "")
9480+
9481+(define_insn "riscv_frflags"
9482+ [(set (match_operand:SI 0 "register_operand" "=r")
9483+ (unspec_volatile [(const_int 0)] UNSPECV_FRFLAGS))]
9484+ "TARGET_HARD_FLOAT"
9485+ "frflags %0")
9486+
9487+(define_insn "riscv_fsflags"
9488+ [(unspec_volatile [(match_operand:SI 0 "csr_operand" "rK")] UNSPECV_FSFLAGS)]
9489+ "TARGET_HARD_FLOAT"
9490+ "fsflags %0")
9491+
9492+(define_insn "stack_tie<mode>"
9493+ [(set (mem:BLK (scratch))
9494+ (unspec:BLK [(match_operand:X 0 "register_operand" "r")
9495+ (match_operand:X 1 "register_operand" "r")]
9496+ UNSPEC_TIE))]
9497+ ""
9498+ ""
9499+ [(set_attr "length" "0")]
9500+)
9501+
9502+(include "sync.md")
9503+(include "peephole.md")
9504+(include "pic.md")
9505+(include "generic.md")
9506diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
9507new file mode 100644
9508index 00000000000..0466bb29d14
9509--- /dev/null
9510+++ b/gcc/config/riscv/riscv.opt
9511@@ -0,0 +1,111 @@
9512+; Options for the RISC-V port of the compiler
9513+;
9514+; Copyright (C) 2011-2017 Free Software Foundation, Inc.
9515+;
9516+; This file is part of GCC.
9517+;
9518+; GCC is free software; you can redistribute it and/or modify it under
9519+; the terms of the GNU General Public License as published by the Free
9520+; Software Foundation; either version 3, or (at your option) any later
9521+; version.
9522+;
9523+; GCC is distributed in the hope that it will be useful, but WITHOUT
9524+; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
9525+; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
9526+; License for more details.
9527+;
9528+; You should have received a copy of the GNU General Public License
9529+; along with GCC; see the file COPYING3. If not see
9530+; <http://www.gnu.org/licenses/>.
9531+
9532+HeaderInclude
9533+config/riscv/riscv-opts.h
9534+
9535+mbranch-cost=
9536+Target RejectNegative Joined UInteger Var(riscv_branch_cost)
9537+-mbranch-cost=N Set the cost of branches to roughly N instructions.
9538+
9539+mplt
9540+Target Report Var(TARGET_PLT) Init(1)
9541+When generating -fpic code, allow the use of PLTs. Ignored for fno-pic.
9542+
9543+mabi=
9544+Target Report RejectNegative Joined Enum(abi_type) Var(riscv_abi) Init(ABI_ILP32)
9545+Specify integer and floating-point calling convention.
9546+
9547+Enum
9548+Name(abi_type) Type(enum riscv_abi_type)
9549+Supported ABIs (for use with the -mabi= option):
9550+
9551+EnumValue
9552+Enum(abi_type) String(ilp32) Value(ABI_ILP32)
9553+
9554+EnumValue
9555+Enum(abi_type) String(ilp32f) Value(ABI_ILP32F)
9556+
9557+EnumValue
9558+Enum(abi_type) String(ilp32d) Value(ABI_ILP32D)
9559+
9560+EnumValue
9561+Enum(abi_type) String(lp64) Value(ABI_LP64)
9562+
9563+EnumValue
9564+Enum(abi_type) String(lp64f) Value(ABI_LP64F)
9565+
9566+EnumValue
9567+Enum(abi_type) String(lp64d) Value(ABI_LP64D)
9568+
9569+mfdiv
9570+Target Report Mask(FDIV)
9571+Use hardware floating-point divide and square root instructions.
9572+
9573+mdiv
9574+Target Report Mask(DIV)
9575+Use hardware instructions for integer division.
9576+
9577+march=
9578+Target Report RejectNegative Joined
9579+-march= Generate code for given RISC-V ISA (e.g. RV64IM). ISA strings must be
9580+lower-case.
9581+
9582+mtune=
9583+Target RejectNegative Joined Var(riscv_tune_string)
9584+-mtune=PROCESSOR Optimize the output for PROCESSOR.
9585+
9586+msmall-data-limit=
9587+Target Joined Separate UInteger Var(g_switch_value) Init(8)
9588+-msmall-data-limit=N Put global and static data smaller than <number> bytes into a special section (on some targets).
9589+
9590+msave-restore
9591+Target Report Mask(SAVE_RESTORE)
9592+Use smaller but slower prologue and epilogue code.
9593+
9594+mcmodel=
9595+Target Report RejectNegative Joined Enum(code_model) Var(riscv_cmodel) Init(TARGET_DEFAULT_CMODEL)
9596+Specify the code model.
9597+
9598+Enum
9599+Name(code_model) Type(enum riscv_code_model)
9600+Known code models (for use with the -mcmodel= option):
9601+
9602+EnumValue
9603+Enum(code_model) String(medlow) Value(CM_MEDLOW)
9604+
9605+EnumValue
9606+Enum(code_model) String(medany) Value(CM_MEDANY)
9607+
9608+mexplicit-relocs
9609+Target Report Mask(EXPLICIT_RELOCS)
9610+Use %reloc() operators, rather than assembly macros, to load addresses.
9611+
9612+Mask(64BIT)
9613+
9614+Mask(MUL)
9615+
9616+Mask(ATOMIC)
9617+
9618+Mask(HARD_FLOAT)
9619+
9620+Mask(DOUBLE_FLOAT)
9621+
9622+Mask(RVC)
9623diff --git a/gcc/config/riscv/sfp-machine.h b/gcc/config/riscv/sfp-machine.h
9624new file mode 100644
9625index 00000000000..b1a27e7ed44
9626--- /dev/null
9627+++ b/gcc/config/riscv/sfp-machine.h
9628@@ -0,0 +1,137 @@
9629+/* Software floating-point machine description for RISC-V.
9630+
9631+ Copyright (C) 2016-2017 Free Software Foundation, Inc.
9632+
9633+This file is part of GCC.
9634+
9635+GCC is free software; you can redistribute it and/or modify it under
9636+the terms of the GNU General Public License as published by the Free
9637+Software Foundation; either version 3, or (at your option) any later
9638+version.
9639+
9640+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
9641+WARRANTY; without even the implied warranty of MERCHANTABILITY or
9642+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
9643+for more details.
9644+
9645+Under Section 7 of GPL version 3, you are granted additional
9646+permissions described in the GCC Runtime Library Exception, version
9647+3.1, as published by the Free Software Foundation.
9648+
9649+You should have received a copy of the GNU General Public License and
9650+a copy of the GCC Runtime Library Exception along with this program;
9651+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
9652+<http://www.gnu.org/licenses/>. */
9653+
9654+#if __riscv_xlen == 32
9655+
9656+#define _FP_W_TYPE_SIZE 32
9657+#define _FP_W_TYPE unsigned long
9658+#define _FP_WS_TYPE signed long
9659+#define _FP_I_TYPE long
9660+
9661+#define _FP_MUL_MEAT_S(R,X,Y) \
9662+ _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
9663+#define _FP_MUL_MEAT_D(R,X,Y) \
9664+ _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
9665+#define _FP_MUL_MEAT_Q(R,X,Y) \
9666+ _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
9667+
9668+#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_udiv_norm(S,R,X,Y)
9669+#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y)
9670+#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
9671+
9672+#define _FP_NANFRAC_S _FP_QNANBIT_S
9673+#define _FP_NANFRAC_D _FP_QNANBIT_D, 0
9674+#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0, 0, 0
9675+
9676+#else
9677+
9678+#define _FP_W_TYPE_SIZE 64
9679+#define _FP_W_TYPE unsigned long long
9680+#define _FP_WS_TYPE signed long long
9681+#define _FP_I_TYPE long long
9682+
9683+#define _FP_MUL_MEAT_S(R,X,Y) \
9684+ _FP_MUL_MEAT_1_imm(_FP_WFRACBITS_S,R,X,Y)
9685+#define _FP_MUL_MEAT_D(R,X,Y) \
9686+ _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
9687+#define _FP_MUL_MEAT_Q(R,X,Y) \
9688+ _FP_MUL_MEAT_2_wide_3mul(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
9689+
9690+#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm)
9691+#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_1_udiv_norm(D,R,X,Y)
9692+#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
9693+
9694+#define _FP_NANFRAC_S _FP_QNANBIT_S
9695+#define _FP_NANFRAC_D _FP_QNANBIT_D
9696+#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0
9697+
9698+#endif
9699+
9700+#if __riscv_xlen == 64
9701+typedef int TItype __attribute__ ((mode (TI)));
9702+typedef unsigned int UTItype __attribute__ ((mode (TI)));
9703+#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
9704+#endif
9705+
9706+/* The type of the result of a floating point comparison. This must
9707+ match __libgcc_cmp_return__ in GCC for the target. */
9708+typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
9709+#define CMPtype __gcc_CMPtype
9710+
9711+#define _FP_NANSIGN_S 0
9712+#define _FP_NANSIGN_D 0
9713+#define _FP_NANSIGN_Q 0
9714+
9715+#define _FP_KEEPNANFRACP 0
9716+#define _FP_QNANNEGATEDP 0
9717+
9718+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
9719+ do { \
9720+ R##_s = _FP_NANSIGN_##fs; \
9721+ _FP_FRAC_SET_##wc(R,_FP_NANFRAC_##fs); \
9722+ R##_c = FP_CLS_NAN; \
9723+ } while (0)
9724+
9725+#define _FP_DECL_EX int _frm __attribute__ ((unused));
9726+#define FP_ROUNDMODE _frm
9727+
9728+#define FP_RND_NEAREST 0x0
9729+#define FP_RND_ZERO 0x1
9730+#define FP_RND_PINF 0x3
9731+#define FP_RND_MINF 0x2
9732+
9733+#define FP_EX_INVALID 0x10
9734+#define FP_EX_OVERFLOW 0x04
9735+#define FP_EX_UNDERFLOW 0x02
9736+#define FP_EX_DIVZERO 0x08
9737+#define FP_EX_INEXACT 0x01
9738+
9739+#define _FP_TININESS_AFTER_ROUNDING 1
9740+
9741+#ifdef __riscv_flen
9742+#define FP_INIT_ROUNDMODE \
9743+do { \
9744+ __asm__ volatile ("frrm %0" : "=r" (_frm)); \
9745+} while (0)
9746+
9747+#define FP_HANDLE_EXCEPTIONS \
9748+do { \
9749+ if (__builtin_expect (_fex, 0)) \
9750+ __asm__ volatile ("csrs fflags, %0" : : "rK" (_fex)); \
9751+} while (0)
9752+#else
9753+#define FP_INIT_ROUNDMODE _frm = FP_RND_NEAREST
9754+#endif
9755+
9756+#define __LITTLE_ENDIAN 1234
9757+#define __BIG_ENDIAN 4321
9758+
9759+#define __BYTE_ORDER __LITTLE_ENDIAN
9760+
9761+
9762+/* Define ALIASNAME as a strong alias for NAME. */
9763+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
9764+# define _strong_alias(name, aliasname) \
9765+ extern __typeof (name) aliasname __attribute__ ((alias (#name)));
9766diff --git a/gcc/config/riscv/sync.md b/gcc/config/riscv/sync.md
9767new file mode 100644
9768index 00000000000..270306c075d
9769--- /dev/null
9770+++ b/gcc/config/riscv/sync.md
9771@@ -0,0 +1,191 @@
9772+;; Machine description for RISC-V atomic operations.
9773+;; Copyright (C) 2011-2017 Free Software Foundation, Inc.
9774+;; Contributed by Andrew Waterman (andrew@sifive.com).
9775+;; Based on MIPS target for GNU compiler.
9776+
9777+;; This file is part of GCC.
9778+
9779+;; GCC is free software; you can redistribute it and/or modify
9780+;; it under the terms of the GNU General Public License as published by
9781+;; the Free Software Foundation; either version 3, or (at your option)
9782+;; any later version.
9783+
9784+;; GCC is distributed in the hope that it will be useful,
9785+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
9786+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9787+;; GNU General Public License for more details.
9788+
9789+;; You should have received a copy of the GNU General Public License
9790+;; along with GCC; see the file COPYING3. If not see
9791+;; <http://www.gnu.org/licenses/>.
9792+
9793+(define_c_enum "unspec" [
9794+ UNSPEC_COMPARE_AND_SWAP
9795+ UNSPEC_SYNC_OLD_OP
9796+ UNSPEC_SYNC_EXCHANGE
9797+ UNSPEC_ATOMIC_STORE
9798+ UNSPEC_MEMORY_BARRIER
9799+])
9800+
9801+(define_code_iterator any_atomic [plus ior xor and])
9802+(define_code_attr atomic_optab
9803+ [(plus "add") (ior "or") (xor "xor") (and "and")])
9804+
9805+;; Memory barriers.
9806+
9807+(define_expand "memory_barrier"
9808+ [(set (match_dup 0)
9809+ (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))]
9810+ ""
9811+{
9812+ operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
9813+ MEM_VOLATILE_P (operands[0]) = 1;
9814+ emit_insn (gen_mem_thread_fence_1 (operands[0]));
9815+ DONE;
9816+})
9817+
9818+;; Until the RISC-V memory model (hence its mapping from C++) is finalized,
9819+;; conservatively emit a full FENCE.
9820+(define_insn "mem_thread_fence_1"
9821+ [(set (match_operand:BLK 0 "" "")
9822+ (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))]
9823+ ""
9824+ "fence\trw,rw")
9825+
9826+;; Atomic memory operations.
9827+
9828+;; Implement atomic stores with amoswap. Fall back to fences for atomic loads.
9829+(define_insn "atomic_store<mode>"
9830+ [(set (match_operand:GPR 0 "memory_operand" "=A")
9831+ (unspec_volatile:GPR
9832+ [(match_operand:GPR 1 "reg_or_0_operand" "rJ")
9833+ (match_operand:SI 2 "const_int_operand")] ;; model
9834+ UNSPEC_ATOMIC_STORE))]
9835+ "TARGET_ATOMIC"
9836+ "%F2amoswap.<amo>%A2 zero,%z1,%0"
9837+ [(set (attr "length") (const_int 8))])
9838+
9839+(define_insn "atomic_<atomic_optab><mode>"
9840+ [(set (match_operand:GPR 0 "memory_operand" "+A")
9841+ (unspec_volatile:GPR
9842+ [(any_atomic:GPR (match_dup 0)
9843+ (match_operand:GPR 1 "reg_or_0_operand" "rJ"))
9844+ (match_operand:SI 2 "const_int_operand")] ;; model
9845+ UNSPEC_SYNC_OLD_OP))]
9846+ "TARGET_ATOMIC"
9847+ "%F2amo<insn>.<amo>%A2 zero,%z1,%0"
9848+ [(set (attr "length") (const_int 8))])
9849+
9850+(define_insn "atomic_fetch_<atomic_optab><mode>"
9851+ [(set (match_operand:GPR 0 "register_operand" "=&r")
9852+ (match_operand:GPR 1 "memory_operand" "+A"))
9853+ (set (match_dup 1)
9854+ (unspec_volatile:GPR
9855+ [(any_atomic:GPR (match_dup 1)
9856+ (match_operand:GPR 2 "reg_or_0_operand" "rJ"))
9857+ (match_operand:SI 3 "const_int_operand")] ;; model
9858+ UNSPEC_SYNC_OLD_OP))]
9859+ "TARGET_ATOMIC"
9860+ "%F3amo<insn>.<amo>%A3 %0,%z2,%1"
9861+ [(set (attr "length") (const_int 8))])
9862+
9863+(define_insn "atomic_exchange<mode>"
9864+ [(set (match_operand:GPR 0 "register_operand" "=&r")
9865+ (unspec_volatile:GPR
9866+ [(match_operand:GPR 1 "memory_operand" "+A")
9867+ (match_operand:SI 3 "const_int_operand")] ;; model
9868+ UNSPEC_SYNC_EXCHANGE))
9869+ (set (match_dup 1)
9870+ (match_operand:GPR 2 "register_operand" "0"))]
9871+ "TARGET_ATOMIC"
9872+ "%F3amoswap.<amo>%A3 %0,%z2,%1"
9873+ [(set (attr "length") (const_int 8))])
9874+
9875+(define_insn "atomic_cas_value_strong<mode>"
9876+ [(set (match_operand:GPR 0 "register_operand" "=&r")
9877+ (match_operand:GPR 1 "memory_operand" "+A"))
9878+ (set (match_dup 1)
9879+ (unspec_volatile:GPR [(match_operand:GPR 2 "reg_or_0_operand" "rJ")
9880+ (match_operand:GPR 3 "reg_or_0_operand" "rJ")
9881+ (match_operand:SI 4 "const_int_operand") ;; mod_s
9882+ (match_operand:SI 5 "const_int_operand")] ;; mod_f
9883+ UNSPEC_COMPARE_AND_SWAP))
9884+ (clobber (match_scratch:GPR 6 "=&r"))]
9885+ "TARGET_ATOMIC"
9886+ "%F5 1: lr.<amo>%A5 %0,%1; bne %0,%z2,1f; sc.<amo>%A4 %6,%z3,%1; bnez %6,1b; 1:"
9887+ [(set (attr "length") (const_int 20))])
9888+
9889+(define_expand "atomic_compare_and_swap<mode>"
9890+ [(match_operand:SI 0 "register_operand" "") ;; bool output
9891+ (match_operand:GPR 1 "register_operand" "") ;; val output
9892+ (match_operand:GPR 2 "memory_operand" "") ;; memory
9893+ (match_operand:GPR 3 "reg_or_0_operand" "") ;; expected value
9894+ (match_operand:GPR 4 "reg_or_0_operand" "") ;; desired value
9895+ (match_operand:SI 5 "const_int_operand" "") ;; is_weak
9896+ (match_operand:SI 6 "const_int_operand" "") ;; mod_s
9897+ (match_operand:SI 7 "const_int_operand" "")] ;; mod_f
9898+ "TARGET_ATOMIC"
9899+{
9900+ emit_insn (gen_atomic_cas_value_strong<mode> (operands[1], operands[2],
9901+ operands[3], operands[4],
9902+ operands[6], operands[7]));
9903+
9904+ rtx compare = operands[1];
9905+ if (operands[3] != const0_rtx)
9906+ {
9907+ rtx difference = gen_rtx_MINUS (<MODE>mode, operands[1], operands[3]);
9908+ compare = gen_reg_rtx (<MODE>mode);
9909+ emit_insn (gen_rtx_SET (VOIDmode, compare, difference));
9910+ }
9911+
9912+ if (word_mode != <MODE>mode)
9913+ {
9914+ rtx reg = gen_reg_rtx (word_mode);
9915+ emit_insn (gen_rtx_SET (VOIDmode, reg, gen_rtx_SIGN_EXTEND (word_mode, compare)));
9916+ compare = reg;
9917+ }
9918+
9919+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], gen_rtx_EQ (SImode, compare, const0_rtx)));
9920+ DONE;
9921+})
9922+
9923+(define_expand "atomic_test_and_set"
9924+ [(match_operand:QI 0 "register_operand" "") ;; bool output
9925+ (match_operand:QI 1 "memory_operand" "+A") ;; memory
9926+ (match_operand:SI 2 "const_int_operand" "")] ;; model
9927+ "TARGET_ATOMIC"
9928+{
9929+ /* We have no QImode atomics, so use the address LSBs to form a mask,
9930+ then use an aligned SImode atomic. */
9931+ rtx result = operands[0];
9932+ rtx mem = operands[1];
9933+ rtx model = operands[2];
9934+ rtx addr = force_reg (Pmode, XEXP (mem, 0));
9935+
9936+ rtx aligned_addr = gen_reg_rtx (Pmode);
9937+ emit_move_insn (aligned_addr, gen_rtx_AND (Pmode, addr, GEN_INT (-4)));
9938+
9939+ rtx aligned_mem = change_address (mem, SImode, aligned_addr);
9940+ set_mem_alias_set (aligned_mem, 0);
9941+
9942+ rtx offset = gen_reg_rtx (SImode);
9943+ emit_move_insn (offset, gen_rtx_AND (SImode, gen_lowpart (SImode, addr),
9944+ GEN_INT (3)));
9945+
9946+ rtx tmp = gen_reg_rtx (SImode);
9947+ emit_move_insn (tmp, GEN_INT (1));
9948+
9949+ rtx shmt = gen_reg_rtx (SImode);
9950+ emit_move_insn (shmt, gen_rtx_ASHIFT (SImode, offset, GEN_INT (3)));
9951+
9952+ rtx word = gen_reg_rtx (SImode);
9953+ emit_move_insn (word, gen_rtx_ASHIFT (SImode, tmp, shmt));
9954+
9955+ tmp = gen_reg_rtx (SImode);
9956+ emit_insn (gen_atomic_fetch_orsi (tmp, aligned_mem, word, model));
9957+
9958+ emit_move_insn (gen_lowpart (SImode, result),
9959+ gen_rtx_LSHIFTRT (SImode, tmp,
9960+ gen_lowpart (SImode, shmt)));
9961+ DONE;
9962+})
9963diff --git a/gcc/config/riscv/t-elf b/gcc/config/riscv/t-elf
9964new file mode 100644
9965index 00000000000..1abefb2eaeb
9966--- /dev/null
9967+++ b/gcc/config/riscv/t-elf
9968@@ -0,0 +1,13 @@
9969+LIB2FUNCS_EXTRA = $(srcdir)/config/riscv/save-restore.S \
9970+ $(srcdir)/config/riscv/muldi3.S \
9971+ $(srcdir)/config/riscv/multi3.S \
9972+ $(srcdir)/config/riscv/div.S \
9973+ $(srcdir)/config/riscv/atomic.c \
9974+
9975+$(T)crti.o: $(srcdir)/config/riscv/crti.S $(GCC_PASSES)
9976+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
9977+ -c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/riscv/crti.S
9978+
9979+$(T)crtn.o: $(srcdir)/config/riscv/crtn.S $(GCC_PASSES)
9980+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
9981+ -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/riscv/crtn.S
9982diff --git a/gcc/config/riscv/t-elf32 b/gcc/config/riscv/t-elf32
9983new file mode 100644
9984index 00000000000..f3751234d55
9985--- /dev/null
9986+++ b/gcc/config/riscv/t-elf32
9987@@ -0,0 +1 @@
9988+LIB2FUNCS_EXCLUDE += _divsi3 _modsi3 _udivsi3 _umodsi3 _mulsi3 _muldi3
9989diff --git a/gcc/config/riscv/t-elf64 b/gcc/config/riscv/t-elf64
9990new file mode 100644
9991index 00000000000..f3751234d55
9992--- /dev/null
9993+++ b/gcc/config/riscv/t-elf64
9994@@ -0,0 +1 @@
9995+LIB2FUNCS_EXCLUDE += _divsi3 _modsi3 _udivsi3 _umodsi3 _mulsi3 _muldi3
9996diff --git a/gcc/config/riscv/t-linux b/gcc/config/riscv/t-linux
9997new file mode 100644
9998index 00000000000..216d2776a18
9999--- /dev/null
10000+++ b/gcc/config/riscv/t-linux
10001@@ -0,0 +1,3 @@
10002+# Only XLEN and ABI affect Linux multilib dir names, e.g. /lib32/ilp32d/
10003+MULTILIB_DIRNAMES := $(patsubst rv32%,lib32,$(patsubst rv64%,lib64,$(MULTILIB_DIRNAMES)))
10004+MULTILIB_OSDIRNAMES := $(patsubst lib%,../lib%,$(MULTILIB_DIRNAMES))
10005diff --git a/gcc/config/riscv/t-riscv b/gcc/config/riscv/t-riscv
10006new file mode 100644
10007index 00000000000..0745471ec5e
10008--- /dev/null
10009+++ b/gcc/config/riscv/t-riscv
10010@@ -0,0 +1,11 @@
10011+# riscv-builtins.o: $(srcdir)/config/riscv/riscv-builtins.c $(CONFIG_H) \
10012+# $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) $(RECOG_H) langhooks.h \
10013+# $(DIAGNOSTIC_CORE_H) $(OPTABS_H) $(srcdir)/config/riscv/riscv-ftypes.def \
10014+# $(srcdir)/config/riscv/riscv-modes.def
10015+# $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
10016+# $(srcdir)/config/riscv/riscv-builtins.c
10017+#
10018+# riscv-c.o: $(srcdir)/config/riscv/riscv-c.c $(CONFIG_H) $(SYSTEM_H) \
10019+# coretypes.h $(TM_H) $(TREE_H) output.h $(C_COMMON_H) $(TARGET_H)
10020+# $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
10021+# $(srcdir)/config/riscv/riscv-c.c
10022diff --git a/gcc/config/riscv/t-softfp32 b/gcc/config/riscv/t-softfp32
10023new file mode 100644
10024index 00000000000..7d1d7f0615a
10025--- /dev/null
10026+++ b/gcc/config/riscv/t-softfp32
10027@@ -0,0 +1,28 @@
10028+gcc_compile_bare = $(CC) $(INTERNAL_CFLAGS) $(CFLAGS-$(<F))
10029+ABI_SINGLE:=$(findstring __riscv_float_abi_single,$(shell $(gcc_compile_bare) -dM -E - </dev/null))
10030+ABI_DOUBLE:=$(findstring __riscv_float_abi_double,$(shell $(gcc_compile_bare) -dM -E - </dev/null))
10031+ABI_QUAD:=$(findstring __riscv_float_abi_quad,$(shell $(gcc_compile_bare) -dM -E - </dev/null))
10032+
10033+softfp_machine_header := riscv/sfp-machine.h
10034+softfp_int_modes := si di
10035+softfp_exclude_libgcc2 := n
10036+
10037+ifndef ABI_QUAD
10038+ifdef ABI_DOUBLE
10039+
10040+softfp_float_modes := tf
10041+softfp_extensions := sftf dftf
10042+softfp_truncations := tfsf tfdf
10043+
10044+else
10045+
10046+softfp_float_modes := df tf
10047+softfp_extensions := sfdf sftf dftf
10048+softfp_truncations := dfsf tfsf tfdf
10049+
10050+ifndef ABI_SINGLE
10051+softfp_float_modes += sf
10052+endif
10053+
10054+endif
10055+endif
10056diff --git a/gcc/config/riscv/t-softfp64 b/gcc/config/riscv/t-softfp64
10057new file mode 100644
10058index 00000000000..75870951202
10059--- /dev/null
10060+++ b/gcc/config/riscv/t-softfp64
10061@@ -0,0 +1,3 @@
10062+include $(srcdir)/config/riscv/t-softfp32
10063+
10064+softfp_int_modes += ti
10065diff --git a/gcc/config/rs6000/linux.h b/gcc/config/rs6000/linux.h
10066index 77c8f61035b..55e56510714 100644
10067--- a/gcc/config/rs6000/linux.h
10068+++ b/gcc/config/rs6000/linux.h
10069@@ -29,8 +29,16 @@
10070
10071 #ifdef SINGLE_LIBC
10072 #define OPTION_GLIBC (DEFAULT_LIBC == LIBC_GLIBC)
10073+#define OPTION_UCLIBC (DEFAULT_LIBC == LIBC_UCLIBC)
10074+#define OPTION_BIONIC (DEFAULT_LIBC == LIBC_BIONIC)
10075+#undef OPTION_MUSL
10076+#define OPTION_MUSL (DEFAULT_LIBC == LIBC_MUSL)
10077 #else
10078 #define OPTION_GLIBC (linux_libc == LIBC_GLIBC)
10079+#define OPTION_UCLIBC (linux_libc == LIBC_UCLIBC)
10080+#define OPTION_BIONIC (linux_libc == LIBC_BIONIC)
10081+#undef OPTION_MUSL
10082+#define OPTION_MUSL (linux_libc == LIBC_MUSL)
10083 #endif
10084
10085 /* glibc has float and long double forms of math functions. */
10086diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h
10087index e6840d63e80..2d7d289c2cf 100644
10088--- a/gcc/config/rs6000/linux64.h
10089+++ b/gcc/config/rs6000/linux64.h
10090@@ -309,8 +309,16 @@ extern int dot_symbols;
10091
10092 #ifdef SINGLE_LIBC
10093 #define OPTION_GLIBC (DEFAULT_LIBC == LIBC_GLIBC)
10094+#define OPTION_UCLIBC (DEFAULT_LIBC == LIBC_UCLIBC)
10095+#define OPTION_BIONIC (DEFAULT_LIBC == LIBC_BIONIC)
10096+#undef OPTION_MUSL
10097+#define OPTION_MUSL (DEFAULT_LIBC == LIBC_MUSL)
10098 #else
10099 #define OPTION_GLIBC (linux_libc == LIBC_GLIBC)
10100+#define OPTION_UCLIBC (linux_libc == LIBC_UCLIBC)
10101+#define OPTION_BIONIC (linux_libc == LIBC_BIONIC)
10102+#undef OPTION_MUSL
10103+#define OPTION_MUSL (linux_libc == LIBC_MUSL)
10104 #endif
10105
10106 /* glibc has float and long double forms of math functions. */
10107diff --git a/gcc/config/sh/linux.h b/gcc/config/sh/linux.h
10108index a090dae1cab..ed6e2c2508b 100644
10109--- a/gcc/config/sh/linux.h
10110+++ b/gcc/config/sh/linux.h
10111@@ -47,6 +47,27 @@ along with GCC; see the file COPYING3. If not see
10112
10113 #define TARGET_ASM_FILE_END file_end_indicate_exec_stack
10114
10115+#if TARGET_ENDIAN_DEFAULT == MASK_LITTLE_ENDIAN
10116+#define MUSL_DYNAMIC_LINKER_E "%{mb:eb}"
10117+#else
10118+#define MUSL_DYNAMIC_LINKER_E "%{!ml:eb}"
10119+#endif
10120+
10121+#if TARGET_CPU_DEFAULT & (MASK_HARD_SH2A_DOUBLE | MASK_SH4)
10122+/* "-nofpu" if any nofpu option is specified. */
10123+#define MUSL_DYNAMIC_LINKER_FP \
10124+ "%{m1|m2|m2a-nofpu|m3|m4-nofpu|m4-100-nofpu|m4-200-nofpu|m4-300-nofpu|" \
10125+ "m4-340|m4-400|m4-500|m4al:-nofpu}"
10126+#else
10127+/* "-nofpu" if none of the hard fpu options are specified. */
10128+#define MUSL_DYNAMIC_LINKER_FP "%{m2a|m4|m4-100|m4-200|m4-300|m4a:;:-nofpu}"
10129+#endif
10130+
10131+#undef MUSL_DYNAMIC_LINKER
10132+#define MUSL_DYNAMIC_LINKER \
10133+ "/lib/ld-musl-sh" MUSL_DYNAMIC_LINKER_E MUSL_DYNAMIC_LINKER_FP \
10134+ "%{mfdpic:-fdpic}.so.1"
10135+
10136 #define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2"
10137
10138 #undef SUBTARGET_LINK_EMUL_SUFFIX
10139diff --git a/gcc/configure b/gcc/configure
10140index c8caff252f4..1c23292d8a5 100755
10141--- a/gcc/configure
10142+++ b/gcc/configure
10143@@ -22738,6 +22738,17 @@ x3: .space 8
10144 tls_first_minor=14
10145 tls_as_opt="-a64 --fatal-warnings"
10146 ;;
10147+ riscv*-*-*)
10148+ conftest_s='
10149+ .section .tdata,"awT",@progbits
10150+x: .word 2
10151+ .text
10152+ la.tls.gd a0,x
10153+ call __tls_get_addr'
10154+ tls_first_major=2
10155+ tls_first_minor=21
10156+ tls_as_opt='--fatal-warnings'
10157+ ;;
10158 s390-*-*)
10159 conftest_s='
10160 .section ".tdata","awT",@progbits
10161@@ -25776,6 +25787,9 @@ if test "${gcc_cv_libc_provides_ssp+set}" = set; then :
10162 else
10163 gcc_cv_libc_provides_ssp=no
10164 case "$target" in
10165+ *-*-musl*)
10166+ # All versions of musl provide stack protector
10167+ gcc_cv_libc_provides_ssp=yes;;
10168 *-*-linux* | *-*-kfreebsd*-gnu | *-*-knetbsd*-gnu)
10169 # glibc 2.4 and later provides __stack_chk_fail and
10170 # either __stack_chk_guard, or TLS access to stack guard canary.
10171@@ -25804,6 +25818,7 @@ else
10172 # <http://gcc.gnu.org/ml/gcc/2008-10/msg00130.html>) and for now
10173 # simply assert that glibc does provide this, which is true for all
10174 # realistically usable GNU/Hurd configurations.
10175+ # All supported versions of musl provide it as well
10176 gcc_cv_libc_provides_ssp=yes;;
10177 *-*-darwin* | *-*-freebsd*)
10178 ac_fn_c_check_func "$LINENO" "__stack_chk_fail" "ac_cv_func___stack_chk_fail"
10179@@ -25869,6 +25884,16 @@ case "$target" in
10180 gcc_cv_target_dl_iterate_phdr=no
10181 fi
10182 ;;
10183+ *-*-dragonfly* | *-*-freebsd*)
10184+ if grep dl_iterate_phdr $target_header_dir/sys/link_elf.h > /dev/null 2>&1; then
10185+ gcc_cv_target_dl_iterate_phdr=yes
10186+ else
10187+ gcc_cv_target_dl_iterate_phdr=no
10188+ fi
10189+ ;;
10190+ *-linux-musl*)
10191+ gcc_cv_target_dl_iterate_phdr=yes
10192+ ;;
10193 esac
10194
10195 if test x$gcc_cv_target_dl_iterate_phdr = xyes; then
10196diff --git a/gcc/configure.ac b/gcc/configure.ac
10197index 48605c851b2..8a3a1e11e03 100644
10198--- a/gcc/configure.ac
10199+++ b/gcc/configure.ac
10200@@ -2899,6 +2899,17 @@ x3: .space 8
10201 tls_first_minor=14
10202 tls_as_opt="-a64 --fatal-warnings"
10203 ;;
10204+ riscv*-*-*)
10205+ conftest_s='
10206+ .section .tdata,"awT",@progbits
10207+x: .word 2
10208+ .text
10209+ la.tls.gd a0,x
10210+ call __tls_get_addr'
10211+ tls_first_major=2
10212+ tls_first_minor=21
10213+ tls_as_opt='--fatal-warnings'
10214+ ;;
10215 s390-*-*)
10216 conftest_s='
10217 .section ".tdata","awT",@progbits
10218@@ -3863,7 +3874,7 @@ esac
10219 # version to the per-target configury.
10220 case "$cpu_type" in
10221 alpha | arm | avr | bfin | cris | i386 | m32c | m68k | microblaze | mips \
10222- | pa | rs6000 | score | sparc | spu | xstormy16 | xtensa)
10223+ | pa | riscv | rs6000 | score | sparc | spu | xstormy16 | xtensa)
10224 insn="nop"
10225 ;;
10226 ia64 | s390)
10227@@ -4364,6 +4375,9 @@ AC_CACHE_CHECK(__stack_chk_fail in target C library,
10228 gcc_cv_libc_provides_ssp,
10229 [gcc_cv_libc_provides_ssp=no
10230 case "$target" in
10231+ *-*-musl*)
10232+ # All versions of musl provide stack protector
10233+ gcc_cv_libc_provides_ssp=yes;;
10234 *-*-linux* | *-*-kfreebsd*-gnu | *-*-knetbsd*-gnu)
10235 [# glibc 2.4 and later provides __stack_chk_fail and
10236 # either __stack_chk_guard, or TLS access to stack guard canary.
10237@@ -4392,6 +4406,7 @@ AC_CACHE_CHECK(__stack_chk_fail in target C library,
10238 # <http://gcc.gnu.org/ml/gcc/2008-10/msg00130.html>) and for now
10239 # simply assert that glibc does provide this, which is true for all
10240 # realistically usable GNU/Hurd configurations.
10241+ # All supported versions of musl provide it as well
10242 gcc_cv_libc_provides_ssp=yes;;
10243 *-*-darwin* | *-*-freebsd*)
10244 AC_CHECK_FUNC(__stack_chk_fail,[gcc_cv_libc_provides_ssp=yes],
10245@@ -4442,6 +4457,16 @@ case "$target" in
10246 gcc_cv_target_dl_iterate_phdr=no
10247 fi
10248 ;;
10249+ *-*-dragonfly* | *-*-freebsd*)
10250+ if grep dl_iterate_phdr $target_header_dir/sys/link_elf.h > /dev/null 2>&1; then
10251+ gcc_cv_target_dl_iterate_phdr=yes
10252+ else
10253+ gcc_cv_target_dl_iterate_phdr=no
10254+ fi
10255+ ;;
10256+ *-linux-musl*)
10257+ gcc_cv_target_dl_iterate_phdr=yes
10258+ ;;
10259 esac
10260 GCC_TARGET_TEMPLATE([TARGET_DL_ITERATE_PHDR])
10261 if test x$gcc_cv_target_dl_iterate_phdr = xyes; then
10262diff --git a/gcc/doc/contrib.texi b/gcc/doc/contrib.texi
10263index e52dcf9be74..181482b9a7f 100644
10264--- a/gcc/doc/contrib.texi
10265+++ b/gcc/doc/contrib.texi
10266@@ -160,6 +160,10 @@ John-Marc Chandonia for various libgcj patches.
10267 Denis Chertykov for contributing and maintaining the AVR port, the first GCC port
10268 for an 8-bit architecture.
10269
10270+@item
10271+Kito Cheng for his work on the RISC-V port, including bringing up the test
10272+suite and maintenance.
10273+
10274 @item
10275 Scott Christley for his Objective-C contributions.
10276
10277@@ -201,6 +205,9 @@ Ian Dall for major improvements to the NS32k port.
10278 Paul Dale for his work to add uClinux platform support to the
10279 m68k backend.
10280
10281+@item
10282+Palmer Dabbelt for his work maintaining the RISC-V port.
10283+
10284 @item
10285 Dario Dariol contributed the four varieties of sample programs
10286 that print a copy of their source.
10287@@ -960,6 +967,9 @@ associated configure steps.
10288 @item
10289 Todd Vierling for contributions for NetBSD ports.
10290
10291+@item
10292+Andrew Waterman for contributing the RISC-V port, as well as maintaining it.
10293+
10294 @item
10295 Jonathan Wakely for contributing libstdc++ Doxygen notes and XHTML
10296 guidance.
10297diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
10298index 75c202e9068..276476213f4 100644
10299--- a/gcc/doc/install.texi
10300+++ b/gcc/doc/install.texi
10301@@ -4122,7 +4122,38 @@ Embedded PowerPC system in little endian mode.
10302 @html
10303 <hr />
10304 @end html
10305-@heading @anchor{rx-x-elf}rx-*-elf
10306+@anchor{riscv32-x-elf}
10307+@heading riscv32-*-elf
10308+The RISC-V RV32 instruction set.
10309+This configuration is intended for embedded systems.
10310+
10311+@html
10312+<hr />
10313+@end html
10314+@anchor{riscv64-x-elf}
10315+@heading riscv64-*-elf
10316+The RISC-V RV64 instruction set.
10317+This configuration is intended for embedded systems.
10318+
10319+@html
10320+<hr />
10321+@end html
10322+@anchor{riscv32-x-linux}
10323+@heading riscv32-*-linux
10324+The RISC-V RV32 instruction set running GNU/Linux.
10325+
10326+@html
10327+<hr />
10328+@end html
10329+@anchor{riscv64-x-linux}
10330+@heading riscv64-*-linux
10331+The RISC-V RV64 instruction set running GNU/Linux.
10332+
10333+@html
10334+<hr />
10335+@end html
10336+@anchor{rx-x-elf}
10337+@heading rx-*-elf
10338 The Renesas RX processor. See
10339 @uref{http://eu.renesas.com/fmwk.jsp?cnt=rx600_series_landing.jsp&fp=/products/mpumcu/rx_family/rx600_series}
10340 for more information about this processor.
10341diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
10342index acd45706428..fe5f9143293 100644
10343--- a/gcc/doc/invoke.texi
10344+++ b/gcc/doc/invoke.texi
10345@@ -569,7 +569,7 @@ Objective-C and Objective-C++ Dialects}.
10346 -mcpu=@var{cpu}}
10347
10348 @emph{GNU/Linux Options}
10349-@gccoptlist{-mglibc -muclibc -mbionic -mandroid @gol
10350+@gccoptlist{-mglibc -muclibc -mmusl -mbionic -mandroid @gol
10351 -tno-android-cc -tno-android-ld}
10352
10353 @emph{H8/300 Options}
10354@@ -814,6 +814,20 @@ See RS/6000 and PowerPC Options.
10355 -mno-recip-precision @gol
10356 -mveclibabi=@var{type} -mfriz -mno-friz}
10357
10358+@emph{RISC-V Options}
10359+@gccoptlist{-mbranch-cost=@var{N-instruction} @gol
10360+-mmemcpy -mno-memcpy @gol
10361+-mplt -mno-plt @gol
10362+-mabi=@var{ABI-string} @gol
10363+-mfdiv -mno-fdiv @gol
10364+-mdiv -mno-div @gol
10365+-march=@var{ISA-string} @gol
10366+-mtune=@var{processor-string} @gol
10367+-msmall-data-limit=@var{N-bytes} @gol
10368+-msave-restore -mno-save-restore @gol
10369+-mcmodel=@var{code-model} @gol
10370+-mexplicit-relocs -mno-explicit-relocs @gol}
10371+
10372 @emph{RX Options}
10373 @gccoptlist{-m64bit-doubles -m32bit-doubles -fpu -nofpu@gol
10374 -mcpu=@gol
10375@@ -9999,6 +10013,7 @@ platform.
10376 * picoChip Options::
10377 * PowerPC Options::
10378 * RS/6000 and PowerPC Options::
10379+* RISC-V Options::
10380 * RX Options::
10381 * S/390 and zSeries Options::
10382 * Score Options::
10383@@ -11897,13 +11912,19 @@ These @samp{-m} options are defined for GNU/Linux targets:
10384 @item -mglibc
10385 @opindex mglibc
10386 Use the GNU C library. This is the default except
10387-on @samp{*-*-linux-*uclibc*} and @samp{*-*-linux-*android*} targets.
10388+on @samp{*-*-linux-*uclibc*}, @samp{*-*-linux-*musl*} and
10389+@samp{*-*-linux-*android*} targets.
10390
10391 @item -muclibc
10392 @opindex muclibc
10393 Use uClibc C library. This is the default on
10394 @samp{*-*-linux-*uclibc*} targets.
10395
10396+@item -mmusl
10397+@opindex mmusl
10398+Use the musl C library. This is the default on
10399+@samp{*-*-linux-*musl*} targets.
10400+
10401 @item -mbionic
10402 @opindex mbionic
10403 Use Bionic C library. This is the default on
10404@@ -16420,6 +16441,70 @@ point. The @code{friz} instruction does not return the same value if
10405 the floating point number is too large to fit in an integer.
10406 @end table
10407
10408+@node RISC-V Options
10409+@subsection RISC-V Options
10410+@cindex RISC-V Options
10411+
10412+These command-line options are defined for RISC-V targets:
10413+
10414+@table @gcctabopt
10415+@item -mbranch-cost=@var{n}
10416+@opindex mbranch-cost
10417+Set the cost of branches to roughly @var{n} instructions.
10418+
10419+@item -mmemcpy
10420+@itemx -mno-memcpy
10421+@opindex mmemcpy
10422+Don't optimize block moves.
10423+
10424+@item -mplt
10425+@itemx -mno-plt
10426+@opindex plt
10427+When generating PIC code, allow the use of PLTs. Ignored for non-PIC.
10428+
10429+@item -mabi=@var{ABI-string}
10430+@opindex mabi
10431+Specify integer and floating-point calling convention. This defaults to the
10432+natural calling convention: e.g.@ LP64 for RV64I, ILP32 for RV32I, LP64D for
10433+RV64G.
10434+
10435+@item -mfdiv
10436+@itemx -mno-fdiv
10437+@opindex mfdiv
10438+Use hardware floating-point divide and square root instructions. This requires
10439+the F or D extensions for floating-point registers.
10440+
10441+@item -mdiv
10442+@itemx -mno-div
10443+@opindex mdiv
10444+Use hardware instructions for integer division. This requires the M extension.
10445+
10446+@item -march=@var{ISA-string}
10447+@opindex march
10448+Generate code for given RISC-V ISA (e.g.@ @samp{rv64im}). ISA strings must be
10449+lower-case. Examples include @samp{rv64i}, @samp{rv32g}, and @samp{rv32imaf}.
10450+
10451+@item -mtune=@var{processor-string}
10452+@opindex mtune
10453+Optimize the output for the given processor, specified by microarchitecture
10454+name.
10455+
10456+@item -msmall-data-limit=@var{n}
10457+@opindex msmall-data-limit
10458+Put global and static data smaller than @var{n} bytes into a special section
10459+(on some targets).
10460+
10461+@item -msave-restore
10462+@itemx -mno-save-restore
10463+@opindex msave-restore
10464+Use smaller but slower prologue and epilogue code.
10465+
10466+@item -mcmodel=@var{code-model}
10467+@opindex mcmodel
10468+Specify the code model.
10469+
10470+@end table
10471+
10472 @node RX Options
10473 @subsection RX Options
10474 @cindex RX Options
10475diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
10476index b659015a03b..e46fa2b89b0 100644
10477--- a/gcc/doc/md.texi
10478+++ b/gcc/doc/md.texi
10479@@ -2994,6 +2994,26 @@ A memory reference that is encoded within the opcode.
10480
10481 @end table
10482
10483+@item RISC-V---@file{config/riscv/constraints.md}
10484+@table @code
10485+
10486+@item f
10487+A floating-point register (if availiable).
10488+
10489+@item I
10490+An I-type 12-bit signed immediate.
10491+
10492+@item J
10493+Integer zero.
10494+
10495+@item K
10496+A 5-bit unsigned immediate for CSR access instructions.
10497+
10498+@item A
10499+An address that is held in a general-purpose register.
10500+
10501+@end table
10502+
10503 @item RX---@file{config/rx/constraints.md}
10504 @table @code
10505 @item Q
10506diff --git a/gcc/hwint.h b/gcc/hwint.h
10507index 1eadd45da73..f661a0ce9e9 100644
10508--- a/gcc/hwint.h
10509+++ b/gcc/hwint.h
10510@@ -74,6 +74,15 @@ extern char sizeof_long_long_must_be_8[sizeof(long long) == 8 ? 1 : -1];
10511 # endif
10512 #endif
10513
10514+#define HOST_WIDE_INT_C(X) X ## LL
10515+#define HOST_WIDE_INT_UC(X) HOST_WIDE_INT_C (X ## U)
10516+#define HOST_WIDE_INT_0 HOST_WIDE_INT_C (0)
10517+#define HOST_WIDE_INT_0U HOST_WIDE_INT_UC (0)
10518+#define HOST_WIDE_INT_1 HOST_WIDE_INT_C (1)
10519+#define HOST_WIDE_INT_1U HOST_WIDE_INT_UC (1)
10520+#define HOST_WIDE_INT_M1 HOST_WIDE_INT_C (-1)
10521+#define HOST_WIDE_INT_M1U HOST_WIDE_INT_UC (-1)
10522+
10523 /* Various printf format strings for HOST_WIDE_INT. */
10524
10525 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
10526@@ -257,4 +266,42 @@ least_common_multiple (int a, int b)
10527 return (abs (a) * abs (b) / gcd (a, b));
10528 }
10529
10530+
10531+/* Like ctz_hwi, except 0 when x == 0. */
10532+
10533+static inline int
10534+ctz_or_zero (unsigned HOST_WIDE_INT x)
10535+{
10536+ return ffs_hwi (x) - 1;
10537+}
10538+
10539+/* Sign extend SRC starting from PREC. */
10540+
10541+static inline HOST_WIDE_INT
10542+sext_hwi (HOST_WIDE_INT src, unsigned int prec)
10543+{
10544+ if (prec == HOST_BITS_PER_WIDE_INT)
10545+ return src;
10546+ else
10547+#if defined (__GNUC__)
10548+ {
10549+ /* Take the faster path if the implementation-defined bits it's relying
10550+ on are implemented the way we expect them to be. Namely, conversion
10551+ from unsigned to signed preserves bit pattern, and right shift of
10552+ a signed value propagates the sign bit.
10553+ We have to convert from signed to unsigned and back, because when left
10554+ shifting signed values, any overflow is undefined behavior. */
10555+ int shift = HOST_BITS_PER_WIDE_INT - prec;
10556+ return ((HOST_WIDE_INT) ((unsigned HOST_WIDE_INT) src << shift)) >> shift;
10557+ }
10558+#else
10559+ {
10560+ /* Fall back to the slower, well defined path otherwise. */
10561+ HOST_WIDE_INT sign_mask = HOST_WIDE_INT_1 << (prec - 1);
10562+ HOST_WIDE_INT value_mask = (HOST_WIDE_INT_1U << prec) - HOST_WIDE_INT_1U;
10563+ return (((src & value_mask) ^ sign_mask) - sign_mask);
10564+ }
10565+#endif
10566+}
10567+
10568 #endif /* ! GCC_HWINT_H */
10569diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c
10570index d05f8149170..d4ef8de4813 100644
10571--- a/gcc/tree-ssa-operands.c
10572+++ b/gcc/tree-ssa-operands.c
10573@@ -300,6 +300,7 @@ static inline void *
10574 ssa_operand_alloc (unsigned size)
10575 {
10576 char *ptr;
10577+ int x;
10578
10579 gcc_assert (size == sizeof (struct use_optype_d)
10580 || size == sizeof (struct def_optype_d));
10581@@ -334,8 +335,8 @@ ssa_operand_alloc (unsigned size)
10582 gimple_ssa_operands (cfun)->operand_memory_index = 0;
10583 }
10584
10585- ptr = &(gimple_ssa_operands (cfun)->operand_memory
10586- ->mem[gimple_ssa_operands (cfun)->operand_memory_index]);
10587+ x = gimple_ssa_operands (cfun)->operand_memory_index;
10588+ ptr = &(gimple_ssa_operands (cfun)->operand_memory->mem[x]);
10589 gimple_ssa_operands (cfun)->operand_memory_index += size;
10590 return ptr;
10591 }
10592diff --git a/gcc/unwind-dw2-fde-glibc.c b/gcc/unwind-dw2-fde-glibc.c
10593index d8e3c0e934b..e81b130d135 100644
10594--- a/gcc/unwind-dw2-fde-glibc.c
10595+++ b/gcc/unwind-dw2-fde-glibc.c
10596@@ -53,7 +53,19 @@
10597 #endif
10598
10599 #if !defined(inhibit_libc) && defined(HAVE_LD_EH_FRAME_HDR) \
10600- && defined(__FreeBSD__) && __FreeBSD__ >= 7
10601+ && defined(__BIONIC__)
10602+# define USE_PT_GNU_EH_FRAME
10603+#endif
10604+
10605+#if !defined(inhibit_libc) && defined(HAVE_LD_EH_FRAME_HDR) \
10606+ && defined(TARGET_DL_ITERATE_PHDR) \
10607+ && defined(__linux__)
10608+# define USE_PT_GNU_EH_FRAME
10609+#endif
10610+
10611+#if !defined(inhibit_libc) && defined(HAVE_LD_EH_FRAME_HDR) \
10612+ && defined(TARGET_DL_ITERATE_PHDR) \
10613+ && (defined(__DragonFly__) || defined(__FreeBSD__))
10614 # define ElfW __ElfN
10615 # define USE_PT_GNU_EH_FRAME
10616 #endif
10617diff --git a/guix.scm b/guix.scm
10618new file mode 100644
10619index 00000000000..8498a36ef13
10620--- /dev/null
10621+++ b/guix.scm
10622@@ -0,0 +1,78 @@
10623+(use-modules (ice-9 popen)
10624+ (ice-9 rdelim)
10625+ (srfi srfi-1)
10626+ (guix packages)
10627+ (guix utils)
10628+ (guix gexp)
10629+ (guix profiles)
10630+ (guix download)
10631+ (gnu packages flex)
10632+ (gnu packages gcc))
10633+
10634+(define %source-dir (dirname (current-filename)))
10635+
10636+(define %git-commit
10637+ (read-line
10638+ (open-pipe "git show HEAD | head -1 | cut -d ' ' -f 2 " OPEN_READ)))
10639+
10640+(define (keep-file? file stat)
10641+ ;; Return #t if FILE in this repository must be kept, #f otherwise. FILE is
10642+ ;; an absolute file name and STAT is the result of 'lstat' applied to FILE.
10643+ (not (or (any (lambda (str) (string-contains file str))
10644+ '(".git" ".log"))
10645+ (any (lambda (str) (string-suffix? str file))
10646+ '("guix.scm")))))
10647+
10648+(define-public gcc-mine
10649+ (package
10650+ (inherit gcc-4.7)
10651+ (version (string-append "4.6.4-HEAD"))
10652+ (source (local-file %source-dir
10653+ #:recursive? #t
10654+ #:select? keep-file?))
10655+
10656+ (native-inputs
10657+ (modify-inputs (package-native-inputs gcc-4.7)
10658+ (prepend flex)))
10659+
10660+ (arguments
10661+ (substitute-keyword-arguments (package-arguments gcc-4.7)
10662+ ((#:phases phases)
10663+ `(modify-phases ,phases
10664+ (add-after 'unpack 'patch-for-glibc-2.26
10665+ ;; https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81712
10666+ ;; TODO: Make this dependant on the glibc version in the build.
10667+ (lambda _
10668+ (for-each
10669+ (lambda (dir)
10670+ (substitute* (string-append "gcc/config/"
10671+ dir "/linux-unwind.h")
10672+ (("struct ucontext") "ucontext_t")))
10673+ '("alpha" "bfin" "i386" "pa" "sh" "xtensa" "riscv"))))
10674+ (add-after 'unpack 'dont-build-stage2-with-debug
10675+ (lambda _
10676+ (substitute* "config/bootstrap-debug.mk"
10677+ (("STAGE2_CFLAGS.*") ""))))
10678+ (add-after 'unpack 'ignore-bad-compare
10679+ ;; From Makefile.in:57786:
10680+ ;; Since the 'compare' process will fail (on debugging information) if any
10681+ ;; directory names are different, we need to link the gcc directory for
10682+ ;; the previous stage to a constant name ('prev-gcc'), and to make the name of
10683+ ;; the build directories constant as well. For the latter, we use naked names
10684+ ;; like 'gcc', because the scripts in that directory assume it. We use
10685+ ;; mv on platforms where symlinks to directories do not work or are not
10686+ ;; reliable.
10687+ ;; We ignore the bad compare until we can figure out how the debug
10688+ ;; information made its way into the stage2 build on riscv64.
10689+ (lambda _
10690+ (substitute* "Makefile.in"
10691+ (("cat \\.bad_compare;")
10692+ "cat \\.bad_compare; echo \"Ignoring bad compare!\"; exit 0;"))))
10693+ (add-after 'unpack 'setenv
10694+ ;; This phase is modeled after the one in commencement for gcc-mesboot1.
10695+ ;; We don't want gcc-11:lib in CPLUS_INCLUDE_PATH, it messes with
10696+ ;; libstdc++ from gcc-4.6.
10697+ (lambda _
10698+ (setenv "CPLUS_INCLUDE_PATH" (getenv "C_INCLUDE_PATH"))))))))))
10699+
10700+gcc-mine
10701diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
10702index 3ad049540ce..ad0364d133f 100644
10703--- a/libgcc/ChangeLog
10704+++ b/libgcc/ChangeLog
10705@@ -1,3 +1,21 @@
10706+2017-02-06 Palmer Dabbelt <palmer@dabbelt.com>
10707+
10708+ * config.host: Add RISC-V tuples.
10709+ * config/riscv/atomic.c: New file.
10710+ * config/riscv/crti.S: Likewise.
10711+ * config/riscv/crtn.S: Likewise.
10712+ * config/riscv/div.S: Likewise.
10713+ * config/riscv/linux-unwind.h: Likewise.
10714+ * config/riscv/muldi3.S: Likewise.
10715+ * config/riscv/multi3.S: Likewise.
10716+ * config/riscv/save-restore.S: Likewise.
10717+ * config/riscv/sfp-machine.h: Likewise.
10718+ * config/riscv/t-elf: Likewise.
10719+ * config/riscv/t-elf32: Likewise.
10720+ * config/riscv/t-elf64: Likewise.
10721+ * config/riscv/t-softfp32: Likewise.
10722+ * config/riscv/t-softfp64: Likewise.
10723+
10724 2013-04-12 Release Manager
10725
10726 * GCC 4.6.4 released.
10727diff --git a/libgcc/config.host b/libgcc/config.host
10728index 25e949e0fe3..ea8e2a3f368 100644
10729--- a/libgcc/config.host
10730+++ b/libgcc/config.host
10731@@ -121,6 +121,9 @@ rs6000*-*-*)
10732 score*-*-*)
10733 cpu_type=score
10734 ;;
10735+riscv*-*-*)
10736+ cpu_type=riscv
10737+ ;;
10738 sparc64*-*-*)
10739 cpu_type=sparc
10740 ;;
10741@@ -497,6 +500,12 @@ powerpcle-*-eabisim*)
10742 ;;
10743 powerpcle-*-eabi*)
10744 ;;
10745+riscv*-*-elf)
10746+ tmake_file="${tmake_file} riscv/t-softfp${host_address} t-softfp"
10747+ ;;
10748+riscv*-*-linux*)
10749+ tmake_file="${tmake_file} riscv/t-softfp${host_address} t-softfp"
10750+ ;;
10751 rs6000-ibm-aix4.[3456789]* | powerpc-ibm-aix4.[3456789]*)
10752 ;;
10753 rs6000-ibm-aix5.1.* | powerpc-ibm-aix5.1.*)
10754diff --git a/libgcc/config/riscv/sfp-machine.h b/libgcc/config/riscv/sfp-machine.h
10755new file mode 100644
10756index 00000000000..b1a27e7ed44
10757--- /dev/null
10758+++ b/libgcc/config/riscv/sfp-machine.h
10759@@ -0,0 +1,137 @@
10760+/* Software floating-point machine description for RISC-V.
10761+
10762+ Copyright (C) 2016-2017 Free Software Foundation, Inc.
10763+
10764+This file is part of GCC.
10765+
10766+GCC is free software; you can redistribute it and/or modify it under
10767+the terms of the GNU General Public License as published by the Free
10768+Software Foundation; either version 3, or (at your option) any later
10769+version.
10770+
10771+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
10772+WARRANTY; without even the implied warranty of MERCHANTABILITY or
10773+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
10774+for more details.
10775+
10776+Under Section 7 of GPL version 3, you are granted additional
10777+permissions described in the GCC Runtime Library Exception, version
10778+3.1, as published by the Free Software Foundation.
10779+
10780+You should have received a copy of the GNU General Public License and
10781+a copy of the GCC Runtime Library Exception along with this program;
10782+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
10783+<http://www.gnu.org/licenses/>. */
10784+
10785+#if __riscv_xlen == 32
10786+
10787+#define _FP_W_TYPE_SIZE 32
10788+#define _FP_W_TYPE unsigned long
10789+#define _FP_WS_TYPE signed long
10790+#define _FP_I_TYPE long
10791+
10792+#define _FP_MUL_MEAT_S(R,X,Y) \
10793+ _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
10794+#define _FP_MUL_MEAT_D(R,X,Y) \
10795+ _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
10796+#define _FP_MUL_MEAT_Q(R,X,Y) \
10797+ _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
10798+
10799+#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_udiv_norm(S,R,X,Y)
10800+#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y)
10801+#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
10802+
10803+#define _FP_NANFRAC_S _FP_QNANBIT_S
10804+#define _FP_NANFRAC_D _FP_QNANBIT_D, 0
10805+#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0, 0, 0
10806+
10807+#else
10808+
10809+#define _FP_W_TYPE_SIZE 64
10810+#define _FP_W_TYPE unsigned long long
10811+#define _FP_WS_TYPE signed long long
10812+#define _FP_I_TYPE long long
10813+
10814+#define _FP_MUL_MEAT_S(R,X,Y) \
10815+ _FP_MUL_MEAT_1_imm(_FP_WFRACBITS_S,R,X,Y)
10816+#define _FP_MUL_MEAT_D(R,X,Y) \
10817+ _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
10818+#define _FP_MUL_MEAT_Q(R,X,Y) \
10819+ _FP_MUL_MEAT_2_wide_3mul(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
10820+
10821+#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm)
10822+#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_1_udiv_norm(D,R,X,Y)
10823+#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
10824+
10825+#define _FP_NANFRAC_S _FP_QNANBIT_S
10826+#define _FP_NANFRAC_D _FP_QNANBIT_D
10827+#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0
10828+
10829+#endif
10830+
10831+#if __riscv_xlen == 64
10832+typedef int TItype __attribute__ ((mode (TI)));
10833+typedef unsigned int UTItype __attribute__ ((mode (TI)));
10834+#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
10835+#endif
10836+
10837+/* The type of the result of a floating point comparison. This must
10838+ match __libgcc_cmp_return__ in GCC for the target. */
10839+typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
10840+#define CMPtype __gcc_CMPtype
10841+
10842+#define _FP_NANSIGN_S 0
10843+#define _FP_NANSIGN_D 0
10844+#define _FP_NANSIGN_Q 0
10845+
10846+#define _FP_KEEPNANFRACP 0
10847+#define _FP_QNANNEGATEDP 0
10848+
10849+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
10850+ do { \
10851+ R##_s = _FP_NANSIGN_##fs; \
10852+ _FP_FRAC_SET_##wc(R,_FP_NANFRAC_##fs); \
10853+ R##_c = FP_CLS_NAN; \
10854+ } while (0)
10855+
10856+#define _FP_DECL_EX int _frm __attribute__ ((unused));
10857+#define FP_ROUNDMODE _frm
10858+
10859+#define FP_RND_NEAREST 0x0
10860+#define FP_RND_ZERO 0x1
10861+#define FP_RND_PINF 0x3
10862+#define FP_RND_MINF 0x2
10863+
10864+#define FP_EX_INVALID 0x10
10865+#define FP_EX_OVERFLOW 0x04
10866+#define FP_EX_UNDERFLOW 0x02
10867+#define FP_EX_DIVZERO 0x08
10868+#define FP_EX_INEXACT 0x01
10869+
10870+#define _FP_TININESS_AFTER_ROUNDING 1
10871+
10872+#ifdef __riscv_flen
10873+#define FP_INIT_ROUNDMODE \
10874+do { \
10875+ __asm__ volatile ("frrm %0" : "=r" (_frm)); \
10876+} while (0)
10877+
10878+#define FP_HANDLE_EXCEPTIONS \
10879+do { \
10880+ if (__builtin_expect (_fex, 0)) \
10881+ __asm__ volatile ("csrs fflags, %0" : : "rK" (_fex)); \
10882+} while (0)
10883+#else
10884+#define FP_INIT_ROUNDMODE _frm = FP_RND_NEAREST
10885+#endif
10886+
10887+#define __LITTLE_ENDIAN 1234
10888+#define __BIG_ENDIAN 4321
10889+
10890+#define __BYTE_ORDER __LITTLE_ENDIAN
10891+
10892+
10893+/* Define ALIASNAME as a strong alias for NAME. */
10894+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
10895+# define _strong_alias(name, aliasname) \
10896+ extern __typeof (name) aliasname __attribute__ ((alias (#name)));
10897diff --git a/libgcc/config/riscv/t-softfp32 b/libgcc/config/riscv/t-softfp32
10898new file mode 100644
10899index 00000000000..c4bd3871b93
10900--- /dev/null
10901+++ b/libgcc/config/riscv/t-softfp32
10902@@ -0,0 +1,27 @@
10903+ABI_SINGLE:=$(findstring __riscv_float_abi_single,$(shell $(gcc_compile_bare) -dM -E - </dev/null))
10904+ABI_DOUBLE:=$(findstring __riscv_float_abi_double,$(shell $(gcc_compile_bare) -dM -E - </dev/null))
10905+ABI_QUAD:=$(findstring __riscv_float_abi_quad,$(shell $(gcc_compile_bare) -dM -E - </dev/null))
10906+
10907+softfp_machine_header := riscv/sfp-machine.h
10908+softfp_int_modes := si di
10909+softfp_exclude_libgcc2 := n
10910+
10911+ifndef ABI_QUAD
10912+ifdef ABI_DOUBLE
10913+
10914+softfp_float_modes := tf
10915+softfp_extensions := sftf dftf
10916+softfp_truncations := tfsf tfdf
10917+
10918+else
10919+
10920+softfp_float_modes := df tf
10921+softfp_extensions := sfdf sftf dftf
10922+softfp_truncations := dfsf tfsf tfdf
10923+
10924+ifndef ABI_SINGLE
10925+softfp_float_modes += sf
10926+endif
10927+
10928+endif
10929+endif
10930diff --git a/libgcc/config/riscv/t-softfp64 b/libgcc/config/riscv/t-softfp64
10931new file mode 100644
10932index 00000000000..75870951202
10933--- /dev/null
10934+++ b/libgcc/config/riscv/t-softfp64
10935@@ -0,0 +1,3 @@
10936+include $(srcdir)/config/riscv/t-softfp32
10937+
10938+softfp_int_modes += ti
10939diff --git a/libiberty/configure b/libiberty/configure
10940index bdabe8d1a35..9569073e3d4 100755
10941--- a/libiberty/configure
10942+++ b/libiberty/configure
10943@@ -4859,6 +4859,7 @@ if [ "${shared}" = "yes" ]; then
10944 PICFLAG=-fpic ;;
10945 m68k-*-*) PICFLAG=-fpic ;;
10946 mips*-*-linux*) PICFLAG=-fPIC ;;
10947+ riscv*-*-linux*) PICFLAG=-fPIC ;;
10948 powerpc*-*-aix*) ;;
10949 powerpc*-*-*) PICFLAG=-fPIC ;;
10950 sparc*-*-*) case "${CFLAGS}" in
10951diff --git a/libiberty/configure.ac b/libiberty/configure.ac
10952index 9f1ff04938e..ece4a8844bd 100644
10953--- a/libiberty/configure.ac
10954+++ b/libiberty/configure.ac
10955@@ -210,6 +210,7 @@ if [[ "${shared}" = "yes" ]]; then
10956 PICFLAG=-fpic ;;
10957 m68k-*-*) PICFLAG=-fpic ;;
10958 mips*-*-linux*) PICFLAG=-fPIC ;;
10959+ riscv*-*-linux*) PICFLAG=-fPIC ;;
10960 powerpc*-*-aix*) ;;
10961 powerpc*-*-*) PICFLAG=-fPIC ;;
10962 sparc*-*-*) case "${CFLAGS}" in
10963diff --git a/manifest.scm b/manifest.scm
10964new file mode 100644
10965index 00000000000..3a2220bf9e8
10966--- /dev/null
10967+++ b/manifest.scm
10968@@ -0,0 +1,6 @@
10969+(load "guix.scm")
10970+
10971+(packages->manifest (list gcc-mine
10972+ binutils
10973+ glibc
10974+ (list glibc "static")))