1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/patches/gcc/3.4.4/900-nios2.patch Sun Jul 01 21:21:11 2007 +0000
1.3 @@ -0,0 +1,10211 @@
1.4 +--- gcc-3.4.3/gcc/Makefile.in
1.5 ++++ gcc-3.4.3-nios2/gcc/Makefile.in
1.6 +@@ -3085,7 +3085,7 @@ install-mkheaders: stmp-int-hdrs $(STMP_
1.7 + $(INSTALL_DATA) $(srcdir)/README-fixinc \
1.8 + $(DESTDIR)$(itoolsdatadir)/include/README ; \
1.9 + $(INSTALL_SCRIPT) fixinc.sh $(DESTDIR)$(itoolsdir)/fixinc.sh ; \
1.10 +- $(INSTALL_PROGRAM) fixinc/fixincl $(DESTDIR)$(itoolsdir)/fixincl ; \
1.11 ++ $(INSTALL_PROGRAM) fixinc/fixincl$(build_exeext) $(DESTDIR)$(itoolsdir)/fixincl$(build_exeext) ; \
1.12 + $(INSTALL_DATA) $(srcdir)/gsyslimits.h \
1.13 + $(DESTDIR)$(itoolsdatadir)/gsyslimits.h ; \
1.14 + else :; fi
1.15 +--- gcc-3.4.3/gcc/combine.c
1.16 ++++ gcc-3.4.3-nios2/gcc/combine.c
1.17 +@@ -4380,6 +4380,14 @@ combine_simplify_rtx (rtx x, enum machin
1.18 + mode);
1.19 + }
1.20 +
1.21 ++#ifndef __nios2__
1.22 ++/* This screws up Nios II in this test case:
1.23 ++
1.24 ++if (x & 1)
1.25 ++ return 2;
1.26 ++else
1.27 ++ return 3;
1.28 ++*/
1.29 + else if (STORE_FLAG_VALUE == 1
1.30 + && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT
1.31 + && op1 == const0_rtx
1.32 +@@ -4391,6 +4399,7 @@ combine_simplify_rtx (rtx x, enum machin
1.33 + gen_lowpart_for_combine (mode, op0),
1.34 + const1_rtx);
1.35 + }
1.36 ++#endif
1.37 +
1.38 + else if (STORE_FLAG_VALUE == 1
1.39 + && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT
1.40 +--- gcc-3.4.3/gcc/config/nios2/crti.asm
1.41 ++++ gcc-3.4.3-nios2/gcc/config/nios2/crti.asm
1.42 +@@ -0,0 +1,88 @@
1.43 ++/*
1.44 ++ Copyright (C) 2003
1.45 ++ by Jonah Graham (jgraham@altera.com)
1.46 ++
1.47 ++This file is free software; you can redistribute it and/or modify it
1.48 ++under the terms of the GNU General Public License as published by the
1.49 ++Free Software Foundation; either version 2, or (at your option) any
1.50 ++later version.
1.51 ++
1.52 ++In addition to the permissions in the GNU General Public License, the
1.53 ++Free Software Foundation gives you unlimited permission to link the
1.54 ++compiled version of this file with other programs, and to distribute
1.55 ++those programs without any restriction coming from the use of this
1.56 ++file. (The General Public License restrictions do apply in other
1.57 ++respects; for example, they cover modification of the file, and
1.58 ++distribution when not linked into another program.)
1.59 ++
1.60 ++This file is distributed in the hope that it will be useful, but
1.61 ++WITHOUT ANY WARRANTY; without even the implied warranty of
1.62 ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1.63 ++General Public License for more details.
1.64 ++
1.65 ++You should have received a copy of the GNU General Public License
1.66 ++along with this program; see the file COPYING. If not, write to
1.67 ++the Free Software Foundation, 59 Temple Place - Suite 330,
1.68 ++Boston, MA 02111-1307, USA.
1.69 ++
1.70 ++ As a special exception, if you link this library with files
1.71 ++ compiled with GCC to produce an executable, this does not cause
1.72 ++ the resulting executable to be covered by the GNU General Public License.
1.73 ++ This exception does not however invalidate any other reasons why
1.74 ++ the executable file might be covered by the GNU General Public License.
1.75 ++
1.76 ++
1.77 ++This file just make a stack frame for the contents of the .fini and
1.78 ++.init sections. Users may put any desired instructions in those
1.79 ++sections.
1.80 ++
1.81 ++
1.82 ++While technically any code can be put in the init and fini sections
1.83 ++most stuff will not work other than stuff which obeys the call frame
1.84 ++and ABI. All the call-preserved registers are saved, the call clobbered
1.85 ++registers should have been saved by the code calling init and fini.
1.86 ++
1.87 ++See crtstuff.c for an example of code that inserts itself in the
1.88 ++init and fini sections.
1.89 ++
1.90 ++See crt0.s for the code that calls init and fini.
1.91 ++*/
1.92 ++
1.93 ++ .file "crti.asm"
1.94 ++
1.95 ++ .section ".init"
1.96 ++ .align 2
1.97 ++ .global _init
1.98 ++_init:
1.99 ++ addi sp, sp, -48
1.100 ++ stw ra, 44(sp)
1.101 ++ stw r23, 40(sp)
1.102 ++ stw r22, 36(sp)
1.103 ++ stw r21, 32(sp)
1.104 ++ stw r20, 28(sp)
1.105 ++ stw r19, 24(sp)
1.106 ++ stw r18, 20(sp)
1.107 ++ stw r17, 16(sp)
1.108 ++ stw r16, 12(sp)
1.109 ++ stw fp, 8(sp)
1.110 ++ mov fp, sp
1.111 ++
1.112 ++
1.113 ++ .section ".fini"
1.114 ++ .align 2
1.115 ++ .global _fini
1.116 ++_fini:
1.117 ++ addi sp, sp, -48
1.118 ++ stw ra, 44(sp)
1.119 ++ stw r23, 40(sp)
1.120 ++ stw r22, 36(sp)
1.121 ++ stw r21, 32(sp)
1.122 ++ stw r20, 28(sp)
1.123 ++ stw r19, 24(sp)
1.124 ++ stw r18, 20(sp)
1.125 ++ stw r17, 16(sp)
1.126 ++ stw r16, 12(sp)
1.127 ++ stw fp, 8(sp)
1.128 ++ mov fp, sp
1.129 ++
1.130 ++
1.131 +--- gcc-3.4.3/gcc/config/nios2/crtn.asm
1.132 ++++ gcc-3.4.3-nios2/gcc/config/nios2/crtn.asm
1.133 +@@ -0,0 +1,70 @@
1.134 ++/*
1.135 ++ Copyright (C) 2003
1.136 ++ by Jonah Graham (jgraham@altera.com)
1.137 ++
1.138 ++This file is free software; you can redistribute it and/or modify it
1.139 ++under the terms of the GNU General Public License as published by the
1.140 ++Free Software Foundation; either version 2, or (at your option) any
1.141 ++later version.
1.142 ++
1.143 ++In addition to the permissions in the GNU General Public License, the
1.144 ++Free Software Foundation gives you unlimited permission to link the
1.145 ++compiled version of this file with other programs, and to distribute
1.146 ++those programs without any restriction coming from the use of this
1.147 ++file. (The General Public License restrictions do apply in other
1.148 ++respects; for example, they cover modification of the file, and
1.149 ++distribution when not linked into another program.)
1.150 ++
1.151 ++This file is distributed in the hope that it will be useful, but
1.152 ++WITHOUT ANY WARRANTY; without even the implied warranty of
1.153 ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1.154 ++General Public License for more details.
1.155 ++
1.156 ++You should have received a copy of the GNU General Public License
1.157 ++along with this program; see the file COPYING. If not, write to
1.158 ++the Free Software Foundation, 59 Temple Place - Suite 330,
1.159 ++Boston, MA 02111-1307, USA.
1.160 ++
1.161 ++ As a special exception, if you link this library with files
1.162 ++ compiled with GCC to produce an executable, this does not cause
1.163 ++ the resulting executable to be covered by the GNU General Public License.
1.164 ++ This exception does not however invalidate any other reasons why
1.165 ++ the executable file might be covered by the GNU General Public License.
1.166 ++
1.167 ++
1.168 ++This file just makes sure that the .fini and .init sections do in
1.169 ++fact return. Users may put any desired instructions in those sections.
1.170 ++This file is the last thing linked into any executable.
1.171 ++*/
1.172 ++ .file "crtn.asm"
1.173 ++
1.174 ++
1.175 ++
1.176 ++ .section ".init"
1.177 ++ ldw ra, 44(sp)
1.178 ++ ldw r23, 40(sp)
1.179 ++ ldw r22, 36(sp)
1.180 ++ ldw r21, 32(sp)
1.181 ++ ldw r20, 28(sp)
1.182 ++ ldw r19, 24(sp)
1.183 ++ ldw r18, 20(sp)
1.184 ++ ldw r17, 16(sp)
1.185 ++ ldw r16, 12(sp)
1.186 ++ ldw fp, 8(sp)
1.187 ++ addi sp, sp, -48
1.188 ++ ret
1.189 ++
1.190 ++ .section ".fini"
1.191 ++ ldw ra, 44(sp)
1.192 ++ ldw r23, 40(sp)
1.193 ++ ldw r22, 36(sp)
1.194 ++ ldw r21, 32(sp)
1.195 ++ ldw r20, 28(sp)
1.196 ++ ldw r19, 24(sp)
1.197 ++ ldw r18, 20(sp)
1.198 ++ ldw r17, 16(sp)
1.199 ++ ldw r16, 12(sp)
1.200 ++ ldw fp, 8(sp)
1.201 ++ addi sp, sp, -48
1.202 ++ ret
1.203 ++
1.204 +--- gcc-3.4.3/gcc/config/nios2/lib2-divmod-hi.c
1.205 ++++ gcc-3.4.3-nios2/gcc/config/nios2/lib2-divmod-hi.c
1.206 +@@ -0,0 +1,123 @@
1.207 ++
1.208 ++/* We include auto-host.h here to get HAVE_GAS_HIDDEN. This is
1.209 ++ supposedly valid even though this is a "target" file. */
1.210 ++#include "auto-host.h"
1.211 ++
1.212 ++
1.213 ++#include "tconfig.h"
1.214 ++#include "tsystem.h"
1.215 ++#include "coretypes.h"
1.216 ++#include "tm.h"
1.217 ++
1.218 ++
1.219 ++/* Don't use `fancy_abort' here even if config.h says to use it. */
1.220 ++#ifdef abort
1.221 ++#undef abort
1.222 ++#endif
1.223 ++
1.224 ++
1.225 ++#ifdef HAVE_GAS_HIDDEN
1.226 ++#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
1.227 ++#else
1.228 ++#define ATTRIBUTE_HIDDEN
1.229 ++#endif
1.230 ++
1.231 ++#include "libgcc2.h"
1.232 ++
1.233 ++extern HItype __modhi3 (HItype, HItype);
1.234 ++extern HItype __divhi3 (HItype, HItype);
1.235 ++extern HItype __umodhi3 (HItype, HItype);
1.236 ++extern HItype __udivhi3 (HItype, HItype);
1.237 ++
1.238 ++static UHItype udivmodhi4(UHItype, UHItype, word_type);
1.239 ++
1.240 ++static UHItype
1.241 ++udivmodhi4(UHItype num, UHItype den, word_type modwanted)
1.242 ++{
1.243 ++ UHItype bit = 1;
1.244 ++ UHItype res = 0;
1.245 ++
1.246 ++ while (den < num && bit && !(den & (1L<<15)))
1.247 ++ {
1.248 ++ den <<=1;
1.249 ++ bit <<=1;
1.250 ++ }
1.251 ++ while (bit)
1.252 ++ {
1.253 ++ if (num >= den)
1.254 ++ {
1.255 ++ num -= den;
1.256 ++ res |= bit;
1.257 ++ }
1.258 ++ bit >>=1;
1.259 ++ den >>=1;
1.260 ++ }
1.261 ++ if (modwanted) return num;
1.262 ++ return res;
1.263 ++}
1.264 ++
1.265 ++
1.266 ++HItype
1.267 ++__divhi3 (HItype a, HItype b)
1.268 ++{
1.269 ++ word_type neg = 0;
1.270 ++ HItype res;
1.271 ++
1.272 ++ if (a < 0)
1.273 ++ {
1.274 ++ a = -a;
1.275 ++ neg = !neg;
1.276 ++ }
1.277 ++
1.278 ++ if (b < 0)
1.279 ++ {
1.280 ++ b = -b;
1.281 ++ neg = !neg;
1.282 ++ }
1.283 ++
1.284 ++ res = udivmodhi4 (a, b, 0);
1.285 ++
1.286 ++ if (neg)
1.287 ++ res = -res;
1.288 ++
1.289 ++ return res;
1.290 ++}
1.291 ++
1.292 ++
1.293 ++HItype
1.294 ++__modhi3 (HItype a, HItype b)
1.295 ++{
1.296 ++ word_type neg = 0;
1.297 ++ HItype res;
1.298 ++
1.299 ++ if (a < 0)
1.300 ++ {
1.301 ++ a = -a;
1.302 ++ neg = 1;
1.303 ++ }
1.304 ++
1.305 ++ if (b < 0)
1.306 ++ b = -b;
1.307 ++
1.308 ++ res = udivmodhi4 (a, b, 1);
1.309 ++
1.310 ++ if (neg)
1.311 ++ res = -res;
1.312 ++
1.313 ++ return res;
1.314 ++}
1.315 ++
1.316 ++
1.317 ++HItype
1.318 ++__udivhi3 (HItype a, HItype b)
1.319 ++{
1.320 ++ return udivmodhi4 (a, b, 0);
1.321 ++}
1.322 ++
1.323 ++
1.324 ++HItype
1.325 ++__umodhi3 (HItype a, HItype b)
1.326 ++{
1.327 ++ return udivmodhi4 (a, b, 1);
1.328 ++}
1.329 ++
1.330 +--- gcc-3.4.3/gcc/config/nios2/lib2-divmod.c
1.331 ++++ gcc-3.4.3-nios2/gcc/config/nios2/lib2-divmod.c
1.332 +@@ -0,0 +1,126 @@
1.333 ++
1.334 ++/* We include auto-host.h here to get HAVE_GAS_HIDDEN. This is
1.335 ++ supposedly valid even though this is a "target" file. */
1.336 ++#include "auto-host.h"
1.337 ++
1.338 ++
1.339 ++#include "tconfig.h"
1.340 ++#include "tsystem.h"
1.341 ++#include "coretypes.h"
1.342 ++#include "tm.h"
1.343 ++
1.344 ++
1.345 ++/* Don't use `fancy_abort' here even if config.h says to use it. */
1.346 ++#ifdef abort
1.347 ++#undef abort
1.348 ++#endif
1.349 ++
1.350 ++
1.351 ++#ifdef HAVE_GAS_HIDDEN
1.352 ++#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
1.353 ++#else
1.354 ++#define ATTRIBUTE_HIDDEN
1.355 ++#endif
1.356 ++
1.357 ++#include "libgcc2.h"
1.358 ++
1.359 ++extern SItype __modsi3 (SItype, SItype);
1.360 ++extern SItype __divsi3 (SItype, SItype);
1.361 ++extern SItype __umodsi3 (SItype, SItype);
1.362 ++extern SItype __udivsi3 (SItype, SItype);
1.363 ++
1.364 ++static USItype udivmodsi4(USItype, USItype, word_type);
1.365 ++
1.366 ++/* 16-bit SI divide and modulo as used in NIOS */
1.367 ++
1.368 ++
1.369 ++static USItype
1.370 ++udivmodsi4(USItype num, USItype den, word_type modwanted)
1.371 ++{
1.372 ++ USItype bit = 1;
1.373 ++ USItype res = 0;
1.374 ++
1.375 ++ while (den < num && bit && !(den & (1L<<31)))
1.376 ++ {
1.377 ++ den <<=1;
1.378 ++ bit <<=1;
1.379 ++ }
1.380 ++ while (bit)
1.381 ++ {
1.382 ++ if (num >= den)
1.383 ++ {
1.384 ++ num -= den;
1.385 ++ res |= bit;
1.386 ++ }
1.387 ++ bit >>=1;
1.388 ++ den >>=1;
1.389 ++ }
1.390 ++ if (modwanted) return num;
1.391 ++ return res;
1.392 ++}
1.393 ++
1.394 ++
1.395 ++SItype
1.396 ++__divsi3 (SItype a, SItype b)
1.397 ++{
1.398 ++ word_type neg = 0;
1.399 ++ SItype res;
1.400 ++
1.401 ++ if (a < 0)
1.402 ++ {
1.403 ++ a = -a;
1.404 ++ neg = !neg;
1.405 ++ }
1.406 ++
1.407 ++ if (b < 0)
1.408 ++ {
1.409 ++ b = -b;
1.410 ++ neg = !neg;
1.411 ++ }
1.412 ++
1.413 ++ res = udivmodsi4 (a, b, 0);
1.414 ++
1.415 ++ if (neg)
1.416 ++ res = -res;
1.417 ++
1.418 ++ return res;
1.419 ++}
1.420 ++
1.421 ++
1.422 ++SItype
1.423 ++__modsi3 (SItype a, SItype b)
1.424 ++{
1.425 ++ word_type neg = 0;
1.426 ++ SItype res;
1.427 ++
1.428 ++ if (a < 0)
1.429 ++ {
1.430 ++ a = -a;
1.431 ++ neg = 1;
1.432 ++ }
1.433 ++
1.434 ++ if (b < 0)
1.435 ++ b = -b;
1.436 ++
1.437 ++ res = udivmodsi4 (a, b, 1);
1.438 ++
1.439 ++ if (neg)
1.440 ++ res = -res;
1.441 ++
1.442 ++ return res;
1.443 ++}
1.444 ++
1.445 ++
1.446 ++SItype
1.447 ++__udivsi3 (SItype a, SItype b)
1.448 ++{
1.449 ++ return udivmodsi4 (a, b, 0);
1.450 ++}
1.451 ++
1.452 ++
1.453 ++SItype
1.454 ++__umodsi3 (SItype a, SItype b)
1.455 ++{
1.456 ++ return udivmodsi4 (a, b, 1);
1.457 ++}
1.458 ++
1.459 +--- gcc-3.4.3/gcc/config/nios2/lib2-divtable.c
1.460 ++++ gcc-3.4.3-nios2/gcc/config/nios2/lib2-divtable.c
1.461 +@@ -0,0 +1,46 @@
1.462 ++
1.463 ++/* We include auto-host.h here to get HAVE_GAS_HIDDEN. This is
1.464 ++ supposedly valid even though this is a "target" file. */
1.465 ++#include "auto-host.h"
1.466 ++
1.467 ++
1.468 ++#include "tconfig.h"
1.469 ++#include "tsystem.h"
1.470 ++#include "coretypes.h"
1.471 ++#include "tm.h"
1.472 ++
1.473 ++
1.474 ++/* Don't use `fancy_abort' here even if config.h says to use it. */
1.475 ++#ifdef abort
1.476 ++#undef abort
1.477 ++#endif
1.478 ++
1.479 ++
1.480 ++#ifdef HAVE_GAS_HIDDEN
1.481 ++#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
1.482 ++#else
1.483 ++#define ATTRIBUTE_HIDDEN
1.484 ++#endif
1.485 ++
1.486 ++#include "libgcc2.h"
1.487 ++
1.488 ++UQItype __divsi3_table[] =
1.489 ++{
1.490 ++ 0, 0/1, 0/2, 0/3, 0/4, 0/5, 0/6, 0/7, 0/8, 0/9, 0/10, 0/11, 0/12, 0/13, 0/14, 0/15,
1.491 ++ 0, 1/1, 1/2, 1/3, 1/4, 1/5, 1/6, 1/7, 1/8, 1/9, 1/10, 1/11, 1/12, 1/13, 1/14, 1/15,
1.492 ++ 0, 2/1, 2/2, 2/3, 2/4, 2/5, 2/6, 2/7, 2/8, 2/9, 2/10, 2/11, 2/12, 2/13, 2/14, 2/15,
1.493 ++ 0, 3/1, 3/2, 3/3, 3/4, 3/5, 3/6, 3/7, 3/8, 3/9, 3/10, 3/11, 3/12, 3/13, 3/14, 3/15,
1.494 ++ 0, 4/1, 4/2, 4/3, 4/4, 4/5, 4/6, 4/7, 4/8, 4/9, 4/10, 4/11, 4/12, 4/13, 4/14, 4/15,
1.495 ++ 0, 5/1, 5/2, 5/3, 5/4, 5/5, 5/6, 5/7, 5/8, 5/9, 5/10, 5/11, 5/12, 5/13, 5/14, 5/15,
1.496 ++ 0, 6/1, 6/2, 6/3, 6/4, 6/5, 6/6, 6/7, 6/8, 6/9, 6/10, 6/11, 6/12, 6/13, 6/14, 6/15,
1.497 ++ 0, 7/1, 7/2, 7/3, 7/4, 7/5, 7/6, 7/7, 7/8, 7/9, 7/10, 7/11, 7/12, 7/13, 7/14, 7/15,
1.498 ++ 0, 8/1, 8/2, 8/3, 8/4, 8/5, 8/6, 8/7, 8/8, 8/9, 8/10, 8/11, 8/12, 8/13, 8/14, 8/15,
1.499 ++ 0, 9/1, 9/2, 9/3, 9/4, 9/5, 9/6, 9/7, 9/8, 9/9, 9/10, 9/11, 9/12, 9/13, 9/14, 9/15,
1.500 ++ 0, 10/1, 10/2, 10/3, 10/4, 10/5, 10/6, 10/7, 10/8, 10/9, 10/10, 10/11, 10/12, 10/13, 10/14, 10/15,
1.501 ++ 0, 11/1, 11/2, 11/3, 11/4, 11/5, 11/6, 11/7, 11/8, 11/9, 11/10, 11/11, 11/12, 11/13, 11/14, 11/15,
1.502 ++ 0, 12/1, 12/2, 12/3, 12/4, 12/5, 12/6, 12/7, 12/8, 12/9, 12/10, 12/11, 12/12, 12/13, 12/14, 12/15,
1.503 ++ 0, 13/1, 13/2, 13/3, 13/4, 13/5, 13/6, 13/7, 13/8, 13/9, 13/10, 13/11, 13/12, 13/13, 13/14, 13/15,
1.504 ++ 0, 14/1, 14/2, 14/3, 14/4, 14/5, 14/6, 14/7, 14/8, 14/9, 14/10, 14/11, 14/12, 14/13, 14/14, 14/15,
1.505 ++ 0, 15/1, 15/2, 15/3, 15/4, 15/5, 15/6, 15/7, 15/8, 15/9, 15/10, 15/11, 15/12, 15/13, 15/14, 15/15,
1.506 ++};
1.507 ++
1.508 +--- gcc-3.4.3/gcc/config/nios2/lib2-mul.c
1.509 ++++ gcc-3.4.3-nios2/gcc/config/nios2/lib2-mul.c
1.510 +@@ -0,0 +1,103 @@
1.511 ++/* while we are debugging (ie compile outside of gcc build)
1.512 ++ disable gcc specific headers */
1.513 ++#ifndef DEBUG_MULSI3
1.514 ++
1.515 ++
1.516 ++/* We include auto-host.h here to get HAVE_GAS_HIDDEN. This is
1.517 ++ supposedly valid even though this is a "target" file. */
1.518 ++#include "auto-host.h"
1.519 ++
1.520 ++
1.521 ++#include "tconfig.h"
1.522 ++#include "tsystem.h"
1.523 ++#include "coretypes.h"
1.524 ++#include "tm.h"
1.525 ++
1.526 ++
1.527 ++/* Don't use `fancy_abort' here even if config.h says to use it. */
1.528 ++#ifdef abort
1.529 ++#undef abort
1.530 ++#endif
1.531 ++
1.532 ++
1.533 ++#ifdef HAVE_GAS_HIDDEN
1.534 ++#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
1.535 ++#else
1.536 ++#define ATTRIBUTE_HIDDEN
1.537 ++#endif
1.538 ++
1.539 ++#include "libgcc2.h"
1.540 ++
1.541 ++#else
1.542 ++#define SItype int
1.543 ++#define USItype unsigned int
1.544 ++#endif
1.545 ++
1.546 ++
1.547 ++extern SItype __mulsi3 (SItype, SItype);
1.548 ++
1.549 ++SItype
1.550 ++__mulsi3 (SItype a, SItype b)
1.551 ++{
1.552 ++ SItype res = 0;
1.553 ++ USItype cnt = a;
1.554 ++
1.555 ++ while (cnt)
1.556 ++ {
1.557 ++ if (cnt & 1)
1.558 ++ {
1.559 ++ res += b;
1.560 ++ }
1.561 ++ b <<= 1;
1.562 ++ cnt >>= 1;
1.563 ++ }
1.564 ++
1.565 ++ return res;
1.566 ++}
1.567 ++/*
1.568 ++TODO: Choose best alternative implementation.
1.569 ++
1.570 ++SItype
1.571 ++__divsi3 (SItype a, SItype b)
1.572 ++{
1.573 ++ SItype res = 0;
1.574 ++ USItype cnt = 0;
1.575 ++
1.576 ++ while (cnt < 32)
1.577 ++ {
1.578 ++ if (a & (1L << cnt))
1.579 ++ {
1.580 ++ res += b;
1.581 ++ }
1.582 ++ b <<= 1;
1.583 ++ cnt++;
1.584 ++ }
1.585 ++
1.586 ++ return res;
1.587 ++}
1.588 ++*/
1.589 ++
1.590 ++
1.591 ++#ifdef DEBUG_MULSI3
1.592 ++
1.593 ++int
1.594 ++main ()
1.595 ++{
1.596 ++ int i, j;
1.597 ++ int error = 0;
1.598 ++
1.599 ++ for (i = -1000; i < 1000; i++)
1.600 ++ for (j = -1000; j < 1000; j++)
1.601 ++ {
1.602 ++ int expect = i * j;
1.603 ++ int actual = A__divsi3 (i, j);
1.604 ++ if (expect != actual)
1.605 ++ {
1.606 ++ printf ("error: %d * %d = %d not %d\n", i, j, expect, actual);
1.607 ++ error = 1;
1.608 ++ }
1.609 ++ }
1.610 ++
1.611 ++ return error;
1.612 ++}
1.613 ++#endif
1.614 +--- gcc-3.4.3/gcc/config/nios2/nios2-dp-bit.c
1.615 ++++ gcc-3.4.3-nios2/gcc/config/nios2/nios2-dp-bit.c
1.616 +@@ -0,0 +1,1652 @@
1.617 ++
1.618 ++/* This is a software floating point library which can be used
1.619 ++ for targets without hardware floating point.
1.620 ++ Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004
1.621 ++ Free Software Foundation, Inc.
1.622 ++
1.623 ++This file is free software; you can redistribute it and/or modify it
1.624 ++under the terms of the GNU General Public License as published by the
1.625 ++Free Software Foundation; either version 2, or (at your option) any
1.626 ++later version.
1.627 ++
1.628 ++In addition to the permissions in the GNU General Public License, the
1.629 ++Free Software Foundation gives you unlimited permission to link the
1.630 ++compiled version of this file with other programs, and to distribute
1.631 ++those programs without any restriction coming from the use of this
1.632 ++file. (The General Public License restrictions do apply in other
1.633 ++respects; for example, they cover modification of the file, and
1.634 ++distribution when not linked into another program.)
1.635 ++
1.636 ++This file is distributed in the hope that it will be useful, but
1.637 ++WITHOUT ANY WARRANTY; without even the implied warranty of
1.638 ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1.639 ++General Public License for more details.
1.640 ++
1.641 ++You should have received a copy of the GNU General Public License
1.642 ++along with this program; see the file COPYING. If not, write to
1.643 ++the Free Software Foundation, 59 Temple Place - Suite 330,
1.644 ++Boston, MA 02111-1307, USA. */
1.645 ++
1.646 ++/* As a special exception, if you link this library with other files,
1.647 ++ some of which are compiled with GCC, to produce an executable,
1.648 ++ this library does not by itself cause the resulting executable
1.649 ++ to be covered by the GNU General Public License.
1.650 ++ This exception does not however invalidate any other reasons why
1.651 ++ the executable file might be covered by the GNU General Public License. */
1.652 ++
1.653 ++/* This implements IEEE 754 format arithmetic, but does not provide a
1.654 ++ mechanism for setting the rounding mode, or for generating or handling
1.655 ++ exceptions.
1.656 ++
1.657 ++ The original code by Steve Chamberlain, hacked by Mark Eichin and Jim
1.658 ++ Wilson, all of Cygnus Support. */
1.659 ++
1.660 ++/* The intended way to use this file is to make two copies, add `#define FLOAT'
1.661 ++ to one copy, then compile both copies and add them to libgcc.a. */
1.662 ++
1.663 ++#include "tconfig.h"
1.664 ++#include "coretypes.h"
1.665 ++#include "tm.h"
1.666 ++#include "config/fp-bit.h"
1.667 ++
1.668 ++/* The following macros can be defined to change the behavior of this file:
1.669 ++ FLOAT: Implement a `float', aka SFmode, fp library. If this is not
1.670 ++ defined, then this file implements a `double', aka DFmode, fp library.
1.671 ++ FLOAT_ONLY: Used with FLOAT, to implement a `float' only library, i.e.
1.672 ++ don't include float->double conversion which requires the double library.
1.673 ++ This is useful only for machines which can't support doubles, e.g. some
1.674 ++ 8-bit processors.
1.675 ++ CMPtype: Specify the type that floating point compares should return.
1.676 ++ This defaults to SItype, aka int.
1.677 ++ US_SOFTWARE_GOFAST: This makes all entry points use the same names as the
1.678 ++ US Software goFast library.
1.679 ++ _DEBUG_BITFLOAT: This makes debugging the code a little easier, by adding
1.680 ++ two integers to the FLO_union_type.
1.681 ++ NO_DENORMALS: Disable handling of denormals.
1.682 ++ NO_NANS: Disable nan and infinity handling
1.683 ++ SMALL_MACHINE: Useful when operations on QIs and HIs are faster
1.684 ++ than on an SI */
1.685 ++
1.686 ++/* We don't currently support extended floats (long doubles) on machines
1.687 ++ without hardware to deal with them.
1.688 ++
1.689 ++ These stubs are just to keep the linker from complaining about unresolved
1.690 ++ references which can be pulled in from libio & libstdc++, even if the
1.691 ++ user isn't using long doubles. However, they may generate an unresolved
1.692 ++ external to abort if abort is not used by the function, and the stubs
1.693 ++ are referenced from within libc, since libgcc goes before and after the
1.694 ++ system library. */
1.695 ++
1.696 ++#ifdef DECLARE_LIBRARY_RENAMES
1.697 ++ DECLARE_LIBRARY_RENAMES
1.698 ++#endif
1.699 ++
1.700 ++#ifdef EXTENDED_FLOAT_STUBS
1.701 ++extern void abort (void);
1.702 ++void __extendsfxf2 (void) { abort(); }
1.703 ++void __extenddfxf2 (void) { abort(); }
1.704 ++void __truncxfdf2 (void) { abort(); }
1.705 ++void __truncxfsf2 (void) { abort(); }
1.706 ++void __fixxfsi (void) { abort(); }
1.707 ++void __floatsixf (void) { abort(); }
1.708 ++void __addxf3 (void) { abort(); }
1.709 ++void __subxf3 (void) { abort(); }
1.710 ++void __mulxf3 (void) { abort(); }
1.711 ++void __divxf3 (void) { abort(); }
1.712 ++void __negxf2 (void) { abort(); }
1.713 ++void __eqxf2 (void) { abort(); }
1.714 ++void __nexf2 (void) { abort(); }
1.715 ++void __gtxf2 (void) { abort(); }
1.716 ++void __gexf2 (void) { abort(); }
1.717 ++void __lexf2 (void) { abort(); }
1.718 ++void __ltxf2 (void) { abort(); }
1.719 ++
1.720 ++void __extendsftf2 (void) { abort(); }
1.721 ++void __extenddftf2 (void) { abort(); }
1.722 ++void __trunctfdf2 (void) { abort(); }
1.723 ++void __trunctfsf2 (void) { abort(); }
1.724 ++void __fixtfsi (void) { abort(); }
1.725 ++void __floatsitf (void) { abort(); }
1.726 ++void __addtf3 (void) { abort(); }
1.727 ++void __subtf3 (void) { abort(); }
1.728 ++void __multf3 (void) { abort(); }
1.729 ++void __divtf3 (void) { abort(); }
1.730 ++void __negtf2 (void) { abort(); }
1.731 ++void __eqtf2 (void) { abort(); }
1.732 ++void __netf2 (void) { abort(); }
1.733 ++void __gttf2 (void) { abort(); }
1.734 ++void __getf2 (void) { abort(); }
1.735 ++void __letf2 (void) { abort(); }
1.736 ++void __lttf2 (void) { abort(); }
1.737 ++#else /* !EXTENDED_FLOAT_STUBS, rest of file */
1.738 ++
1.739 ++/* IEEE "special" number predicates */
1.740 ++
1.741 ++#ifdef NO_NANS
1.742 ++
1.743 ++#define nan() 0
1.744 ++#define isnan(x) 0
1.745 ++#define isinf(x) 0
1.746 ++#else
1.747 ++
1.748 ++#if defined L_thenan_sf
1.749 ++const fp_number_type __thenan_sf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
1.750 ++#elif defined L_thenan_df
1.751 ++const fp_number_type __thenan_df = { CLASS_SNAN, 0, 0, {(fractype) 0} };
1.752 ++#elif defined L_thenan_tf
1.753 ++const fp_number_type __thenan_tf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
1.754 ++#elif defined TFLOAT
1.755 ++extern const fp_number_type __thenan_tf;
1.756 ++#elif defined FLOAT
1.757 ++extern const fp_number_type __thenan_sf;
1.758 ++#else
1.759 ++extern const fp_number_type __thenan_df;
1.760 ++#endif
1.761 ++
1.762 ++INLINE
1.763 ++static fp_number_type *
1.764 ++nan (void)
1.765 ++{
1.766 ++ /* Discard the const qualifier... */
1.767 ++#ifdef TFLOAT
1.768 ++ return (fp_number_type *) (& __thenan_tf);
1.769 ++#elif defined FLOAT
1.770 ++ return (fp_number_type *) (& __thenan_sf);
1.771 ++#else
1.772 ++ return (fp_number_type *) (& __thenan_df);
1.773 ++#endif
1.774 ++}
1.775 ++
1.776 ++INLINE
1.777 ++static int
1.778 ++isnan ( fp_number_type * x)
1.779 ++{
1.780 ++ return x->class == CLASS_SNAN || x->class == CLASS_QNAN;
1.781 ++}
1.782 ++
1.783 ++INLINE
1.784 ++static int
1.785 ++isinf ( fp_number_type * x)
1.786 ++{
1.787 ++ return x->class == CLASS_INFINITY;
1.788 ++}
1.789 ++
1.790 ++#endif /* NO_NANS */
1.791 ++
1.792 ++INLINE
1.793 ++static int
1.794 ++iszero ( fp_number_type * x)
1.795 ++{
1.796 ++ return x->class == CLASS_ZERO;
1.797 ++}
1.798 ++
1.799 ++INLINE
1.800 ++static void
1.801 ++flip_sign ( fp_number_type * x)
1.802 ++{
1.803 ++ x->sign = !x->sign;
1.804 ++}
1.805 ++
1.806 ++extern FLO_type pack_d ( fp_number_type * );
1.807 ++
1.808 ++#if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf)
1.809 ++FLO_type
1.810 ++pack_d ( fp_number_type * src)
1.811 ++{
1.812 ++ FLO_union_type dst;
1.813 ++ fractype fraction = src->fraction.ll; /* wasn't unsigned before? */
1.814 ++ int sign = src->sign;
1.815 ++ int exp = 0;
1.816 ++
1.817 ++ if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && (isnan (src) || isinf (src)))
1.818 ++ {
1.819 ++ /* We can't represent these values accurately. By using the
1.820 ++ largest possible magnitude, we guarantee that the conversion
1.821 ++ of infinity is at least as big as any finite number. */
1.822 ++ exp = EXPMAX;
1.823 ++ fraction = ((fractype) 1 << FRACBITS) - 1;
1.824 ++ }
1.825 ++ else if (isnan (src))
1.826 ++ {
1.827 ++ exp = EXPMAX;
1.828 ++ if (src->class == CLASS_QNAN || 1)
1.829 ++ {
1.830 ++#ifdef QUIET_NAN_NEGATED
1.831 ++ fraction |= QUIET_NAN - 1;
1.832 ++#else
1.833 ++ fraction |= QUIET_NAN;
1.834 ++#endif
1.835 ++ }
1.836 ++ }
1.837 ++ else if (isinf (src))
1.838 ++ {
1.839 ++ exp = EXPMAX;
1.840 ++ fraction = 0;
1.841 ++ }
1.842 ++ else if (iszero (src))
1.843 ++ {
1.844 ++ exp = 0;
1.845 ++ fraction = 0;
1.846 ++ }
1.847 ++ else if (fraction == 0)
1.848 ++ {
1.849 ++ exp = 0;
1.850 ++ }
1.851 ++ else
1.852 ++ {
1.853 ++ if (src->normal_exp < NORMAL_EXPMIN)
1.854 ++ {
1.855 ++#ifdef NO_DENORMALS
1.856 ++ /* Go straight to a zero representation if denormals are not
1.857 ++ supported. The denormal handling would be harmless but
1.858 ++ isn't unnecessary. */
1.859 ++ exp = 0;
1.860 ++ fraction = 0;
1.861 ++#else /* NO_DENORMALS */
1.862 ++ /* This number's exponent is too low to fit into the bits
1.863 ++ available in the number, so we'll store 0 in the exponent and
1.864 ++ shift the fraction to the right to make up for it. */
1.865 ++
1.866 ++ int shift = NORMAL_EXPMIN - src->normal_exp;
1.867 ++
1.868 ++ exp = 0;
1.869 ++
1.870 ++ if (shift > FRAC_NBITS - NGARDS)
1.871 ++ {
1.872 ++ /* No point shifting, since it's more that 64 out. */
1.873 ++ fraction = 0;
1.874 ++ }
1.875 ++ else
1.876 ++ {
1.877 ++ int lowbit = (fraction & (((fractype)1 << shift) - 1)) ? 1 : 0;
1.878 ++ fraction = (fraction >> shift) | lowbit;
1.879 ++ }
1.880 ++ if ((fraction & GARDMASK) == GARDMSB)
1.881 ++ {
1.882 ++ if ((fraction & (1 << NGARDS)))
1.883 ++ fraction += GARDROUND + 1;
1.884 ++ }
1.885 ++ else
1.886 ++ {
1.887 ++ /* Add to the guards to round up. */
1.888 ++ fraction += GARDROUND;
1.889 ++ }
1.890 ++ /* Perhaps the rounding means we now need to change the
1.891 ++ exponent, because the fraction is no longer denormal. */
1.892 ++ if (fraction >= IMPLICIT_1)
1.893 ++ {
1.894 ++ exp += 1;
1.895 ++ }
1.896 ++ fraction >>= NGARDS;
1.897 ++#endif /* NO_DENORMALS */
1.898 ++ }
1.899 ++ else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS)
1.900 ++ && src->normal_exp > EXPBIAS)
1.901 ++ {
1.902 ++ exp = EXPMAX;
1.903 ++ fraction = 0;
1.904 ++ }
1.905 ++ else
1.906 ++ {
1.907 ++ exp = src->normal_exp + EXPBIAS;
1.908 ++ if (!ROUND_TOWARDS_ZERO)
1.909 ++ {
1.910 ++ /* IF the gard bits are the all zero, but the first, then we're
1.911 ++ half way between two numbers, choose the one which makes the
1.912 ++ lsb of the answer 0. */
1.913 ++ if ((fraction & GARDMASK) == GARDMSB)
1.914 ++ {
1.915 ++ if (fraction & (1 << NGARDS))
1.916 ++ fraction += GARDROUND + 1;
1.917 ++ }
1.918 ++ else
1.919 ++ {
1.920 ++ /* Add a one to the guards to round up */
1.921 ++ fraction += GARDROUND;
1.922 ++ }
1.923 ++ if (fraction >= IMPLICIT_2)
1.924 ++ {
1.925 ++ fraction >>= 1;
1.926 ++ exp += 1;
1.927 ++ }
1.928 ++ }
1.929 ++ fraction >>= NGARDS;
1.930 ++
1.931 ++ if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp > EXPMAX)
1.932 ++ {
1.933 ++ /* Saturate on overflow. */
1.934 ++ exp = EXPMAX;
1.935 ++ fraction = ((fractype) 1 << FRACBITS) - 1;
1.936 ++ }
1.937 ++ }
1.938 ++ }
1.939 ++
1.940 ++ /* We previously used bitfields to store the number, but this doesn't
1.941 ++ handle little/big endian systems conveniently, so use shifts and
1.942 ++ masks */
1.943 ++#ifdef FLOAT_BIT_ORDER_MISMATCH
1.944 ++ dst.bits.fraction = fraction;
1.945 ++ dst.bits.exp = exp;
1.946 ++ dst.bits.sign = sign;
1.947 ++#else
1.948 ++# if defined TFLOAT && defined HALFFRACBITS
1.949 ++ {
1.950 ++ halffractype high, low, unity;
1.951 ++ int lowsign, lowexp;
1.952 ++
1.953 ++ unity = (halffractype) 1 << HALFFRACBITS;
1.954 ++
1.955 ++ /* Set HIGH to the high double's significand, masking out the implicit 1.
1.956 ++ Set LOW to the low double's full significand. */
1.957 ++ high = (fraction >> (FRACBITS - HALFFRACBITS)) & (unity - 1);
1.958 ++ low = fraction & (unity * 2 - 1);
1.959 ++
1.960 ++ /* Get the initial sign and exponent of the low double. */
1.961 ++ lowexp = exp - HALFFRACBITS - 1;
1.962 ++ lowsign = sign;
1.963 ++
1.964 ++ /* HIGH should be rounded like a normal double, making |LOW| <=
1.965 ++ 0.5 ULP of HIGH. Assume round-to-nearest. */
1.966 ++ if (exp < EXPMAX)
1.967 ++ if (low > unity || (low == unity && (high & 1) == 1))
1.968 ++ {
1.969 ++ /* Round HIGH up and adjust LOW to match. */
1.970 ++ high++;
1.971 ++ if (high == unity)
1.972 ++ {
1.973 ++ /* May make it infinite, but that's OK. */
1.974 ++ high = 0;
1.975 ++ exp++;
1.976 ++ }
1.977 ++ low = unity * 2 - low;
1.978 ++ lowsign ^= 1;
1.979 ++ }
1.980 ++
1.981 ++ high |= (halffractype) exp << HALFFRACBITS;
1.982 ++ high |= (halffractype) sign << (HALFFRACBITS + EXPBITS);
1.983 ++
1.984 ++ if (exp == EXPMAX || exp == 0 || low == 0)
1.985 ++ low = 0;
1.986 ++ else
1.987 ++ {
1.988 ++ while (lowexp > 0 && low < unity)
1.989 ++ {
1.990 ++ low <<= 1;
1.991 ++ lowexp--;
1.992 ++ }
1.993 ++
1.994 ++ if (lowexp <= 0)
1.995 ++ {
1.996 ++ halffractype roundmsb, round;
1.997 ++ int shift;
1.998 ++
1.999 ++ shift = 1 - lowexp;
1.1000 ++ roundmsb = (1 << (shift - 1));
1.1001 ++ round = low & ((roundmsb << 1) - 1);
1.1002 ++
1.1003 ++ low >>= shift;
1.1004 ++ lowexp = 0;
1.1005 ++
1.1006 ++ if (round > roundmsb || (round == roundmsb && (low & 1) == 1))
1.1007 ++ {
1.1008 ++ low++;
1.1009 ++ if (low == unity)
1.1010 ++ /* LOW rounds up to the smallest normal number. */
1.1011 ++ lowexp++;
1.1012 ++ }
1.1013 ++ }
1.1014 ++
1.1015 ++ low &= unity - 1;
1.1016 ++ low |= (halffractype) lowexp << HALFFRACBITS;
1.1017 ++ low |= (halffractype) lowsign << (HALFFRACBITS + EXPBITS);
1.1018 ++ }
1.1019 ++ dst.value_raw = ((fractype) high << HALFSHIFT) | low;
1.1020 ++ }
1.1021 ++# else
1.1022 ++ dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1);
1.1023 ++ dst.value_raw |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << FRACBITS;
1.1024 ++ dst.value_raw |= ((fractype) (sign & 1)) << (FRACBITS | EXPBITS);
1.1025 ++# endif
1.1026 ++#endif
1.1027 ++
1.1028 ++#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
1.1029 ++#ifdef TFLOAT
1.1030 ++ {
1.1031 ++ qrtrfractype tmp1 = dst.words[0];
1.1032 ++ qrtrfractype tmp2 = dst.words[1];
1.1033 ++ dst.words[0] = dst.words[3];
1.1034 ++ dst.words[1] = dst.words[2];
1.1035 ++ dst.words[2] = tmp2;
1.1036 ++ dst.words[3] = tmp1;
1.1037 ++ }
1.1038 ++#else
1.1039 ++ {
1.1040 ++ halffractype tmp = dst.words[0];
1.1041 ++ dst.words[0] = dst.words[1];
1.1042 ++ dst.words[1] = tmp;
1.1043 ++ }
1.1044 ++#endif
1.1045 ++#endif
1.1046 ++
1.1047 ++ return dst.value;
1.1048 ++}
1.1049 ++#endif
1.1050 ++
1.1051 ++#if defined(L_unpack_df) || defined(L_unpack_sf) || defined(L_unpack_tf)
1.1052 ++void
1.1053 ++unpack_d (FLO_union_type * src, fp_number_type * dst)
1.1054 ++{
1.1055 ++ /* We previously used bitfields to store the number, but this doesn't
1.1056 ++ handle little/big endian systems conveniently, so use shifts and
1.1057 ++ masks */
1.1058 ++ fractype fraction;
1.1059 ++ int exp;
1.1060 ++ int sign;
1.1061 ++
1.1062 ++#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
1.1063 ++ FLO_union_type swapped;
1.1064 ++
1.1065 ++#ifdef TFLOAT
1.1066 ++ swapped.words[0] = src->words[3];
1.1067 ++ swapped.words[1] = src->words[2];
1.1068 ++ swapped.words[2] = src->words[1];
1.1069 ++ swapped.words[3] = src->words[0];
1.1070 ++#else
1.1071 ++ swapped.words[0] = src->words[1];
1.1072 ++ swapped.words[1] = src->words[0];
1.1073 ++#endif
1.1074 ++ src = &swapped;
1.1075 ++#endif
1.1076 ++
1.1077 ++#ifdef FLOAT_BIT_ORDER_MISMATCH
1.1078 ++ fraction = src->bits.fraction;
1.1079 ++ exp = src->bits.exp;
1.1080 ++ sign = src->bits.sign;
1.1081 ++#else
1.1082 ++# if defined TFLOAT && defined HALFFRACBITS
1.1083 ++ {
1.1084 ++ halffractype high, low;
1.1085 ++
1.1086 ++ high = src->value_raw >> HALFSHIFT;
1.1087 ++ low = src->value_raw & (((fractype)1 << HALFSHIFT) - 1);
1.1088 ++
1.1089 ++ fraction = high & ((((fractype)1) << HALFFRACBITS) - 1);
1.1090 ++ fraction <<= FRACBITS - HALFFRACBITS;
1.1091 ++ exp = ((int)(high >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
1.1092 ++ sign = ((int)(high >> (((HALFFRACBITS + EXPBITS))))) & 1;
1.1093 ++
1.1094 ++ if (exp != EXPMAX && exp != 0 && low != 0)
1.1095 ++ {
1.1096 ++ int lowexp = ((int)(low >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
1.1097 ++ int lowsign = ((int)(low >> (((HALFFRACBITS + EXPBITS))))) & 1;
1.1098 ++ int shift;
1.1099 ++ fractype xlow;
1.1100 ++
1.1101 ++ xlow = low & ((((fractype)1) << HALFFRACBITS) - 1);
1.1102 ++ if (lowexp)
1.1103 ++ xlow |= (((halffractype)1) << HALFFRACBITS);
1.1104 ++ else
1.1105 ++ lowexp = 1;
1.1106 ++ shift = (FRACBITS - HALFFRACBITS) - (exp - lowexp);
1.1107 ++ if (shift > 0)
1.1108 ++ xlow <<= shift;
1.1109 ++ else if (shift < 0)
1.1110 ++ xlow >>= -shift;
1.1111 ++ if (sign == lowsign)
1.1112 ++ fraction += xlow;
1.1113 ++ else if (fraction >= xlow)
1.1114 ++ fraction -= xlow;
1.1115 ++ else
1.1116 ++ {
1.1117 ++ /* The high part is a power of two but the full number is lower.
1.1118 ++ This code will leave the implicit 1 in FRACTION, but we'd
1.1119 ++ have added that below anyway. */
1.1120 ++ fraction = (((fractype) 1 << FRACBITS) - xlow) << 1;
1.1121 ++ exp--;
1.1122 ++ }
1.1123 ++ }
1.1124 ++ }
1.1125 ++# else
1.1126 ++ fraction = src->value_raw & ((((fractype)1) << FRACBITS) - 1);
1.1127 ++ exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1);
1.1128 ++ sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1;
1.1129 ++# endif
1.1130 ++#endif
1.1131 ++
1.1132 ++ dst->sign = sign;
1.1133 ++ if (exp == 0)
1.1134 ++ {
1.1135 ++ /* Hmm. Looks like 0 */
1.1136 ++ if (fraction == 0
1.1137 ++#ifdef NO_DENORMALS
1.1138 ++ || 1
1.1139 ++#endif
1.1140 ++ )
1.1141 ++ {
1.1142 ++ /* tastes like zero */
1.1143 ++ dst->class = CLASS_ZERO;
1.1144 ++ }
1.1145 ++ else
1.1146 ++ {
1.1147 ++ /* Zero exponent with nonzero fraction - it's denormalized,
1.1148 ++ so there isn't a leading implicit one - we'll shift it so
1.1149 ++ it gets one. */
1.1150 ++ dst->normal_exp = exp - EXPBIAS + 1;
1.1151 ++ fraction <<= NGARDS;
1.1152 ++
1.1153 ++ dst->class = CLASS_NUMBER;
1.1154 ++#if 1
1.1155 ++ while (fraction < IMPLICIT_1)
1.1156 ++ {
1.1157 ++ fraction <<= 1;
1.1158 ++ dst->normal_exp--;
1.1159 ++ }
1.1160 ++#endif
1.1161 ++ dst->fraction.ll = fraction;
1.1162 ++ }
1.1163 ++ }
1.1164 ++ else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp == EXPMAX)
1.1165 ++ {
1.1166 ++ /* Huge exponent*/
1.1167 ++ if (fraction == 0)
1.1168 ++ {
1.1169 ++ /* Attached to a zero fraction - means infinity */
1.1170 ++ dst->class = CLASS_INFINITY;
1.1171 ++ }
1.1172 ++ else
1.1173 ++ {
1.1174 ++ /* Nonzero fraction, means nan */
1.1175 ++#ifdef QUIET_NAN_NEGATED
1.1176 ++ if ((fraction & QUIET_NAN) == 0)
1.1177 ++#else
1.1178 ++ if (fraction & QUIET_NAN)
1.1179 ++#endif
1.1180 ++ {
1.1181 ++ dst->class = CLASS_QNAN;
1.1182 ++ }
1.1183 ++ else
1.1184 ++ {
1.1185 ++ dst->class = CLASS_SNAN;
1.1186 ++ }
1.1187 ++ /* Keep the fraction part as the nan number */
1.1188 ++ dst->fraction.ll = fraction;
1.1189 ++ }
1.1190 ++ }
1.1191 ++ else
1.1192 ++ {
1.1193 ++ /* Nothing strange about this number */
1.1194 ++ dst->normal_exp = exp - EXPBIAS;
1.1195 ++ dst->class = CLASS_NUMBER;
1.1196 ++ dst->fraction.ll = (fraction << NGARDS) | IMPLICIT_1;
1.1197 ++ }
1.1198 ++}
1.1199 ++#endif /* L_unpack_df || L_unpack_sf */
1.1200 ++
1.1201 ++#if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf)
1.1202 ++static fp_number_type *
1.1203 ++_fpadd_parts (fp_number_type * a,
1.1204 ++ fp_number_type * b,
1.1205 ++ fp_number_type * tmp)
1.1206 ++{
1.1207 ++ intfrac tfraction;
1.1208 ++
1.1209 ++ /* Put commonly used fields in local variables. */
1.1210 ++ int a_normal_exp;
1.1211 ++ int b_normal_exp;
1.1212 ++ fractype a_fraction;
1.1213 ++ fractype b_fraction;
1.1214 ++
1.1215 ++ if (isnan (a))
1.1216 ++ {
1.1217 ++ return a;
1.1218 ++ }
1.1219 ++ if (isnan (b))
1.1220 ++ {
1.1221 ++ return b;
1.1222 ++ }
1.1223 ++ if (isinf (a))
1.1224 ++ {
1.1225 ++ /* Adding infinities with opposite signs yields a NaN. */
1.1226 ++ if (isinf (b) && a->sign != b->sign)
1.1227 ++ return nan ();
1.1228 ++ return a;
1.1229 ++ }
1.1230 ++ if (isinf (b))
1.1231 ++ {
1.1232 ++ return b;
1.1233 ++ }
1.1234 ++ if (iszero (b))
1.1235 ++ {
1.1236 ++ if (iszero (a))
1.1237 ++ {
1.1238 ++ *tmp = *a;
1.1239 ++ tmp->sign = a->sign & b->sign;
1.1240 ++ return tmp;
1.1241 ++ }
1.1242 ++ return a;
1.1243 ++ }
1.1244 ++ if (iszero (a))
1.1245 ++ {
1.1246 ++ return b;
1.1247 ++ }
1.1248 ++
1.1249 ++ /* Got two numbers. shift the smaller and increment the exponent till
1.1250 ++ they're the same */
1.1251 ++ {
1.1252 ++ int diff;
1.1253 ++
1.1254 ++ a_normal_exp = a->normal_exp;
1.1255 ++ b_normal_exp = b->normal_exp;
1.1256 ++ a_fraction = a->fraction.ll;
1.1257 ++ b_fraction = b->fraction.ll;
1.1258 ++
1.1259 ++ diff = a_normal_exp - b_normal_exp;
1.1260 ++
1.1261 ++ if (diff < 0)
1.1262 ++ diff = -diff;
1.1263 ++ if (diff < FRAC_NBITS)
1.1264 ++ {
1.1265 ++ /* ??? This does shifts one bit at a time. Optimize. */
1.1266 ++ while (a_normal_exp > b_normal_exp)
1.1267 ++ {
1.1268 ++ b_normal_exp++;
1.1269 ++ LSHIFT (b_fraction);
1.1270 ++ }
1.1271 ++ while (b_normal_exp > a_normal_exp)
1.1272 ++ {
1.1273 ++ a_normal_exp++;
1.1274 ++ LSHIFT (a_fraction);
1.1275 ++ }
1.1276 ++ }
1.1277 ++ else
1.1278 ++ {
1.1279 ++ /* Somethings's up.. choose the biggest */
1.1280 ++ if (a_normal_exp > b_normal_exp)
1.1281 ++ {
1.1282 ++ b_normal_exp = a_normal_exp;
1.1283 ++ b_fraction = 0;
1.1284 ++ }
1.1285 ++ else
1.1286 ++ {
1.1287 ++ a_normal_exp = b_normal_exp;
1.1288 ++ a_fraction = 0;
1.1289 ++ }
1.1290 ++ }
1.1291 ++ }
1.1292 ++
1.1293 ++ if (a->sign != b->sign)
1.1294 ++ {
1.1295 ++ if (a->sign)
1.1296 ++ {
1.1297 ++ tfraction = -a_fraction + b_fraction;
1.1298 ++ }
1.1299 ++ else
1.1300 ++ {
1.1301 ++ tfraction = a_fraction - b_fraction;
1.1302 ++ }
1.1303 ++ if (tfraction >= 0)
1.1304 ++ {
1.1305 ++ tmp->sign = 0;
1.1306 ++ tmp->normal_exp = a_normal_exp;
1.1307 ++ tmp->fraction.ll = tfraction;
1.1308 ++ }
1.1309 ++ else
1.1310 ++ {
1.1311 ++ tmp->sign = 1;
1.1312 ++ tmp->normal_exp = a_normal_exp;
1.1313 ++ tmp->fraction.ll = -tfraction;
1.1314 ++ }
1.1315 ++ /* and renormalize it */
1.1316 ++
1.1317 ++ while (tmp->fraction.ll < IMPLICIT_1 && tmp->fraction.ll)
1.1318 ++ {
1.1319 ++ tmp->fraction.ll <<= 1;
1.1320 ++ tmp->normal_exp--;
1.1321 ++ }
1.1322 ++ }
1.1323 ++ else
1.1324 ++ {
1.1325 ++ tmp->sign = a->sign;
1.1326 ++ tmp->normal_exp = a_normal_exp;
1.1327 ++ tmp->fraction.ll = a_fraction + b_fraction;
1.1328 ++ }
1.1329 ++ tmp->class = CLASS_NUMBER;
1.1330 ++ /* Now the fraction is added, we have to shift down to renormalize the
1.1331 ++ number */
1.1332 ++
1.1333 ++ if (tmp->fraction.ll >= IMPLICIT_2)
1.1334 ++ {
1.1335 ++ LSHIFT (tmp->fraction.ll);
1.1336 ++ tmp->normal_exp++;
1.1337 ++ }
1.1338 ++ return tmp;
1.1339 ++
1.1340 ++}
1.1341 ++
1.1342 ++FLO_type
1.1343 ++add (FLO_type arg_a, FLO_type arg_b)
1.1344 ++{
1.1345 ++ fp_number_type a;
1.1346 ++ fp_number_type b;
1.1347 ++ fp_number_type tmp;
1.1348 ++ fp_number_type *res;
1.1349 ++ FLO_union_type au, bu;
1.1350 ++
1.1351 ++ au.value = arg_a;
1.1352 ++ bu.value = arg_b;
1.1353 ++
1.1354 ++ unpack_d (&au, &a);
1.1355 ++ unpack_d (&bu, &b);
1.1356 ++
1.1357 ++ res = _fpadd_parts (&a, &b, &tmp);
1.1358 ++
1.1359 ++ return pack_d (res);
1.1360 ++}
1.1361 ++
1.1362 ++FLO_type
1.1363 ++sub (FLO_type arg_a, FLO_type arg_b)
1.1364 ++{
1.1365 ++ fp_number_type a;
1.1366 ++ fp_number_type b;
1.1367 ++ fp_number_type tmp;
1.1368 ++ fp_number_type *res;
1.1369 ++ FLO_union_type au, bu;
1.1370 ++
1.1371 ++ au.value = arg_a;
1.1372 ++ bu.value = arg_b;
1.1373 ++
1.1374 ++ unpack_d (&au, &a);
1.1375 ++ unpack_d (&bu, &b);
1.1376 ++
1.1377 ++ b.sign ^= 1;
1.1378 ++
1.1379 ++ res = _fpadd_parts (&a, &b, &tmp);
1.1380 ++
1.1381 ++ return pack_d (res);
1.1382 ++}
1.1383 ++#endif /* L_addsub_sf || L_addsub_df */
1.1384 ++
1.1385 ++#if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf)
1.1386 ++static inline __attribute__ ((__always_inline__)) fp_number_type *
1.1387 ++_fpmul_parts ( fp_number_type * a,
1.1388 ++ fp_number_type * b,
1.1389 ++ fp_number_type * tmp)
1.1390 ++{
1.1391 ++ fractype low = 0;
1.1392 ++ fractype high = 0;
1.1393 ++
1.1394 ++ if (isnan (a))
1.1395 ++ {
1.1396 ++ a->sign = a->sign != b->sign;
1.1397 ++ return a;
1.1398 ++ }
1.1399 ++ if (isnan (b))
1.1400 ++ {
1.1401 ++ b->sign = a->sign != b->sign;
1.1402 ++ return b;
1.1403 ++ }
1.1404 ++ if (isinf (a))
1.1405 ++ {
1.1406 ++ if (iszero (b))
1.1407 ++ return nan ();
1.1408 ++ a->sign = a->sign != b->sign;
1.1409 ++ return a;
1.1410 ++ }
1.1411 ++ if (isinf (b))
1.1412 ++ {
1.1413 ++ if (iszero (a))
1.1414 ++ {
1.1415 ++ return nan ();
1.1416 ++ }
1.1417 ++ b->sign = a->sign != b->sign;
1.1418 ++ return b;
1.1419 ++ }
1.1420 ++ if (iszero (a))
1.1421 ++ {
1.1422 ++ a->sign = a->sign != b->sign;
1.1423 ++ return a;
1.1424 ++ }
1.1425 ++ if (iszero (b))
1.1426 ++ {
1.1427 ++ b->sign = a->sign != b->sign;
1.1428 ++ return b;
1.1429 ++ }
1.1430 ++
1.1431 ++ /* Calculate the mantissa by multiplying both numbers to get a
1.1432 ++ twice-as-wide number. */
1.1433 ++ {
1.1434 ++#if defined(NO_DI_MODE) || defined(TFLOAT)
1.1435 ++ {
1.1436 ++ fractype x = a->fraction.ll;
1.1437 ++ fractype ylow = b->fraction.ll;
1.1438 ++ fractype yhigh = 0;
1.1439 ++ int bit;
1.1440 ++
1.1441 ++ /* ??? This does multiplies one bit at a time. Optimize. */
1.1442 ++ for (bit = 0; bit < FRAC_NBITS; bit++)
1.1443 ++ {
1.1444 ++ int carry;
1.1445 ++
1.1446 ++ if (x & 1)
1.1447 ++ {
1.1448 ++ carry = (low += ylow) < ylow;
1.1449 ++ high += yhigh + carry;
1.1450 ++ }
1.1451 ++ yhigh <<= 1;
1.1452 ++ if (ylow & FRACHIGH)
1.1453 ++ {
1.1454 ++ yhigh |= 1;
1.1455 ++ }
1.1456 ++ ylow <<= 1;
1.1457 ++ x >>= 1;
1.1458 ++ }
1.1459 ++ }
1.1460 ++#elif defined(FLOAT)
1.1461 ++ /* Multiplying two USIs to get a UDI, we're safe. */
1.1462 ++ {
1.1463 ++ UDItype answer = (UDItype)a->fraction.ll * (UDItype)b->fraction.ll;
1.1464 ++
1.1465 ++ high = answer >> BITS_PER_SI;
1.1466 ++ low = answer;
1.1467 ++ }
1.1468 ++#else
1.1469 ++ /* fractype is DImode, but we need the result to be twice as wide.
1.1470 ++ Assuming a widening multiply from DImode to TImode is not
1.1471 ++ available, build one by hand. */
1.1472 ++ {
1.1473 ++ USItype nl = a->fraction.ll;
1.1474 ++ USItype nh = a->fraction.ll >> BITS_PER_SI;
1.1475 ++ USItype ml = b->fraction.ll;
1.1476 ++ USItype mh = b->fraction.ll >> BITS_PER_SI;
1.1477 ++ UDItype pp_ll = (UDItype) ml * nl;
1.1478 ++ UDItype pp_hl = (UDItype) mh * nl;
1.1479 ++ UDItype pp_lh = (UDItype) ml * nh;
1.1480 ++ UDItype pp_hh = (UDItype) mh * nh;
1.1481 ++ UDItype res2 = 0;
1.1482 ++ UDItype res0 = 0;
1.1483 ++ UDItype ps_hh__ = pp_hl + pp_lh;
1.1484 ++ if (ps_hh__ < pp_hl)
1.1485 ++ res2 += (UDItype)1 << BITS_PER_SI;
1.1486 ++ pp_hl = (UDItype)(USItype)ps_hh__ << BITS_PER_SI;
1.1487 ++ res0 = pp_ll + pp_hl;
1.1488 ++ if (res0 < pp_ll)
1.1489 ++ res2++;
1.1490 ++ res2 += (ps_hh__ >> BITS_PER_SI) + pp_hh;
1.1491 ++ high = res2;
1.1492 ++ low = res0;
1.1493 ++ }
1.1494 ++#endif
1.1495 ++ }
1.1496 ++
1.1497 ++ tmp->normal_exp = a->normal_exp + b->normal_exp
1.1498 ++ + FRAC_NBITS - (FRACBITS + NGARDS);
1.1499 ++ tmp->sign = a->sign != b->sign;
1.1500 ++ while (high >= IMPLICIT_2)
1.1501 ++ {
1.1502 ++ tmp->normal_exp++;
1.1503 ++ if (high & 1)
1.1504 ++ {
1.1505 ++ low >>= 1;
1.1506 ++ low |= FRACHIGH;
1.1507 ++ }
1.1508 ++ high >>= 1;
1.1509 ++ }
1.1510 ++ while (high < IMPLICIT_1)
1.1511 ++ {
1.1512 ++ tmp->normal_exp--;
1.1513 ++
1.1514 ++ high <<= 1;
1.1515 ++ if (low & FRACHIGH)
1.1516 ++ high |= 1;
1.1517 ++ low <<= 1;
1.1518 ++ }
1.1519 ++ /* rounding is tricky. if we only round if it won't make us round later. */
1.1520 ++#if 0
1.1521 ++ if (low & FRACHIGH2)
1.1522 ++ {
1.1523 ++ if (((high & GARDMASK) != GARDMSB)
1.1524 ++ && (((high + 1) & GARDMASK) == GARDMSB))
1.1525 ++ {
1.1526 ++ /* don't round, it gets done again later. */
1.1527 ++ }
1.1528 ++ else
1.1529 ++ {
1.1530 ++ high++;
1.1531 ++ }
1.1532 ++ }
1.1533 ++#endif
1.1534 ++ if (!ROUND_TOWARDS_ZERO && (high & GARDMASK) == GARDMSB)
1.1535 ++ {
1.1536 ++ if (high & (1 << NGARDS))
1.1537 ++ {
1.1538 ++ /* half way, so round to even */
1.1539 ++ high += GARDROUND + 1;
1.1540 ++ }
1.1541 ++ else if (low)
1.1542 ++ {
1.1543 ++ /* but we really weren't half way */
1.1544 ++ high += GARDROUND + 1;
1.1545 ++ }
1.1546 ++ }
1.1547 ++ tmp->fraction.ll = high;
1.1548 ++ tmp->class = CLASS_NUMBER;
1.1549 ++ return tmp;
1.1550 ++}
1.1551 ++
1.1552 ++FLO_type
1.1553 ++multiply (FLO_type arg_a, FLO_type arg_b)
1.1554 ++{
1.1555 ++ fp_number_type a;
1.1556 ++ fp_number_type b;
1.1557 ++ fp_number_type tmp;
1.1558 ++ fp_number_type *res;
1.1559 ++ FLO_union_type au, bu;
1.1560 ++
1.1561 ++ au.value = arg_a;
1.1562 ++ bu.value = arg_b;
1.1563 ++
1.1564 ++ unpack_d (&au, &a);
1.1565 ++ unpack_d (&bu, &b);
1.1566 ++
1.1567 ++ res = _fpmul_parts (&a, &b, &tmp);
1.1568 ++
1.1569 ++ return pack_d (res);
1.1570 ++}
1.1571 ++#endif /* L_mul_sf || L_mul_df */
1.1572 ++
1.1573 ++#if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf)
1.1574 ++static inline __attribute__ ((__always_inline__)) fp_number_type *
1.1575 ++_fpdiv_parts (fp_number_type * a,
1.1576 ++ fp_number_type * b)
1.1577 ++{
1.1578 ++ fractype bit;
1.1579 ++ fractype numerator;
1.1580 ++ fractype denominator;
1.1581 ++ fractype quotient;
1.1582 ++
1.1583 ++ if (isnan (a))
1.1584 ++ {
1.1585 ++ return a;
1.1586 ++ }
1.1587 ++ if (isnan (b))
1.1588 ++ {
1.1589 ++ return b;
1.1590 ++ }
1.1591 ++
1.1592 ++ a->sign = a->sign ^ b->sign;
1.1593 ++
1.1594 ++ if (isinf (a) || iszero (a))
1.1595 ++ {
1.1596 ++ if (a->class == b->class)
1.1597 ++ return nan ();
1.1598 ++ return a;
1.1599 ++ }
1.1600 ++
1.1601 ++ if (isinf (b))
1.1602 ++ {
1.1603 ++ a->fraction.ll = 0;
1.1604 ++ a->normal_exp = 0;
1.1605 ++ return a;
1.1606 ++ }
1.1607 ++ if (iszero (b))
1.1608 ++ {
1.1609 ++ a->class = CLASS_INFINITY;
1.1610 ++ return a;
1.1611 ++ }
1.1612 ++
1.1613 ++ /* Calculate the mantissa by multiplying both 64bit numbers to get a
1.1614 ++ 128 bit number */
1.1615 ++ {
1.1616 ++ /* quotient =
1.1617 ++ ( numerator / denominator) * 2^(numerator exponent - denominator exponent)
1.1618 ++ */
1.1619 ++
1.1620 ++ a->normal_exp = a->normal_exp - b->normal_exp;
1.1621 ++ numerator = a->fraction.ll;
1.1622 ++ denominator = b->fraction.ll;
1.1623 ++
1.1624 ++ if (numerator < denominator)
1.1625 ++ {
1.1626 ++ /* Fraction will be less than 1.0 */
1.1627 ++ numerator *= 2;
1.1628 ++ a->normal_exp--;
1.1629 ++ }
1.1630 ++ bit = IMPLICIT_1;
1.1631 ++ quotient = 0;
1.1632 ++ /* ??? Does divide one bit at a time. Optimize. */
1.1633 ++ while (bit)
1.1634 ++ {
1.1635 ++ if (numerator >= denominator)
1.1636 ++ {
1.1637 ++ quotient |= bit;
1.1638 ++ numerator -= denominator;
1.1639 ++ }
1.1640 ++ bit >>= 1;
1.1641 ++ numerator *= 2;
1.1642 ++ }
1.1643 ++
1.1644 ++ if (!ROUND_TOWARDS_ZERO && (quotient & GARDMASK) == GARDMSB)
1.1645 ++ {
1.1646 ++ if (quotient & (1 << NGARDS))
1.1647 ++ {
1.1648 ++ /* half way, so round to even */
1.1649 ++ quotient += GARDROUND + 1;
1.1650 ++ }
1.1651 ++ else if (numerator)
1.1652 ++ {
1.1653 ++ /* but we really weren't half way, more bits exist */
1.1654 ++ quotient += GARDROUND + 1;
1.1655 ++ }
1.1656 ++ }
1.1657 ++
1.1658 ++ a->fraction.ll = quotient;
1.1659 ++ return (a);
1.1660 ++ }
1.1661 ++}
1.1662 ++
1.1663 ++FLO_type
1.1664 ++divide (FLO_type arg_a, FLO_type arg_b)
1.1665 ++{
1.1666 ++ fp_number_type a;
1.1667 ++ fp_number_type b;
1.1668 ++ fp_number_type *res;
1.1669 ++ FLO_union_type au, bu;
1.1670 ++
1.1671 ++ au.value = arg_a;
1.1672 ++ bu.value = arg_b;
1.1673 ++
1.1674 ++ unpack_d (&au, &a);
1.1675 ++ unpack_d (&bu, &b);
1.1676 ++
1.1677 ++ res = _fpdiv_parts (&a, &b);
1.1678 ++
1.1679 ++ return pack_d (res);
1.1680 ++}
1.1681 ++#endif /* L_div_sf || L_div_df */
1.1682 ++
1.1683 ++#if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) \
1.1684 ++ || defined(L_fpcmp_parts_tf)
1.1685 ++/* according to the demo, fpcmp returns a comparison with 0... thus
1.1686 ++ a<b -> -1
1.1687 ++ a==b -> 0
1.1688 ++ a>b -> +1
1.1689 ++ */
1.1690 ++
1.1691 ++int
1.1692 ++__fpcmp_parts (fp_number_type * a, fp_number_type * b)
1.1693 ++{
1.1694 ++#if 0
1.1695 ++ /* either nan -> unordered. Must be checked outside of this routine. */
1.1696 ++ if (isnan (a) && isnan (b))
1.1697 ++ {
1.1698 ++ return 1; /* still unordered! */
1.1699 ++ }
1.1700 ++#endif
1.1701 ++
1.1702 ++ if (isnan (a) || isnan (b))
1.1703 ++ {
1.1704 ++ return 1; /* how to indicate unordered compare? */
1.1705 ++ }
1.1706 ++ if (isinf (a) && isinf (b))
1.1707 ++ {
1.1708 ++ /* +inf > -inf, but +inf != +inf */
1.1709 ++ /* b \a| +inf(0)| -inf(1)
1.1710 ++ ______\+--------+--------
1.1711 ++ +inf(0)| a==b(0)| a<b(-1)
1.1712 ++ -------+--------+--------
1.1713 ++ -inf(1)| a>b(1) | a==b(0)
1.1714 ++ -------+--------+--------
1.1715 ++ So since unordered must be nonzero, just line up the columns...
1.1716 ++ */
1.1717 ++ return b->sign - a->sign;
1.1718 ++ }
1.1719 ++ /* but not both... */
1.1720 ++ if (isinf (a))
1.1721 ++ {
1.1722 ++ return a->sign ? -1 : 1;
1.1723 ++ }
1.1724 ++ if (isinf (b))
1.1725 ++ {
1.1726 ++ return b->sign ? 1 : -1;
1.1727 ++ }
1.1728 ++ if (iszero (a) && iszero (b))
1.1729 ++ {
1.1730 ++ return 0;
1.1731 ++ }
1.1732 ++ if (iszero (a))
1.1733 ++ {
1.1734 ++ return b->sign ? 1 : -1;
1.1735 ++ }
1.1736 ++ if (iszero (b))
1.1737 ++ {
1.1738 ++ return a->sign ? -1 : 1;
1.1739 ++ }
1.1740 ++ /* now both are "normal". */
1.1741 ++ if (a->sign != b->sign)
1.1742 ++ {
1.1743 ++ /* opposite signs */
1.1744 ++ return a->sign ? -1 : 1;
1.1745 ++ }
1.1746 ++ /* same sign; exponents? */
1.1747 ++ if (a->normal_exp > b->normal_exp)
1.1748 ++ {
1.1749 ++ return a->sign ? -1 : 1;
1.1750 ++ }
1.1751 ++ if (a->normal_exp < b->normal_exp)
1.1752 ++ {
1.1753 ++ return a->sign ? 1 : -1;
1.1754 ++ }
1.1755 ++ /* same exponents; check size. */
1.1756 ++ if (a->fraction.ll > b->fraction.ll)
1.1757 ++ {
1.1758 ++ return a->sign ? -1 : 1;
1.1759 ++ }
1.1760 ++ if (a->fraction.ll < b->fraction.ll)
1.1761 ++ {
1.1762 ++ return a->sign ? 1 : -1;
1.1763 ++ }
1.1764 ++ /* after all that, they're equal. */
1.1765 ++ return 0;
1.1766 ++}
1.1767 ++#endif
1.1768 ++
1.1769 ++#if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compoare_tf)
1.1770 ++CMPtype
1.1771 ++compare (FLO_type arg_a, FLO_type arg_b)
1.1772 ++{
1.1773 ++ fp_number_type a;
1.1774 ++ fp_number_type b;
1.1775 ++ FLO_union_type au, bu;
1.1776 ++
1.1777 ++ au.value = arg_a;
1.1778 ++ bu.value = arg_b;
1.1779 ++
1.1780 ++ unpack_d (&au, &a);
1.1781 ++ unpack_d (&bu, &b);
1.1782 ++
1.1783 ++ return __fpcmp_parts (&a, &b);
1.1784 ++}
1.1785 ++#endif /* L_compare_sf || L_compare_df */
1.1786 ++
1.1787 ++#ifndef US_SOFTWARE_GOFAST
1.1788 ++
1.1789 ++/* These should be optimized for their specific tasks someday. */
1.1790 ++
1.1791 ++#if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf)
1.1792 ++CMPtype
1.1793 ++_eq_f2 (FLO_type arg_a, FLO_type arg_b)
1.1794 ++{
1.1795 ++ fp_number_type a;
1.1796 ++ fp_number_type b;
1.1797 ++ FLO_union_type au, bu;
1.1798 ++
1.1799 ++ au.value = arg_a;
1.1800 ++ bu.value = arg_b;
1.1801 ++
1.1802 ++ unpack_d (&au, &a);
1.1803 ++ unpack_d (&bu, &b);
1.1804 ++
1.1805 ++ if (isnan (&a) || isnan (&b))
1.1806 ++ return 1; /* false, truth == 0 */
1.1807 ++
1.1808 ++ return __fpcmp_parts (&a, &b) ;
1.1809 ++}
1.1810 ++#endif /* L_eq_sf || L_eq_df */
1.1811 ++
1.1812 ++#if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf)
1.1813 ++CMPtype
1.1814 ++_ne_f2 (FLO_type arg_a, FLO_type arg_b)
1.1815 ++{
1.1816 ++ fp_number_type a;
1.1817 ++ fp_number_type b;
1.1818 ++ FLO_union_type au, bu;
1.1819 ++
1.1820 ++ au.value = arg_a;
1.1821 ++ bu.value = arg_b;
1.1822 ++
1.1823 ++ unpack_d (&au, &a);
1.1824 ++ unpack_d (&bu, &b);
1.1825 ++
1.1826 ++ if (isnan (&a) || isnan (&b))
1.1827 ++ return 1; /* true, truth != 0 */
1.1828 ++
1.1829 ++ return __fpcmp_parts (&a, &b) ;
1.1830 ++}
1.1831 ++#endif /* L_ne_sf || L_ne_df */
1.1832 ++
1.1833 ++#if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf)
1.1834 ++CMPtype
1.1835 ++_gt_f2 (FLO_type arg_a, FLO_type arg_b)
1.1836 ++{
1.1837 ++ fp_number_type a;
1.1838 ++ fp_number_type b;
1.1839 ++ FLO_union_type au, bu;
1.1840 ++
1.1841 ++ au.value = arg_a;
1.1842 ++ bu.value = arg_b;
1.1843 ++
1.1844 ++ unpack_d (&au, &a);
1.1845 ++ unpack_d (&bu, &b);
1.1846 ++
1.1847 ++ if (isnan (&a) || isnan (&b))
1.1848 ++ return -1; /* false, truth > 0 */
1.1849 ++
1.1850 ++ return __fpcmp_parts (&a, &b);
1.1851 ++}
1.1852 ++#endif /* L_gt_sf || L_gt_df */
1.1853 ++
1.1854 ++#if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf)
1.1855 ++CMPtype
1.1856 ++_ge_f2 (FLO_type arg_a, FLO_type arg_b)
1.1857 ++{
1.1858 ++ fp_number_type a;
1.1859 ++ fp_number_type b;
1.1860 ++ FLO_union_type au, bu;
1.1861 ++
1.1862 ++ au.value = arg_a;
1.1863 ++ bu.value = arg_b;
1.1864 ++
1.1865 ++ unpack_d (&au, &a);
1.1866 ++ unpack_d (&bu, &b);
1.1867 ++
1.1868 ++ if (isnan (&a) || isnan (&b))
1.1869 ++ return -1; /* false, truth >= 0 */
1.1870 ++ return __fpcmp_parts (&a, &b) ;
1.1871 ++}
1.1872 ++#endif /* L_ge_sf || L_ge_df */
1.1873 ++
1.1874 ++#if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf)
1.1875 ++CMPtype
1.1876 ++_lt_f2 (FLO_type arg_a, FLO_type arg_b)
1.1877 ++{
1.1878 ++ fp_number_type a;
1.1879 ++ fp_number_type b;
1.1880 ++ FLO_union_type au, bu;
1.1881 ++
1.1882 ++ au.value = arg_a;
1.1883 ++ bu.value = arg_b;
1.1884 ++
1.1885 ++ unpack_d (&au, &a);
1.1886 ++ unpack_d (&bu, &b);
1.1887 ++
1.1888 ++ if (isnan (&a) || isnan (&b))
1.1889 ++ return 1; /* false, truth < 0 */
1.1890 ++
1.1891 ++ return __fpcmp_parts (&a, &b);
1.1892 ++}
1.1893 ++#endif /* L_lt_sf || L_lt_df */
1.1894 ++
1.1895 ++#if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf)
1.1896 ++CMPtype
1.1897 ++_le_f2 (FLO_type arg_a, FLO_type arg_b)
1.1898 ++{
1.1899 ++ fp_number_type a;
1.1900 ++ fp_number_type b;
1.1901 ++ FLO_union_type au, bu;
1.1902 ++
1.1903 ++ au.value = arg_a;
1.1904 ++ bu.value = arg_b;
1.1905 ++
1.1906 ++ unpack_d (&au, &a);
1.1907 ++ unpack_d (&bu, &b);
1.1908 ++
1.1909 ++ if (isnan (&a) || isnan (&b))
1.1910 ++ return 1; /* false, truth <= 0 */
1.1911 ++
1.1912 ++ return __fpcmp_parts (&a, &b) ;
1.1913 ++}
1.1914 ++#endif /* L_le_sf || L_le_df */
1.1915 ++
1.1916 ++#endif /* ! US_SOFTWARE_GOFAST */
1.1917 ++
1.1918 ++#if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf)
1.1919 ++CMPtype
1.1920 ++_unord_f2 (FLO_type arg_a, FLO_type arg_b)
1.1921 ++{
1.1922 ++ fp_number_type a;
1.1923 ++ fp_number_type b;
1.1924 ++ FLO_union_type au, bu;
1.1925 ++
1.1926 ++ au.value = arg_a;
1.1927 ++ bu.value = arg_b;
1.1928 ++
1.1929 ++ unpack_d (&au, &a);
1.1930 ++ unpack_d (&bu, &b);
1.1931 ++
1.1932 ++ return (isnan (&a) || isnan (&b));
1.1933 ++}
1.1934 ++#endif /* L_unord_sf || L_unord_df */
1.1935 ++
1.1936 ++#if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf)
1.1937 ++FLO_type
1.1938 ++si_to_float (SItype arg_a)
1.1939 ++{
1.1940 ++ fp_number_type in;
1.1941 ++
1.1942 ++ in.class = CLASS_NUMBER;
1.1943 ++ in.sign = arg_a < 0;
1.1944 ++ if (!arg_a)
1.1945 ++ {
1.1946 ++ in.class = CLASS_ZERO;
1.1947 ++ }
1.1948 ++ else
1.1949 ++ {
1.1950 ++ in.normal_exp = FRACBITS + NGARDS;
1.1951 ++ if (in.sign)
1.1952 ++ {
1.1953 ++ /* Special case for minint, since there is no +ve integer
1.1954 ++ representation for it */
1.1955 ++ if (arg_a == (- MAX_SI_INT - 1))
1.1956 ++ {
1.1957 ++ return (FLO_type)(- MAX_SI_INT - 1);
1.1958 ++ }
1.1959 ++ in.fraction.ll = (-arg_a);
1.1960 ++ }
1.1961 ++ else
1.1962 ++ in.fraction.ll = arg_a;
1.1963 ++
1.1964 ++ while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS)))
1.1965 ++ {
1.1966 ++ in.fraction.ll <<= 1;
1.1967 ++ in.normal_exp -= 1;
1.1968 ++ }
1.1969 ++ }
1.1970 ++ return pack_d (&in);
1.1971 ++}
1.1972 ++#endif /* L_si_to_sf || L_si_to_df */
1.1973 ++
1.1974 ++#if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf)
1.1975 ++FLO_type
1.1976 ++usi_to_float (USItype arg_a)
1.1977 ++{
1.1978 ++ fp_number_type in;
1.1979 ++
1.1980 ++ in.sign = 0;
1.1981 ++ if (!arg_a)
1.1982 ++ {
1.1983 ++ in.class = CLASS_ZERO;
1.1984 ++ }
1.1985 ++ else
1.1986 ++ {
1.1987 ++ in.class = CLASS_NUMBER;
1.1988 ++ in.normal_exp = FRACBITS + NGARDS;
1.1989 ++ in.fraction.ll = arg_a;
1.1990 ++
1.1991 ++ while (in.fraction.ll > ((fractype)1 << (FRACBITS + NGARDS)))
1.1992 ++ {
1.1993 ++ in.fraction.ll >>= 1;
1.1994 ++ in.normal_exp += 1;
1.1995 ++ }
1.1996 ++ while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS)))
1.1997 ++ {
1.1998 ++ in.fraction.ll <<= 1;
1.1999 ++ in.normal_exp -= 1;
1.2000 ++ }
1.2001 ++ }
1.2002 ++ return pack_d (&in);
1.2003 ++}
1.2004 ++#endif
1.2005 ++
1.2006 ++#if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si)
1.2007 ++SItype
1.2008 ++float_to_si (FLO_type arg_a)
1.2009 ++{
1.2010 ++ fp_number_type a;
1.2011 ++ SItype tmp;
1.2012 ++ FLO_union_type au;
1.2013 ++
1.2014 ++ au.value = arg_a;
1.2015 ++ unpack_d (&au, &a);
1.2016 ++
1.2017 ++ if (iszero (&a))
1.2018 ++ return 0;
1.2019 ++ if (isnan (&a))
1.2020 ++ return 0;
1.2021 ++ /* get reasonable MAX_SI_INT... */
1.2022 ++ if (isinf (&a))
1.2023 ++ return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
1.2024 ++ /* it is a number, but a small one */
1.2025 ++ if (a.normal_exp < 0)
1.2026 ++ return 0;
1.2027 ++ if (a.normal_exp > BITS_PER_SI - 2)
1.2028 ++ return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
1.2029 ++ tmp = a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
1.2030 ++ return a.sign ? (-tmp) : (tmp);
1.2031 ++}
1.2032 ++#endif /* L_sf_to_si || L_df_to_si */
1.2033 ++
1.2034 ++#if defined(L_sf_to_usi) || defined(L_df_to_usi) || defined(L_tf_to_usi)
1.2035 ++#if defined US_SOFTWARE_GOFAST || defined(L_tf_to_usi)
1.2036 ++/* While libgcc2.c defines its own __fixunssfsi and __fixunsdfsi routines,
1.2037 ++ we also define them for GOFAST because the ones in libgcc2.c have the
1.2038 ++ wrong names and I'd rather define these here and keep GOFAST CYG-LOC's
1.2039 ++ out of libgcc2.c. We can't define these here if not GOFAST because then
1.2040 ++ there'd be duplicate copies. */
1.2041 ++
1.2042 ++USItype
1.2043 ++float_to_usi (FLO_type arg_a)
1.2044 ++{
1.2045 ++ fp_number_type a;
1.2046 ++ FLO_union_type au;
1.2047 ++
1.2048 ++ au.value = arg_a;
1.2049 ++ unpack_d (&au, &a);
1.2050 ++
1.2051 ++ if (iszero (&a))
1.2052 ++ return 0;
1.2053 ++ if (isnan (&a))
1.2054 ++ return 0;
1.2055 ++ /* it is a negative number */
1.2056 ++ if (a.sign)
1.2057 ++ return 0;
1.2058 ++ /* get reasonable MAX_USI_INT... */
1.2059 ++ if (isinf (&a))
1.2060 ++ return MAX_USI_INT;
1.2061 ++ /* it is a number, but a small one */
1.2062 ++ if (a.normal_exp < 0)
1.2063 ++ return 0;
1.2064 ++ if (a.normal_exp > BITS_PER_SI - 1)
1.2065 ++ return MAX_USI_INT;
1.2066 ++ else if (a.normal_exp > (FRACBITS + NGARDS))
1.2067 ++ return a.fraction.ll << (a.normal_exp - (FRACBITS + NGARDS));
1.2068 ++ else
1.2069 ++ return a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
1.2070 ++}
1.2071 ++#endif /* US_SOFTWARE_GOFAST */
1.2072 ++#endif /* L_sf_to_usi || L_df_to_usi */
1.2073 ++
1.2074 ++#if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf)
1.2075 ++FLO_type
1.2076 ++negate (FLO_type arg_a)
1.2077 ++{
1.2078 ++ fp_number_type a;
1.2079 ++ FLO_union_type au;
1.2080 ++
1.2081 ++ au.value = arg_a;
1.2082 ++ unpack_d (&au, &a);
1.2083 ++
1.2084 ++ flip_sign (&a);
1.2085 ++ return pack_d (&a);
1.2086 ++}
1.2087 ++#endif /* L_negate_sf || L_negate_df */
1.2088 ++
1.2089 ++#ifdef FLOAT
1.2090 ++
1.2091 ++#if defined(L_make_sf)
1.2092 ++SFtype
1.2093 ++__make_fp(fp_class_type class,
1.2094 ++ unsigned int sign,
1.2095 ++ int exp,
1.2096 ++ USItype frac)
1.2097 ++{
1.2098 ++ fp_number_type in;
1.2099 ++
1.2100 ++ in.class = class;
1.2101 ++ in.sign = sign;
1.2102 ++ in.normal_exp = exp;
1.2103 ++ in.fraction.ll = frac;
1.2104 ++ return pack_d (&in);
1.2105 ++}
1.2106 ++#endif /* L_make_sf */
1.2107 ++
1.2108 ++#ifndef FLOAT_ONLY
1.2109 ++
1.2110 ++/* This enables one to build an fp library that supports float but not double.
1.2111 ++ Otherwise, we would get an undefined reference to __make_dp.
1.2112 ++ This is needed for some 8-bit ports that can't handle well values that
1.2113 ++ are 8-bytes in size, so we just don't support double for them at all. */
1.2114 ++
1.2115 ++#if defined(L_sf_to_df)
1.2116 ++DFtype
1.2117 ++sf_to_df (SFtype arg_a)
1.2118 ++{
1.2119 ++ fp_number_type in;
1.2120 ++ FLO_union_type au;
1.2121 ++
1.2122 ++ au.value = arg_a;
1.2123 ++ unpack_d (&au, &in);
1.2124 ++
1.2125 ++ return __make_dp (in.class, in.sign, in.normal_exp,
1.2126 ++ ((UDItype) in.fraction.ll) << F_D_BITOFF);
1.2127 ++}
1.2128 ++#endif /* L_sf_to_df */
1.2129 ++
1.2130 ++#if defined(L_sf_to_tf) && defined(TMODES)
1.2131 ++TFtype
1.2132 ++sf_to_tf (SFtype arg_a)
1.2133 ++{
1.2134 ++ fp_number_type in;
1.2135 ++ FLO_union_type au;
1.2136 ++
1.2137 ++ au.value = arg_a;
1.2138 ++ unpack_d (&au, &in);
1.2139 ++
1.2140 ++ return __make_tp (in.class, in.sign, in.normal_exp,
1.2141 ++ ((UTItype) in.fraction.ll) << F_T_BITOFF);
1.2142 ++}
1.2143 ++#endif /* L_sf_to_df */
1.2144 ++
1.2145 ++#endif /* ! FLOAT_ONLY */
1.2146 ++#endif /* FLOAT */
1.2147 ++
1.2148 ++#ifndef FLOAT
1.2149 ++
1.2150 ++extern SFtype __make_fp (fp_class_type, unsigned int, int, USItype);
1.2151 ++
1.2152 ++#if defined(L_make_df)
1.2153 ++DFtype
1.2154 ++__make_dp (fp_class_type class, unsigned int sign, int exp, UDItype frac)
1.2155 ++{
1.2156 ++ fp_number_type in;
1.2157 ++
1.2158 ++ in.class = class;
1.2159 ++ in.sign = sign;
1.2160 ++ in.normal_exp = exp;
1.2161 ++ in.fraction.ll = frac;
1.2162 ++ return pack_d (&in);
1.2163 ++}
1.2164 ++#endif /* L_make_df */
1.2165 ++
1.2166 ++#if defined(L_df_to_sf)
1.2167 ++SFtype
1.2168 ++df_to_sf (DFtype arg_a)
1.2169 ++{
1.2170 ++ fp_number_type in;
1.2171 ++ USItype sffrac;
1.2172 ++ FLO_union_type au;
1.2173 ++
1.2174 ++ au.value = arg_a;
1.2175 ++ unpack_d (&au, &in);
1.2176 ++
1.2177 ++ sffrac = in.fraction.ll >> F_D_BITOFF;
1.2178 ++
1.2179 ++ /* We set the lowest guard bit in SFFRAC if we discarded any non
1.2180 ++ zero bits. */
1.2181 ++ if ((in.fraction.ll & (((USItype) 1 << F_D_BITOFF) - 1)) != 0)
1.2182 ++ sffrac |= 1;
1.2183 ++
1.2184 ++ return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
1.2185 ++}
1.2186 ++#endif /* L_df_to_sf */
1.2187 ++
1.2188 ++#if defined(L_df_to_tf) && defined(TMODES) \
1.2189 ++ && !defined(FLOAT) && !defined(TFLOAT)
1.2190 ++TFtype
1.2191 ++df_to_tf (DFtype arg_a)
1.2192 ++{
1.2193 ++ fp_number_type in;
1.2194 ++ FLO_union_type au;
1.2195 ++
1.2196 ++ au.value = arg_a;
1.2197 ++ unpack_d (&au, &in);
1.2198 ++
1.2199 ++ return __make_tp (in.class, in.sign, in.normal_exp,
1.2200 ++ ((UTItype) in.fraction.ll) << D_T_BITOFF);
1.2201 ++}
1.2202 ++#endif /* L_sf_to_df */
1.2203 ++
1.2204 ++#ifdef TFLOAT
1.2205 ++#if defined(L_make_tf)
1.2206 ++TFtype
1.2207 ++__make_tp(fp_class_type class,
1.2208 ++ unsigned int sign,
1.2209 ++ int exp,
1.2210 ++ UTItype frac)
1.2211 ++{
1.2212 ++ fp_number_type in;
1.2213 ++
1.2214 ++ in.class = class;
1.2215 ++ in.sign = sign;
1.2216 ++ in.normal_exp = exp;
1.2217 ++ in.fraction.ll = frac;
1.2218 ++ return pack_d (&in);
1.2219 ++}
1.2220 ++#endif /* L_make_tf */
1.2221 ++
1.2222 ++#if defined(L_tf_to_df)
1.2223 ++DFtype
1.2224 ++tf_to_df (TFtype arg_a)
1.2225 ++{
1.2226 ++ fp_number_type in;
1.2227 ++ UDItype sffrac;
1.2228 ++ FLO_union_type au;
1.2229 ++
1.2230 ++ au.value = arg_a;
1.2231 ++ unpack_d (&au, &in);
1.2232 ++
1.2233 ++ sffrac = in.fraction.ll >> D_T_BITOFF;
1.2234 ++
1.2235 ++ /* We set the lowest guard bit in SFFRAC if we discarded any non
1.2236 ++ zero bits. */
1.2237 ++ if ((in.fraction.ll & (((UTItype) 1 << D_T_BITOFF) - 1)) != 0)
1.2238 ++ sffrac |= 1;
1.2239 ++
1.2240 ++ return __make_dp (in.class, in.sign, in.normal_exp, sffrac);
1.2241 ++}
1.2242 ++#endif /* L_tf_to_df */
1.2243 ++
1.2244 ++#if defined(L_tf_to_sf)
1.2245 ++SFtype
1.2246 ++tf_to_sf (TFtype arg_a)
1.2247 ++{
1.2248 ++ fp_number_type in;
1.2249 ++ USItype sffrac;
1.2250 ++ FLO_union_type au;
1.2251 ++
1.2252 ++ au.value = arg_a;
1.2253 ++ unpack_d (&au, &in);
1.2254 ++
1.2255 ++ sffrac = in.fraction.ll >> F_T_BITOFF;
1.2256 ++
1.2257 ++ /* We set the lowest guard bit in SFFRAC if we discarded any non
1.2258 ++ zero bits. */
1.2259 ++ if ((in.fraction.ll & (((UTItype) 1 << F_T_BITOFF) - 1)) != 0)
1.2260 ++ sffrac |= 1;
1.2261 ++
1.2262 ++ return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
1.2263 ++}
1.2264 ++#endif /* L_tf_to_sf */
1.2265 ++#endif /* TFLOAT */
1.2266 ++
1.2267 ++#endif /* ! FLOAT */
1.2268 ++#endif /* !EXTENDED_FLOAT_STUBS */
1.2269 +--- gcc-3.4.3/gcc/config/nios2/nios2-fp-bit.c
1.2270 ++++ gcc-3.4.3-nios2/gcc/config/nios2/nios2-fp-bit.c
1.2271 +@@ -0,0 +1,1652 @@
1.2272 ++#define FLOAT
1.2273 ++/* This is a software floating point library which can be used
1.2274 ++ for targets without hardware floating point.
1.2275 ++ Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004
1.2276 ++ Free Software Foundation, Inc.
1.2277 ++
1.2278 ++This file is free software; you can redistribute it and/or modify it
1.2279 ++under the terms of the GNU General Public License as published by the
1.2280 ++Free Software Foundation; either version 2, or (at your option) any
1.2281 ++later version.
1.2282 ++
1.2283 ++In addition to the permissions in the GNU General Public License, the
1.2284 ++Free Software Foundation gives you unlimited permission to link the
1.2285 ++compiled version of this file with other programs, and to distribute
1.2286 ++those programs without any restriction coming from the use of this
1.2287 ++file. (The General Public License restrictions do apply in other
1.2288 ++respects; for example, they cover modification of the file, and
1.2289 ++distribution when not linked into another program.)
1.2290 ++
1.2291 ++This file is distributed in the hope that it will be useful, but
1.2292 ++WITHOUT ANY WARRANTY; without even the implied warranty of
1.2293 ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1.2294 ++General Public License for more details.
1.2295 ++
1.2296 ++You should have received a copy of the GNU General Public License
1.2297 ++along with this program; see the file COPYING. If not, write to
1.2298 ++the Free Software Foundation, 59 Temple Place - Suite 330,
1.2299 ++Boston, MA 02111-1307, USA. */
1.2300 ++
1.2301 ++/* As a special exception, if you link this library with other files,
1.2302 ++ some of which are compiled with GCC, to produce an executable,
1.2303 ++ this library does not by itself cause the resulting executable
1.2304 ++ to be covered by the GNU General Public License.
1.2305 ++ This exception does not however invalidate any other reasons why
1.2306 ++ the executable file might be covered by the GNU General Public License. */
1.2307 ++
1.2308 ++/* This implements IEEE 754 format arithmetic, but does not provide a
1.2309 ++ mechanism for setting the rounding mode, or for generating or handling
1.2310 ++ exceptions.
1.2311 ++
1.2312 ++ The original code by Steve Chamberlain, hacked by Mark Eichin and Jim
1.2313 ++ Wilson, all of Cygnus Support. */
1.2314 ++
1.2315 ++/* The intended way to use this file is to make two copies, add `#define FLOAT'
1.2316 ++ to one copy, then compile both copies and add them to libgcc.a. */
1.2317 ++
1.2318 ++#include "tconfig.h"
1.2319 ++#include "coretypes.h"
1.2320 ++#include "tm.h"
1.2321 ++#include "config/fp-bit.h"
1.2322 ++
1.2323 ++/* The following macros can be defined to change the behavior of this file:
1.2324 ++ FLOAT: Implement a `float', aka SFmode, fp library. If this is not
1.2325 ++ defined, then this file implements a `double', aka DFmode, fp library.
1.2326 ++ FLOAT_ONLY: Used with FLOAT, to implement a `float' only library, i.e.
1.2327 ++ don't include float->double conversion which requires the double library.
1.2328 ++ This is useful only for machines which can't support doubles, e.g. some
1.2329 ++ 8-bit processors.
1.2330 ++ CMPtype: Specify the type that floating point compares should return.
1.2331 ++ This defaults to SItype, aka int.
1.2332 ++ US_SOFTWARE_GOFAST: This makes all entry points use the same names as the
1.2333 ++ US Software goFast library.
1.2334 ++ _DEBUG_BITFLOAT: This makes debugging the code a little easier, by adding
1.2335 ++ two integers to the FLO_union_type.
1.2336 ++ NO_DENORMALS: Disable handling of denormals.
1.2337 ++ NO_NANS: Disable nan and infinity handling
1.2338 ++ SMALL_MACHINE: Useful when operations on QIs and HIs are faster
1.2339 ++ than on an SI */
1.2340 ++
1.2341 ++/* We don't currently support extended floats (long doubles) on machines
1.2342 ++ without hardware to deal with them.
1.2343 ++
1.2344 ++ These stubs are just to keep the linker from complaining about unresolved
1.2345 ++ references which can be pulled in from libio & libstdc++, even if the
1.2346 ++ user isn't using long doubles. However, they may generate an unresolved
1.2347 ++ external to abort if abort is not used by the function, and the stubs
1.2348 ++ are referenced from within libc, since libgcc goes before and after the
1.2349 ++ system library. */
1.2350 ++
1.2351 ++#ifdef DECLARE_LIBRARY_RENAMES
1.2352 ++ DECLARE_LIBRARY_RENAMES
1.2353 ++#endif
1.2354 ++
1.2355 ++#ifdef EXTENDED_FLOAT_STUBS
1.2356 ++extern void abort (void);
1.2357 ++void __extendsfxf2 (void) { abort(); }
1.2358 ++void __extenddfxf2 (void) { abort(); }
1.2359 ++void __truncxfdf2 (void) { abort(); }
1.2360 ++void __truncxfsf2 (void) { abort(); }
1.2361 ++void __fixxfsi (void) { abort(); }
1.2362 ++void __floatsixf (void) { abort(); }
1.2363 ++void __addxf3 (void) { abort(); }
1.2364 ++void __subxf3 (void) { abort(); }
1.2365 ++void __mulxf3 (void) { abort(); }
1.2366 ++void __divxf3 (void) { abort(); }
1.2367 ++void __negxf2 (void) { abort(); }
1.2368 ++void __eqxf2 (void) { abort(); }
1.2369 ++void __nexf2 (void) { abort(); }
1.2370 ++void __gtxf2 (void) { abort(); }
1.2371 ++void __gexf2 (void) { abort(); }
1.2372 ++void __lexf2 (void) { abort(); }
1.2373 ++void __ltxf2 (void) { abort(); }
1.2374 ++
1.2375 ++void __extendsftf2 (void) { abort(); }
1.2376 ++void __extenddftf2 (void) { abort(); }
1.2377 ++void __trunctfdf2 (void) { abort(); }
1.2378 ++void __trunctfsf2 (void) { abort(); }
1.2379 ++void __fixtfsi (void) { abort(); }
1.2380 ++void __floatsitf (void) { abort(); }
1.2381 ++void __addtf3 (void) { abort(); }
1.2382 ++void __subtf3 (void) { abort(); }
1.2383 ++void __multf3 (void) { abort(); }
1.2384 ++void __divtf3 (void) { abort(); }
1.2385 ++void __negtf2 (void) { abort(); }
1.2386 ++void __eqtf2 (void) { abort(); }
1.2387 ++void __netf2 (void) { abort(); }
1.2388 ++void __gttf2 (void) { abort(); }
1.2389 ++void __getf2 (void) { abort(); }
1.2390 ++void __letf2 (void) { abort(); }
1.2391 ++void __lttf2 (void) { abort(); }
1.2392 ++#else /* !EXTENDED_FLOAT_STUBS, rest of file */
1.2393 ++
1.2394 ++/* IEEE "special" number predicates */
1.2395 ++
1.2396 ++#ifdef NO_NANS
1.2397 ++
1.2398 ++#define nan() 0
1.2399 ++#define isnan(x) 0
1.2400 ++#define isinf(x) 0
1.2401 ++#else
1.2402 ++
1.2403 ++#if defined L_thenan_sf
1.2404 ++const fp_number_type __thenan_sf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
1.2405 ++#elif defined L_thenan_df
1.2406 ++const fp_number_type __thenan_df = { CLASS_SNAN, 0, 0, {(fractype) 0} };
1.2407 ++#elif defined L_thenan_tf
1.2408 ++const fp_number_type __thenan_tf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
1.2409 ++#elif defined TFLOAT
1.2410 ++extern const fp_number_type __thenan_tf;
1.2411 ++#elif defined FLOAT
1.2412 ++extern const fp_number_type __thenan_sf;
1.2413 ++#else
1.2414 ++extern const fp_number_type __thenan_df;
1.2415 ++#endif
1.2416 ++
1.2417 ++INLINE
1.2418 ++static fp_number_type *
1.2419 ++nan (void)
1.2420 ++{
1.2421 ++ /* Discard the const qualifier... */
1.2422 ++#ifdef TFLOAT
1.2423 ++ return (fp_number_type *) (& __thenan_tf);
1.2424 ++#elif defined FLOAT
1.2425 ++ return (fp_number_type *) (& __thenan_sf);
1.2426 ++#else
1.2427 ++ return (fp_number_type *) (& __thenan_df);
1.2428 ++#endif
1.2429 ++}
1.2430 ++
1.2431 ++INLINE
1.2432 ++static int
1.2433 ++isnan ( fp_number_type * x)
1.2434 ++{
1.2435 ++ return x->class == CLASS_SNAN || x->class == CLASS_QNAN;
1.2436 ++}
1.2437 ++
1.2438 ++INLINE
1.2439 ++static int
1.2440 ++isinf ( fp_number_type * x)
1.2441 ++{
1.2442 ++ return x->class == CLASS_INFINITY;
1.2443 ++}
1.2444 ++
1.2445 ++#endif /* NO_NANS */
1.2446 ++
1.2447 ++INLINE
1.2448 ++static int
1.2449 ++iszero ( fp_number_type * x)
1.2450 ++{
1.2451 ++ return x->class == CLASS_ZERO;
1.2452 ++}
1.2453 ++
1.2454 ++INLINE
1.2455 ++static void
1.2456 ++flip_sign ( fp_number_type * x)
1.2457 ++{
1.2458 ++ x->sign = !x->sign;
1.2459 ++}
1.2460 ++
1.2461 ++extern FLO_type pack_d ( fp_number_type * );
1.2462 ++
1.2463 ++#if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf)
1.2464 ++FLO_type
1.2465 ++pack_d ( fp_number_type * src)
1.2466 ++{
1.2467 ++ FLO_union_type dst;
1.2468 ++ fractype fraction = src->fraction.ll; /* wasn't unsigned before? */
1.2469 ++ int sign = src->sign;
1.2470 ++ int exp = 0;
1.2471 ++
1.2472 ++ if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && (isnan (src) || isinf (src)))
1.2473 ++ {
1.2474 ++ /* We can't represent these values accurately. By using the
1.2475 ++ largest possible magnitude, we guarantee that the conversion
1.2476 ++ of infinity is at least as big as any finite number. */
1.2477 ++ exp = EXPMAX;
1.2478 ++ fraction = ((fractype) 1 << FRACBITS) - 1;
1.2479 ++ }
1.2480 ++ else if (isnan (src))
1.2481 ++ {
1.2482 ++ exp = EXPMAX;
1.2483 ++ if (src->class == CLASS_QNAN || 1)
1.2484 ++ {
1.2485 ++#ifdef QUIET_NAN_NEGATED
1.2486 ++ fraction |= QUIET_NAN - 1;
1.2487 ++#else
1.2488 ++ fraction |= QUIET_NAN;
1.2489 ++#endif
1.2490 ++ }
1.2491 ++ }
1.2492 ++ else if (isinf (src))
1.2493 ++ {
1.2494 ++ exp = EXPMAX;
1.2495 ++ fraction = 0;
1.2496 ++ }
1.2497 ++ else if (iszero (src))
1.2498 ++ {
1.2499 ++ exp = 0;
1.2500 ++ fraction = 0;
1.2501 ++ }
1.2502 ++ else if (fraction == 0)
1.2503 ++ {
1.2504 ++ exp = 0;
1.2505 ++ }
1.2506 ++ else
1.2507 ++ {
1.2508 ++ if (src->normal_exp < NORMAL_EXPMIN)
1.2509 ++ {
1.2510 ++#ifdef NO_DENORMALS
1.2511 ++ /* Go straight to a zero representation if denormals are not
1.2512 ++ supported. The denormal handling would be harmless but
1.2513 ++ isn't unnecessary. */
1.2514 ++ exp = 0;
1.2515 ++ fraction = 0;
1.2516 ++#else /* NO_DENORMALS */
1.2517 ++ /* This number's exponent is too low to fit into the bits
1.2518 ++ available in the number, so we'll store 0 in the exponent and
1.2519 ++ shift the fraction to the right to make up for it. */
1.2520 ++
1.2521 ++ int shift = NORMAL_EXPMIN - src->normal_exp;
1.2522 ++
1.2523 ++ exp = 0;
1.2524 ++
1.2525 ++ if (shift > FRAC_NBITS - NGARDS)
1.2526 ++ {
1.2527 ++ /* No point shifting, since it's more that 64 out. */
1.2528 ++ fraction = 0;
1.2529 ++ }
1.2530 ++ else
1.2531 ++ {
1.2532 ++ int lowbit = (fraction & (((fractype)1 << shift) - 1)) ? 1 : 0;
1.2533 ++ fraction = (fraction >> shift) | lowbit;
1.2534 ++ }
1.2535 ++ if ((fraction & GARDMASK) == GARDMSB)
1.2536 ++ {
1.2537 ++ if ((fraction & (1 << NGARDS)))
1.2538 ++ fraction += GARDROUND + 1;
1.2539 ++ }
1.2540 ++ else
1.2541 ++ {
1.2542 ++ /* Add to the guards to round up. */
1.2543 ++ fraction += GARDROUND;
1.2544 ++ }
1.2545 ++ /* Perhaps the rounding means we now need to change the
1.2546 ++ exponent, because the fraction is no longer denormal. */
1.2547 ++ if (fraction >= IMPLICIT_1)
1.2548 ++ {
1.2549 ++ exp += 1;
1.2550 ++ }
1.2551 ++ fraction >>= NGARDS;
1.2552 ++#endif /* NO_DENORMALS */
1.2553 ++ }
1.2554 ++ else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS)
1.2555 ++ && src->normal_exp > EXPBIAS)
1.2556 ++ {
1.2557 ++ exp = EXPMAX;
1.2558 ++ fraction = 0;
1.2559 ++ }
1.2560 ++ else
1.2561 ++ {
1.2562 ++ exp = src->normal_exp + EXPBIAS;
1.2563 ++ if (!ROUND_TOWARDS_ZERO)
1.2564 ++ {
1.2565 ++ /* IF the gard bits are the all zero, but the first, then we're
1.2566 ++ half way between two numbers, choose the one which makes the
1.2567 ++ lsb of the answer 0. */
1.2568 ++ if ((fraction & GARDMASK) == GARDMSB)
1.2569 ++ {
1.2570 ++ if (fraction & (1 << NGARDS))
1.2571 ++ fraction += GARDROUND + 1;
1.2572 ++ }
1.2573 ++ else
1.2574 ++ {
1.2575 ++ /* Add a one to the guards to round up */
1.2576 ++ fraction += GARDROUND;
1.2577 ++ }
1.2578 ++ if (fraction >= IMPLICIT_2)
1.2579 ++ {
1.2580 ++ fraction >>= 1;
1.2581 ++ exp += 1;
1.2582 ++ }
1.2583 ++ }
1.2584 ++ fraction >>= NGARDS;
1.2585 ++
1.2586 ++ if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp > EXPMAX)
1.2587 ++ {
1.2588 ++ /* Saturate on overflow. */
1.2589 ++ exp = EXPMAX;
1.2590 ++ fraction = ((fractype) 1 << FRACBITS) - 1;
1.2591 ++ }
1.2592 ++ }
1.2593 ++ }
1.2594 ++
1.2595 ++ /* We previously used bitfields to store the number, but this doesn't
1.2596 ++ handle little/big endian systems conveniently, so use shifts and
1.2597 ++ masks */
1.2598 ++#ifdef FLOAT_BIT_ORDER_MISMATCH
1.2599 ++ dst.bits.fraction = fraction;
1.2600 ++ dst.bits.exp = exp;
1.2601 ++ dst.bits.sign = sign;
1.2602 ++#else
1.2603 ++# if defined TFLOAT && defined HALFFRACBITS
1.2604 ++ {
1.2605 ++ halffractype high, low, unity;
1.2606 ++ int lowsign, lowexp;
1.2607 ++
1.2608 ++ unity = (halffractype) 1 << HALFFRACBITS;
1.2609 ++
1.2610 ++ /* Set HIGH to the high double's significand, masking out the implicit 1.
1.2611 ++ Set LOW to the low double's full significand. */
1.2612 ++ high = (fraction >> (FRACBITS - HALFFRACBITS)) & (unity - 1);
1.2613 ++ low = fraction & (unity * 2 - 1);
1.2614 ++
1.2615 ++ /* Get the initial sign and exponent of the low double. */
1.2616 ++ lowexp = exp - HALFFRACBITS - 1;
1.2617 ++ lowsign = sign;
1.2618 ++
1.2619 ++ /* HIGH should be rounded like a normal double, making |LOW| <=
1.2620 ++ 0.5 ULP of HIGH. Assume round-to-nearest. */
1.2621 ++ if (exp < EXPMAX)
1.2622 ++ if (low > unity || (low == unity && (high & 1) == 1))
1.2623 ++ {
1.2624 ++ /* Round HIGH up and adjust LOW to match. */
1.2625 ++ high++;
1.2626 ++ if (high == unity)
1.2627 ++ {
1.2628 ++ /* May make it infinite, but that's OK. */
1.2629 ++ high = 0;
1.2630 ++ exp++;
1.2631 ++ }
1.2632 ++ low = unity * 2 - low;
1.2633 ++ lowsign ^= 1;
1.2634 ++ }
1.2635 ++
1.2636 ++ high |= (halffractype) exp << HALFFRACBITS;
1.2637 ++ high |= (halffractype) sign << (HALFFRACBITS + EXPBITS);
1.2638 ++
1.2639 ++ if (exp == EXPMAX || exp == 0 || low == 0)
1.2640 ++ low = 0;
1.2641 ++ else
1.2642 ++ {
1.2643 ++ while (lowexp > 0 && low < unity)
1.2644 ++ {
1.2645 ++ low <<= 1;
1.2646 ++ lowexp--;
1.2647 ++ }
1.2648 ++
1.2649 ++ if (lowexp <= 0)
1.2650 ++ {
1.2651 ++ halffractype roundmsb, round;
1.2652 ++ int shift;
1.2653 ++
1.2654 ++ shift = 1 - lowexp;
1.2655 ++ roundmsb = (1 << (shift - 1));
1.2656 ++ round = low & ((roundmsb << 1) - 1);
1.2657 ++
1.2658 ++ low >>= shift;
1.2659 ++ lowexp = 0;
1.2660 ++
1.2661 ++ if (round > roundmsb || (round == roundmsb && (low & 1) == 1))
1.2662 ++ {
1.2663 ++ low++;
1.2664 ++ if (low == unity)
1.2665 ++ /* LOW rounds up to the smallest normal number. */
1.2666 ++ lowexp++;
1.2667 ++ }
1.2668 ++ }
1.2669 ++
1.2670 ++ low &= unity - 1;
1.2671 ++ low |= (halffractype) lowexp << HALFFRACBITS;
1.2672 ++ low |= (halffractype) lowsign << (HALFFRACBITS + EXPBITS);
1.2673 ++ }
1.2674 ++ dst.value_raw = ((fractype) high << HALFSHIFT) | low;
1.2675 ++ }
1.2676 ++# else
1.2677 ++ dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1);
1.2678 ++ dst.value_raw |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << FRACBITS;
1.2679 ++ dst.value_raw |= ((fractype) (sign & 1)) << (FRACBITS | EXPBITS);
1.2680 ++# endif
1.2681 ++#endif
1.2682 ++
1.2683 ++#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
1.2684 ++#ifdef TFLOAT
1.2685 ++ {
1.2686 ++ qrtrfractype tmp1 = dst.words[0];
1.2687 ++ qrtrfractype tmp2 = dst.words[1];
1.2688 ++ dst.words[0] = dst.words[3];
1.2689 ++ dst.words[1] = dst.words[2];
1.2690 ++ dst.words[2] = tmp2;
1.2691 ++ dst.words[3] = tmp1;
1.2692 ++ }
1.2693 ++#else
1.2694 ++ {
1.2695 ++ halffractype tmp = dst.words[0];
1.2696 ++ dst.words[0] = dst.words[1];
1.2697 ++ dst.words[1] = tmp;
1.2698 ++ }
1.2699 ++#endif
1.2700 ++#endif
1.2701 ++
1.2702 ++ return dst.value;
1.2703 ++}
1.2704 ++#endif
1.2705 ++
1.2706 ++#if defined(L_unpack_df) || defined(L_unpack_sf) || defined(L_unpack_tf)
1.2707 ++void
1.2708 ++unpack_d (FLO_union_type * src, fp_number_type * dst)
1.2709 ++{
1.2710 ++ /* We previously used bitfields to store the number, but this doesn't
1.2711 ++ handle little/big endian systems conveniently, so use shifts and
1.2712 ++ masks */
1.2713 ++ fractype fraction;
1.2714 ++ int exp;
1.2715 ++ int sign;
1.2716 ++
1.2717 ++#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
1.2718 ++ FLO_union_type swapped;
1.2719 ++
1.2720 ++#ifdef TFLOAT
1.2721 ++ swapped.words[0] = src->words[3];
1.2722 ++ swapped.words[1] = src->words[2];
1.2723 ++ swapped.words[2] = src->words[1];
1.2724 ++ swapped.words[3] = src->words[0];
1.2725 ++#else
1.2726 ++ swapped.words[0] = src->words[1];
1.2727 ++ swapped.words[1] = src->words[0];
1.2728 ++#endif
1.2729 ++ src = &swapped;
1.2730 ++#endif
1.2731 ++
1.2732 ++#ifdef FLOAT_BIT_ORDER_MISMATCH
1.2733 ++ fraction = src->bits.fraction;
1.2734 ++ exp = src->bits.exp;
1.2735 ++ sign = src->bits.sign;
1.2736 ++#else
1.2737 ++# if defined TFLOAT && defined HALFFRACBITS
1.2738 ++ {
1.2739 ++ halffractype high, low;
1.2740 ++
1.2741 ++ high = src->value_raw >> HALFSHIFT;
1.2742 ++ low = src->value_raw & (((fractype)1 << HALFSHIFT) - 1);
1.2743 ++
1.2744 ++ fraction = high & ((((fractype)1) << HALFFRACBITS) - 1);
1.2745 ++ fraction <<= FRACBITS - HALFFRACBITS;
1.2746 ++ exp = ((int)(high >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
1.2747 ++ sign = ((int)(high >> (((HALFFRACBITS + EXPBITS))))) & 1;
1.2748 ++
1.2749 ++ if (exp != EXPMAX && exp != 0 && low != 0)
1.2750 ++ {
1.2751 ++ int lowexp = ((int)(low >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
1.2752 ++ int lowsign = ((int)(low >> (((HALFFRACBITS + EXPBITS))))) & 1;
1.2753 ++ int shift;
1.2754 ++ fractype xlow;
1.2755 ++
1.2756 ++ xlow = low & ((((fractype)1) << HALFFRACBITS) - 1);
1.2757 ++ if (lowexp)
1.2758 ++ xlow |= (((halffractype)1) << HALFFRACBITS);
1.2759 ++ else
1.2760 ++ lowexp = 1;
1.2761 ++ shift = (FRACBITS - HALFFRACBITS) - (exp - lowexp);
1.2762 ++ if (shift > 0)
1.2763 ++ xlow <<= shift;
1.2764 ++ else if (shift < 0)
1.2765 ++ xlow >>= -shift;
1.2766 ++ if (sign == lowsign)
1.2767 ++ fraction += xlow;
1.2768 ++ else if (fraction >= xlow)
1.2769 ++ fraction -= xlow;
1.2770 ++ else
1.2771 ++ {
1.2772 ++ /* The high part is a power of two but the full number is lower.
1.2773 ++ This code will leave the implicit 1 in FRACTION, but we'd
1.2774 ++ have added that below anyway. */
1.2775 ++ fraction = (((fractype) 1 << FRACBITS) - xlow) << 1;
1.2776 ++ exp--;
1.2777 ++ }
1.2778 ++ }
1.2779 ++ }
1.2780 ++# else
1.2781 ++ fraction = src->value_raw & ((((fractype)1) << FRACBITS) - 1);
1.2782 ++ exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1);
1.2783 ++ sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1;
1.2784 ++# endif
1.2785 ++#endif
1.2786 ++
1.2787 ++ dst->sign = sign;
1.2788 ++ if (exp == 0)
1.2789 ++ {
1.2790 ++ /* Hmm. Looks like 0 */
1.2791 ++ if (fraction == 0
1.2792 ++#ifdef NO_DENORMALS
1.2793 ++ || 1
1.2794 ++#endif
1.2795 ++ )
1.2796 ++ {
1.2797 ++ /* tastes like zero */
1.2798 ++ dst->class = CLASS_ZERO;
1.2799 ++ }
1.2800 ++ else
1.2801 ++ {
1.2802 ++ /* Zero exponent with nonzero fraction - it's denormalized,
1.2803 ++ so there isn't a leading implicit one - we'll shift it so
1.2804 ++ it gets one. */
1.2805 ++ dst->normal_exp = exp - EXPBIAS + 1;
1.2806 ++ fraction <<= NGARDS;
1.2807 ++
1.2808 ++ dst->class = CLASS_NUMBER;
1.2809 ++#if 1
1.2810 ++ while (fraction < IMPLICIT_1)
1.2811 ++ {
1.2812 ++ fraction <<= 1;
1.2813 ++ dst->normal_exp--;
1.2814 ++ }
1.2815 ++#endif
1.2816 ++ dst->fraction.ll = fraction;
1.2817 ++ }
1.2818 ++ }
1.2819 ++ else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp == EXPMAX)
1.2820 ++ {
1.2821 ++ /* Huge exponent*/
1.2822 ++ if (fraction == 0)
1.2823 ++ {
1.2824 ++ /* Attached to a zero fraction - means infinity */
1.2825 ++ dst->class = CLASS_INFINITY;
1.2826 ++ }
1.2827 ++ else
1.2828 ++ {
1.2829 ++ /* Nonzero fraction, means nan */
1.2830 ++#ifdef QUIET_NAN_NEGATED
1.2831 ++ if ((fraction & QUIET_NAN) == 0)
1.2832 ++#else
1.2833 ++ if (fraction & QUIET_NAN)
1.2834 ++#endif
1.2835 ++ {
1.2836 ++ dst->class = CLASS_QNAN;
1.2837 ++ }
1.2838 ++ else
1.2839 ++ {
1.2840 ++ dst->class = CLASS_SNAN;
1.2841 ++ }
1.2842 ++ /* Keep the fraction part as the nan number */
1.2843 ++ dst->fraction.ll = fraction;
1.2844 ++ }
1.2845 ++ }
1.2846 ++ else
1.2847 ++ {
1.2848 ++ /* Nothing strange about this number */
1.2849 ++ dst->normal_exp = exp - EXPBIAS;
1.2850 ++ dst->class = CLASS_NUMBER;
1.2851 ++ dst->fraction.ll = (fraction << NGARDS) | IMPLICIT_1;
1.2852 ++ }
1.2853 ++}
1.2854 ++#endif /* L_unpack_df || L_unpack_sf */
1.2855 ++
1.2856 ++#if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf)
1.2857 ++static fp_number_type *
1.2858 ++_fpadd_parts (fp_number_type * a,
1.2859 ++ fp_number_type * b,
1.2860 ++ fp_number_type * tmp)
1.2861 ++{
1.2862 ++ intfrac tfraction;
1.2863 ++
1.2864 ++ /* Put commonly used fields in local variables. */
1.2865 ++ int a_normal_exp;
1.2866 ++ int b_normal_exp;
1.2867 ++ fractype a_fraction;
1.2868 ++ fractype b_fraction;
1.2869 ++
1.2870 ++ if (isnan (a))
1.2871 ++ {
1.2872 ++ return a;
1.2873 ++ }
1.2874 ++ if (isnan (b))
1.2875 ++ {
1.2876 ++ return b;
1.2877 ++ }
1.2878 ++ if (isinf (a))
1.2879 ++ {
1.2880 ++ /* Adding infinities with opposite signs yields a NaN. */
1.2881 ++ if (isinf (b) && a->sign != b->sign)
1.2882 ++ return nan ();
1.2883 ++ return a;
1.2884 ++ }
1.2885 ++ if (isinf (b))
1.2886 ++ {
1.2887 ++ return b;
1.2888 ++ }
1.2889 ++ if (iszero (b))
1.2890 ++ {
1.2891 ++ if (iszero (a))
1.2892 ++ {
1.2893 ++ *tmp = *a;
1.2894 ++ tmp->sign = a->sign & b->sign;
1.2895 ++ return tmp;
1.2896 ++ }
1.2897 ++ return a;
1.2898 ++ }
1.2899 ++ if (iszero (a))
1.2900 ++ {
1.2901 ++ return b;
1.2902 ++ }
1.2903 ++
1.2904 ++ /* Got two numbers. shift the smaller and increment the exponent till
1.2905 ++ they're the same */
1.2906 ++ {
1.2907 ++ int diff;
1.2908 ++
1.2909 ++ a_normal_exp = a->normal_exp;
1.2910 ++ b_normal_exp = b->normal_exp;
1.2911 ++ a_fraction = a->fraction.ll;
1.2912 ++ b_fraction = b->fraction.ll;
1.2913 ++
1.2914 ++ diff = a_normal_exp - b_normal_exp;
1.2915 ++
1.2916 ++ if (diff < 0)
1.2917 ++ diff = -diff;
1.2918 ++ if (diff < FRAC_NBITS)
1.2919 ++ {
1.2920 ++ /* ??? This does shifts one bit at a time. Optimize. */
1.2921 ++ while (a_normal_exp > b_normal_exp)
1.2922 ++ {
1.2923 ++ b_normal_exp++;
1.2924 ++ LSHIFT (b_fraction);
1.2925 ++ }
1.2926 ++ while (b_normal_exp > a_normal_exp)
1.2927 ++ {
1.2928 ++ a_normal_exp++;
1.2929 ++ LSHIFT (a_fraction);
1.2930 ++ }
1.2931 ++ }
1.2932 ++ else
1.2933 ++ {
1.2934 ++ /* Somethings's up.. choose the biggest */
1.2935 ++ if (a_normal_exp > b_normal_exp)
1.2936 ++ {
1.2937 ++ b_normal_exp = a_normal_exp;
1.2938 ++ b_fraction = 0;
1.2939 ++ }
1.2940 ++ else
1.2941 ++ {
1.2942 ++ a_normal_exp = b_normal_exp;
1.2943 ++ a_fraction = 0;
1.2944 ++ }
1.2945 ++ }
1.2946 ++ }
1.2947 ++
1.2948 ++ if (a->sign != b->sign)
1.2949 ++ {
1.2950 ++ if (a->sign)
1.2951 ++ {
1.2952 ++ tfraction = -a_fraction + b_fraction;
1.2953 ++ }
1.2954 ++ else
1.2955 ++ {
1.2956 ++ tfraction = a_fraction - b_fraction;
1.2957 ++ }
1.2958 ++ if (tfraction >= 0)
1.2959 ++ {
1.2960 ++ tmp->sign = 0;
1.2961 ++ tmp->normal_exp = a_normal_exp;
1.2962 ++ tmp->fraction.ll = tfraction;
1.2963 ++ }
1.2964 ++ else
1.2965 ++ {
1.2966 ++ tmp->sign = 1;
1.2967 ++ tmp->normal_exp = a_normal_exp;
1.2968 ++ tmp->fraction.ll = -tfraction;
1.2969 ++ }
1.2970 ++ /* and renormalize it */
1.2971 ++
1.2972 ++ while (tmp->fraction.ll < IMPLICIT_1 && tmp->fraction.ll)
1.2973 ++ {
1.2974 ++ tmp->fraction.ll <<= 1;
1.2975 ++ tmp->normal_exp--;
1.2976 ++ }
1.2977 ++ }
1.2978 ++ else
1.2979 ++ {
1.2980 ++ tmp->sign = a->sign;
1.2981 ++ tmp->normal_exp = a_normal_exp;
1.2982 ++ tmp->fraction.ll = a_fraction + b_fraction;
1.2983 ++ }
1.2984 ++ tmp->class = CLASS_NUMBER;
1.2985 ++ /* Now the fraction is added, we have to shift down to renormalize the
1.2986 ++ number */
1.2987 ++
1.2988 ++ if (tmp->fraction.ll >= IMPLICIT_2)
1.2989 ++ {
1.2990 ++ LSHIFT (tmp->fraction.ll);
1.2991 ++ tmp->normal_exp++;
1.2992 ++ }
1.2993 ++ return tmp;
1.2994 ++
1.2995 ++}
1.2996 ++
1.2997 ++FLO_type
1.2998 ++add (FLO_type arg_a, FLO_type arg_b)
1.2999 ++{
1.3000 ++ fp_number_type a;
1.3001 ++ fp_number_type b;
1.3002 ++ fp_number_type tmp;
1.3003 ++ fp_number_type *res;
1.3004 ++ FLO_union_type au, bu;
1.3005 ++
1.3006 ++ au.value = arg_a;
1.3007 ++ bu.value = arg_b;
1.3008 ++
1.3009 ++ unpack_d (&au, &a);
1.3010 ++ unpack_d (&bu, &b);
1.3011 ++
1.3012 ++ res = _fpadd_parts (&a, &b, &tmp);
1.3013 ++
1.3014 ++ return pack_d (res);
1.3015 ++}
1.3016 ++
1.3017 ++FLO_type
1.3018 ++sub (FLO_type arg_a, FLO_type arg_b)
1.3019 ++{
1.3020 ++ fp_number_type a;
1.3021 ++ fp_number_type b;
1.3022 ++ fp_number_type tmp;
1.3023 ++ fp_number_type *res;
1.3024 ++ FLO_union_type au, bu;
1.3025 ++
1.3026 ++ au.value = arg_a;
1.3027 ++ bu.value = arg_b;
1.3028 ++
1.3029 ++ unpack_d (&au, &a);
1.3030 ++ unpack_d (&bu, &b);
1.3031 ++
1.3032 ++ b.sign ^= 1;
1.3033 ++
1.3034 ++ res = _fpadd_parts (&a, &b, &tmp);
1.3035 ++
1.3036 ++ return pack_d (res);
1.3037 ++}
1.3038 ++#endif /* L_addsub_sf || L_addsub_df */
1.3039 ++
1.3040 ++#if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf)
1.3041 ++static inline __attribute__ ((__always_inline__)) fp_number_type *
1.3042 ++_fpmul_parts ( fp_number_type * a,
1.3043 ++ fp_number_type * b,
1.3044 ++ fp_number_type * tmp)
1.3045 ++{
1.3046 ++ fractype low = 0;
1.3047 ++ fractype high = 0;
1.3048 ++
1.3049 ++ if (isnan (a))
1.3050 ++ {
1.3051 ++ a->sign = a->sign != b->sign;
1.3052 ++ return a;
1.3053 ++ }
1.3054 ++ if (isnan (b))
1.3055 ++ {
1.3056 ++ b->sign = a->sign != b->sign;
1.3057 ++ return b;
1.3058 ++ }
1.3059 ++ if (isinf (a))
1.3060 ++ {
1.3061 ++ if (iszero (b))
1.3062 ++ return nan ();
1.3063 ++ a->sign = a->sign != b->sign;
1.3064 ++ return a;
1.3065 ++ }
1.3066 ++ if (isinf (b))
1.3067 ++ {
1.3068 ++ if (iszero (a))
1.3069 ++ {
1.3070 ++ return nan ();
1.3071 ++ }
1.3072 ++ b->sign = a->sign != b->sign;
1.3073 ++ return b;
1.3074 ++ }
1.3075 ++ if (iszero (a))
1.3076 ++ {
1.3077 ++ a->sign = a->sign != b->sign;
1.3078 ++ return a;
1.3079 ++ }
1.3080 ++ if (iszero (b))
1.3081 ++ {
1.3082 ++ b->sign = a->sign != b->sign;
1.3083 ++ return b;
1.3084 ++ }
1.3085 ++
1.3086 ++ /* Calculate the mantissa by multiplying both numbers to get a
1.3087 ++ twice-as-wide number. */
1.3088 ++ {
1.3089 ++#if defined(NO_DI_MODE) || defined(TFLOAT)
1.3090 ++ {
1.3091 ++ fractype x = a->fraction.ll;
1.3092 ++ fractype ylow = b->fraction.ll;
1.3093 ++ fractype yhigh = 0;
1.3094 ++ int bit;
1.3095 ++
1.3096 ++ /* ??? This does multiplies one bit at a time. Optimize. */
1.3097 ++ for (bit = 0; bit < FRAC_NBITS; bit++)
1.3098 ++ {
1.3099 ++ int carry;
1.3100 ++
1.3101 ++ if (x & 1)
1.3102 ++ {
1.3103 ++ carry = (low += ylow) < ylow;
1.3104 ++ high += yhigh + carry;
1.3105 ++ }
1.3106 ++ yhigh <<= 1;
1.3107 ++ if (ylow & FRACHIGH)
1.3108 ++ {
1.3109 ++ yhigh |= 1;
1.3110 ++ }
1.3111 ++ ylow <<= 1;
1.3112 ++ x >>= 1;
1.3113 ++ }
1.3114 ++ }
1.3115 ++#elif defined(FLOAT)
1.3116 ++ /* Multiplying two USIs to get a UDI, we're safe. */
1.3117 ++ {
1.3118 ++ UDItype answer = (UDItype)a->fraction.ll * (UDItype)b->fraction.ll;
1.3119 ++
1.3120 ++ high = answer >> BITS_PER_SI;
1.3121 ++ low = answer;
1.3122 ++ }
1.3123 ++#else
1.3124 ++ /* fractype is DImode, but we need the result to be twice as wide.
1.3125 ++ Assuming a widening multiply from DImode to TImode is not
1.3126 ++ available, build one by hand. */
1.3127 ++ {
1.3128 ++ USItype nl = a->fraction.ll;
1.3129 ++ USItype nh = a->fraction.ll >> BITS_PER_SI;
1.3130 ++ USItype ml = b->fraction.ll;
1.3131 ++ USItype mh = b->fraction.ll >> BITS_PER_SI;
1.3132 ++ UDItype pp_ll = (UDItype) ml * nl;
1.3133 ++ UDItype pp_hl = (UDItype) mh * nl;
1.3134 ++ UDItype pp_lh = (UDItype) ml * nh;
1.3135 ++ UDItype pp_hh = (UDItype) mh * nh;
1.3136 ++ UDItype res2 = 0;
1.3137 ++ UDItype res0 = 0;
1.3138 ++ UDItype ps_hh__ = pp_hl + pp_lh;
1.3139 ++ if (ps_hh__ < pp_hl)
1.3140 ++ res2 += (UDItype)1 << BITS_PER_SI;
1.3141 ++ pp_hl = (UDItype)(USItype)ps_hh__ << BITS_PER_SI;
1.3142 ++ res0 = pp_ll + pp_hl;
1.3143 ++ if (res0 < pp_ll)
1.3144 ++ res2++;
1.3145 ++ res2 += (ps_hh__ >> BITS_PER_SI) + pp_hh;
1.3146 ++ high = res2;
1.3147 ++ low = res0;
1.3148 ++ }
1.3149 ++#endif
1.3150 ++ }
1.3151 ++
1.3152 ++ tmp->normal_exp = a->normal_exp + b->normal_exp
1.3153 ++ + FRAC_NBITS - (FRACBITS + NGARDS);
1.3154 ++ tmp->sign = a->sign != b->sign;
1.3155 ++ while (high >= IMPLICIT_2)
1.3156 ++ {
1.3157 ++ tmp->normal_exp++;
1.3158 ++ if (high & 1)
1.3159 ++ {
1.3160 ++ low >>= 1;
1.3161 ++ low |= FRACHIGH;
1.3162 ++ }
1.3163 ++ high >>= 1;
1.3164 ++ }
1.3165 ++ while (high < IMPLICIT_1)
1.3166 ++ {
1.3167 ++ tmp->normal_exp--;
1.3168 ++
1.3169 ++ high <<= 1;
1.3170 ++ if (low & FRACHIGH)
1.3171 ++ high |= 1;
1.3172 ++ low <<= 1;
1.3173 ++ }
1.3174 ++ /* rounding is tricky. if we only round if it won't make us round later. */
1.3175 ++#if 0
1.3176 ++ if (low & FRACHIGH2)
1.3177 ++ {
1.3178 ++ if (((high & GARDMASK) != GARDMSB)
1.3179 ++ && (((high + 1) & GARDMASK) == GARDMSB))
1.3180 ++ {
1.3181 ++ /* don't round, it gets done again later. */
1.3182 ++ }
1.3183 ++ else
1.3184 ++ {
1.3185 ++ high++;
1.3186 ++ }
1.3187 ++ }
1.3188 ++#endif
1.3189 ++ if (!ROUND_TOWARDS_ZERO && (high & GARDMASK) == GARDMSB)
1.3190 ++ {
1.3191 ++ if (high & (1 << NGARDS))
1.3192 ++ {
1.3193 ++ /* half way, so round to even */
1.3194 ++ high += GARDROUND + 1;
1.3195 ++ }
1.3196 ++ else if (low)
1.3197 ++ {
1.3198 ++ /* but we really weren't half way */
1.3199 ++ high += GARDROUND + 1;
1.3200 ++ }
1.3201 ++ }
1.3202 ++ tmp->fraction.ll = high;
1.3203 ++ tmp->class = CLASS_NUMBER;
1.3204 ++ return tmp;
1.3205 ++}
1.3206 ++
1.3207 ++FLO_type
1.3208 ++multiply (FLO_type arg_a, FLO_type arg_b)
1.3209 ++{
1.3210 ++ fp_number_type a;
1.3211 ++ fp_number_type b;
1.3212 ++ fp_number_type tmp;
1.3213 ++ fp_number_type *res;
1.3214 ++ FLO_union_type au, bu;
1.3215 ++
1.3216 ++ au.value = arg_a;
1.3217 ++ bu.value = arg_b;
1.3218 ++
1.3219 ++ unpack_d (&au, &a);
1.3220 ++ unpack_d (&bu, &b);
1.3221 ++
1.3222 ++ res = _fpmul_parts (&a, &b, &tmp);
1.3223 ++
1.3224 ++ return pack_d (res);
1.3225 ++}
1.3226 ++#endif /* L_mul_sf || L_mul_df */
1.3227 ++
1.3228 ++#if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf)
1.3229 ++static inline __attribute__ ((__always_inline__)) fp_number_type *
1.3230 ++_fpdiv_parts (fp_number_type * a,
1.3231 ++ fp_number_type * b)
1.3232 ++{
1.3233 ++ fractype bit;
1.3234 ++ fractype numerator;
1.3235 ++ fractype denominator;
1.3236 ++ fractype quotient;
1.3237 ++
1.3238 ++ if (isnan (a))
1.3239 ++ {
1.3240 ++ return a;
1.3241 ++ }
1.3242 ++ if (isnan (b))
1.3243 ++ {
1.3244 ++ return b;
1.3245 ++ }
1.3246 ++
1.3247 ++ a->sign = a->sign ^ b->sign;
1.3248 ++
1.3249 ++ if (isinf (a) || iszero (a))
1.3250 ++ {
1.3251 ++ if (a->class == b->class)
1.3252 ++ return nan ();
1.3253 ++ return a;
1.3254 ++ }
1.3255 ++
1.3256 ++ if (isinf (b))
1.3257 ++ {
1.3258 ++ a->fraction.ll = 0;
1.3259 ++ a->normal_exp = 0;
1.3260 ++ return a;
1.3261 ++ }
1.3262 ++ if (iszero (b))
1.3263 ++ {
1.3264 ++ a->class = CLASS_INFINITY;
1.3265 ++ return a;
1.3266 ++ }
1.3267 ++
1.3268 ++ /* Calculate the mantissa by multiplying both 64bit numbers to get a
1.3269 ++ 128 bit number */
1.3270 ++ {
1.3271 ++ /* quotient =
1.3272 ++ ( numerator / denominator) * 2^(numerator exponent - denominator exponent)
1.3273 ++ */
1.3274 ++
1.3275 ++ a->normal_exp = a->normal_exp - b->normal_exp;
1.3276 ++ numerator = a->fraction.ll;
1.3277 ++ denominator = b->fraction.ll;
1.3278 ++
1.3279 ++ if (numerator < denominator)
1.3280 ++ {
1.3281 ++ /* Fraction will be less than 1.0 */
1.3282 ++ numerator *= 2;
1.3283 ++ a->normal_exp--;
1.3284 ++ }
1.3285 ++ bit = IMPLICIT_1;
1.3286 ++ quotient = 0;
1.3287 ++ /* ??? Does divide one bit at a time. Optimize. */
1.3288 ++ while (bit)
1.3289 ++ {
1.3290 ++ if (numerator >= denominator)
1.3291 ++ {
1.3292 ++ quotient |= bit;
1.3293 ++ numerator -= denominator;
1.3294 ++ }
1.3295 ++ bit >>= 1;
1.3296 ++ numerator *= 2;
1.3297 ++ }
1.3298 ++
1.3299 ++ if (!ROUND_TOWARDS_ZERO && (quotient & GARDMASK) == GARDMSB)
1.3300 ++ {
1.3301 ++ if (quotient & (1 << NGARDS))
1.3302 ++ {
1.3303 ++ /* half way, so round to even */
1.3304 ++ quotient += GARDROUND + 1;
1.3305 ++ }
1.3306 ++ else if (numerator)
1.3307 ++ {
1.3308 ++ /* but we really weren't half way, more bits exist */
1.3309 ++ quotient += GARDROUND + 1;
1.3310 ++ }
1.3311 ++ }
1.3312 ++
1.3313 ++ a->fraction.ll = quotient;
1.3314 ++ return (a);
1.3315 ++ }
1.3316 ++}
1.3317 ++
1.3318 ++FLO_type
1.3319 ++divide (FLO_type arg_a, FLO_type arg_b)
1.3320 ++{
1.3321 ++ fp_number_type a;
1.3322 ++ fp_number_type b;
1.3323 ++ fp_number_type *res;
1.3324 ++ FLO_union_type au, bu;
1.3325 ++
1.3326 ++ au.value = arg_a;
1.3327 ++ bu.value = arg_b;
1.3328 ++
1.3329 ++ unpack_d (&au, &a);
1.3330 ++ unpack_d (&bu, &b);
1.3331 ++
1.3332 ++ res = _fpdiv_parts (&a, &b);
1.3333 ++
1.3334 ++ return pack_d (res);
1.3335 ++}
1.3336 ++#endif /* L_div_sf || L_div_df */
1.3337 ++
1.3338 ++#if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) \
1.3339 ++ || defined(L_fpcmp_parts_tf)
1.3340 ++/* according to the demo, fpcmp returns a comparison with 0... thus
1.3341 ++ a<b -> -1
1.3342 ++ a==b -> 0
1.3343 ++ a>b -> +1
1.3344 ++ */
1.3345 ++
1.3346 ++int
1.3347 ++__fpcmp_parts (fp_number_type * a, fp_number_type * b)
1.3348 ++{
1.3349 ++#if 0
1.3350 ++ /* either nan -> unordered. Must be checked outside of this routine. */
1.3351 ++ if (isnan (a) && isnan (b))
1.3352 ++ {
1.3353 ++ return 1; /* still unordered! */
1.3354 ++ }
1.3355 ++#endif
1.3356 ++
1.3357 ++ if (isnan (a) || isnan (b))
1.3358 ++ {
1.3359 ++ return 1; /* how to indicate unordered compare? */
1.3360 ++ }
1.3361 ++ if (isinf (a) && isinf (b))
1.3362 ++ {
1.3363 ++ /* +inf > -inf, but +inf != +inf */
1.3364 ++ /* b \a| +inf(0)| -inf(1)
1.3365 ++ ______\+--------+--------
1.3366 ++ +inf(0)| a==b(0)| a<b(-1)
1.3367 ++ -------+--------+--------
1.3368 ++ -inf(1)| a>b(1) | a==b(0)
1.3369 ++ -------+--------+--------
1.3370 ++ So since unordered must be nonzero, just line up the columns...
1.3371 ++ */
1.3372 ++ return b->sign - a->sign;
1.3373 ++ }
1.3374 ++ /* but not both... */
1.3375 ++ if (isinf (a))
1.3376 ++ {
1.3377 ++ return a->sign ? -1 : 1;
1.3378 ++ }
1.3379 ++ if (isinf (b))
1.3380 ++ {
1.3381 ++ return b->sign ? 1 : -1;
1.3382 ++ }
1.3383 ++ if (iszero (a) && iszero (b))
1.3384 ++ {
1.3385 ++ return 0;
1.3386 ++ }
1.3387 ++ if (iszero (a))
1.3388 ++ {
1.3389 ++ return b->sign ? 1 : -1;
1.3390 ++ }
1.3391 ++ if (iszero (b))
1.3392 ++ {
1.3393 ++ return a->sign ? -1 : 1;
1.3394 ++ }
1.3395 ++ /* now both are "normal". */
1.3396 ++ if (a->sign != b->sign)
1.3397 ++ {
1.3398 ++ /* opposite signs */
1.3399 ++ return a->sign ? -1 : 1;
1.3400 ++ }
1.3401 ++ /* same sign; exponents? */
1.3402 ++ if (a->normal_exp > b->normal_exp)
1.3403 ++ {
1.3404 ++ return a->sign ? -1 : 1;
1.3405 ++ }
1.3406 ++ if (a->normal_exp < b->normal_exp)
1.3407 ++ {
1.3408 ++ return a->sign ? 1 : -1;
1.3409 ++ }
1.3410 ++ /* same exponents; check size. */
1.3411 ++ if (a->fraction.ll > b->fraction.ll)
1.3412 ++ {
1.3413 ++ return a->sign ? -1 : 1;
1.3414 ++ }
1.3415 ++ if (a->fraction.ll < b->fraction.ll)
1.3416 ++ {
1.3417 ++ return a->sign ? 1 : -1;
1.3418 ++ }
1.3419 ++ /* after all that, they're equal. */
1.3420 ++ return 0;
1.3421 ++}
1.3422 ++#endif
1.3423 ++
1.3424 ++#if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compoare_tf)
1.3425 ++CMPtype
1.3426 ++compare (FLO_type arg_a, FLO_type arg_b)
1.3427 ++{
1.3428 ++ fp_number_type a;
1.3429 ++ fp_number_type b;
1.3430 ++ FLO_union_type au, bu;
1.3431 ++
1.3432 ++ au.value = arg_a;
1.3433 ++ bu.value = arg_b;
1.3434 ++
1.3435 ++ unpack_d (&au, &a);
1.3436 ++ unpack_d (&bu, &b);
1.3437 ++
1.3438 ++ return __fpcmp_parts (&a, &b);
1.3439 ++}
1.3440 ++#endif /* L_compare_sf || L_compare_df */
1.3441 ++
1.3442 ++#ifndef US_SOFTWARE_GOFAST
1.3443 ++
1.3444 ++/* These should be optimized for their specific tasks someday. */
1.3445 ++
1.3446 ++#if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf)
1.3447 ++CMPtype
1.3448 ++_eq_f2 (FLO_type arg_a, FLO_type arg_b)
1.3449 ++{
1.3450 ++ fp_number_type a;
1.3451 ++ fp_number_type b;
1.3452 ++ FLO_union_type au, bu;
1.3453 ++
1.3454 ++ au.value = arg_a;
1.3455 ++ bu.value = arg_b;
1.3456 ++
1.3457 ++ unpack_d (&au, &a);
1.3458 ++ unpack_d (&bu, &b);
1.3459 ++
1.3460 ++ if (isnan (&a) || isnan (&b))
1.3461 ++ return 1; /* false, truth == 0 */
1.3462 ++
1.3463 ++ return __fpcmp_parts (&a, &b) ;
1.3464 ++}
1.3465 ++#endif /* L_eq_sf || L_eq_df */
1.3466 ++
1.3467 ++#if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf)
1.3468 ++CMPtype
1.3469 ++_ne_f2 (FLO_type arg_a, FLO_type arg_b)
1.3470 ++{
1.3471 ++ fp_number_type a;
1.3472 ++ fp_number_type b;
1.3473 ++ FLO_union_type au, bu;
1.3474 ++
1.3475 ++ au.value = arg_a;
1.3476 ++ bu.value = arg_b;
1.3477 ++
1.3478 ++ unpack_d (&au, &a);
1.3479 ++ unpack_d (&bu, &b);
1.3480 ++
1.3481 ++ if (isnan (&a) || isnan (&b))
1.3482 ++ return 1; /* true, truth != 0 */
1.3483 ++
1.3484 ++ return __fpcmp_parts (&a, &b) ;
1.3485 ++}
1.3486 ++#endif /* L_ne_sf || L_ne_df */
1.3487 ++
1.3488 ++#if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf)
1.3489 ++CMPtype
1.3490 ++_gt_f2 (FLO_type arg_a, FLO_type arg_b)
1.3491 ++{
1.3492 ++ fp_number_type a;
1.3493 ++ fp_number_type b;
1.3494 ++ FLO_union_type au, bu;
1.3495 ++
1.3496 ++ au.value = arg_a;
1.3497 ++ bu.value = arg_b;
1.3498 ++
1.3499 ++ unpack_d (&au, &a);
1.3500 ++ unpack_d (&bu, &b);
1.3501 ++
1.3502 ++ if (isnan (&a) || isnan (&b))
1.3503 ++ return -1; /* false, truth > 0 */
1.3504 ++
1.3505 ++ return __fpcmp_parts (&a, &b);
1.3506 ++}
1.3507 ++#endif /* L_gt_sf || L_gt_df */
1.3508 ++
1.3509 ++#if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf)
1.3510 ++CMPtype
1.3511 ++_ge_f2 (FLO_type arg_a, FLO_type arg_b)
1.3512 ++{
1.3513 ++ fp_number_type a;
1.3514 ++ fp_number_type b;
1.3515 ++ FLO_union_type au, bu;
1.3516 ++
1.3517 ++ au.value = arg_a;
1.3518 ++ bu.value = arg_b;
1.3519 ++
1.3520 ++ unpack_d (&au, &a);
1.3521 ++ unpack_d (&bu, &b);
1.3522 ++
1.3523 ++ if (isnan (&a) || isnan (&b))
1.3524 ++ return -1; /* false, truth >= 0 */
1.3525 ++ return __fpcmp_parts (&a, &b) ;
1.3526 ++}
1.3527 ++#endif /* L_ge_sf || L_ge_df */
1.3528 ++
1.3529 ++#if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf)
1.3530 ++CMPtype
1.3531 ++_lt_f2 (FLO_type arg_a, FLO_type arg_b)
1.3532 ++{
1.3533 ++ fp_number_type a;
1.3534 ++ fp_number_type b;
1.3535 ++ FLO_union_type au, bu;
1.3536 ++
1.3537 ++ au.value = arg_a;
1.3538 ++ bu.value = arg_b;
1.3539 ++
1.3540 ++ unpack_d (&au, &a);
1.3541 ++ unpack_d (&bu, &b);
1.3542 ++
1.3543 ++ if (isnan (&a) || isnan (&b))
1.3544 ++ return 1; /* false, truth < 0 */
1.3545 ++
1.3546 ++ return __fpcmp_parts (&a, &b);
1.3547 ++}
1.3548 ++#endif /* L_lt_sf || L_lt_df */
1.3549 ++
1.3550 ++#if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf)
1.3551 ++CMPtype
1.3552 ++_le_f2 (FLO_type arg_a, FLO_type arg_b)
1.3553 ++{
1.3554 ++ fp_number_type a;
1.3555 ++ fp_number_type b;
1.3556 ++ FLO_union_type au, bu;
1.3557 ++
1.3558 ++ au.value = arg_a;
1.3559 ++ bu.value = arg_b;
1.3560 ++
1.3561 ++ unpack_d (&au, &a);
1.3562 ++ unpack_d (&bu, &b);
1.3563 ++
1.3564 ++ if (isnan (&a) || isnan (&b))
1.3565 ++ return 1; /* false, truth <= 0 */
1.3566 ++
1.3567 ++ return __fpcmp_parts (&a, &b) ;
1.3568 ++}
1.3569 ++#endif /* L_le_sf || L_le_df */
1.3570 ++
1.3571 ++#endif /* ! US_SOFTWARE_GOFAST */
1.3572 ++
1.3573 ++#if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf)
1.3574 ++CMPtype
1.3575 ++_unord_f2 (FLO_type arg_a, FLO_type arg_b)
1.3576 ++{
1.3577 ++ fp_number_type a;
1.3578 ++ fp_number_type b;
1.3579 ++ FLO_union_type au, bu;
1.3580 ++
1.3581 ++ au.value = arg_a;
1.3582 ++ bu.value = arg_b;
1.3583 ++
1.3584 ++ unpack_d (&au, &a);
1.3585 ++ unpack_d (&bu, &b);
1.3586 ++
1.3587 ++ return (isnan (&a) || isnan (&b));
1.3588 ++}
1.3589 ++#endif /* L_unord_sf || L_unord_df */
1.3590 ++
1.3591 ++#if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf)
1.3592 ++FLO_type
1.3593 ++si_to_float (SItype arg_a)
1.3594 ++{
1.3595 ++ fp_number_type in;
1.3596 ++
1.3597 ++ in.class = CLASS_NUMBER;
1.3598 ++ in.sign = arg_a < 0;
1.3599 ++ if (!arg_a)
1.3600 ++ {
1.3601 ++ in.class = CLASS_ZERO;
1.3602 ++ }
1.3603 ++ else
1.3604 ++ {
1.3605 ++ in.normal_exp = FRACBITS + NGARDS;
1.3606 ++ if (in.sign)
1.3607 ++ {
1.3608 ++ /* Special case for minint, since there is no +ve integer
1.3609 ++ representation for it */
1.3610 ++ if (arg_a == (- MAX_SI_INT - 1))
1.3611 ++ {
1.3612 ++ return (FLO_type)(- MAX_SI_INT - 1);
1.3613 ++ }
1.3614 ++ in.fraction.ll = (-arg_a);
1.3615 ++ }
1.3616 ++ else
1.3617 ++ in.fraction.ll = arg_a;
1.3618 ++
1.3619 ++ while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS)))
1.3620 ++ {
1.3621 ++ in.fraction.ll <<= 1;
1.3622 ++ in.normal_exp -= 1;
1.3623 ++ }
1.3624 ++ }
1.3625 ++ return pack_d (&in);
1.3626 ++}
1.3627 ++#endif /* L_si_to_sf || L_si_to_df */
1.3628 ++
1.3629 ++#if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf)
1.3630 ++FLO_type
1.3631 ++usi_to_float (USItype arg_a)
1.3632 ++{
1.3633 ++ fp_number_type in;
1.3634 ++
1.3635 ++ in.sign = 0;
1.3636 ++ if (!arg_a)
1.3637 ++ {
1.3638 ++ in.class = CLASS_ZERO;
1.3639 ++ }
1.3640 ++ else
1.3641 ++ {
1.3642 ++ in.class = CLASS_NUMBER;
1.3643 ++ in.normal_exp = FRACBITS + NGARDS;
1.3644 ++ in.fraction.ll = arg_a;
1.3645 ++
1.3646 ++ while (in.fraction.ll > ((fractype)1 << (FRACBITS + NGARDS)))
1.3647 ++ {
1.3648 ++ in.fraction.ll >>= 1;
1.3649 ++ in.normal_exp += 1;
1.3650 ++ }
1.3651 ++ while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS)))
1.3652 ++ {
1.3653 ++ in.fraction.ll <<= 1;
1.3654 ++ in.normal_exp -= 1;
1.3655 ++ }
1.3656 ++ }
1.3657 ++ return pack_d (&in);
1.3658 ++}
1.3659 ++#endif
1.3660 ++
1.3661 ++#if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si)
1.3662 ++SItype
1.3663 ++float_to_si (FLO_type arg_a)
1.3664 ++{
1.3665 ++ fp_number_type a;
1.3666 ++ SItype tmp;
1.3667 ++ FLO_union_type au;
1.3668 ++
1.3669 ++ au.value = arg_a;
1.3670 ++ unpack_d (&au, &a);
1.3671 ++
1.3672 ++ if (iszero (&a))
1.3673 ++ return 0;
1.3674 ++ if (isnan (&a))
1.3675 ++ return 0;
1.3676 ++ /* get reasonable MAX_SI_INT... */
1.3677 ++ if (isinf (&a))
1.3678 ++ return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
1.3679 ++ /* it is a number, but a small one */
1.3680 ++ if (a.normal_exp < 0)
1.3681 ++ return 0;
1.3682 ++ if (a.normal_exp > BITS_PER_SI - 2)
1.3683 ++ return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
1.3684 ++ tmp = a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
1.3685 ++ return a.sign ? (-tmp) : (tmp);
1.3686 ++}
1.3687 ++#endif /* L_sf_to_si || L_df_to_si */
1.3688 ++
1.3689 ++#if defined(L_sf_to_usi) || defined(L_df_to_usi) || defined(L_tf_to_usi)
1.3690 ++#if defined US_SOFTWARE_GOFAST || defined(L_tf_to_usi)
1.3691 ++/* While libgcc2.c defines its own __fixunssfsi and __fixunsdfsi routines,
1.3692 ++ we also define them for GOFAST because the ones in libgcc2.c have the
1.3693 ++ wrong names and I'd rather define these here and keep GOFAST CYG-LOC's
1.3694 ++ out of libgcc2.c. We can't define these here if not GOFAST because then
1.3695 ++ there'd be duplicate copies. */
1.3696 ++
1.3697 ++USItype
1.3698 ++float_to_usi (FLO_type arg_a)
1.3699 ++{
1.3700 ++ fp_number_type a;
1.3701 ++ FLO_union_type au;
1.3702 ++
1.3703 ++ au.value = arg_a;
1.3704 ++ unpack_d (&au, &a);
1.3705 ++
1.3706 ++ if (iszero (&a))
1.3707 ++ return 0;
1.3708 ++ if (isnan (&a))
1.3709 ++ return 0;
1.3710 ++ /* it is a negative number */
1.3711 ++ if (a.sign)
1.3712 ++ return 0;
1.3713 ++ /* get reasonable MAX_USI_INT... */
1.3714 ++ if (isinf (&a))
1.3715 ++ return MAX_USI_INT;
1.3716 ++ /* it is a number, but a small one */
1.3717 ++ if (a.normal_exp < 0)
1.3718 ++ return 0;
1.3719 ++ if (a.normal_exp > BITS_PER_SI - 1)
1.3720 ++ return MAX_USI_INT;
1.3721 ++ else if (a.normal_exp > (FRACBITS + NGARDS))
1.3722 ++ return a.fraction.ll << (a.normal_exp - (FRACBITS + NGARDS));
1.3723 ++ else
1.3724 ++ return a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
1.3725 ++}
1.3726 ++#endif /* US_SOFTWARE_GOFAST */
1.3727 ++#endif /* L_sf_to_usi || L_df_to_usi */
1.3728 ++
1.3729 ++#if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf)
1.3730 ++FLO_type
1.3731 ++negate (FLO_type arg_a)
1.3732 ++{
1.3733 ++ fp_number_type a;
1.3734 ++ FLO_union_type au;
1.3735 ++
1.3736 ++ au.value = arg_a;
1.3737 ++ unpack_d (&au, &a);
1.3738 ++
1.3739 ++ flip_sign (&a);
1.3740 ++ return pack_d (&a);
1.3741 ++}
1.3742 ++#endif /* L_negate_sf || L_negate_df */
1.3743 ++
1.3744 ++#ifdef FLOAT
1.3745 ++
1.3746 ++#if defined(L_make_sf)
1.3747 ++SFtype
1.3748 ++__make_fp(fp_class_type class,
1.3749 ++ unsigned int sign,
1.3750 ++ int exp,
1.3751 ++ USItype frac)
1.3752 ++{
1.3753 ++ fp_number_type in;
1.3754 ++
1.3755 ++ in.class = class;
1.3756 ++ in.sign = sign;
1.3757 ++ in.normal_exp = exp;
1.3758 ++ in.fraction.ll = frac;
1.3759 ++ return pack_d (&in);
1.3760 ++}
1.3761 ++#endif /* L_make_sf */
1.3762 ++
1.3763 ++#ifndef FLOAT_ONLY
1.3764 ++
1.3765 ++/* This enables one to build an fp library that supports float but not double.
1.3766 ++ Otherwise, we would get an undefined reference to __make_dp.
1.3767 ++ This is needed for some 8-bit ports that can't handle well values that
1.3768 ++ are 8-bytes in size, so we just don't support double for them at all. */
1.3769 ++
1.3770 ++#if defined(L_sf_to_df)
1.3771 ++DFtype
1.3772 ++sf_to_df (SFtype arg_a)
1.3773 ++{
1.3774 ++ fp_number_type in;
1.3775 ++ FLO_union_type au;
1.3776 ++
1.3777 ++ au.value = arg_a;
1.3778 ++ unpack_d (&au, &in);
1.3779 ++
1.3780 ++ return __make_dp (in.class, in.sign, in.normal_exp,
1.3781 ++ ((UDItype) in.fraction.ll) << F_D_BITOFF);
1.3782 ++}
1.3783 ++#endif /* L_sf_to_df */
1.3784 ++
1.3785 ++#if defined(L_sf_to_tf) && defined(TMODES)
1.3786 ++TFtype
1.3787 ++sf_to_tf (SFtype arg_a)
1.3788 ++{
1.3789 ++ fp_number_type in;
1.3790 ++ FLO_union_type au;
1.3791 ++
1.3792 ++ au.value = arg_a;
1.3793 ++ unpack_d (&au, &in);
1.3794 ++
1.3795 ++ return __make_tp (in.class, in.sign, in.normal_exp,
1.3796 ++ ((UTItype) in.fraction.ll) << F_T_BITOFF);
1.3797 ++}
1.3798 ++#endif /* L_sf_to_df */
1.3799 ++
1.3800 ++#endif /* ! FLOAT_ONLY */
1.3801 ++#endif /* FLOAT */
1.3802 ++
1.3803 ++#ifndef FLOAT
1.3804 ++
1.3805 ++extern SFtype __make_fp (fp_class_type, unsigned int, int, USItype);
1.3806 ++
1.3807 ++#if defined(L_make_df)
1.3808 ++DFtype
1.3809 ++__make_dp (fp_class_type class, unsigned int sign, int exp, UDItype frac)
1.3810 ++{
1.3811 ++ fp_number_type in;
1.3812 ++
1.3813 ++ in.class = class;
1.3814 ++ in.sign = sign;
1.3815 ++ in.normal_exp = exp;
1.3816 ++ in.fraction.ll = frac;
1.3817 ++ return pack_d (&in);
1.3818 ++}
1.3819 ++#endif /* L_make_df */
1.3820 ++
1.3821 ++#if defined(L_df_to_sf)
1.3822 ++SFtype
1.3823 ++df_to_sf (DFtype arg_a)
1.3824 ++{
1.3825 ++ fp_number_type in;
1.3826 ++ USItype sffrac;
1.3827 ++ FLO_union_type au;
1.3828 ++
1.3829 ++ au.value = arg_a;
1.3830 ++ unpack_d (&au, &in);
1.3831 ++
1.3832 ++ sffrac = in.fraction.ll >> F_D_BITOFF;
1.3833 ++
1.3834 ++ /* We set the lowest guard bit in SFFRAC if we discarded any non
1.3835 ++ zero bits. */
1.3836 ++ if ((in.fraction.ll & (((USItype) 1 << F_D_BITOFF) - 1)) != 0)
1.3837 ++ sffrac |= 1;
1.3838 ++
1.3839 ++ return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
1.3840 ++}
1.3841 ++#endif /* L_df_to_sf */
1.3842 ++
1.3843 ++#if defined(L_df_to_tf) && defined(TMODES) \
1.3844 ++ && !defined(FLOAT) && !defined(TFLOAT)
1.3845 ++TFtype
1.3846 ++df_to_tf (DFtype arg_a)
1.3847 ++{
1.3848 ++ fp_number_type in;
1.3849 ++ FLO_union_type au;
1.3850 ++
1.3851 ++ au.value = arg_a;
1.3852 ++ unpack_d (&au, &in);
1.3853 ++
1.3854 ++ return __make_tp (in.class, in.sign, in.normal_exp,
1.3855 ++ ((UTItype) in.fraction.ll) << D_T_BITOFF);
1.3856 ++}
1.3857 ++#endif /* L_sf_to_df */
1.3858 ++
1.3859 ++#ifdef TFLOAT
1.3860 ++#if defined(L_make_tf)
1.3861 ++TFtype
1.3862 ++__make_tp(fp_class_type class,
1.3863 ++ unsigned int sign,
1.3864 ++ int exp,
1.3865 ++ UTItype frac)
1.3866 ++{
1.3867 ++ fp_number_type in;
1.3868 ++
1.3869 ++ in.class = class;
1.3870 ++ in.sign = sign;
1.3871 ++ in.normal_exp = exp;
1.3872 ++ in.fraction.ll = frac;
1.3873 ++ return pack_d (&in);
1.3874 ++}
1.3875 ++#endif /* L_make_tf */
1.3876 ++
1.3877 ++#if defined(L_tf_to_df)
1.3878 ++DFtype
1.3879 ++tf_to_df (TFtype arg_a)
1.3880 ++{
1.3881 ++ fp_number_type in;
1.3882 ++ UDItype sffrac;
1.3883 ++ FLO_union_type au;
1.3884 ++
1.3885 ++ au.value = arg_a;
1.3886 ++ unpack_d (&au, &in);
1.3887 ++
1.3888 ++ sffrac = in.fraction.ll >> D_T_BITOFF;
1.3889 ++
1.3890 ++ /* We set the lowest guard bit in SFFRAC if we discarded any non
1.3891 ++ zero bits. */
1.3892 ++ if ((in.fraction.ll & (((UTItype) 1 << D_T_BITOFF) - 1)) != 0)
1.3893 ++ sffrac |= 1;
1.3894 ++
1.3895 ++ return __make_dp (in.class, in.sign, in.normal_exp, sffrac);
1.3896 ++}
1.3897 ++#endif /* L_tf_to_df */
1.3898 ++
1.3899 ++#if defined(L_tf_to_sf)
1.3900 ++SFtype
1.3901 ++tf_to_sf (TFtype arg_a)
1.3902 ++{
1.3903 ++ fp_number_type in;
1.3904 ++ USItype sffrac;
1.3905 ++ FLO_union_type au;
1.3906 ++
1.3907 ++ au.value = arg_a;
1.3908 ++ unpack_d (&au, &in);
1.3909 ++
1.3910 ++ sffrac = in.fraction.ll >> F_T_BITOFF;
1.3911 ++
1.3912 ++ /* We set the lowest guard bit in SFFRAC if we discarded any non
1.3913 ++ zero bits. */
1.3914 ++ if ((in.fraction.ll & (((UTItype) 1 << F_T_BITOFF) - 1)) != 0)
1.3915 ++ sffrac |= 1;
1.3916 ++
1.3917 ++ return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
1.3918 ++}
1.3919 ++#endif /* L_tf_to_sf */
1.3920 ++#endif /* TFLOAT */
1.3921 ++
1.3922 ++#endif /* ! FLOAT */
1.3923 ++#endif /* !EXTENDED_FLOAT_STUBS */
1.3924 +--- gcc-3.4.3/gcc/config/nios2/nios2-protos.h
1.3925 ++++ gcc-3.4.3-nios2/gcc/config/nios2/nios2-protos.h
1.3926 +@@ -0,0 +1,70 @@
1.3927 ++/* Subroutines for assembler code output for Altera NIOS 2G NIOS2 version.
1.3928 ++ Copyright (C) 2003 Altera
1.3929 ++ Contributed by Jonah Graham (jgraham@altera.com).
1.3930 ++
1.3931 ++This file is part of GNU CC.
1.3932 ++
1.3933 ++GNU CC is free software; you can redistribute it and/or modify
1.3934 ++it under the terms of the GNU General Public License as published by
1.3935 ++the Free Software Foundation; either version 2, or (at your option)
1.3936 ++any later version.
1.3937 ++
1.3938 ++GNU CC is distributed in the hope that it will be useful,
1.3939 ++but WITHOUT ANY WARRANTY; without even the implied warranty of
1.3940 ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.3941 ++GNU General Public License for more details.
1.3942 ++
1.3943 ++You should have received a copy of the GNU General Public License
1.3944 ++along with GNU CC; see the file COPYING. If not, write to
1.3945 ++the Free Software Foundation, 59 Temple Place - Suite 330,
1.3946 ++Boston, MA 02111-1307, USA. */
1.3947 ++
1.3948 ++extern void dump_frame_size (FILE *);
1.3949 ++extern HOST_WIDE_INT compute_frame_size (void);
1.3950 ++extern int nios2_initial_elimination_offset (int, int);
1.3951 ++extern void override_options (void);
1.3952 ++extern void optimization_options (int, int);
1.3953 ++extern int nios2_can_use_return_insn (void);
1.3954 ++extern void expand_prologue (void);
1.3955 ++extern void expand_epilogue (bool);
1.3956 ++extern void function_profiler (FILE *, int);
1.3957 ++
1.3958 ++
1.3959 ++#ifdef RTX_CODE
1.3960 ++extern int nios2_legitimate_address (rtx, enum machine_mode, int);
1.3961 ++extern void nios2_print_operand (FILE *, rtx, int);
1.3962 ++extern void nios2_print_operand_address (FILE *, rtx);
1.3963 ++
1.3964 ++extern int nios2_emit_move_sequence (rtx *, enum machine_mode);
1.3965 ++extern int nios2_emit_expensive_div (rtx *, enum machine_mode);
1.3966 ++
1.3967 ++extern void gen_int_relational (enum rtx_code, rtx, rtx, rtx, rtx);
1.3968 ++extern void gen_conditional_move (rtx *, enum machine_mode);
1.3969 ++extern const char *asm_output_opcode (FILE *, const char *);
1.3970 ++
1.3971 ++/* predicates */
1.3972 ++extern int arith_operand (rtx, enum machine_mode);
1.3973 ++extern int uns_arith_operand (rtx, enum machine_mode);
1.3974 ++extern int logical_operand (rtx, enum machine_mode);
1.3975 ++extern int shift_operand (rtx, enum machine_mode);
1.3976 ++extern int reg_or_0_operand (rtx, enum machine_mode);
1.3977 ++extern int equality_op (rtx, enum machine_mode);
1.3978 ++extern int custom_insn_opcode (rtx, enum machine_mode);
1.3979 ++extern int rdwrctl_operand (rtx, enum machine_mode);
1.3980 ++
1.3981 ++# ifdef HAVE_MACHINE_MODES
1.3982 ++# if defined TREE_CODE
1.3983 ++extern void function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
1.3984 ++extern rtx function_arg (const CUMULATIVE_ARGS *, enum machine_mode, tree, int);
1.3985 ++extern int function_arg_partial_nregs (const CUMULATIVE_ARGS *, enum machine_mode, tree, int);
1.3986 ++extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree, int);
1.3987 ++extern int nios2_setup_incoming_varargs (const CUMULATIVE_ARGS *, enum machine_mode, tree, int);
1.3988 ++
1.3989 ++# endif /* TREE_CODE */
1.3990 ++# endif /* HAVE_MACHINE_MODES */
1.3991 ++#endif
1.3992 ++
1.3993 ++#ifdef TREE_CODE
1.3994 ++extern int nios2_return_in_memory (tree);
1.3995 ++
1.3996 ++#endif /* TREE_CODE */
1.3997 +--- gcc-3.4.3/gcc/config/nios2/nios2.c
1.3998 ++++ gcc-3.4.3-nios2/gcc/config/nios2/nios2.c
1.3999 +@@ -0,0 +1,2853 @@
1.4000 ++/* Subroutines for assembler code output for Altera NIOS 2G NIOS2 version.
1.4001 ++ Copyright (C) 2003 Altera
1.4002 ++ Contributed by Jonah Graham (jgraham@altera.com).
1.4003 ++
1.4004 ++This file is part of GNU CC.
1.4005 ++
1.4006 ++GNU CC is free software; you can redistribute it and/or modify
1.4007 ++it under the terms of the GNU General Public License as published by
1.4008 ++the Free Software Foundation; either version 2, or (at your option)
1.4009 ++any later version.
1.4010 ++
1.4011 ++GNU CC is distributed in the hope that it will be useful,
1.4012 ++but WITHOUT ANY WARRANTY; without even the implied warranty of
1.4013 ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.4014 ++GNU General Public License for more details.
1.4015 ++
1.4016 ++You should have received a copy of the GNU General Public License
1.4017 ++along with GNU CC; see the file COPYING. If not, write to
1.4018 ++the Free Software Foundation, 59 Temple Place - Suite 330,
1.4019 ++Boston, MA 02111-1307, USA. */
1.4020 ++
1.4021 ++
1.4022 ++#include <stdio.h>
1.4023 ++#include "config.h"
1.4024 ++#include "system.h"
1.4025 ++#include "coretypes.h"
1.4026 ++#include "tm.h"
1.4027 ++#include "rtl.h"
1.4028 ++#include "tree.h"
1.4029 ++#include "tm_p.h"
1.4030 ++#include "regs.h"
1.4031 ++#include "hard-reg-set.h"
1.4032 ++#include "real.h"
1.4033 ++#include "insn-config.h"
1.4034 ++#include "conditions.h"
1.4035 ++#include "output.h"
1.4036 ++#include "insn-attr.h"
1.4037 ++#include "flags.h"
1.4038 ++#include "recog.h"
1.4039 ++#include "expr.h"
1.4040 ++#include "toplev.h"
1.4041 ++#include "basic-block.h"
1.4042 ++#include "function.h"
1.4043 ++#include "ggc.h"
1.4044 ++#include "reload.h"
1.4045 ++#include "debug.h"
1.4046 ++#include "optabs.h"
1.4047 ++#include "target.h"
1.4048 ++#include "target-def.h"
1.4049 ++
1.4050 ++/* local prototypes */
1.4051 ++static bool nios2_rtx_costs (rtx, int, int, int *);
1.4052 ++
1.4053 ++static void nios2_asm_function_prologue (FILE *, HOST_WIDE_INT);
1.4054 ++static int nios2_use_dfa_pipeline_interface (void);
1.4055 ++static int nios2_issue_rate (void);
1.4056 ++static struct machine_function *nios2_init_machine_status (void);
1.4057 ++static bool nios2_in_small_data_p (tree);
1.4058 ++static rtx save_reg (int, HOST_WIDE_INT, rtx);
1.4059 ++static rtx restore_reg (int, HOST_WIDE_INT);
1.4060 ++static unsigned int nios2_section_type_flags (tree, const char *, int);
1.4061 ++static void nios2_init_builtins (void);
1.4062 ++static rtx nios2_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1.4063 ++static bool nios2_function_ok_for_sibcall (tree, tree);
1.4064 ++static void nios2_encode_section_info (tree, rtx, int);
1.4065 ++
1.4066 ++/* Initialize the GCC target structure. */
1.4067 ++#undef TARGET_ASM_FUNCTION_PROLOGUE
1.4068 ++#define TARGET_ASM_FUNCTION_PROLOGUE nios2_asm_function_prologue
1.4069 ++
1.4070 ++#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
1.4071 ++#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE \
1.4072 ++ nios2_use_dfa_pipeline_interface
1.4073 ++#undef TARGET_SCHED_ISSUE_RATE
1.4074 ++#define TARGET_SCHED_ISSUE_RATE nios2_issue_rate
1.4075 ++#undef TARGET_IN_SMALL_DATA_P
1.4076 ++#define TARGET_IN_SMALL_DATA_P nios2_in_small_data_p
1.4077 ++#undef TARGET_ENCODE_SECTION_INFO
1.4078 ++#define TARGET_ENCODE_SECTION_INFO nios2_encode_section_info
1.4079 ++#undef TARGET_SECTION_TYPE_FLAGS
1.4080 ++#define TARGET_SECTION_TYPE_FLAGS nios2_section_type_flags
1.4081 ++
1.4082 ++#undef TARGET_INIT_BUILTINS
1.4083 ++#define TARGET_INIT_BUILTINS nios2_init_builtins
1.4084 ++#undef TARGET_EXPAND_BUILTIN
1.4085 ++#define TARGET_EXPAND_BUILTIN nios2_expand_builtin
1.4086 ++
1.4087 ++#undef TARGET_FUNCTION_OK_FOR_SIBCALL
1.4088 ++#define TARGET_FUNCTION_OK_FOR_SIBCALL nios2_function_ok_for_sibcall
1.4089 ++
1.4090 ++#undef TARGET_RTX_COSTS
1.4091 ++#define TARGET_RTX_COSTS nios2_rtx_costs
1.4092 ++
1.4093 ++
1.4094 ++struct gcc_target targetm = TARGET_INITIALIZER;
1.4095 ++
1.4096 ++
1.4097 ++
1.4098 ++/* Threshold for data being put into the small data/bss area, instead
1.4099 ++ of the normal data area (references to the small data/bss area take
1.4100 ++ 1 instruction, and use the global pointer, references to the normal
1.4101 ++ data area takes 2 instructions). */
1.4102 ++unsigned HOST_WIDE_INT nios2_section_threshold = NIOS2_DEFAULT_GVALUE;
1.4103 ++
1.4104 ++
1.4105 ++/* Structure to be filled in by compute_frame_size with register
1.4106 ++ save masks, and offsets for the current function. */
1.4107 ++
1.4108 ++struct nios2_frame_info
1.4109 ++GTY (())
1.4110 ++{
1.4111 ++ long total_size; /* # bytes that the entire frame takes up */
1.4112 ++ long var_size; /* # bytes that variables take up */
1.4113 ++ long args_size; /* # bytes that outgoing arguments take up */
1.4114 ++ int save_reg_size; /* # bytes needed to store gp regs */
1.4115 ++ int save_reg_rounded; /* # bytes needed to store gp regs */
1.4116 ++ long save_regs_offset; /* offset from new sp to store gp registers */
1.4117 ++ int initialized; /* != 0 if frame size already calculated */
1.4118 ++ int num_regs; /* number of gp registers saved */
1.4119 ++};
1.4120 ++
1.4121 ++struct machine_function
1.4122 ++GTY (())
1.4123 ++{
1.4124 ++
1.4125 ++ /* Current frame information, calculated by compute_frame_size. */
1.4126 ++ struct nios2_frame_info frame;
1.4127 ++};
1.4128 ++
1.4129 ++
1.4130 ++/***************************************
1.4131 ++ * Section encodings
1.4132 ++ ***************************************/
1.4133 ++
1.4134 ++
1.4135 ++
1.4136 ++
1.4137 ++
1.4138 ++/***************************************
1.4139 ++ * Stack Layout and Calling Conventions
1.4140 ++ ***************************************/
1.4141 ++
1.4142 ++
1.4143 ++#define TOO_BIG_OFFSET(X) ((X) > ((1 << 15) - 1))
1.4144 ++#define TEMP_REG_NUM 8
1.4145 ++
1.4146 ++static void
1.4147 ++nios2_asm_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
1.4148 ++{
1.4149 ++ if (flag_verbose_asm || flag_debug_asm)
1.4150 ++ {
1.4151 ++ compute_frame_size ();
1.4152 ++ dump_frame_size (file);
1.4153 ++ }
1.4154 ++}
1.4155 ++
1.4156 ++static rtx
1.4157 ++save_reg (int regno, HOST_WIDE_INT offset, rtx cfa_store_reg)
1.4158 ++{
1.4159 ++ rtx insn, stack_slot;
1.4160 ++
1.4161 ++ stack_slot = gen_rtx_PLUS (SImode,
1.4162 ++ cfa_store_reg,
1.4163 ++ GEN_INT (offset));
1.4164 ++
1.4165 ++ insn = emit_insn (gen_rtx_SET (SImode,
1.4166 ++ gen_rtx_MEM (SImode, stack_slot),
1.4167 ++ gen_rtx_REG (SImode, regno)));
1.4168 ++
1.4169 ++ RTX_FRAME_RELATED_P (insn) = 1;
1.4170 ++
1.4171 ++ return insn;
1.4172 ++}
1.4173 ++
1.4174 ++static rtx
1.4175 ++restore_reg (int regno, HOST_WIDE_INT offset)
1.4176 ++{
1.4177 ++ rtx insn, stack_slot;
1.4178 ++
1.4179 ++ if (TOO_BIG_OFFSET (offset))
1.4180 ++ {
1.4181 ++ stack_slot = gen_rtx_REG (SImode, TEMP_REG_NUM);
1.4182 ++ insn = emit_insn (gen_rtx_SET (SImode,
1.4183 ++ stack_slot,
1.4184 ++ GEN_INT (offset)));
1.4185 ++
1.4186 ++ insn = emit_insn (gen_rtx_SET (SImode,
1.4187 ++ stack_slot,
1.4188 ++ gen_rtx_PLUS (SImode,
1.4189 ++ stack_slot,
1.4190 ++ stack_pointer_rtx)));
1.4191 ++ }
1.4192 ++ else
1.4193 ++ {
1.4194 ++ stack_slot = gen_rtx_PLUS (SImode,
1.4195 ++ stack_pointer_rtx,
1.4196 ++ GEN_INT (offset));
1.4197 ++ }
1.4198 ++
1.4199 ++ stack_slot = gen_rtx_MEM (SImode, stack_slot);
1.4200 ++
1.4201 ++ insn = emit_move_insn (gen_rtx_REG (SImode, regno), stack_slot);
1.4202 ++
1.4203 ++ return insn;
1.4204 ++}
1.4205 ++
1.4206 ++
1.4207 ++/* There are two possible paths for prologue expansion,
1.4208 ++- the first is if the total frame size is < 2^15-1. In that
1.4209 ++case all the immediates will fit into the 16-bit immediate
1.4210 ++fields.
1.4211 ++- the second is when the frame size is too big, in that
1.4212 ++case an additional temporary register is used, first
1.4213 ++as a cfa_temp to offset the sp, second as the cfa_store
1.4214 ++register.
1.4215 ++
1.4216 ++See the comment above dwarf2out_frame_debug_expr in
1.4217 ++dwarf2out.c for more explanation of the "rules."
1.4218 ++
1.4219 ++
1.4220 ++Case 1:
1.4221 ++Rule # Example Insn Effect
1.4222 ++2 addi sp, sp, -total_frame_size cfa.reg=sp, cfa.offset=total_frame_size
1.4223 ++ cfa_store.reg=sp, cfa_store.offset=total_frame_size
1.4224 ++12 stw ra, offset(sp)
1.4225 ++12 stw r16, offset(sp)
1.4226 ++1 mov fp, sp
1.4227 ++
1.4228 ++Case 2:
1.4229 ++Rule # Example Insn Effect
1.4230 ++6 movi r8, total_frame_size cfa_temp.reg=r8, cfa_temp.offset=total_frame_size
1.4231 ++2 sub sp, sp, r8 cfa.reg=sp, cfa.offset=total_frame_size
1.4232 ++ cfa_store.reg=sp, cfa_store.offset=total_frame_size
1.4233 ++5 add r8, r8, sp cfa_store.reg=r8, cfa_store.offset=0
1.4234 ++12 stw ra, offset(r8)
1.4235 ++12 stw r16, offset(r8)
1.4236 ++1 mov fp, sp
1.4237 ++
1.4238 ++*/
1.4239 ++
1.4240 ++void
1.4241 ++expand_prologue ()
1.4242 ++{
1.4243 ++ int i;
1.4244 ++ HOST_WIDE_INT total_frame_size;
1.4245 ++ int cfa_store_offset;
1.4246 ++ rtx insn;
1.4247 ++ rtx cfa_store_reg = 0;
1.4248 ++
1.4249 ++ total_frame_size = compute_frame_size ();
1.4250 ++
1.4251 ++ if (total_frame_size)
1.4252 ++ {
1.4253 ++
1.4254 ++ if (TOO_BIG_OFFSET (total_frame_size))
1.4255 ++ {
1.4256 ++ /* cfa_temp and cfa_store_reg are the same register,
1.4257 ++ cfa_store_reg overwrites cfa_temp */
1.4258 ++ cfa_store_reg = gen_rtx_REG (SImode, TEMP_REG_NUM);
1.4259 ++ insn = emit_insn (gen_rtx_SET (SImode,
1.4260 ++ cfa_store_reg,
1.4261 ++ GEN_INT (total_frame_size)));
1.4262 ++
1.4263 ++ RTX_FRAME_RELATED_P (insn) = 1;
1.4264 ++
1.4265 ++
1.4266 ++ insn = gen_rtx_SET (SImode,
1.4267 ++ stack_pointer_rtx,
1.4268 ++ gen_rtx_MINUS (SImode,
1.4269 ++ stack_pointer_rtx,
1.4270 ++ cfa_store_reg));
1.4271 ++
1.4272 ++ insn = emit_insn (insn);
1.4273 ++ RTX_FRAME_RELATED_P (insn) = 1;
1.4274 ++
1.4275 ++
1.4276 ++ /* if there are no registers to save, I don't need to
1.4277 ++ create a cfa_store */
1.4278 ++ if (cfun->machine->frame.save_reg_size)
1.4279 ++ {
1.4280 ++ insn = gen_rtx_SET (SImode,
1.4281 ++ cfa_store_reg,
1.4282 ++ gen_rtx_PLUS (SImode,
1.4283 ++ cfa_store_reg,
1.4284 ++ stack_pointer_rtx));
1.4285 ++
1.4286 ++ insn = emit_insn (insn);
1.4287 ++ RTX_FRAME_RELATED_P (insn) = 1;
1.4288 ++ }
1.4289 ++
1.4290 ++ cfa_store_offset
1.4291 ++ = total_frame_size
1.4292 ++ - (cfun->machine->frame.save_regs_offset
1.4293 ++ + cfun->machine->frame.save_reg_rounded);
1.4294 ++ }
1.4295 ++ else
1.4296 ++ {
1.4297 ++ insn = gen_rtx_SET (SImode,
1.4298 ++ stack_pointer_rtx,
1.4299 ++ gen_rtx_PLUS (SImode,
1.4300 ++ stack_pointer_rtx,
1.4301 ++ GEN_INT (-total_frame_size)));
1.4302 ++ insn = emit_insn (insn);
1.4303 ++ RTX_FRAME_RELATED_P (insn) = 1;
1.4304 ++
1.4305 ++ cfa_store_reg = stack_pointer_rtx;
1.4306 ++ cfa_store_offset
1.4307 ++ = cfun->machine->frame.save_regs_offset
1.4308 ++ + cfun->machine->frame.save_reg_rounded;
1.4309 ++ }
1.4310 ++ }
1.4311 ++
1.4312 ++ if (MUST_SAVE_REGISTER (RA_REGNO))
1.4313 ++ {
1.4314 ++ cfa_store_offset -= 4;
1.4315 ++ save_reg (RA_REGNO, cfa_store_offset, cfa_store_reg);
1.4316 ++ }
1.4317 ++ if (MUST_SAVE_REGISTER (FP_REGNO))
1.4318 ++ {
1.4319 ++ cfa_store_offset -= 4;
1.4320 ++ save_reg (FP_REGNO, cfa_store_offset, cfa_store_reg);
1.4321 ++ }
1.4322 ++
1.4323 ++ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1.4324 ++ {
1.4325 ++ if (MUST_SAVE_REGISTER (i) && i != FP_REGNO && i != RA_REGNO)
1.4326 ++ {
1.4327 ++ cfa_store_offset -= 4;
1.4328 ++ save_reg (i, cfa_store_offset, cfa_store_reg);
1.4329 ++ }
1.4330 ++ }
1.4331 ++
1.4332 ++ if (frame_pointer_needed)
1.4333 ++ {
1.4334 ++ insn = emit_insn (gen_rtx_SET (SImode,
1.4335 ++ gen_rtx_REG (SImode, FP_REGNO),
1.4336 ++ gen_rtx_REG (SImode, SP_REGNO)));
1.4337 ++
1.4338 ++ RTX_FRAME_RELATED_P (insn) = 1;
1.4339 ++ }
1.4340 ++
1.4341 ++ /* If we are profiling, make sure no instructions are scheduled before
1.4342 ++ the call to mcount. */
1.4343 ++ if (current_function_profile)
1.4344 ++ emit_insn (gen_blockage ());
1.4345 ++}
1.4346 ++
1.4347 ++void
1.4348 ++expand_epilogue (bool sibcall_p)
1.4349 ++{
1.4350 ++ rtx insn;
1.4351 ++ int i;
1.4352 ++ HOST_WIDE_INT total_frame_size;
1.4353 ++ int register_store_offset;
1.4354 ++
1.4355 ++ total_frame_size = compute_frame_size ();
1.4356 ++
1.4357 ++ if (!sibcall_p && nios2_can_use_return_insn ())
1.4358 ++ {
1.4359 ++ insn = emit_jump_insn (gen_return ());
1.4360 ++ return;
1.4361 ++ }
1.4362 ++
1.4363 ++ emit_insn (gen_blockage ());
1.4364 ++
1.4365 ++ register_store_offset =
1.4366 ++ cfun->machine->frame.save_regs_offset +
1.4367 ++ cfun->machine->frame.save_reg_rounded;
1.4368 ++
1.4369 ++ if (MUST_SAVE_REGISTER (RA_REGNO))
1.4370 ++ {
1.4371 ++ register_store_offset -= 4;
1.4372 ++ restore_reg (RA_REGNO, register_store_offset);
1.4373 ++ }
1.4374 ++
1.4375 ++ if (MUST_SAVE_REGISTER (FP_REGNO))
1.4376 ++ {
1.4377 ++ register_store_offset -= 4;
1.4378 ++ restore_reg (FP_REGNO, register_store_offset);
1.4379 ++ }
1.4380 ++
1.4381 ++ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1.4382 ++ {
1.4383 ++ if (MUST_SAVE_REGISTER (i) && i != FP_REGNO && i != RA_REGNO)
1.4384 ++ {
1.4385 ++ register_store_offset -= 4;
1.4386 ++ restore_reg (i, register_store_offset);
1.4387 ++ }
1.4388 ++ }
1.4389 ++
1.4390 ++ if (total_frame_size)
1.4391 ++ {
1.4392 ++ rtx sp_adjust;
1.4393 ++
1.4394 ++ if (TOO_BIG_OFFSET (total_frame_size))
1.4395 ++ {
1.4396 ++ sp_adjust = gen_rtx_REG (SImode, TEMP_REG_NUM);
1.4397 ++ insn = emit_insn (gen_rtx_SET (SImode,
1.4398 ++ sp_adjust,
1.4399 ++ GEN_INT (total_frame_size)));
1.4400 ++
1.4401 ++ }
1.4402 ++ else
1.4403 ++ {
1.4404 ++ sp_adjust = GEN_INT (total_frame_size);
1.4405 ++ }
1.4406 ++
1.4407 ++ insn = gen_rtx_SET (SImode,
1.4408 ++ stack_pointer_rtx,
1.4409 ++ gen_rtx_PLUS (SImode,
1.4410 ++ stack_pointer_rtx,
1.4411 ++ sp_adjust));
1.4412 ++ insn = emit_insn (insn);
1.4413 ++ }
1.4414 ++
1.4415 ++
1.4416 ++ if (!sibcall_p)
1.4417 ++ {
1.4418 ++ insn = emit_jump_insn (gen_return_from_epilogue (gen_rtx (REG, Pmode,
1.4419 ++ RA_REGNO)));
1.4420 ++ }
1.4421 ++}
1.4422 ++
1.4423 ++
1.4424 ++bool
1.4425 ++nios2_function_ok_for_sibcall (tree a ATTRIBUTE_UNUSED, tree b ATTRIBUTE_UNUSED)
1.4426 ++{
1.4427 ++ return true;
1.4428 ++}
1.4429 ++
1.4430 ++
1.4431 ++
1.4432 ++
1.4433 ++
1.4434 ++/* ----------------------- *
1.4435 ++ * Profiling
1.4436 ++ * ----------------------- */
1.4437 ++
1.4438 ++void
1.4439 ++function_profiler (FILE *file, int labelno)
1.4440 ++{
1.4441 ++ fprintf (file, "\t%s mcount begin, label: .LP%d\n",
1.4442 ++ ASM_COMMENT_START, labelno);
1.4443 ++ fprintf (file, "\tnextpc\tr8\n");
1.4444 ++ fprintf (file, "\tmov\tr9, ra\n");
1.4445 ++ fprintf (file, "\tmovhi\tr10, %%hiadj(.LP%d)\n", labelno);
1.4446 ++ fprintf (file, "\taddi\tr10, r10, %%lo(.LP%d)\n", labelno);
1.4447 ++ fprintf (file, "\tcall\tmcount\n");
1.4448 ++ fprintf (file, "\tmov\tra, r9\n");
1.4449 ++ fprintf (file, "\t%s mcount end\n", ASM_COMMENT_START);
1.4450 ++}
1.4451 ++
1.4452 ++
1.4453 ++/***************************************
1.4454 ++ * Stack Layout
1.4455 ++ ***************************************/
1.4456 ++
1.4457 ++
1.4458 ++void
1.4459 ++dump_frame_size (FILE *file)
1.4460 ++{
1.4461 ++ fprintf (file, "\t%s Current Frame Info\n", ASM_COMMENT_START);
1.4462 ++
1.4463 ++ fprintf (file, "\t%s total_size = %ld\n", ASM_COMMENT_START,
1.4464 ++ cfun->machine->frame.total_size);
1.4465 ++ fprintf (file, "\t%s var_size = %ld\n", ASM_COMMENT_START,
1.4466 ++ cfun->machine->frame.var_size);
1.4467 ++ fprintf (file, "\t%s args_size = %ld\n", ASM_COMMENT_START,
1.4468 ++ cfun->machine->frame.args_size);
1.4469 ++ fprintf (file, "\t%s save_reg_size = %d\n", ASM_COMMENT_START,
1.4470 ++ cfun->machine->frame.save_reg_size);
1.4471 ++ fprintf (file, "\t%s save_reg_rounded = %d\n", ASM_COMMENT_START,
1.4472 ++ cfun->machine->frame.save_reg_rounded);
1.4473 ++ fprintf (file, "\t%s initialized = %d\n", ASM_COMMENT_START,
1.4474 ++ cfun->machine->frame.initialized);
1.4475 ++ fprintf (file, "\t%s num_regs = %d\n", ASM_COMMENT_START,
1.4476 ++ cfun->machine->frame.num_regs);
1.4477 ++ fprintf (file, "\t%s save_regs_offset = %ld\n", ASM_COMMENT_START,
1.4478 ++ cfun->machine->frame.save_regs_offset);
1.4479 ++ fprintf (file, "\t%s current_function_is_leaf = %d\n", ASM_COMMENT_START,
1.4480 ++ current_function_is_leaf);
1.4481 ++ fprintf (file, "\t%s frame_pointer_needed = %d\n", ASM_COMMENT_START,
1.4482 ++ frame_pointer_needed);
1.4483 ++ fprintf (file, "\t%s pretend_args_size = %d\n", ASM_COMMENT_START,
1.4484 ++ current_function_pretend_args_size);
1.4485 ++
1.4486 ++}
1.4487 ++
1.4488 ++
1.4489 ++/* Return the bytes needed to compute the frame pointer from the current
1.4490 ++ stack pointer.
1.4491 ++*/
1.4492 ++
1.4493 ++HOST_WIDE_INT
1.4494 ++compute_frame_size ()
1.4495 ++{
1.4496 ++ unsigned int regno;
1.4497 ++ HOST_WIDE_INT var_size; /* # of var. bytes allocated */
1.4498 ++ HOST_WIDE_INT total_size; /* # bytes that the entire frame takes up */
1.4499 ++ HOST_WIDE_INT save_reg_size; /* # bytes needed to store callee save regs */
1.4500 ++ HOST_WIDE_INT save_reg_rounded;
1.4501 ++ /* # bytes needed to store callee save regs (rounded) */
1.4502 ++ HOST_WIDE_INT out_args_size; /* # bytes needed for outgoing args */
1.4503 ++
1.4504 ++ save_reg_size = 0;
1.4505 ++ var_size = STACK_ALIGN (get_frame_size ());
1.4506 ++ out_args_size = STACK_ALIGN (current_function_outgoing_args_size);
1.4507 ++
1.4508 ++ total_size = var_size + out_args_size;
1.4509 ++
1.4510 ++ /* Calculate space needed for gp registers. */
1.4511 ++ for (regno = 0; regno <= FIRST_PSEUDO_REGISTER; regno++)
1.4512 ++ {
1.4513 ++ if (MUST_SAVE_REGISTER (regno))
1.4514 ++ {
1.4515 ++ save_reg_size += 4;
1.4516 ++ }
1.4517 ++ }
1.4518 ++
1.4519 ++ save_reg_rounded = STACK_ALIGN (save_reg_size);
1.4520 ++ total_size += save_reg_rounded;
1.4521 ++
1.4522 ++ total_size += STACK_ALIGN (current_function_pretend_args_size);
1.4523 ++
1.4524 ++ /* Save other computed information. */
1.4525 ++ cfun->machine->frame.total_size = total_size;
1.4526 ++ cfun->machine->frame.var_size = var_size;
1.4527 ++ cfun->machine->frame.args_size = current_function_outgoing_args_size;
1.4528 ++ cfun->machine->frame.save_reg_size = save_reg_size;
1.4529 ++ cfun->machine->frame.save_reg_rounded = save_reg_rounded;
1.4530 ++ cfun->machine->frame.initialized = reload_completed;
1.4531 ++ cfun->machine->frame.num_regs = save_reg_size / UNITS_PER_WORD;
1.4532 ++
1.4533 ++ cfun->machine->frame.save_regs_offset
1.4534 ++ = save_reg_rounded ? current_function_outgoing_args_size + var_size : 0;
1.4535 ++
1.4536 ++ return total_size;
1.4537 ++}
1.4538 ++
1.4539 ++
1.4540 ++int
1.4541 ++nios2_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED)
1.4542 ++{
1.4543 ++ int offset;
1.4544 ++
1.4545 ++ /* Set OFFSET to the offset from the stack pointer. */
1.4546 ++ switch (from)
1.4547 ++ {
1.4548 ++ case FRAME_POINTER_REGNUM:
1.4549 ++ offset = 0;
1.4550 ++ break;
1.4551 ++
1.4552 ++ case ARG_POINTER_REGNUM:
1.4553 ++ compute_frame_size ();
1.4554 ++ offset = cfun->machine->frame.total_size;
1.4555 ++ offset -= current_function_pretend_args_size;
1.4556 ++ break;
1.4557 ++
1.4558 ++ case RETURN_ADDRESS_POINTER_REGNUM:
1.4559 ++ compute_frame_size ();
1.4560 ++ /* since the return address is always the first of the
1.4561 ++ saved registers, return the offset to the beginning
1.4562 ++ of the saved registers block */
1.4563 ++ offset = cfun->machine->frame.save_regs_offset;
1.4564 ++ break;
1.4565 ++
1.4566 ++ default:
1.4567 ++ abort ();
1.4568 ++ }
1.4569 ++
1.4570 ++ return offset;
1.4571 ++}
1.4572 ++
1.4573 ++/* Return nonzero if this function is known to have a null epilogue.
1.4574 ++ This allows the optimizer to omit jumps to jumps if no stack
1.4575 ++ was created. */
1.4576 ++int
1.4577 ++nios2_can_use_return_insn ()
1.4578 ++{
1.4579 ++ if (!reload_completed)
1.4580 ++ return 0;
1.4581 ++
1.4582 ++ if (regs_ever_live[RA_REGNO] || current_function_profile)
1.4583 ++ return 0;
1.4584 ++
1.4585 ++ if (cfun->machine->frame.initialized)
1.4586 ++ return cfun->machine->frame.total_size == 0;
1.4587 ++
1.4588 ++ return compute_frame_size () == 0;
1.4589 ++}
1.4590 ++
1.4591 ++
1.4592 ++
1.4593 ++
1.4594 ++
1.4595 ++/***************************************
1.4596 ++ *
1.4597 ++ ***************************************/
1.4598 ++
1.4599 ++const char *nios2_sys_nosys_string; /* for -msys=nosys */
1.4600 ++const char *nios2_sys_lib_string; /* for -msys-lib= */
1.4601 ++const char *nios2_sys_crt0_string; /* for -msys-crt0= */
1.4602 ++
1.4603 ++void
1.4604 ++override_options ()
1.4605 ++{
1.4606 ++ /* Function to allocate machine-dependent function status. */
1.4607 ++ init_machine_status = &nios2_init_machine_status;
1.4608 ++
1.4609 ++ nios2_section_threshold
1.4610 ++ = g_switch_set ? g_switch_value : NIOS2_DEFAULT_GVALUE;
1.4611 ++
1.4612 ++ if (nios2_sys_nosys_string && *nios2_sys_nosys_string)
1.4613 ++ {
1.4614 ++ error ("invalid option '-msys=nosys%s'", nios2_sys_nosys_string);
1.4615 ++ }
1.4616 ++
1.4617 ++ /* If we don't have mul, we don't have mulx either! */
1.4618 ++ if (!TARGET_HAS_MUL && TARGET_HAS_MULX)
1.4619 ++ {
1.4620 ++ target_flags &= ~HAS_MULX_FLAG;
1.4621 ++ }
1.4622 ++
1.4623 ++}
1.4624 ++
1.4625 ++void
1.4626 ++optimization_options (int level, int size)
1.4627 ++{
1.4628 ++ if (level || size)
1.4629 ++ {
1.4630 ++ target_flags |= INLINE_MEMCPY_FLAG;
1.4631 ++ }
1.4632 ++
1.4633 ++ if (level >= 3 && !size)
1.4634 ++ {
1.4635 ++ target_flags |= FAST_SW_DIV_FLAG;
1.4636 ++ }
1.4637 ++}
1.4638 ++
1.4639 ++/* Allocate a chunk of memory for per-function machine-dependent data. */
1.4640 ++static struct machine_function *
1.4641 ++nios2_init_machine_status ()
1.4642 ++{
1.4643 ++ return ((struct machine_function *)
1.4644 ++ ggc_alloc_cleared (sizeof (struct machine_function)));
1.4645 ++}
1.4646 ++
1.4647 ++
1.4648 ++
1.4649 ++/*****************
1.4650 ++ * Describing Relative Costs of Operations
1.4651 ++ *****************/
1.4652 ++
1.4653 ++/* Compute a (partial) cost for rtx X. Return true if the complete
1.4654 ++ cost has been computed, and false if subexpressions should be
1.4655 ++ scanned. In either case, *TOTAL contains the cost result. */
1.4656 ++
1.4657 ++
1.4658 ++
1.4659 ++static bool
1.4660 ++nios2_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total)
1.4661 ++{
1.4662 ++ switch (code)
1.4663 ++ {
1.4664 ++ case CONST_INT:
1.4665 ++ if (INTVAL (x) == 0)
1.4666 ++ {
1.4667 ++ *total = COSTS_N_INSNS (0);
1.4668 ++ return true;
1.4669 ++ }
1.4670 ++ else if (SMALL_INT (INTVAL (x))
1.4671 ++ || SMALL_INT_UNSIGNED (INTVAL (x))
1.4672 ++ || UPPER16_INT (INTVAL (x)))
1.4673 ++ {
1.4674 ++ *total = COSTS_N_INSNS (2);
1.4675 ++ return true;
1.4676 ++ }
1.4677 ++ else
1.4678 ++ {
1.4679 ++ *total = COSTS_N_INSNS (4);
1.4680 ++ return true;
1.4681 ++ }
1.4682 ++
1.4683 ++ case LABEL_REF:
1.4684 ++ case SYMBOL_REF:
1.4685 ++ /* ??? gp relative stuff will fit in here */
1.4686 ++ /* fall through */
1.4687 ++ case CONST:
1.4688 ++ case CONST_DOUBLE:
1.4689 ++ {
1.4690 ++ *total = COSTS_N_INSNS (4);
1.4691 ++ return true;
1.4692 ++ }
1.4693 ++
1.4694 ++ case MULT:
1.4695 ++ {
1.4696 ++ *total = COSTS_N_INSNS (1);
1.4697 ++ return false;
1.4698 ++ }
1.4699 ++ case SIGN_EXTEND:
1.4700 ++ {
1.4701 ++ *total = COSTS_N_INSNS (3);
1.4702 ++ return false;
1.4703 ++ }
1.4704 ++ case ZERO_EXTEND:
1.4705 ++ {
1.4706 ++ *total = COSTS_N_INSNS (1);
1.4707 ++ return false;
1.4708 ++ }
1.4709 ++
1.4710 ++ default:
1.4711 ++ return false;
1.4712 ++ }
1.4713 ++}
1.4714 ++
1.4715 ++
1.4716 ++/***************************************
1.4717 ++ * INSTRUCTION SUPPORT
1.4718 ++ *
1.4719 ++ * These functions are used within the Machine Description to
1.4720 ++ * handle common or complicated output and expansions from
1.4721 ++ * instructions.
1.4722 ++ ***************************************/
1.4723 ++
1.4724 ++int
1.4725 ++nios2_emit_move_sequence (rtx *operands, enum machine_mode mode)
1.4726 ++{
1.4727 ++ rtx to = operands[0];
1.4728 ++ rtx from = operands[1];
1.4729 ++
1.4730 ++ if (!register_operand (to, mode) && !reg_or_0_operand (from, mode))
1.4731 ++ {
1.4732 ++ if (no_new_pseudos)
1.4733 ++ internal_error ("Trying to force_reg no_new_pseudos == 1");
1.4734 ++ from = copy_to_mode_reg (mode, from);
1.4735 ++ }
1.4736 ++
1.4737 ++ operands[0] = to;
1.4738 ++ operands[1] = from;
1.4739 ++ return 0;
1.4740 ++}
1.4741 ++
1.4742 ++/* Divide Support */
1.4743 ++
1.4744 ++/*
1.4745 ++ If -O3 is used, we want to output a table lookup for
1.4746 ++ divides between small numbers (both num and den >= 0
1.4747 ++ and < 0x10). The overhead of this method in the worse
1.4748 ++ case is 40 bytes in the text section (10 insns) and
1.4749 ++ 256 bytes in the data section. Additional divides do
1.4750 ++ not incur additional penalties in the data section.
1.4751 ++
1.4752 ++ Code speed is improved for small divides by about 5x
1.4753 ++ when using this method in the worse case (~9 cycles
1.4754 ++ vs ~45). And in the worse case divides not within the
1.4755 ++ table are penalized by about 10% (~5 cycles vs ~45).
1.4756 ++ However in the typical case the penalty is not as bad
1.4757 ++ because doing the long divide in only 45 cycles is
1.4758 ++ quite optimistic.
1.4759 ++
1.4760 ++ ??? It would be nice to have some benchmarks other
1.4761 ++ than Dhrystone to back this up.
1.4762 ++
1.4763 ++ This bit of expansion is to create this instruction
1.4764 ++ sequence as rtl.
1.4765 ++ or $8, $4, $5
1.4766 ++ slli $9, $4, 4
1.4767 ++ cmpgeui $3, $8, 16
1.4768 ++ beq $3, $0, .L3
1.4769 ++ or $10, $9, $5
1.4770 ++ add $12, $11, divide_table
1.4771 ++ ldbu $2, 0($12)
1.4772 ++ br .L1
1.4773 ++.L3:
1.4774 ++ call slow_div
1.4775 ++.L1:
1.4776 ++# continue here with result in $2
1.4777 ++
1.4778 ++ ??? Ideally I would like the emit libcall block to contain
1.4779 ++ all of this code, but I don't know how to do that. What it
1.4780 ++ means is that if the divide can be eliminated, it may not
1.4781 ++ completely disappear.
1.4782 ++
1.4783 ++ ??? The __divsi3_table label should ideally be moved out
1.4784 ++ of this block and into a global. If it is placed into the
1.4785 ++ sdata section we can save even more cycles by doing things
1.4786 ++ gp relative.
1.4787 ++*/
1.4788 ++int
1.4789 ++nios2_emit_expensive_div (rtx *operands, enum machine_mode mode)
1.4790 ++{
1.4791 ++ rtx or_result, shift_left_result;
1.4792 ++ rtx lookup_value;
1.4793 ++ rtx lab1, lab3;
1.4794 ++ rtx insns;
1.4795 ++ rtx libfunc;
1.4796 ++ rtx final_result;
1.4797 ++ rtx tmp;
1.4798 ++
1.4799 ++ /* it may look a little generic, but only SImode
1.4800 ++ is supported for now */
1.4801 ++ if (mode != SImode)
1.4802 ++ abort ();
1.4803 ++
1.4804 ++ libfunc = sdiv_optab->handlers[(int) SImode].libfunc;
1.4805 ++
1.4806 ++
1.4807 ++
1.4808 ++ lab1 = gen_label_rtx ();
1.4809 ++ lab3 = gen_label_rtx ();
1.4810 ++
1.4811 ++ or_result = expand_simple_binop (SImode, IOR,
1.4812 ++ operands[1], operands[2],
1.4813 ++ 0, 0, OPTAB_LIB_WIDEN);
1.4814 ++
1.4815 ++ emit_cmp_and_jump_insns (or_result, GEN_INT (15), GTU, 0,
1.4816 ++ GET_MODE (or_result), 0, lab3);
1.4817 ++ JUMP_LABEL (get_last_insn ()) = lab3;
1.4818 ++
1.4819 ++ shift_left_result = expand_simple_binop (SImode, ASHIFT,
1.4820 ++ operands[1], GEN_INT (4),
1.4821 ++ 0, 0, OPTAB_LIB_WIDEN);
1.4822 ++
1.4823 ++ lookup_value = expand_simple_binop (SImode, IOR,
1.4824 ++ shift_left_result, operands[2],
1.4825 ++ 0, 0, OPTAB_LIB_WIDEN);
1.4826 ++
1.4827 ++ convert_move (operands[0],
1.4828 ++ gen_rtx (MEM, QImode,
1.4829 ++ gen_rtx (PLUS, SImode,
1.4830 ++ lookup_value,
1.4831 ++ gen_rtx_SYMBOL_REF (SImode, "__divsi3_table"))),
1.4832 ++ 1);
1.4833 ++
1.4834 ++
1.4835 ++ tmp = emit_jump_insn (gen_jump (lab1));
1.4836 ++ JUMP_LABEL (tmp) = lab1;
1.4837 ++ emit_barrier ();
1.4838 ++
1.4839 ++ emit_label (lab3);
1.4840 ++ LABEL_NUSES (lab3) = 1;
1.4841 ++
1.4842 ++ start_sequence ();
1.4843 ++ final_result = emit_library_call_value (libfunc, NULL_RTX,
1.4844 ++ LCT_CONST, SImode, 2,
1.4845 ++ operands[1], SImode,
1.4846 ++ operands[2], SImode);
1.4847 ++
1.4848 ++
1.4849 ++ insns = get_insns ();
1.4850 ++ end_sequence ();
1.4851 ++ emit_libcall_block (insns, operands[0], final_result,
1.4852 ++ gen_rtx (DIV, SImode, operands[1], operands[2]));
1.4853 ++
1.4854 ++ emit_label (lab1);
1.4855 ++ LABEL_NUSES (lab1) = 1;
1.4856 ++ return 1;
1.4857 ++}
1.4858 ++
1.4859 ++/* Branches/Compares */
1.4860 ++
1.4861 ++/* the way of handling branches/compares
1.4862 ++ in gcc is heavily borrowed from MIPS */
1.4863 ++
1.4864 ++enum internal_test
1.4865 ++{
1.4866 ++ ITEST_EQ,
1.4867 ++ ITEST_NE,
1.4868 ++ ITEST_GT,
1.4869 ++ ITEST_GE,
1.4870 ++ ITEST_LT,
1.4871 ++ ITEST_LE,
1.4872 ++ ITEST_GTU,
1.4873 ++ ITEST_GEU,
1.4874 ++ ITEST_LTU,
1.4875 ++ ITEST_LEU,
1.4876 ++ ITEST_MAX
1.4877 ++};
1.4878 ++
1.4879 ++static enum internal_test map_test_to_internal_test (enum rtx_code);
1.4880 ++
1.4881 ++/* Cached operands, and operator to compare for use in set/branch/trap
1.4882 ++ on condition codes. */
1.4883 ++rtx branch_cmp[2];
1.4884 ++enum cmp_type branch_type;
1.4885 ++
1.4886 ++/* Make normal rtx_code into something we can index from an array */
1.4887 ++
1.4888 ++static enum internal_test
1.4889 ++map_test_to_internal_test (enum rtx_code test_code)
1.4890 ++{
1.4891 ++ enum internal_test test = ITEST_MAX;
1.4892 ++
1.4893 ++ switch (test_code)
1.4894 ++ {
1.4895 ++ case EQ:
1.4896 ++ test = ITEST_EQ;
1.4897 ++ break;
1.4898 ++ case NE:
1.4899 ++ test = ITEST_NE;
1.4900 ++ break;
1.4901 ++ case GT:
1.4902 ++ test = ITEST_GT;
1.4903 ++ break;
1.4904 ++ case GE:
1.4905 ++ test = ITEST_GE;
1.4906 ++ break;
1.4907 ++ case LT:
1.4908 ++ test = ITEST_LT;
1.4909 ++ break;
1.4910 ++ case LE:
1.4911 ++ test = ITEST_LE;
1.4912 ++ break;
1.4913 ++ case GTU:
1.4914 ++ test = ITEST_GTU;
1.4915 ++ break;
1.4916 ++ case GEU:
1.4917 ++ test = ITEST_GEU;
1.4918 ++ break;
1.4919 ++ case LTU:
1.4920 ++ test = ITEST_LTU;
1.4921 ++ break;
1.4922 ++ case LEU:
1.4923 ++ test = ITEST_LEU;
1.4924 ++ break;
1.4925 ++ default:
1.4926 ++ break;
1.4927 ++ }
1.4928 ++
1.4929 ++ return test;
1.4930 ++}
1.4931 ++
1.4932 ++/* Generate the code to compare (and possibly branch) two integer values
1.4933 ++ TEST_CODE is the comparison code we are trying to emulate
1.4934 ++ (or implement directly)
1.4935 ++ RESULT is where to store the result of the comparison,
1.4936 ++ or null to emit a branch
1.4937 ++ CMP0 CMP1 are the two comparison operands
1.4938 ++ DESTINATION is the destination of the branch, or null to only compare
1.4939 ++ */
1.4940 ++
1.4941 ++void
1.4942 ++gen_int_relational (enum rtx_code test_code, /* relational test (EQ, etc) */
1.4943 ++ rtx result, /* result to store comp. or 0 if branch */
1.4944 ++ rtx cmp0, /* first operand to compare */
1.4945 ++ rtx cmp1, /* second operand to compare */
1.4946 ++ rtx destination) /* destination of the branch, or 0 if compare */
1.4947 ++{
1.4948 ++ struct cmp_info
1.4949 ++ {
1.4950 ++ /* for register (or 0) compares */
1.4951 ++ enum rtx_code test_code_reg; /* code to use in instruction (LT vs. LTU) */
1.4952 ++ int reverse_regs; /* reverse registers in test */
1.4953 ++
1.4954 ++ /* for immediate compares */
1.4955 ++ enum rtx_code test_code_const;
1.4956 ++ /* code to use in instruction (LT vs. LTU) */
1.4957 ++ int const_low; /* low bound of constant we can accept */
1.4958 ++ int const_high; /* high bound of constant we can accept */
1.4959 ++ int const_add; /* constant to add */
1.4960 ++
1.4961 ++ /* generic info */
1.4962 ++ int unsignedp; /* != 0 for unsigned comparisons. */
1.4963 ++ };
1.4964 ++
1.4965 ++ static const struct cmp_info info[(int) ITEST_MAX] = {
1.4966 ++
1.4967 ++ {EQ, 0, EQ, -32768, 32767, 0, 0}, /* EQ */
1.4968 ++ {NE, 0, NE, -32768, 32767, 0, 0}, /* NE */
1.4969 ++
1.4970 ++ {LT, 1, GE, -32769, 32766, 1, 0}, /* GT */
1.4971 ++ {GE, 0, GE, -32768, 32767, 0, 0}, /* GE */
1.4972 ++ {LT, 0, LT, -32768, 32767, 0, 0}, /* LT */
1.4973 ++ {GE, 1, LT, -32769, 32766, 1, 0}, /* LE */
1.4974 ++
1.4975 ++ {LTU, 1, GEU, 0, 65534, 1, 0}, /* GTU */
1.4976 ++ {GEU, 0, GEU, 0, 65535, 0, 0}, /* GEU */
1.4977 ++ {LTU, 0, LTU, 0, 65535, 0, 0}, /* LTU */
1.4978 ++ {GEU, 1, LTU, 0, 65534, 1, 0}, /* LEU */
1.4979 ++ };
1.4980 ++
1.4981 ++ enum internal_test test;
1.4982 ++ enum machine_mode mode;
1.4983 ++ const struct cmp_info *p_info;
1.4984 ++ int branch_p;
1.4985 ++
1.4986 ++
1.4987 ++
1.4988 ++
1.4989 ++ test = map_test_to_internal_test (test_code);
1.4990 ++ if (test == ITEST_MAX)
1.4991 ++ abort ();
1.4992 ++
1.4993 ++ p_info = &info[(int) test];
1.4994 ++
1.4995 ++ mode = GET_MODE (cmp0);
1.4996 ++ if (mode == VOIDmode)
1.4997 ++ mode = GET_MODE (cmp1);
1.4998 ++
1.4999 ++ branch_p = (destination != 0);
1.5000 ++
1.5001 ++ /* We can't, under any circumstances, have const_ints in cmp0
1.5002 ++ ??? Actually we could have const0 */
1.5003 ++ if (GET_CODE (cmp0) == CONST_INT)
1.5004 ++ cmp0 = force_reg (mode, cmp0);
1.5005 ++
1.5006 ++ /* if the comparison is against an int not in legal range
1.5007 ++ move it into a register */
1.5008 ++ if (GET_CODE (cmp1) == CONST_INT)
1.5009 ++ {
1.5010 ++ HOST_WIDE_INT value = INTVAL (cmp1);
1.5011 ++
1.5012 ++ if (value < p_info->const_low || value > p_info->const_high)
1.5013 ++ cmp1 = force_reg (mode, cmp1);
1.5014 ++ }
1.5015 ++
1.5016 ++ /* Comparison to constants, may involve adding 1 to change a GT into GE.
1.5017 ++ Comparison between two registers, may involve switching operands. */
1.5018 ++ if (GET_CODE (cmp1) == CONST_INT)
1.5019 ++ {
1.5020 ++ if (p_info->const_add != 0)
1.5021 ++ {
1.5022 ++ HOST_WIDE_INT new = INTVAL (cmp1) + p_info->const_add;
1.5023 ++
1.5024 ++ /* If modification of cmp1 caused overflow,
1.5025 ++ we would get the wrong answer if we follow the usual path;
1.5026 ++ thus, x > 0xffffffffU would turn into x > 0U. */
1.5027 ++ if ((p_info->unsignedp
1.5028 ++ ? (unsigned HOST_WIDE_INT) new >
1.5029 ++ (unsigned HOST_WIDE_INT) INTVAL (cmp1)
1.5030 ++ : new > INTVAL (cmp1)) != (p_info->const_add > 0))
1.5031 ++ {
1.5032 ++ /* ??? This case can never happen with the current numbers,
1.5033 ++ but I am paranoid and would rather an abort than
1.5034 ++ a bug I will never find */
1.5035 ++ abort ();
1.5036 ++ }
1.5037 ++ else
1.5038 ++ cmp1 = GEN_INT (new);
1.5039 ++ }
1.5040 ++ }
1.5041 ++
1.5042 ++ else if (p_info->reverse_regs)
1.5043 ++ {
1.5044 ++ rtx temp = cmp0;
1.5045 ++ cmp0 = cmp1;
1.5046 ++ cmp1 = temp;
1.5047 ++ }
1.5048 ++
1.5049 ++
1.5050 ++
1.5051 ++ if (branch_p)
1.5052 ++ {
1.5053 ++ if (register_operand (cmp0, mode) && register_operand (cmp1, mode))
1.5054 ++ {
1.5055 ++ rtx insn;
1.5056 ++ rtx cond = gen_rtx (p_info->test_code_reg, mode, cmp0, cmp1);
1.5057 ++ rtx label = gen_rtx_LABEL_REF (VOIDmode, destination);
1.5058 ++
1.5059 ++ insn = gen_rtx_SET (VOIDmode, pc_rtx,
1.5060 ++ gen_rtx_IF_THEN_ELSE (VOIDmode,
1.5061 ++ cond, label, pc_rtx));
1.5062 ++ emit_jump_insn (insn);
1.5063 ++ }
1.5064 ++ else
1.5065 ++ {
1.5066 ++ rtx cond, label;
1.5067 ++
1.5068 ++ result = gen_reg_rtx (mode);
1.5069 ++
1.5070 ++ emit_move_insn (result,
1.5071 ++ gen_rtx (p_info->test_code_const, mode, cmp0,
1.5072 ++ cmp1));
1.5073 ++
1.5074 ++ cond = gen_rtx (NE, mode, result, const0_rtx);
1.5075 ++ label = gen_rtx_LABEL_REF (VOIDmode, destination);
1.5076 ++
1.5077 ++ emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
1.5078 ++ gen_rtx_IF_THEN_ELSE (VOIDmode,
1.5079 ++ cond,
1.5080 ++ label, pc_rtx)));
1.5081 ++ }
1.5082 ++ }
1.5083 ++ else
1.5084 ++ {
1.5085 ++ if (register_operand (cmp0, mode) && register_operand (cmp1, mode))
1.5086 ++ {
1.5087 ++ emit_move_insn (result,
1.5088 ++ gen_rtx (p_info->test_code_reg, mode, cmp0, cmp1));
1.5089 ++ }
1.5090 ++ else
1.5091 ++ {
1.5092 ++ emit_move_insn (result,
1.5093 ++ gen_rtx (p_info->test_code_const, mode, cmp0,
1.5094 ++ cmp1));
1.5095 ++ }
1.5096 ++ }
1.5097 ++
1.5098 ++}
1.5099 ++
1.5100 ++
1.5101 ++/* ??? For now conditional moves are only supported
1.5102 ++ when the mode of the operands being compared are
1.5103 ++ the same as the ones being moved */
1.5104 ++
1.5105 ++void
1.5106 ++gen_conditional_move (rtx *operands, enum machine_mode mode)
1.5107 ++{
1.5108 ++ rtx insn, cond;
1.5109 ++ rtx cmp_reg = gen_reg_rtx (mode);
1.5110 ++ enum rtx_code cmp_code = GET_CODE (operands[1]);
1.5111 ++ enum rtx_code move_code = EQ;
1.5112 ++
1.5113 ++ /* emit a comparison if it is not "simple".
1.5114 ++ Simple comparisons are X eq 0 and X ne 0 */
1.5115 ++ if ((cmp_code == EQ || cmp_code == NE) && branch_cmp[1] == const0_rtx)
1.5116 ++ {
1.5117 ++ cmp_reg = branch_cmp[0];
1.5118 ++ move_code = cmp_code;
1.5119 ++ }
1.5120 ++ else if ((cmp_code == EQ || cmp_code == NE) && branch_cmp[0] == const0_rtx)
1.5121 ++ {
1.5122 ++ cmp_reg = branch_cmp[1];
1.5123 ++ move_code = cmp_code == EQ ? NE : EQ;
1.5124 ++ }
1.5125 ++ else
1.5126 ++ gen_int_relational (cmp_code, cmp_reg, branch_cmp[0], branch_cmp[1],
1.5127 ++ NULL_RTX);
1.5128 ++
1.5129 ++ cond = gen_rtx (move_code, VOIDmode, cmp_reg, CONST0_RTX (mode));
1.5130 ++ insn = gen_rtx_SET (mode, operands[0],
1.5131 ++ gen_rtx_IF_THEN_ELSE (mode,
1.5132 ++ cond, operands[2], operands[3]));
1.5133 ++ emit_insn (insn);
1.5134 ++}
1.5135 ++
1.5136 ++/*******************
1.5137 ++ * Addressing Modes
1.5138 ++ *******************/
1.5139 ++
1.5140 ++int
1.5141 ++nios2_legitimate_address (rtx operand, enum machine_mode mode ATTRIBUTE_UNUSED,
1.5142 ++ int strict)
1.5143 ++{
1.5144 ++ int ret_val = 0;
1.5145 ++
1.5146 ++ switch (GET_CODE (operand))
1.5147 ++ {
1.5148 ++ /* direct. */
1.5149 ++ case SYMBOL_REF:
1.5150 ++ if (SYMBOL_REF_IN_NIOS2_SMALL_DATA_P (operand))
1.5151 ++ {
1.5152 ++ ret_val = 1;
1.5153 ++ break;
1.5154 ++ }
1.5155 ++ /* else, fall through */
1.5156 ++ case LABEL_REF:
1.5157 ++ case CONST_INT:
1.5158 ++ case CONST:
1.5159 ++ case CONST_DOUBLE:
1.5160 ++ /* ??? In here I need to add gp addressing */
1.5161 ++ ret_val = 0;
1.5162 ++
1.5163 ++ break;
1.5164 ++
1.5165 ++ /* Register indirect. */
1.5166 ++ case REG:
1.5167 ++ ret_val = REG_OK_FOR_BASE_P2 (operand, strict);
1.5168 ++ break;
1.5169 ++
1.5170 ++ /* Register indirect with displacement */
1.5171 ++ case PLUS:
1.5172 ++ {
1.5173 ++ rtx op0 = XEXP (operand, 0);
1.5174 ++ rtx op1 = XEXP (operand, 1);
1.5175 ++
1.5176 ++ if (REG_P (op0) && REG_P (op1))
1.5177 ++ ret_val = 0;
1.5178 ++ else if (REG_P (op0) && CONSTANT_P (op1))
1.5179 ++ ret_val = REG_OK_FOR_BASE_P2 (op0, strict)
1.5180 ++ && SMALL_INT (INTVAL (op1));
1.5181 ++ else if (REG_P (op1) && CONSTANT_P (op0))
1.5182 ++ ret_val = REG_OK_FOR_BASE_P2 (op1, strict)
1.5183 ++ && SMALL_INT (INTVAL (op0));
1.5184 ++ else
1.5185 ++ ret_val = 0;
1.5186 ++ }
1.5187 ++ break;
1.5188 ++
1.5189 ++ default:
1.5190 ++ ret_val = 0;
1.5191 ++ break;
1.5192 ++ }
1.5193 ++
1.5194 ++ return ret_val;
1.5195 ++}
1.5196 ++
1.5197 ++/* Return true if EXP should be placed in the small data section. */
1.5198 ++
1.5199 ++static bool
1.5200 ++nios2_in_small_data_p (tree exp)
1.5201 ++{
1.5202 ++ /* We want to merge strings, so we never consider them small data. */
1.5203 ++ if (TREE_CODE (exp) == STRING_CST)
1.5204 ++ return false;
1.5205 ++
1.5206 ++ if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
1.5207 ++ {
1.5208 ++ const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
1.5209 ++ /* ??? these string names need moving into
1.5210 ++ an array in some header file */
1.5211 ++ if (nios2_section_threshold > 0
1.5212 ++ && (strcmp (section, ".sbss") == 0
1.5213 ++ || strncmp (section, ".sbss.", 6) == 0
1.5214 ++ || strcmp (section, ".sdata") == 0
1.5215 ++ || strncmp (section, ".sdata.", 7) == 0))
1.5216 ++ return true;
1.5217 ++ }
1.5218 ++ else if (TREE_CODE (exp) == VAR_DECL)
1.5219 ++ {
1.5220 ++ HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
1.5221 ++
1.5222 ++ /* If this is an incomplete type with size 0, then we can't put it
1.5223 ++ in sdata because it might be too big when completed. */
1.5224 ++ if (size > 0 && size <= nios2_section_threshold)
1.5225 ++ return true;
1.5226 ++ }
1.5227 ++
1.5228 ++ return false;
1.5229 ++}
1.5230 ++
1.5231 ++static void
1.5232 ++nios2_encode_section_info (tree decl, rtx rtl, int first)
1.5233 ++{
1.5234 ++
1.5235 ++ rtx symbol;
1.5236 ++ int flags;
1.5237 ++
1.5238 ++ default_encode_section_info (decl, rtl, first);
1.5239 ++
1.5240 ++ /* Careful not to prod global register variables. */
1.5241 ++ if (GET_CODE (rtl) != MEM)
1.5242 ++ return;
1.5243 ++ symbol = XEXP (rtl, 0);
1.5244 ++ if (GET_CODE (symbol) != SYMBOL_REF)
1.5245 ++ return;
1.5246 ++
1.5247 ++ flags = SYMBOL_REF_FLAGS (symbol);
1.5248 ++
1.5249 ++ /* We don't want weak variables to be addressed with gp in case they end up with
1.5250 ++ value 0 which is not within 2^15 of $gp */
1.5251 ++ if (DECL_P (decl) && DECL_WEAK (decl))
1.5252 ++ flags |= SYMBOL_FLAG_WEAK_DECL;
1.5253 ++
1.5254 ++ SYMBOL_REF_FLAGS (symbol) = flags;
1.5255 ++}
1.5256 ++
1.5257 ++
1.5258 ++static unsigned int
1.5259 ++nios2_section_type_flags (tree decl, const char *name, int reloc)
1.5260 ++{
1.5261 ++ unsigned int flags;
1.5262 ++
1.5263 ++ flags = default_section_type_flags (decl, name, reloc);
1.5264 ++
1.5265 ++ /* ??? these string names need moving into an array in some header file */
1.5266 ++ if (strcmp (name, ".sbss") == 0
1.5267 ++ || strncmp (name, ".sbss.", 6) == 0
1.5268 ++ || strcmp (name, ".sdata") == 0
1.5269 ++ || strncmp (name, ".sdata.", 7) == 0)
1.5270 ++ flags |= SECTION_SMALL;
1.5271 ++
1.5272 ++ return flags;
1.5273 ++}
1.5274 ++
1.5275 ++
1.5276 ++
1.5277 ++
1.5278 ++/*****************************************
1.5279 ++ * Defining the Output Assembler Language
1.5280 ++ *****************************************/
1.5281 ++
1.5282 ++/* -------------- *
1.5283 ++ * Output of Data
1.5284 ++ * -------------- */
1.5285 ++
1.5286 ++
1.5287 ++/* -------------------------------- *
1.5288 ++ * Output of Assembler Instructions
1.5289 ++ * -------------------------------- */
1.5290 ++
1.5291 ++
1.5292 ++/* print the operand OP to file stream
1.5293 ++ FILE modified by LETTER. LETTER
1.5294 ++ can be one of:
1.5295 ++ i: print "i" if OP is an immediate, except 0
1.5296 ++ o: print "io" if OP is volatile
1.5297 ++
1.5298 ++ z: for const0_rtx print $0 instead of 0
1.5299 ++ H: for %hiadj
1.5300 ++ L: for %lo
1.5301 ++ U: for upper half of 32 bit value
1.5302 ++ */
1.5303 ++
1.5304 ++void
1.5305 ++nios2_print_operand (FILE *file, rtx op, int letter)
1.5306 ++{
1.5307 ++
1.5308 ++ switch (letter)
1.5309 ++ {
1.5310 ++ case 'i':
1.5311 ++ if (CONSTANT_P (op) && (op != const0_rtx))
1.5312 ++ fprintf (file, "i");
1.5313 ++ return;
1.5314 ++
1.5315 ++ case 'o':
1.5316 ++ if (GET_CODE (op) == MEM
1.5317 ++ && ((MEM_VOLATILE_P (op) && !TARGET_CACHE_VOLATILE)
1.5318 ++ || TARGET_BYPASS_CACHE))
1.5319 ++ fprintf (file, "io");
1.5320 ++ return;
1.5321 ++
1.5322 ++ default:
1.5323 ++ break;
1.5324 ++ }
1.5325 ++
1.5326 ++ if (comparison_operator (op, VOIDmode))
1.5327 ++ {
1.5328 ++ if (letter == 0)
1.5329 ++ {
1.5330 ++ fprintf (file, "%s", GET_RTX_NAME (GET_CODE (op)));
1.5331 ++ return;
1.5332 ++ }
1.5333 ++ }
1.5334 ++
1.5335 ++
1.5336 ++ switch (GET_CODE (op))
1.5337 ++ {
1.5338 ++ case REG:
1.5339 ++ if (letter == 0 || letter == 'z')
1.5340 ++ {
1.5341 ++ fprintf (file, "%s", reg_names[REGNO (op)]);
1.5342 ++ return;
1.5343 ++ }
1.5344 ++
1.5345 ++ case CONST_INT:
1.5346 ++ if (INTVAL (op) == 0 && letter == 'z')
1.5347 ++ {
1.5348 ++ fprintf (file, "zero");
1.5349 ++ return;
1.5350 ++ }
1.5351 ++ else if (letter == 'U')
1.5352 ++ {
1.5353 ++ HOST_WIDE_INT val = INTVAL (op);
1.5354 ++ rtx new_op;
1.5355 ++ val = (val / 65536) & 0xFFFF;
1.5356 ++ new_op = GEN_INT (val);
1.5357 ++ output_addr_const (file, new_op);
1.5358 ++ return;
1.5359 ++ }
1.5360 ++
1.5361 ++ /* else, fall through */
1.5362 ++ case CONST:
1.5363 ++ case LABEL_REF:
1.5364 ++ case SYMBOL_REF:
1.5365 ++ case CONST_DOUBLE:
1.5366 ++ if (letter == 0 || letter == 'z')
1.5367 ++ {
1.5368 ++ output_addr_const (file, op);
1.5369 ++ return;
1.5370 ++ }
1.5371 ++ else if (letter == 'H')
1.5372 ++ {
1.5373 ++ fprintf (file, "%%hiadj(");
1.5374 ++ output_addr_const (file, op);
1.5375 ++ fprintf (file, ")");
1.5376 ++ return;
1.5377 ++ }
1.5378 ++ else if (letter == 'L')
1.5379 ++ {
1.5380 ++ fprintf (file, "%%lo(");
1.5381 ++ output_addr_const (file, op);
1.5382 ++ fprintf (file, ")");
1.5383 ++ return;
1.5384 ++ }
1.5385 ++
1.5386 ++
1.5387 ++ case SUBREG:
1.5388 ++ case MEM:
1.5389 ++ if (letter == 0)
1.5390 ++ {
1.5391 ++ output_address (op);
1.5392 ++ return;
1.5393 ++ }
1.5394 ++
1.5395 ++ case CODE_LABEL:
1.5396 ++ if (letter == 0)
1.5397 ++ {
1.5398 ++ output_addr_const (file, op);
1.5399 ++ return;
1.5400 ++ }
1.5401 ++
1.5402 ++ default:
1.5403 ++ break;
1.5404 ++ }
1.5405 ++
1.5406 ++ fprintf (stderr, "Missing way to print (%c) ", letter);
1.5407 ++ debug_rtx (op);
1.5408 ++ abort ();
1.5409 ++}
1.5410 ++
1.5411 ++static int gprel_constant (rtx);
1.5412 ++
1.5413 ++static int
1.5414 ++gprel_constant (rtx op)
1.5415 ++{
1.5416 ++ if (GET_CODE (op) == SYMBOL_REF
1.5417 ++ && SYMBOL_REF_IN_NIOS2_SMALL_DATA_P (op))
1.5418 ++ {
1.5419 ++ return 1;
1.5420 ++ }
1.5421 ++ else if (GET_CODE (op) == CONST
1.5422 ++ && GET_CODE (XEXP (op, 0)) == PLUS)
1.5423 ++ {
1.5424 ++ return gprel_constant (XEXP (XEXP (op, 0), 0));
1.5425 ++ }
1.5426 ++ else
1.5427 ++ {
1.5428 ++ return 0;
1.5429 ++ }
1.5430 ++}
1.5431 ++
1.5432 ++void
1.5433 ++nios2_print_operand_address (FILE *file, rtx op)
1.5434 ++{
1.5435 ++ switch (GET_CODE (op))
1.5436 ++ {
1.5437 ++ case CONST:
1.5438 ++ case CONST_INT:
1.5439 ++ case LABEL_REF:
1.5440 ++ case CONST_DOUBLE:
1.5441 ++ case SYMBOL_REF:
1.5442 ++ if (gprel_constant (op))
1.5443 ++ {
1.5444 ++ fprintf (file, "%%gprel(");
1.5445 ++ output_addr_const (file, op);
1.5446 ++ fprintf (file, ")(%s)", reg_names[GP_REGNO]);
1.5447 ++ return;
1.5448 ++ }
1.5449 ++
1.5450 ++ break;
1.5451 ++
1.5452 ++ case PLUS:
1.5453 ++ {
1.5454 ++ rtx op0 = XEXP (op, 0);
1.5455 ++ rtx op1 = XEXP (op, 1);
1.5456 ++
1.5457 ++ if (REG_P (op0) && CONSTANT_P (op1))
1.5458 ++ {
1.5459 ++ output_addr_const (file, op1);
1.5460 ++ fprintf (file, "(%s)", reg_names[REGNO (op0)]);
1.5461 ++ return;
1.5462 ++ }
1.5463 ++ else if (REG_P (op1) && CONSTANT_P (op0))
1.5464 ++ {
1.5465 ++ output_addr_const (file, op0);
1.5466 ++ fprintf (file, "(%s)", reg_names[REGNO (op1)]);
1.5467 ++ return;
1.5468 ++ }
1.5469 ++ }
1.5470 ++ break;
1.5471 ++
1.5472 ++ case REG:
1.5473 ++ fprintf (file, "0(%s)", reg_names[REGNO (op)]);
1.5474 ++ return;
1.5475 ++
1.5476 ++ case MEM:
1.5477 ++ {
1.5478 ++ rtx base = XEXP (op, 0);
1.5479 ++ PRINT_OPERAND_ADDRESS (file, base);
1.5480 ++ return;
1.5481 ++ }
1.5482 ++ default:
1.5483 ++ break;
1.5484 ++ }
1.5485 ++
1.5486 ++ fprintf (stderr, "Missing way to print address\n");
1.5487 ++ debug_rtx (op);
1.5488 ++ abort ();
1.5489 ++}
1.5490 ++
1.5491 ++
1.5492 ++
1.5493 ++
1.5494 ++
1.5495 ++/****************************
1.5496 ++ * Predicates
1.5497 ++ ****************************/
1.5498 ++
1.5499 ++int
1.5500 ++arith_operand (rtx op, enum machine_mode mode)
1.5501 ++{
1.5502 ++ if (GET_CODE (op) == CONST_INT && SMALL_INT (INTVAL (op)))
1.5503 ++ return 1;
1.5504 ++
1.5505 ++ return register_operand (op, mode);
1.5506 ++}
1.5507 ++
1.5508 ++int
1.5509 ++uns_arith_operand (rtx op, enum machine_mode mode)
1.5510 ++{
1.5511 ++ if (GET_CODE (op) == CONST_INT && SMALL_INT_UNSIGNED (INTVAL (op)))
1.5512 ++ return 1;
1.5513 ++
1.5514 ++ return register_operand (op, mode);
1.5515 ++}
1.5516 ++
1.5517 ++int
1.5518 ++logical_operand (rtx op, enum machine_mode mode)
1.5519 ++{
1.5520 ++ if (GET_CODE (op) == CONST_INT
1.5521 ++ && (SMALL_INT_UNSIGNED (INTVAL (op)) || UPPER16_INT (INTVAL (op))))
1.5522 ++ return 1;
1.5523 ++
1.5524 ++ return register_operand (op, mode);
1.5525 ++}
1.5526 ++
1.5527 ++int
1.5528 ++shift_operand (rtx op, enum machine_mode mode)
1.5529 ++{
1.5530 ++ if (GET_CODE (op) == CONST_INT && SHIFT_INT (INTVAL (op)))
1.5531 ++ return 1;
1.5532 ++
1.5533 ++ return register_operand (op, mode);
1.5534 ++}
1.5535 ++
1.5536 ++int
1.5537 ++rdwrctl_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1.5538 ++{
1.5539 ++ return GET_CODE (op) == CONST_INT && RDWRCTL_INT (INTVAL (op));
1.5540 ++}
1.5541 ++
1.5542 ++/* Return truth value of whether OP is a register or the constant 0. */
1.5543 ++
1.5544 ++int
1.5545 ++reg_or_0_operand (rtx op, enum machine_mode mode)
1.5546 ++{
1.5547 ++ switch (GET_CODE (op))
1.5548 ++ {
1.5549 ++ case CONST_INT:
1.5550 ++ return INTVAL (op) == 0;
1.5551 ++
1.5552 ++ case CONST_DOUBLE:
1.5553 ++ return op == CONST0_RTX (mode);
1.5554 ++
1.5555 ++ default:
1.5556 ++ break;
1.5557 ++ }
1.5558 ++
1.5559 ++ return register_operand (op, mode);
1.5560 ++}
1.5561 ++
1.5562 ++
1.5563 ++int
1.5564 ++equality_op (rtx op, enum machine_mode mode)
1.5565 ++{
1.5566 ++ if (mode != GET_MODE (op))
1.5567 ++ return 0;
1.5568 ++
1.5569 ++ return GET_CODE (op) == EQ || GET_CODE (op) == NE;
1.5570 ++}
1.5571 ++
1.5572 ++int
1.5573 ++custom_insn_opcode (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1.5574 ++{
1.5575 ++ return GET_CODE (op) == CONST_INT && CUSTOM_INSN_OPCODE (INTVAL (op));
1.5576 ++}
1.5577 ++
1.5578 ++
1.5579 ++
1.5580 ++
1.5581 ++
1.5582 ++
1.5583 ++
1.5584 ++/*****************************************************************************
1.5585 ++**
1.5586 ++** instruction scheduler
1.5587 ++**
1.5588 ++*****************************************************************************/
1.5589 ++static int
1.5590 ++nios2_use_dfa_pipeline_interface ()
1.5591 ++{
1.5592 ++ return 1;
1.5593 ++}
1.5594 ++
1.5595 ++
1.5596 ++static int
1.5597 ++nios2_issue_rate ()
1.5598 ++{
1.5599 ++#ifdef MAX_DFA_ISSUE_RATE
1.5600 ++ return MAX_DFA_ISSUE_RATE;
1.5601 ++#else
1.5602 ++ return 1;
1.5603 ++#endif
1.5604 ++}
1.5605 ++
1.5606 ++
1.5607 ++const char *
1.5608 ++asm_output_opcode (FILE *file ATTRIBUTE_UNUSED,
1.5609 ++ const char *ptr ATTRIBUTE_UNUSED)
1.5610 ++{
1.5611 ++ const char *p;
1.5612 ++
1.5613 ++ p = ptr;
1.5614 ++ return ptr;
1.5615 ++}
1.5616 ++
1.5617 ++
1.5618 ++
1.5619 ++/*****************************************************************************
1.5620 ++**
1.5621 ++** function arguments
1.5622 ++**
1.5623 ++*****************************************************************************/
1.5624 ++
1.5625 ++void
1.5626 ++init_cumulative_args (CUMULATIVE_ARGS *cum,
1.5627 ++ tree fntype ATTRIBUTE_UNUSED,
1.5628 ++ rtx libname ATTRIBUTE_UNUSED,
1.5629 ++ tree fndecl ATTRIBUTE_UNUSED,
1.5630 ++ int n_named_args ATTRIBUTE_UNUSED)
1.5631 ++{
1.5632 ++ cum->regs_used = 0;
1.5633 ++}
1.5634 ++
1.5635 ++
1.5636 ++/* Update the data in CUM to advance over an argument
1.5637 ++ of mode MODE and data type TYPE.
1.5638 ++ (TYPE is null for libcalls where that information may not be available.) */
1.5639 ++
1.5640 ++void
1.5641 ++function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
1.5642 ++ tree type ATTRIBUTE_UNUSED, int named ATTRIBUTE_UNUSED)
1.5643 ++{
1.5644 ++ HOST_WIDE_INT param_size;
1.5645 ++
1.5646 ++ if (mode == BLKmode)
1.5647 ++ {
1.5648 ++ param_size = int_size_in_bytes (type);
1.5649 ++ if (param_size < 0)
1.5650 ++ internal_error
1.5651 ++ ("Do not know how to handle large structs or variable length types");
1.5652 ++ }
1.5653 ++ else
1.5654 ++ {
1.5655 ++ param_size = GET_MODE_SIZE (mode);
1.5656 ++ }
1.5657 ++
1.5658 ++ /* convert to words (round up) */
1.5659 ++ param_size = (3 + param_size) / 4;
1.5660 ++
1.5661 ++ if (cum->regs_used + param_size > NUM_ARG_REGS)
1.5662 ++ {
1.5663 ++ cum->regs_used = NUM_ARG_REGS;
1.5664 ++ }
1.5665 ++ else
1.5666 ++ {
1.5667 ++ cum->regs_used += param_size;
1.5668 ++ }
1.5669 ++
1.5670 ++ return;
1.5671 ++}
1.5672 ++
1.5673 ++/* Define where to put the arguments to a function. Value is zero to
1.5674 ++ push the argument on the stack, or a hard register in which to
1.5675 ++ store the argument.
1.5676 ++
1.5677 ++ MODE is the argument's machine mode.
1.5678 ++ TYPE is the data type of the argument (as a tree).
1.5679 ++ This is null for libcalls where that information may
1.5680 ++ not be available.
1.5681 ++ CUM is a variable of type CUMULATIVE_ARGS which gives info about
1.5682 ++ the preceding args and about the function being called.
1.5683 ++ NAMED is nonzero if this argument is a named parameter
1.5684 ++ (otherwise it is an extra parameter matching an ellipsis). */
1.5685 ++rtx
1.5686 ++function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
1.5687 ++ tree type ATTRIBUTE_UNUSED, int named ATTRIBUTE_UNUSED)
1.5688 ++{
1.5689 ++ rtx return_rtx = NULL_RTX;
1.5690 ++
1.5691 ++ if (cum->regs_used < NUM_ARG_REGS)
1.5692 ++ {
1.5693 ++ return_rtx = gen_rtx_REG (mode, FIRST_ARG_REGNO + cum->regs_used);
1.5694 ++ }
1.5695 ++
1.5696 ++ return return_rtx;
1.5697 ++}
1.5698 ++
1.5699 ++int
1.5700 ++function_arg_partial_nregs (const CUMULATIVE_ARGS *cum,
1.5701 ++ enum machine_mode mode, tree type,
1.5702 ++ int named ATTRIBUTE_UNUSED)
1.5703 ++{
1.5704 ++ HOST_WIDE_INT param_size;
1.5705 ++
1.5706 ++ if (mode == BLKmode)
1.5707 ++ {
1.5708 ++ param_size = int_size_in_bytes (type);
1.5709 ++ if (param_size < 0)
1.5710 ++ internal_error
1.5711 ++ ("Do not know how to handle large structs or variable length types");
1.5712 ++ }
1.5713 ++ else
1.5714 ++ {
1.5715 ++ param_size = GET_MODE_SIZE (mode);
1.5716 ++ }
1.5717 ++
1.5718 ++ /* convert to words (round up) */
1.5719 ++ param_size = (3 + param_size) / 4;
1.5720 ++
1.5721 ++ if (cum->regs_used < NUM_ARG_REGS
1.5722 ++ && cum->regs_used + param_size > NUM_ARG_REGS)
1.5723 ++ {
1.5724 ++ return NUM_ARG_REGS - cum->regs_used;
1.5725 ++ }
1.5726 ++ else
1.5727 ++ {
1.5728 ++ return 0;
1.5729 ++ }
1.5730 ++}
1.5731 ++
1.5732 ++
1.5733 ++int
1.5734 ++nios2_return_in_memory (tree type)
1.5735 ++{
1.5736 ++ int res = ((int_size_in_bytes (type) > (2 * UNITS_PER_WORD))
1.5737 ++ || (int_size_in_bytes (type) == -1));
1.5738 ++
1.5739 ++ return res;
1.5740 ++}
1.5741 ++
1.5742 ++/* ??? It may be possible to eliminate the copyback and implement
1.5743 ++ my own va_arg type, but that is more work for now. */
1.5744 ++int
1.5745 ++nios2_setup_incoming_varargs (const CUMULATIVE_ARGS *cum,
1.5746 ++ enum machine_mode mode, tree type,
1.5747 ++ int no_rtl)
1.5748 ++{
1.5749 ++ CUMULATIVE_ARGS local_cum;
1.5750 ++ int regs_to_push;
1.5751 ++
1.5752 ++ local_cum = *cum;
1.5753 ++ FUNCTION_ARG_ADVANCE (local_cum, mode, type, 1);
1.5754 ++
1.5755 ++ regs_to_push = NUM_ARG_REGS - local_cum.regs_used;
1.5756 ++
1.5757 ++ if (!no_rtl)
1.5758 ++ {
1.5759 ++ if (regs_to_push > 0)
1.5760 ++ {
1.5761 ++ rtx ptr, mem;
1.5762 ++
1.5763 ++ ptr = virtual_incoming_args_rtx;
1.5764 ++ mem = gen_rtx_MEM (BLKmode, ptr);
1.5765 ++
1.5766 ++ /* va_arg is an array access in this case, which causes
1.5767 ++ it to get MEM_IN_STRUCT_P set. We must set it here
1.5768 ++ so that the insn scheduler won't assume that these
1.5769 ++ stores can't possibly overlap with the va_arg loads. */
1.5770 ++ MEM_SET_IN_STRUCT_P (mem, 1);
1.5771 ++
1.5772 ++ emit_insn (gen_blockage ());
1.5773 ++ move_block_from_reg (local_cum.regs_used + FIRST_ARG_REGNO, mem,
1.5774 ++ regs_to_push);
1.5775 ++ emit_insn (gen_blockage ());
1.5776 ++ }
1.5777 ++ }
1.5778 ++
1.5779 ++ return regs_to_push * UNITS_PER_WORD;
1.5780 ++
1.5781 ++}
1.5782 ++
1.5783 ++
1.5784 ++
1.5785 ++/*****************************************************************************
1.5786 ++**
1.5787 ++** builtins
1.5788 ++**
1.5789 ++** This method for handling builtins is from CSP where _many_ more types of
1.5790 ++** expanders have already been written. Check there first before writing
1.5791 ++** new ones.
1.5792 ++**
1.5793 ++*****************************************************************************/
1.5794 ++
1.5795 ++enum nios2_builtins
1.5796 ++{
1.5797 ++ NIOS2_BUILTIN_LDBIO,
1.5798 ++ NIOS2_BUILTIN_LDBUIO,
1.5799 ++ NIOS2_BUILTIN_LDHIO,
1.5800 ++ NIOS2_BUILTIN_LDHUIO,
1.5801 ++ NIOS2_BUILTIN_LDWIO,
1.5802 ++ NIOS2_BUILTIN_STBIO,
1.5803 ++ NIOS2_BUILTIN_STHIO,
1.5804 ++ NIOS2_BUILTIN_STWIO,
1.5805 ++ NIOS2_BUILTIN_SYNC,
1.5806 ++ NIOS2_BUILTIN_RDCTL,
1.5807 ++ NIOS2_BUILTIN_WRCTL,
1.5808 ++
1.5809 ++ NIOS2_BUILTIN_CUSTOM_N,
1.5810 ++ NIOS2_BUILTIN_CUSTOM_NI,
1.5811 ++ NIOS2_BUILTIN_CUSTOM_NF,
1.5812 ++ NIOS2_BUILTIN_CUSTOM_NP,
1.5813 ++ NIOS2_BUILTIN_CUSTOM_NII,
1.5814 ++ NIOS2_BUILTIN_CUSTOM_NIF,
1.5815 ++ NIOS2_BUILTIN_CUSTOM_NIP,
1.5816 ++ NIOS2_BUILTIN_CUSTOM_NFI,
1.5817 ++ NIOS2_BUILTIN_CUSTOM_NFF,
1.5818 ++ NIOS2_BUILTIN_CUSTOM_NFP,
1.5819 ++ NIOS2_BUILTIN_CUSTOM_NPI,
1.5820 ++ NIOS2_BUILTIN_CUSTOM_NPF,
1.5821 ++ NIOS2_BUILTIN_CUSTOM_NPP,
1.5822 ++ NIOS2_BUILTIN_CUSTOM_IN,
1.5823 ++ NIOS2_BUILTIN_CUSTOM_INI,
1.5824 ++ NIOS2_BUILTIN_CUSTOM_INF,
1.5825 ++ NIOS2_BUILTIN_CUSTOM_INP,
1.5826 ++ NIOS2_BUILTIN_CUSTOM_INII,
1.5827 ++ NIOS2_BUILTIN_CUSTOM_INIF,
1.5828 ++ NIOS2_BUILTIN_CUSTOM_INIP,
1.5829 ++ NIOS2_BUILTIN_CUSTOM_INFI,
1.5830 ++ NIOS2_BUILTIN_CUSTOM_INFF,
1.5831 ++ NIOS2_BUILTIN_CUSTOM_INFP,
1.5832 ++ NIOS2_BUILTIN_CUSTOM_INPI,
1.5833 ++ NIOS2_BUILTIN_CUSTOM_INPF,
1.5834 ++ NIOS2_BUILTIN_CUSTOM_INPP,
1.5835 ++ NIOS2_BUILTIN_CUSTOM_FN,
1.5836 ++ NIOS2_BUILTIN_CUSTOM_FNI,
1.5837 ++ NIOS2_BUILTIN_CUSTOM_FNF,
1.5838 ++ NIOS2_BUILTIN_CUSTOM_FNP,
1.5839 ++ NIOS2_BUILTIN_CUSTOM_FNII,
1.5840 ++ NIOS2_BUILTIN_CUSTOM_FNIF,
1.5841 ++ NIOS2_BUILTIN_CUSTOM_FNIP,
1.5842 ++ NIOS2_BUILTIN_CUSTOM_FNFI,
1.5843 ++ NIOS2_BUILTIN_CUSTOM_FNFF,
1.5844 ++ NIOS2_BUILTIN_CUSTOM_FNFP,
1.5845 ++ NIOS2_BUILTIN_CUSTOM_FNPI,
1.5846 ++ NIOS2_BUILTIN_CUSTOM_FNPF,
1.5847 ++ NIOS2_BUILTIN_CUSTOM_FNPP,
1.5848 ++ NIOS2_BUILTIN_CUSTOM_PN,
1.5849 ++ NIOS2_BUILTIN_CUSTOM_PNI,
1.5850 ++ NIOS2_BUILTIN_CUSTOM_PNF,
1.5851 ++ NIOS2_BUILTIN_CUSTOM_PNP,
1.5852 ++ NIOS2_BUILTIN_CUSTOM_PNII,
1.5853 ++ NIOS2_BUILTIN_CUSTOM_PNIF,
1.5854 ++ NIOS2_BUILTIN_CUSTOM_PNIP,
1.5855 ++ NIOS2_BUILTIN_CUSTOM_PNFI,
1.5856 ++ NIOS2_BUILTIN_CUSTOM_PNFF,
1.5857 ++ NIOS2_BUILTIN_CUSTOM_PNFP,
1.5858 ++ NIOS2_BUILTIN_CUSTOM_PNPI,
1.5859 ++ NIOS2_BUILTIN_CUSTOM_PNPF,
1.5860 ++ NIOS2_BUILTIN_CUSTOM_PNPP,
1.5861 ++
1.5862 ++
1.5863 ++ LIM_NIOS2_BUILTINS
1.5864 ++};
1.5865 ++
1.5866 ++struct builtin_description
1.5867 ++{
1.5868 ++ const enum insn_code icode;
1.5869 ++ const char *const name;
1.5870 ++ const enum nios2_builtins code;
1.5871 ++ const tree *type;
1.5872 ++ rtx (* expander) PARAMS ((const struct builtin_description *,
1.5873 ++ tree, rtx, rtx, enum machine_mode, int));
1.5874 ++};
1.5875 ++
1.5876 ++static rtx nios2_expand_STXIO (const struct builtin_description *,
1.5877 ++ tree, rtx, rtx, enum machine_mode, int);
1.5878 ++static rtx nios2_expand_LDXIO (const struct builtin_description *,
1.5879 ++ tree, rtx, rtx, enum machine_mode, int);
1.5880 ++static rtx nios2_expand_sync (const struct builtin_description *,
1.5881 ++ tree, rtx, rtx, enum machine_mode, int);
1.5882 ++static rtx nios2_expand_rdctl (const struct builtin_description *,
1.5883 ++ tree, rtx, rtx, enum machine_mode, int);
1.5884 ++static rtx nios2_expand_wrctl (const struct builtin_description *,
1.5885 ++ tree, rtx, rtx, enum machine_mode, int);
1.5886 ++
1.5887 ++static rtx nios2_expand_custom_n (const struct builtin_description *,
1.5888 ++ tree, rtx, rtx, enum machine_mode, int);
1.5889 ++static rtx nios2_expand_custom_Xn (const struct builtin_description *,
1.5890 ++ tree, rtx, rtx, enum machine_mode, int);
1.5891 ++static rtx nios2_expand_custom_nX (const struct builtin_description *,
1.5892 ++ tree, rtx, rtx, enum machine_mode, int);
1.5893 ++static rtx nios2_expand_custom_XnX (const struct builtin_description *,
1.5894 ++ tree, rtx, rtx, enum machine_mode, int);
1.5895 ++static rtx nios2_expand_custom_nXX (const struct builtin_description *,
1.5896 ++ tree, rtx, rtx, enum machine_mode, int);
1.5897 ++static rtx nios2_expand_custom_XnXX (const struct builtin_description *,
1.5898 ++ tree, rtx, rtx, enum machine_mode, int);
1.5899 ++
1.5900 ++static tree endlink;
1.5901 ++
1.5902 ++/* int fn (volatile const void *)
1.5903 ++ */
1.5904 ++static tree int_ftype_volatile_const_void_p;
1.5905 ++
1.5906 ++/* int fn (int)
1.5907 ++ */
1.5908 ++static tree int_ftype_int;
1.5909 ++
1.5910 ++/* void fn (int, int)
1.5911 ++ */
1.5912 ++static tree void_ftype_int_int;
1.5913 ++
1.5914 ++/* void fn (volatile void *, int)
1.5915 ++ */
1.5916 ++static tree void_ftype_volatile_void_p_int;
1.5917 ++
1.5918 ++/* void fn (void)
1.5919 ++ */
1.5920 ++static tree void_ftype_void;
1.5921 ++
1.5922 ++static tree custom_n;
1.5923 ++static tree custom_ni;
1.5924 ++static tree custom_nf;
1.5925 ++static tree custom_np;
1.5926 ++static tree custom_nii;
1.5927 ++static tree custom_nif;
1.5928 ++static tree custom_nip;
1.5929 ++static tree custom_nfi;
1.5930 ++static tree custom_nff;
1.5931 ++static tree custom_nfp;
1.5932 ++static tree custom_npi;
1.5933 ++static tree custom_npf;
1.5934 ++static tree custom_npp;
1.5935 ++static tree custom_in;
1.5936 ++static tree custom_ini;
1.5937 ++static tree custom_inf;
1.5938 ++static tree custom_inp;
1.5939 ++static tree custom_inii;
1.5940 ++static tree custom_inif;
1.5941 ++static tree custom_inip;
1.5942 ++static tree custom_infi;
1.5943 ++static tree custom_inff;
1.5944 ++static tree custom_infp;
1.5945 ++static tree custom_inpi;
1.5946 ++static tree custom_inpf;
1.5947 ++static tree custom_inpp;
1.5948 ++static tree custom_fn;
1.5949 ++static tree custom_fni;
1.5950 ++static tree custom_fnf;
1.5951 ++static tree custom_fnp;
1.5952 ++static tree custom_fnii;
1.5953 ++static tree custom_fnif;
1.5954 ++static tree custom_fnip;
1.5955 ++static tree custom_fnfi;
1.5956 ++static tree custom_fnff;
1.5957 ++static tree custom_fnfp;
1.5958 ++static tree custom_fnpi;
1.5959 ++static tree custom_fnpf;
1.5960 ++static tree custom_fnpp;
1.5961 ++static tree custom_pn;
1.5962 ++static tree custom_pni;
1.5963 ++static tree custom_pnf;
1.5964 ++static tree custom_pnp;
1.5965 ++static tree custom_pnii;
1.5966 ++static tree custom_pnif;
1.5967 ++static tree custom_pnip;
1.5968 ++static tree custom_pnfi;
1.5969 ++static tree custom_pnff;
1.5970 ++static tree custom_pnfp;
1.5971 ++static tree custom_pnpi;
1.5972 ++static tree custom_pnpf;
1.5973 ++static tree custom_pnpp;
1.5974 ++
1.5975 ++
1.5976 ++static const struct builtin_description bdesc[] = {
1.5977 ++ {CODE_FOR_ldbio, "__builtin_ldbio", NIOS2_BUILTIN_LDBIO, &int_ftype_volatile_const_void_p, nios2_expand_LDXIO},
1.5978 ++ {CODE_FOR_ldbuio, "__builtin_ldbuio", NIOS2_BUILTIN_LDBUIO, &int_ftype_volatile_const_void_p, nios2_expand_LDXIO},
1.5979 ++ {CODE_FOR_ldhio, "__builtin_ldhio", NIOS2_BUILTIN_LDHIO, &int_ftype_volatile_const_void_p, nios2_expand_LDXIO},
1.5980 ++ {CODE_FOR_ldhuio, "__builtin_ldhuio", NIOS2_BUILTIN_LDHUIO, &int_ftype_volatile_const_void_p, nios2_expand_LDXIO},
1.5981 ++ {CODE_FOR_ldwio, "__builtin_ldwio", NIOS2_BUILTIN_LDWIO, &int_ftype_volatile_const_void_p, nios2_expand_LDXIO},
1.5982 ++
1.5983 ++ {CODE_FOR_stbio, "__builtin_stbio", NIOS2_BUILTIN_STBIO, &void_ftype_volatile_void_p_int, nios2_expand_STXIO},
1.5984 ++ {CODE_FOR_sthio, "__builtin_sthio", NIOS2_BUILTIN_STHIO, &void_ftype_volatile_void_p_int, nios2_expand_STXIO},
1.5985 ++ {CODE_FOR_stwio, "__builtin_stwio", NIOS2_BUILTIN_STWIO, &void_ftype_volatile_void_p_int, nios2_expand_STXIO},
1.5986 ++
1.5987 ++ {CODE_FOR_sync, "__builtin_sync", NIOS2_BUILTIN_SYNC, &void_ftype_void, nios2_expand_sync},
1.5988 ++ {CODE_FOR_rdctl, "__builtin_rdctl", NIOS2_BUILTIN_RDCTL, &int_ftype_int, nios2_expand_rdctl},
1.5989 ++ {CODE_FOR_wrctl, "__builtin_wrctl", NIOS2_BUILTIN_WRCTL, &void_ftype_int_int, nios2_expand_wrctl},
1.5990 ++
1.5991 ++ {CODE_FOR_custom_n, "__builtin_custom_n", NIOS2_BUILTIN_CUSTOM_N, &custom_n, nios2_expand_custom_n},
1.5992 ++ {CODE_FOR_custom_ni, "__builtin_custom_ni", NIOS2_BUILTIN_CUSTOM_NI, &custom_ni, nios2_expand_custom_nX},
1.5993 ++ {CODE_FOR_custom_nf, "__builtin_custom_nf", NIOS2_BUILTIN_CUSTOM_NF, &custom_nf, nios2_expand_custom_nX},
1.5994 ++ {CODE_FOR_custom_np, "__builtin_custom_np", NIOS2_BUILTIN_CUSTOM_NP, &custom_np, nios2_expand_custom_nX},
1.5995 ++ {CODE_FOR_custom_nii, "__builtin_custom_nii", NIOS2_BUILTIN_CUSTOM_NII, &custom_nii, nios2_expand_custom_nXX},
1.5996 ++ {CODE_FOR_custom_nif, "__builtin_custom_nif", NIOS2_BUILTIN_CUSTOM_NIF, &custom_nif, nios2_expand_custom_nXX},
1.5997 ++ {CODE_FOR_custom_nip, "__builtin_custom_nip", NIOS2_BUILTIN_CUSTOM_NIP, &custom_nip, nios2_expand_custom_nXX},
1.5998 ++ {CODE_FOR_custom_nfi, "__builtin_custom_nfi", NIOS2_BUILTIN_CUSTOM_NFI, &custom_nfi, nios2_expand_custom_nXX},
1.5999 ++ {CODE_FOR_custom_nff, "__builtin_custom_nff", NIOS2_BUILTIN_CUSTOM_NFF, &custom_nff, nios2_expand_custom_nXX},
1.6000 ++ {CODE_FOR_custom_nfp, "__builtin_custom_nfp", NIOS2_BUILTIN_CUSTOM_NFP, &custom_nfp, nios2_expand_custom_nXX},
1.6001 ++ {CODE_FOR_custom_npi, "__builtin_custom_npi", NIOS2_BUILTIN_CUSTOM_NPI, &custom_npi, nios2_expand_custom_nXX},
1.6002 ++ {CODE_FOR_custom_npf, "__builtin_custom_npf", NIOS2_BUILTIN_CUSTOM_NPF, &custom_npf, nios2_expand_custom_nXX},
1.6003 ++ {CODE_FOR_custom_npp, "__builtin_custom_npp", NIOS2_BUILTIN_CUSTOM_NPP, &custom_npp, nios2_expand_custom_nXX},
1.6004 ++ {CODE_FOR_custom_in, "__builtin_custom_in", NIOS2_BUILTIN_CUSTOM_IN, &custom_in, nios2_expand_custom_Xn},
1.6005 ++ {CODE_FOR_custom_ini, "__builtin_custom_ini", NIOS2_BUILTIN_CUSTOM_INI, &custom_ini, nios2_expand_custom_XnX},
1.6006 ++ {CODE_FOR_custom_inf, "__builtin_custom_inf", NIOS2_BUILTIN_CUSTOM_INF, &custom_inf, nios2_expand_custom_XnX},
1.6007 ++ {CODE_FOR_custom_inp, "__builtin_custom_inp", NIOS2_BUILTIN_CUSTOM_INP, &custom_inp, nios2_expand_custom_XnX},
1.6008 ++ {CODE_FOR_custom_inii, "__builtin_custom_inii", NIOS2_BUILTIN_CUSTOM_INII, &custom_inii, nios2_expand_custom_XnXX},
1.6009 ++ {CODE_FOR_custom_inif, "__builtin_custom_inif", NIOS2_BUILTIN_CUSTOM_INIF, &custom_inif, nios2_expand_custom_XnXX},
1.6010 ++ {CODE_FOR_custom_inip, "__builtin_custom_inip", NIOS2_BUILTIN_CUSTOM_INIP, &custom_inip, nios2_expand_custom_XnXX},
1.6011 ++ {CODE_FOR_custom_infi, "__builtin_custom_infi", NIOS2_BUILTIN_CUSTOM_INFI, &custom_infi, nios2_expand_custom_XnXX},
1.6012 ++ {CODE_FOR_custom_inff, "__builtin_custom_inff", NIOS2_BUILTIN_CUSTOM_INFF, &custom_inff, nios2_expand_custom_XnXX},
1.6013 ++ {CODE_FOR_custom_infp, "__builtin_custom_infp", NIOS2_BUILTIN_CUSTOM_INFP, &custom_infp, nios2_expand_custom_XnXX},
1.6014 ++ {CODE_FOR_custom_inpi, "__builtin_custom_inpi", NIOS2_BUILTIN_CUSTOM_INPI, &custom_inpi, nios2_expand_custom_XnXX},
1.6015 ++ {CODE_FOR_custom_inpf, "__builtin_custom_inpf", NIOS2_BUILTIN_CUSTOM_INPF, &custom_inpf, nios2_expand_custom_XnXX},
1.6016 ++ {CODE_FOR_custom_inpp, "__builtin_custom_inpp", NIOS2_BUILTIN_CUSTOM_INPP, &custom_inpp, nios2_expand_custom_XnXX},
1.6017 ++ {CODE_FOR_custom_fn, "__builtin_custom_fn", NIOS2_BUILTIN_CUSTOM_FN, &custom_fn, nios2_expand_custom_Xn},
1.6018 ++ {CODE_FOR_custom_fni, "__builtin_custom_fni", NIOS2_BUILTIN_CUSTOM_FNI, &custom_fni, nios2_expand_custom_XnX},
1.6019 ++ {CODE_FOR_custom_fnf, "__builtin_custom_fnf", NIOS2_BUILTIN_CUSTOM_FNF, &custom_fnf, nios2_expand_custom_XnX},
1.6020 ++ {CODE_FOR_custom_fnp, "__builtin_custom_fnp", NIOS2_BUILTIN_CUSTOM_FNP, &custom_fnp, nios2_expand_custom_XnX},
1.6021 ++ {CODE_FOR_custom_fnii, "__builtin_custom_fnii", NIOS2_BUILTIN_CUSTOM_FNII, &custom_fnii, nios2_expand_custom_XnXX},
1.6022 ++ {CODE_FOR_custom_fnif, "__builtin_custom_fnif", NIOS2_BUILTIN_CUSTOM_FNIF, &custom_fnif, nios2_expand_custom_XnXX},
1.6023 ++ {CODE_FOR_custom_fnip, "__builtin_custom_fnip", NIOS2_BUILTIN_CUSTOM_FNIP, &custom_fnip, nios2_expand_custom_XnXX},
1.6024 ++ {CODE_FOR_custom_fnfi, "__builtin_custom_fnfi", NIOS2_BUILTIN_CUSTOM_FNFI, &custom_fnfi, nios2_expand_custom_XnXX},
1.6025 ++ {CODE_FOR_custom_fnff, "__builtin_custom_fnff", NIOS2_BUILTIN_CUSTOM_FNFF, &custom_fnff, nios2_expand_custom_XnXX},
1.6026 ++ {CODE_FOR_custom_fnfp, "__builtin_custom_fnfp", NIOS2_BUILTIN_CUSTOM_FNFP, &custom_fnfp, nios2_expand_custom_XnXX},
1.6027 ++ {CODE_FOR_custom_fnpi, "__builtin_custom_fnpi", NIOS2_BUILTIN_CUSTOM_FNPI, &custom_fnpi, nios2_expand_custom_XnXX},
1.6028 ++ {CODE_FOR_custom_fnpf, "__builtin_custom_fnpf", NIOS2_BUILTIN_CUSTOM_FNPF, &custom_fnpf, nios2_expand_custom_XnXX},
1.6029 ++ {CODE_FOR_custom_fnpp, "__builtin_custom_fnpp", NIOS2_BUILTIN_CUSTOM_FNPP, &custom_fnpp, nios2_expand_custom_XnXX},
1.6030 ++ {CODE_FOR_custom_pn, "__builtin_custom_pn", NIOS2_BUILTIN_CUSTOM_PN, &custom_pn, nios2_expand_custom_Xn},
1.6031 ++ {CODE_FOR_custom_pni, "__builtin_custom_pni", NIOS2_BUILTIN_CUSTOM_PNI, &custom_pni, nios2_expand_custom_XnX},
1.6032 ++ {CODE_FOR_custom_pnf, "__builtin_custom_pnf", NIOS2_BUILTIN_CUSTOM_PNF, &custom_pnf, nios2_expand_custom_XnX},
1.6033 ++ {CODE_FOR_custom_pnp, "__builtin_custom_pnp", NIOS2_BUILTIN_CUSTOM_PNP, &custom_pnp, nios2_expand_custom_XnX},
1.6034 ++ {CODE_FOR_custom_pnii, "__builtin_custom_pnii", NIOS2_BUILTIN_CUSTOM_PNII, &custom_pnii, nios2_expand_custom_XnXX},
1.6035 ++ {CODE_FOR_custom_pnif, "__builtin_custom_pnif", NIOS2_BUILTIN_CUSTOM_PNIF, &custom_pnif, nios2_expand_custom_XnXX},
1.6036 ++ {CODE_FOR_custom_pnip, "__builtin_custom_pnip", NIOS2_BUILTIN_CUSTOM_PNIP, &custom_pnip, nios2_expand_custom_XnXX},
1.6037 ++ {CODE_FOR_custom_pnfi, "__builtin_custom_pnfi", NIOS2_BUILTIN_CUSTOM_PNFI, &custom_pnfi, nios2_expand_custom_XnXX},
1.6038 ++ {CODE_FOR_custom_pnff, "__builtin_custom_pnff", NIOS2_BUILTIN_CUSTOM_PNFF, &custom_pnff, nios2_expand_custom_XnXX},
1.6039 ++ {CODE_FOR_custom_pnfp, "__builtin_custom_pnfp", NIOS2_BUILTIN_CUSTOM_PNFP, &custom_pnfp, nios2_expand_custom_XnXX},
1.6040 ++ {CODE_FOR_custom_pnpi, "__builtin_custom_pnpi", NIOS2_BUILTIN_CUSTOM_PNPI, &custom_pnpi, nios2_expand_custom_XnXX},
1.6041 ++ {CODE_FOR_custom_pnpf, "__builtin_custom_pnpf", NIOS2_BUILTIN_CUSTOM_PNPF, &custom_pnpf, nios2_expand_custom_XnXX},
1.6042 ++ {CODE_FOR_custom_pnpp, "__builtin_custom_pnpp", NIOS2_BUILTIN_CUSTOM_PNPP, &custom_pnpp, nios2_expand_custom_XnXX},
1.6043 ++
1.6044 ++
1.6045 ++ {0, 0, 0, 0, 0},
1.6046 ++};
1.6047 ++
1.6048 ++/* This does not have a closing bracket on purpose (see use) */
1.6049 ++#define def_param(TYPE) \
1.6050 ++ tree_cons (NULL_TREE, TYPE,
1.6051 ++
1.6052 ++static void
1.6053 ++nios2_init_builtins ()
1.6054 ++{
1.6055 ++ const struct builtin_description *d;
1.6056 ++
1.6057 ++
1.6058 ++ endlink = void_list_node;
1.6059 ++
1.6060 ++ /* Special indenting here because one of the brackets is in def_param */
1.6061 ++ /* *INDENT-OFF* */
1.6062 ++
1.6063 ++ /* int fn (volatile const void *)
1.6064 ++ */
1.6065 ++ int_ftype_volatile_const_void_p
1.6066 ++ = build_function_type (integer_type_node,
1.6067 ++ def_param (build_qualified_type (ptr_type_node,
1.6068 ++ TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE))
1.6069 ++ endlink));
1.6070 ++
1.6071 ++
1.6072 ++ /* void fn (volatile void *, int)
1.6073 ++ */
1.6074 ++ void_ftype_volatile_void_p_int
1.6075 ++ = build_function_type (void_type_node,
1.6076 ++ def_param (build_qualified_type (ptr_type_node,
1.6077 ++ TYPE_QUAL_VOLATILE))
1.6078 ++ def_param (integer_type_node)
1.6079 ++ endlink)));
1.6080 ++
1.6081 ++ /* void fn (void)
1.6082 ++ */
1.6083 ++ void_ftype_void
1.6084 ++ = build_function_type (void_type_node,
1.6085 ++ endlink);
1.6086 ++
1.6087 ++ /* int fn (int)
1.6088 ++ */
1.6089 ++ int_ftype_int
1.6090 ++ = build_function_type (integer_type_node,
1.6091 ++ def_param (integer_type_node)
1.6092 ++ endlink));
1.6093 ++
1.6094 ++ /* void fn (int, int)
1.6095 ++ */
1.6096 ++ void_ftype_int_int
1.6097 ++ = build_function_type (void_type_node,
1.6098 ++ def_param (integer_type_node)
1.6099 ++ def_param (integer_type_node)
1.6100 ++ endlink)));
1.6101 ++
1.6102 ++
1.6103 ++#define CUSTOM_NUM def_param (integer_type_node)
1.6104 ++
1.6105 ++ custom_n
1.6106 ++ = build_function_type (void_type_node,
1.6107 ++ CUSTOM_NUM
1.6108 ++ endlink));
1.6109 ++ custom_ni
1.6110 ++ = build_function_type (void_type_node,
1.6111 ++ CUSTOM_NUM
1.6112 ++ def_param (integer_type_node)
1.6113 ++ endlink)));
1.6114 ++ custom_nf
1.6115 ++ = build_function_type (void_type_node,
1.6116 ++ CUSTOM_NUM
1.6117 ++ def_param (float_type_node)
1.6118 ++ endlink)));
1.6119 ++ custom_np
1.6120 ++ = build_function_type (void_type_node,
1.6121 ++ CUSTOM_NUM
1.6122 ++ def_param (ptr_type_node)
1.6123 ++ endlink)));
1.6124 ++ custom_nii
1.6125 ++ = build_function_type (void_type_node,
1.6126 ++ CUSTOM_NUM
1.6127 ++ def_param (integer_type_node)
1.6128 ++ def_param (integer_type_node)
1.6129 ++ endlink))));
1.6130 ++ custom_nif
1.6131 ++ = build_function_type (void_type_node,
1.6132 ++ CUSTOM_NUM
1.6133 ++ def_param (integer_type_node)
1.6134 ++ def_param (float_type_node)
1.6135 ++ endlink))));
1.6136 ++ custom_nip
1.6137 ++ = build_function_type (void_type_node,
1.6138 ++ CUSTOM_NUM
1.6139 ++ def_param (integer_type_node)
1.6140 ++ def_param (ptr_type_node)
1.6141 ++ endlink))));
1.6142 ++ custom_nfi
1.6143 ++ = build_function_type (void_type_node,
1.6144 ++ CUSTOM_NUM
1.6145 ++ def_param (float_type_node)
1.6146 ++ def_param (integer_type_node)
1.6147 ++ endlink))));
1.6148 ++ custom_nff
1.6149 ++ = build_function_type (void_type_node,
1.6150 ++ CUSTOM_NUM
1.6151 ++ def_param (float_type_node)
1.6152 ++ def_param (float_type_node)
1.6153 ++ endlink))));
1.6154 ++ custom_nfp
1.6155 ++ = build_function_type (void_type_node,
1.6156 ++ CUSTOM_NUM
1.6157 ++ def_param (float_type_node)
1.6158 ++ def_param (ptr_type_node)
1.6159 ++ endlink))));
1.6160 ++ custom_npi
1.6161 ++ = build_function_type (void_type_node,
1.6162 ++ CUSTOM_NUM
1.6163 ++ def_param (ptr_type_node)
1.6164 ++ def_param (integer_type_node)
1.6165 ++ endlink))));
1.6166 ++ custom_npf
1.6167 ++ = build_function_type (void_type_node,
1.6168 ++ CUSTOM_NUM
1.6169 ++ def_param (ptr_type_node)
1.6170 ++ def_param (float_type_node)
1.6171 ++ endlink))));
1.6172 ++ custom_npp
1.6173 ++ = build_function_type (void_type_node,
1.6174 ++ CUSTOM_NUM
1.6175 ++ def_param (ptr_type_node)
1.6176 ++ def_param (ptr_type_node)
1.6177 ++ endlink))));
1.6178 ++
1.6179 ++ custom_in
1.6180 ++ = build_function_type (integer_type_node,
1.6181 ++ CUSTOM_NUM
1.6182 ++ endlink));
1.6183 ++ custom_ini
1.6184 ++ = build_function_type (integer_type_node,
1.6185 ++ CUSTOM_NUM
1.6186 ++ def_param (integer_type_node)
1.6187 ++ endlink)));
1.6188 ++ custom_inf
1.6189 ++ = build_function_type (integer_type_node,
1.6190 ++ CUSTOM_NUM
1.6191 ++ def_param (float_type_node)
1.6192 ++ endlink)));
1.6193 ++ custom_inp
1.6194 ++ = build_function_type (integer_type_node,
1.6195 ++ CUSTOM_NUM
1.6196 ++ def_param (ptr_type_node)
1.6197 ++ endlink)));
1.6198 ++ custom_inii
1.6199 ++ = build_function_type (integer_type_node,
1.6200 ++ CUSTOM_NUM
1.6201 ++ def_param (integer_type_node)
1.6202 ++ def_param (integer_type_node)
1.6203 ++ endlink))));
1.6204 ++ custom_inif
1.6205 ++ = build_function_type (integer_type_node,
1.6206 ++ CUSTOM_NUM
1.6207 ++ def_param (integer_type_node)
1.6208 ++ def_param (float_type_node)
1.6209 ++ endlink))));
1.6210 ++ custom_inip
1.6211 ++ = build_function_type (integer_type_node,
1.6212 ++ CUSTOM_NUM
1.6213 ++ def_param (integer_type_node)
1.6214 ++ def_param (ptr_type_node)
1.6215 ++ endlink))));
1.6216 ++ custom_infi
1.6217 ++ = build_function_type (integer_type_node,
1.6218 ++ CUSTOM_NUM
1.6219 ++ def_param (float_type_node)
1.6220 ++ def_param (integer_type_node)
1.6221 ++ endlink))));
1.6222 ++ custom_inff
1.6223 ++ = build_function_type (integer_type_node,
1.6224 ++ CUSTOM_NUM
1.6225 ++ def_param (float_type_node)
1.6226 ++ def_param (float_type_node)
1.6227 ++ endlink))));
1.6228 ++ custom_infp
1.6229 ++ = build_function_type (integer_type_node,
1.6230 ++ CUSTOM_NUM
1.6231 ++ def_param (float_type_node)
1.6232 ++ def_param (ptr_type_node)
1.6233 ++ endlink))));
1.6234 ++ custom_inpi
1.6235 ++ = build_function_type (integer_type_node,
1.6236 ++ CUSTOM_NUM
1.6237 ++ def_param (ptr_type_node)
1.6238 ++ def_param (integer_type_node)
1.6239 ++ endlink))));
1.6240 ++ custom_inpf
1.6241 ++ = build_function_type (integer_type_node,
1.6242 ++ CUSTOM_NUM
1.6243 ++ def_param (ptr_type_node)
1.6244 ++ def_param (float_type_node)
1.6245 ++ endlink))));
1.6246 ++ custom_inpp
1.6247 ++ = build_function_type (integer_type_node,
1.6248 ++ CUSTOM_NUM
1.6249 ++ def_param (ptr_type_node)
1.6250 ++ def_param (ptr_type_node)
1.6251 ++ endlink))));
1.6252 ++
1.6253 ++ custom_fn
1.6254 ++ = build_function_type (float_type_node,
1.6255 ++ CUSTOM_NUM
1.6256 ++ endlink));
1.6257 ++ custom_fni
1.6258 ++ = build_function_type (float_type_node,
1.6259 ++ CUSTOM_NUM
1.6260 ++ def_param (integer_type_node)
1.6261 ++ endlink)));
1.6262 ++ custom_fnf
1.6263 ++ = build_function_type (float_type_node,
1.6264 ++ CUSTOM_NUM
1.6265 ++ def_param (float_type_node)
1.6266 ++ endlink)));
1.6267 ++ custom_fnp
1.6268 ++ = build_function_type (float_type_node,
1.6269 ++ CUSTOM_NUM
1.6270 ++ def_param (ptr_type_node)
1.6271 ++ endlink)));
1.6272 ++ custom_fnii
1.6273 ++ = build_function_type (float_type_node,
1.6274 ++ CUSTOM_NUM
1.6275 ++ def_param (integer_type_node)
1.6276 ++ def_param (integer_type_node)
1.6277 ++ endlink))));
1.6278 ++ custom_fnif
1.6279 ++ = build_function_type (float_type_node,
1.6280 ++ CUSTOM_NUM
1.6281 ++ def_param (integer_type_node)
1.6282 ++ def_param (float_type_node)
1.6283 ++ endlink))));
1.6284 ++ custom_fnip
1.6285 ++ = build_function_type (float_type_node,
1.6286 ++ CUSTOM_NUM
1.6287 ++ def_param (integer_type_node)
1.6288 ++ def_param (ptr_type_node)
1.6289 ++ endlink))));
1.6290 ++ custom_fnfi
1.6291 ++ = build_function_type (float_type_node,
1.6292 ++ CUSTOM_NUM
1.6293 ++ def_param (float_type_node)
1.6294 ++ def_param (integer_type_node)
1.6295 ++ endlink))));
1.6296 ++ custom_fnff
1.6297 ++ = build_function_type (float_type_node,
1.6298 ++ CUSTOM_NUM
1.6299 ++ def_param (float_type_node)
1.6300 ++ def_param (float_type_node)
1.6301 ++ endlink))));
1.6302 ++ custom_fnfp
1.6303 ++ = build_function_type (float_type_node,
1.6304 ++ CUSTOM_NUM
1.6305 ++ def_param (float_type_node)
1.6306 ++ def_param (ptr_type_node)
1.6307 ++ endlink))));
1.6308 ++ custom_fnpi
1.6309 ++ = build_function_type (float_type_node,
1.6310 ++ CUSTOM_NUM
1.6311 ++ def_param (ptr_type_node)
1.6312 ++ def_param (integer_type_node)
1.6313 ++ endlink))));
1.6314 ++ custom_fnpf
1.6315 ++ = build_function_type (float_type_node,
1.6316 ++ CUSTOM_NUM
1.6317 ++ def_param (ptr_type_node)
1.6318 ++ def_param (float_type_node)
1.6319 ++ endlink))));
1.6320 ++ custom_fnpp
1.6321 ++ = build_function_type (float_type_node,
1.6322 ++ CUSTOM_NUM
1.6323 ++ def_param (ptr_type_node)
1.6324 ++ def_param (ptr_type_node)
1.6325 ++ endlink))));
1.6326 ++
1.6327 ++
1.6328 ++ custom_pn
1.6329 ++ = build_function_type (ptr_type_node,
1.6330 ++ CUSTOM_NUM
1.6331 ++ endlink));
1.6332 ++ custom_pni
1.6333 ++ = build_function_type (ptr_type_node,
1.6334 ++ CUSTOM_NUM
1.6335 ++ def_param (integer_type_node)
1.6336 ++ endlink)));
1.6337 ++ custom_pnf
1.6338 ++ = build_function_type (ptr_type_node,
1.6339 ++ CUSTOM_NUM
1.6340 ++ def_param (float_type_node)
1.6341 ++ endlink)));
1.6342 ++ custom_pnp
1.6343 ++ = build_function_type (ptr_type_node,
1.6344 ++ CUSTOM_NUM
1.6345 ++ def_param (ptr_type_node)
1.6346 ++ endlink)));
1.6347 ++ custom_pnii
1.6348 ++ = build_function_type (ptr_type_node,
1.6349 ++ CUSTOM_NUM
1.6350 ++ def_param (integer_type_node)
1.6351 ++ def_param (integer_type_node)
1.6352 ++ endlink))));
1.6353 ++ custom_pnif
1.6354 ++ = build_function_type (ptr_type_node,
1.6355 ++ CUSTOM_NUM
1.6356 ++ def_param (integer_type_node)
1.6357 ++ def_param (float_type_node)
1.6358 ++ endlink))));
1.6359 ++ custom_pnip
1.6360 ++ = build_function_type (ptr_type_node,
1.6361 ++ CUSTOM_NUM
1.6362 ++ def_param (integer_type_node)
1.6363 ++ def_param (ptr_type_node)
1.6364 ++ endlink))));
1.6365 ++ custom_pnfi
1.6366 ++ = build_function_type (ptr_type_node,
1.6367 ++ CUSTOM_NUM
1.6368 ++ def_param (float_type_node)
1.6369 ++ def_param (integer_type_node)
1.6370 ++ endlink))));
1.6371 ++ custom_pnff
1.6372 ++ = build_function_type (ptr_type_node,
1.6373 ++ CUSTOM_NUM
1.6374 ++ def_param (float_type_node)
1.6375 ++ def_param (float_type_node)
1.6376 ++ endlink))));
1.6377 ++ custom_pnfp
1.6378 ++ = build_function_type (ptr_type_node,
1.6379 ++ CUSTOM_NUM
1.6380 ++ def_param (float_type_node)
1.6381 ++ def_param (ptr_type_node)
1.6382 ++ endlink))));
1.6383 ++ custom_pnpi
1.6384 ++ = build_function_type (ptr_type_node,
1.6385 ++ CUSTOM_NUM
1.6386 ++ def_param (ptr_type_node)
1.6387 ++ def_param (integer_type_node)
1.6388 ++ endlink))));
1.6389 ++ custom_pnpf
1.6390 ++ = build_function_type (ptr_type_node,
1.6391 ++ CUSTOM_NUM
1.6392 ++ def_param (ptr_type_node)
1.6393 ++ def_param (float_type_node)
1.6394 ++ endlink))));
1.6395 ++ custom_pnpp
1.6396 ++ = build_function_type (ptr_type_node,
1.6397 ++ CUSTOM_NUM
1.6398 ++ def_param (ptr_type_node)
1.6399 ++ def_param (ptr_type_node)
1.6400 ++ endlink))));
1.6401 ++
1.6402 ++
1.6403 ++
1.6404 ++ /* *INDENT-ON* */
1.6405 ++
1.6406 ++
1.6407 ++ for (d = bdesc; d->name; d++)
1.6408 ++ {
1.6409 ++ builtin_function (d->name, *d->type, d->code,
1.6410 ++ BUILT_IN_MD, NULL, NULL);
1.6411 ++ }
1.6412 ++}
1.6413 ++
1.6414 ++/* Expand an expression EXP that calls a built-in function,
1.6415 ++ with result going to TARGET if that's convenient
1.6416 ++ (and in mode MODE if that's convenient).
1.6417 ++ SUBTARGET may be used as the target for computing one of EXP's operands.
1.6418 ++ IGNORE is nonzero if the value is to be ignored. */
1.6419 ++
1.6420 ++static rtx
1.6421 ++nios2_expand_builtin (tree exp, rtx target, rtx subtarget,
1.6422 ++ enum machine_mode mode, int ignore)
1.6423 ++{
1.6424 ++ const struct builtin_description *d;
1.6425 ++ tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1.6426 ++ unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
1.6427 ++
1.6428 ++ for (d = bdesc; d->name; d++)
1.6429 ++ if (d->code == fcode)
1.6430 ++ return (d->expander) (d, exp, target, subtarget, mode, ignore);
1.6431 ++
1.6432 ++ /* we should have seen one of the functins we registered */
1.6433 ++ abort ();
1.6434 ++}
1.6435 ++
1.6436 ++static rtx nios2_create_target (const struct builtin_description *, rtx);
1.6437 ++
1.6438 ++
1.6439 ++static rtx
1.6440 ++nios2_create_target (const struct builtin_description *d, rtx target)
1.6441 ++{
1.6442 ++ if (!target
1.6443 ++ || !(*insn_data[d->icode].operand[0].predicate) (target,
1.6444 ++ insn_data[d->icode].operand[0].mode))
1.6445 ++ {
1.6446 ++ target = gen_reg_rtx (insn_data[d->icode].operand[0].mode);
1.6447 ++ }
1.6448 ++
1.6449 ++ return target;
1.6450 ++}
1.6451 ++
1.6452 ++
1.6453 ++static rtx nios2_extract_opcode (const struct builtin_description *, int, tree);
1.6454 ++static rtx nios2_extract_operand (const struct builtin_description *, int, int, tree);
1.6455 ++
1.6456 ++static rtx
1.6457 ++nios2_extract_opcode (const struct builtin_description *d, int op, tree arglist)
1.6458 ++{
1.6459 ++ enum machine_mode mode = insn_data[d->icode].operand[op].mode;
1.6460 ++ tree arg = TREE_VALUE (arglist);
1.6461 ++ rtx opcode = expand_expr (arg, NULL_RTX, mode, 0);
1.6462 ++ opcode = protect_from_queue (opcode, 0);
1.6463 ++
1.6464 ++ if (!(*insn_data[d->icode].operand[op].predicate) (opcode, mode))
1.6465 ++ error ("Custom instruction opcode must be compile time constant in the range 0-255 for %s", d->name);
1.6466 ++
1.6467 ++ return opcode;
1.6468 ++}
1.6469 ++
1.6470 ++static rtx
1.6471 ++nios2_extract_operand (const struct builtin_description *d, int op, int argnum, tree arglist)
1.6472 ++{
1.6473 ++ enum machine_mode mode = insn_data[d->icode].operand[op].mode;
1.6474 ++ tree arg = TREE_VALUE (arglist);
1.6475 ++ rtx operand = expand_expr (arg, NULL_RTX, mode, 0);
1.6476 ++ operand = protect_from_queue (operand, 0);
1.6477 ++
1.6478 ++ if (!(*insn_data[d->icode].operand[op].predicate) (operand, mode))
1.6479 ++ operand = copy_to_mode_reg (mode, operand);
1.6480 ++
1.6481 ++ /* ??? Better errors would be nice */
1.6482 ++ if (!(*insn_data[d->icode].operand[op].predicate) (operand, mode))
1.6483 ++ error ("Invalid argument %d to %s", argnum, d->name);
1.6484 ++
1.6485 ++ return operand;
1.6486 ++}
1.6487 ++
1.6488 ++
1.6489 ++static rtx
1.6490 ++nios2_expand_custom_n (const struct builtin_description *d, tree exp,
1.6491 ++ rtx target ATTRIBUTE_UNUSED, rtx subtarget ATTRIBUTE_UNUSED,
1.6492 ++ enum machine_mode mode ATTRIBUTE_UNUSED, int ignore ATTRIBUTE_UNUSED)
1.6493 ++{
1.6494 ++ tree arglist = TREE_OPERAND (exp, 1);
1.6495 ++ rtx pat;
1.6496 ++ rtx opcode;
1.6497 ++
1.6498 ++ /* custom_n should have exactly one operand */
1.6499 ++ if (insn_data[d->icode].n_operands != 1)
1.6500 ++ abort ();
1.6501 ++
1.6502 ++ opcode = nios2_extract_opcode (d, 0, arglist);
1.6503 ++
1.6504 ++ pat = GEN_FCN (d->icode) (opcode);
1.6505 ++ if (!pat)
1.6506 ++ return 0;
1.6507 ++ emit_insn (pat);
1.6508 ++ return 0;
1.6509 ++}
1.6510 ++
1.6511 ++static rtx
1.6512 ++nios2_expand_custom_Xn (const struct builtin_description *d, tree exp,
1.6513 ++ rtx target, rtx subtarget ATTRIBUTE_UNUSED,
1.6514 ++ enum machine_mode mode ATTRIBUTE_UNUSED,
1.6515 ++ int ignore ATTRIBUTE_UNUSED)
1.6516 ++{
1.6517 ++ tree arglist = TREE_OPERAND (exp, 1);
1.6518 ++ rtx pat;
1.6519 ++ rtx opcode;
1.6520 ++
1.6521 ++ /* custom_Xn should have exactly two operands */
1.6522 ++ if (insn_data[d->icode].n_operands != 2)
1.6523 ++ abort ();
1.6524 ++
1.6525 ++ target = nios2_create_target (d, target);
1.6526 ++ opcode = nios2_extract_opcode (d, 1, arglist);
1.6527 ++
1.6528 ++ pat = GEN_FCN (d->icode) (target, opcode);
1.6529 ++ if (!pat)
1.6530 ++ return 0;
1.6531 ++ emit_insn (pat);
1.6532 ++ return target;
1.6533 ++}
1.6534 ++
1.6535 ++static rtx
1.6536 ++nios2_expand_custom_nX (const struct builtin_description *d, tree exp,
1.6537 ++ rtx target ATTRIBUTE_UNUSED, rtx subtarget ATTRIBUTE_UNUSED,
1.6538 ++ enum machine_mode mode ATTRIBUTE_UNUSED, int ignore ATTRIBUTE_UNUSED)
1.6539 ++{
1.6540 ++ tree arglist = TREE_OPERAND (exp, 1);
1.6541 ++ rtx pat;
1.6542 ++ rtx opcode;
1.6543 ++ rtx operands[1];
1.6544 ++ int i;
1.6545 ++
1.6546 ++
1.6547 ++ /* custom_nX should have exactly two operands */
1.6548 ++ if (insn_data[d->icode].n_operands != 2)
1.6549 ++ abort ();
1.6550 ++
1.6551 ++ opcode = nios2_extract_opcode (d, 0, arglist);
1.6552 ++ for (i = 0; i < 1; i++)
1.6553 ++ {
1.6554 ++ arglist = TREE_CHAIN (arglist);
1.6555 ++ operands[i] = nios2_extract_operand (d, i + 1, i + 1, arglist);
1.6556 ++ }
1.6557 ++
1.6558 ++ pat = GEN_FCN (d->icode) (opcode, operands[0]);
1.6559 ++ if (!pat)
1.6560 ++ return 0;
1.6561 ++ emit_insn (pat);
1.6562 ++ return 0;
1.6563 ++}
1.6564 ++
1.6565 ++static rtx
1.6566 ++nios2_expand_custom_XnX (const struct builtin_description *d, tree exp, rtx target,
1.6567 ++ rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED,
1.6568 ++ int ignore ATTRIBUTE_UNUSED)
1.6569 ++{
1.6570 ++ tree arglist = TREE_OPERAND (exp, 1);
1.6571 ++ rtx pat;
1.6572 ++ rtx opcode;
1.6573 ++ rtx operands[1];
1.6574 ++ int i;
1.6575 ++
1.6576 ++ /* custom_Xn should have exactly three operands */
1.6577 ++ if (insn_data[d->icode].n_operands != 3)
1.6578 ++ abort ();
1.6579 ++
1.6580 ++ target = nios2_create_target (d, target);
1.6581 ++ opcode = nios2_extract_opcode (d, 1, arglist);
1.6582 ++
1.6583 ++ for (i = 0; i < 1; i++)
1.6584 ++ {
1.6585 ++ arglist = TREE_CHAIN (arglist);
1.6586 ++ operands[i] = nios2_extract_operand (d, i + 2, i + 1, arglist);
1.6587 ++ }
1.6588 ++
1.6589 ++ pat = GEN_FCN (d->icode) (target, opcode, operands[0]);
1.6590 ++
1.6591 ++ if (!pat)
1.6592 ++ return 0;
1.6593 ++ emit_insn (pat);
1.6594 ++ return target;
1.6595 ++}
1.6596 ++
1.6597 ++static rtx
1.6598 ++nios2_expand_custom_nXX (const struct builtin_description *d, tree exp, rtx target ATTRIBUTE_UNUSED,
1.6599 ++ rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED,
1.6600 ++ int ignore ATTRIBUTE_UNUSED)
1.6601 ++{
1.6602 ++ tree arglist = TREE_OPERAND (exp, 1);
1.6603 ++ rtx pat;
1.6604 ++ rtx opcode;
1.6605 ++ rtx operands[2];
1.6606 ++ int i;
1.6607 ++
1.6608 ++
1.6609 ++ /* custom_nX should have exactly three operands */
1.6610 ++ if (insn_data[d->icode].n_operands != 3)
1.6611 ++ abort ();
1.6612 ++
1.6613 ++ opcode = nios2_extract_opcode (d, 0, arglist);
1.6614 ++ for (i = 0; i < 2; i++)
1.6615 ++ {
1.6616 ++ arglist = TREE_CHAIN (arglist);
1.6617 ++ operands[i] = nios2_extract_operand (d, i + 1, i + 1, arglist);
1.6618 ++ }
1.6619 ++
1.6620 ++ pat = GEN_FCN (d->icode) (opcode, operands[0], operands[1]);
1.6621 ++ if (!pat)
1.6622 ++ return 0;
1.6623 ++ emit_insn (pat);
1.6624 ++ return 0;
1.6625 ++}
1.6626 ++
1.6627 ++static rtx
1.6628 ++nios2_expand_custom_XnXX (const struct builtin_description *d, tree exp, rtx target,
1.6629 ++ rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED,
1.6630 ++ int ignore ATTRIBUTE_UNUSED)
1.6631 ++{
1.6632 ++ tree arglist = TREE_OPERAND (exp, 1);
1.6633 ++ rtx pat;
1.6634 ++ rtx opcode;
1.6635 ++ rtx operands[2];
1.6636 ++ int i;
1.6637 ++
1.6638 ++
1.6639 ++ /* custom_XnX should have exactly four operands */
1.6640 ++ if (insn_data[d->icode].n_operands != 4)
1.6641 ++ abort ();
1.6642 ++
1.6643 ++ target = nios2_create_target (d, target);
1.6644 ++ opcode = nios2_extract_opcode (d, 1, arglist);
1.6645 ++ for (i = 0; i < 2; i++)
1.6646 ++ {
1.6647 ++ arglist = TREE_CHAIN (arglist);
1.6648 ++ operands[i] = nios2_extract_operand (d, i + 2, i + 1, arglist);
1.6649 ++ }
1.6650 ++
1.6651 ++ pat = GEN_FCN (d->icode) (target, opcode, operands[0], operands[1]);
1.6652 ++
1.6653 ++ if (!pat)
1.6654 ++ return 0;
1.6655 ++ emit_insn (pat);
1.6656 ++ return target;
1.6657 ++}
1.6658 ++
1.6659 ++
1.6660 ++
1.6661 ++static rtx
1.6662 ++nios2_expand_STXIO (const struct builtin_description *d, tree exp, rtx target ATTRIBUTE_UNUSED,
1.6663 ++ rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED,
1.6664 ++ int ignore ATTRIBUTE_UNUSED)
1.6665 ++{
1.6666 ++ tree arglist = TREE_OPERAND (exp, 1);
1.6667 ++ rtx pat;
1.6668 ++ rtx store_dest, store_val;
1.6669 ++ enum insn_code icode = d->icode;
1.6670 ++
1.6671 ++ /* stores should have exactly two operands */
1.6672 ++ if (insn_data[icode].n_operands != 2)
1.6673 ++ abort ();
1.6674 ++
1.6675 ++ /* process the destination of the store */
1.6676 ++ {
1.6677 ++ enum machine_mode mode = insn_data[icode].operand[0].mode;
1.6678 ++ tree arg = TREE_VALUE (arglist);
1.6679 ++ store_dest = expand_expr (arg, NULL_RTX, VOIDmode, 0);
1.6680 ++ store_dest = protect_from_queue (store_dest, 0);
1.6681 ++
1.6682 ++ store_dest = gen_rtx_MEM (mode, copy_to_mode_reg (Pmode, store_dest));
1.6683 ++
1.6684 ++ /* ??? Better errors would be nice */
1.6685 ++ if (!(*insn_data[icode].operand[0].predicate) (store_dest, mode))
1.6686 ++ error ("Invalid argument 1 to %s", d->name);
1.6687 ++ }
1.6688 ++
1.6689 ++
1.6690 ++ /* process the value to store */
1.6691 ++ {
1.6692 ++ enum machine_mode mode = insn_data[icode].operand[1].mode;
1.6693 ++ tree arg = TREE_VALUE (TREE_CHAIN (arglist));
1.6694 ++ store_val = expand_expr (arg, NULL_RTX, mode, 0);
1.6695 ++ store_val = protect_from_queue (store_val, 0);
1.6696 ++
1.6697 ++ if (!(*insn_data[icode].operand[1].predicate) (store_val, mode))
1.6698 ++ store_val = copy_to_mode_reg (mode, store_val);
1.6699 ++
1.6700 ++ /* ??? Better errors would be nice */
1.6701 ++ if (!(*insn_data[icode].operand[1].predicate) (store_val, mode))
1.6702 ++ error ("Invalid argument 2 to %s", d->name);
1.6703 ++ }
1.6704 ++
1.6705 ++ pat = GEN_FCN (d->icode) (store_dest, store_val);
1.6706 ++ if (!pat)
1.6707 ++ return 0;
1.6708 ++ emit_insn (pat);
1.6709 ++ return 0;
1.6710 ++}
1.6711 ++
1.6712 ++
1.6713 ++static rtx
1.6714 ++nios2_expand_LDXIO (const struct builtin_description * d, tree exp, rtx target,
1.6715 ++ rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED,
1.6716 ++ int ignore ATTRIBUTE_UNUSED)
1.6717 ++{
1.6718 ++ tree arglist = TREE_OPERAND (exp, 1);
1.6719 ++ rtx pat;
1.6720 ++ rtx ld_src;
1.6721 ++ enum insn_code icode = d->icode;
1.6722 ++
1.6723 ++ /* loads should have exactly two operands */
1.6724 ++ if (insn_data[icode].n_operands != 2)
1.6725 ++ abort ();
1.6726 ++
1.6727 ++ target = nios2_create_target (d, target);
1.6728 ++
1.6729 ++ {
1.6730 ++ enum machine_mode mode = insn_data[icode].operand[1].mode;
1.6731 ++ tree arg = TREE_VALUE (arglist);
1.6732 ++ ld_src = expand_expr (arg, NULL_RTX, VOIDmode, 0);
1.6733 ++ ld_src = protect_from_queue (ld_src, 0);
1.6734 ++
1.6735 ++ ld_src = gen_rtx_MEM (mode, copy_to_mode_reg (Pmode, ld_src));
1.6736 ++
1.6737 ++ /* ??? Better errors would be nice */
1.6738 ++ if (!(*insn_data[icode].operand[1].predicate) (ld_src, mode))
1.6739 ++ {
1.6740 ++ error ("Invalid argument 1 to %s", d->name);
1.6741 ++ }
1.6742 ++ }
1.6743 ++
1.6744 ++ pat = GEN_FCN (d->icode) (target, ld_src);
1.6745 ++ if (!pat)
1.6746 ++ return 0;
1.6747 ++ emit_insn (pat);
1.6748 ++ return target;
1.6749 ++}
1.6750 ++
1.6751 ++
1.6752 ++static rtx
1.6753 ++nios2_expand_sync (const struct builtin_description * d ATTRIBUTE_UNUSED,
1.6754 ++ tree exp ATTRIBUTE_UNUSED, rtx target ATTRIBUTE_UNUSED,
1.6755 ++ rtx subtarget ATTRIBUTE_UNUSED,
1.6756 ++ enum machine_mode mode ATTRIBUTE_UNUSED,
1.6757 ++ int ignore ATTRIBUTE_UNUSED)
1.6758 ++{
1.6759 ++ emit_insn (gen_sync ());
1.6760 ++ return 0;
1.6761 ++}
1.6762 ++
1.6763 ++static rtx
1.6764 ++nios2_expand_rdctl (const struct builtin_description * d ATTRIBUTE_UNUSED,
1.6765 ++ tree exp ATTRIBUTE_UNUSED, rtx target ATTRIBUTE_UNUSED,
1.6766 ++ rtx subtarget ATTRIBUTE_UNUSED,
1.6767 ++ enum machine_mode mode ATTRIBUTE_UNUSED,
1.6768 ++ int ignore ATTRIBUTE_UNUSED)
1.6769 ++{
1.6770 ++ tree arglist = TREE_OPERAND (exp, 1);
1.6771 ++ rtx pat;
1.6772 ++ rtx rdctl_reg;
1.6773 ++ enum insn_code icode = d->icode;
1.6774 ++
1.6775 ++ /* rdctl should have exactly two operands */
1.6776 ++ if (insn_data[icode].n_operands != 2)
1.6777 ++ abort ();
1.6778 ++
1.6779 ++ target = nios2_create_target (d, target);
1.6780 ++
1.6781 ++ {
1.6782 ++ enum machine_mode mode = insn_data[icode].operand[1].mode;
1.6783 ++ tree arg = TREE_VALUE (arglist);
1.6784 ++ rdctl_reg = expand_expr (arg, NULL_RTX, VOIDmode, 0);
1.6785 ++ rdctl_reg = protect_from_queue (rdctl_reg, 0);
1.6786 ++
1.6787 ++ if (!(*insn_data[icode].operand[1].predicate) (rdctl_reg, mode))
1.6788 ++ {
1.6789 ++ error ("Control register number must be in range 0-31 for %s", d->name);
1.6790 ++ }
1.6791 ++ }
1.6792 ++
1.6793 ++ pat = GEN_FCN (d->icode) (target, rdctl_reg);
1.6794 ++ if (!pat)
1.6795 ++ return 0;
1.6796 ++ emit_insn (pat);
1.6797 ++ return target;
1.6798 ++}
1.6799 ++
1.6800 ++static rtx
1.6801 ++nios2_expand_wrctl (const struct builtin_description * d ATTRIBUTE_UNUSED,
1.6802 ++ tree exp ATTRIBUTE_UNUSED, rtx target ATTRIBUTE_UNUSED,
1.6803 ++ rtx subtarget ATTRIBUTE_UNUSED,
1.6804 ++ enum machine_mode mode ATTRIBUTE_UNUSED,
1.6805 ++ int ignore ATTRIBUTE_UNUSED)
1.6806 ++{
1.6807 ++ tree arglist = TREE_OPERAND (exp, 1);
1.6808 ++ rtx pat;
1.6809 ++ rtx wrctl_reg, store_val;
1.6810 ++ enum insn_code icode = d->icode;
1.6811 ++
1.6812 ++ /* stores should have exactly two operands */
1.6813 ++ if (insn_data[icode].n_operands != 2)
1.6814 ++ abort ();
1.6815 ++
1.6816 ++ /* process the destination of the store */
1.6817 ++ {
1.6818 ++ enum machine_mode mode = insn_data[icode].operand[0].mode;
1.6819 ++ tree arg = TREE_VALUE (arglist);
1.6820 ++ wrctl_reg = expand_expr (arg, NULL_RTX, VOIDmode, 0);
1.6821 ++ wrctl_reg = protect_from_queue (wrctl_reg, 0);
1.6822 ++
1.6823 ++ if (!(*insn_data[icode].operand[0].predicate) (wrctl_reg, mode))
1.6824 ++ error ("Control register number must be in range 0-31 for %s", d->name);
1.6825 ++ }
1.6826 ++
1.6827 ++
1.6828 ++ /* process the value to store */
1.6829 ++ {
1.6830 ++ enum machine_mode mode = insn_data[icode].operand[1].mode;
1.6831 ++ tree arg = TREE_VALUE (TREE_CHAIN (arglist));
1.6832 ++ store_val = expand_expr (arg, NULL_RTX, mode, 0);
1.6833 ++ store_val = protect_from_queue (store_val, 0);
1.6834 ++
1.6835 ++ if (!(*insn_data[icode].operand[1].predicate) (store_val, mode))
1.6836 ++ store_val = copy_to_mode_reg (mode, store_val);
1.6837 ++
1.6838 ++ /* ??? Better errors would be nice */
1.6839 ++ if (!(*insn_data[icode].operand[1].predicate) (store_val, mode))
1.6840 ++ error ("Invalid argument 2 to %s", d->name);
1.6841 ++ }
1.6842 ++
1.6843 ++ pat = GEN_FCN (d->icode) (wrctl_reg, store_val);
1.6844 ++ if (!pat)
1.6845 ++ return 0;
1.6846 ++ emit_insn (pat);
1.6847 ++ return 0;
1.6848 ++}
1.6849 ++
1.6850 ++
1.6851 ++#include "gt-nios2.h"
1.6852 ++
1.6853 +--- gcc-3.4.3/gcc/config/nios2/nios2.h
1.6854 ++++ gcc-3.4.3-nios2/gcc/config/nios2/nios2.h
1.6855 +@@ -0,0 +1,824 @@
1.6856 ++/* Definitions of target machine for Altera NIOS 2G NIOS2 version.
1.6857 ++ Copyright (C) 2003 Altera
1.6858 ++ Contributed by Jonah Graham (jgraham@altera.com).
1.6859 ++
1.6860 ++This file is part of GNU CC.
1.6861 ++
1.6862 ++GNU CC is free software; you can redistribute it and/or modify
1.6863 ++it under the terms of the GNU General Public License as published by
1.6864 ++the Free Software Foundation; either version 2, or (at your option)
1.6865 ++any later version.
1.6866 ++
1.6867 ++GNU CC is distributed in the hope that it will be useful,
1.6868 ++but WITHOUT ANY WARRANTY; without even the implied warranty of
1.6869 ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.6870 ++GNU General Public License for more details.
1.6871 ++
1.6872 ++You should have received a copy of the GNU General Public License
1.6873 ++along with GNU CC; see the file COPYING. If not, write to
1.6874 ++the Free Software Foundation, 59 Temple Place - Suite 330,
1.6875 ++Boston, MA 02111-1307, USA. */
1.6876 ++
1.6877 ++
1.6878 ++
1.6879 ++#define TARGET_CPU_CPP_BUILTINS() \
1.6880 ++ do \
1.6881 ++ { \
1.6882 ++ builtin_define_std ("NIOS2"); \
1.6883 ++ builtin_define_std ("nios2"); \
1.6884 ++ builtin_define ("_GNU_SOURCE"); \
1.6885 ++ } \
1.6886 ++ while (0)
1.6887 ++#define TARGET_VERSION fprintf (stderr, " (Altera Nios II)")
1.6888 ++
1.6889 ++
1.6890 ++
1.6891 ++
1.6892 ++
1.6893 ++/*********************************
1.6894 ++ * Run-time Target Specification
1.6895 ++ *********************************/
1.6896 ++
1.6897 ++#define HAS_DIV_FLAG 0x0001
1.6898 ++#define HAS_MUL_FLAG 0x0002
1.6899 ++#define HAS_MULX_FLAG 0x0004
1.6900 ++#define FAST_SW_DIV_FLAG 0x0008
1.6901 ++#define INLINE_MEMCPY_FLAG 0x00010
1.6902 ++#define CACHE_VOLATILE_FLAG 0x0020
1.6903 ++#define BYPASS_CACHE_FLAG 0x0040
1.6904 ++
1.6905 ++extern int target_flags;
1.6906 ++#define TARGET_HAS_DIV (target_flags & HAS_DIV_FLAG)
1.6907 ++#define TARGET_HAS_MUL (target_flags & HAS_MUL_FLAG)
1.6908 ++#define TARGET_HAS_MULX (target_flags & HAS_MULX_FLAG)
1.6909 ++#define TARGET_FAST_SW_DIV (target_flags & FAST_SW_DIV_FLAG)
1.6910 ++#define TARGET_INLINE_MEMCPY (target_flags & INLINE_MEMCPY_FLAG)
1.6911 ++#define TARGET_CACHE_VOLATILE (target_flags & CACHE_VOLATILE_FLAG)
1.6912 ++#define TARGET_BYPASS_CACHE (target_flags & BYPASS_CACHE_FLAG)
1.6913 ++
1.6914 ++#define TARGET_SWITCHES \
1.6915 ++{ \
1.6916 ++ { "hw-div", HAS_DIV_FLAG, \
1.6917 ++ N_("Enable DIV, DIVU") }, \
1.6918 ++ { "no-hw-div", -HAS_DIV_FLAG, \
1.6919 ++ N_("Disable DIV, DIVU (default)") }, \
1.6920 ++ { "hw-mul", HAS_MUL_FLAG, \
1.6921 ++ N_("Enable MUL instructions (default)") }, \
1.6922 ++ { "hw-mulx", HAS_MULX_FLAG, \
1.6923 ++ N_("Enable MULX instructions, assume fast shifter") }, \
1.6924 ++ { "no-hw-mul", -HAS_MUL_FLAG, \
1.6925 ++ N_("Disable MUL instructions") }, \
1.6926 ++ { "no-hw-mulx", -HAS_MULX_FLAG, \
1.6927 ++ N_("Disable MULX instructions, assume slow shifter (default and implied by -mno-hw-mul)") }, \
1.6928 ++ { "fast-sw-div", FAST_SW_DIV_FLAG, \
1.6929 ++ N_("Use table based fast divide (default at -O3)") }, \
1.6930 ++ { "no-fast-sw-div", -FAST_SW_DIV_FLAG, \
1.6931 ++ N_("Don't use table based fast divide ever") }, \
1.6932 ++ { "inline-memcpy", INLINE_MEMCPY_FLAG, \
1.6933 ++ N_("Inline small memcpy (default when optimizing)") }, \
1.6934 ++ { "no-inline-memcpy", -INLINE_MEMCPY_FLAG, \
1.6935 ++ N_("Don't Inline small memcpy") }, \
1.6936 ++ { "cache-volatile", CACHE_VOLATILE_FLAG, \
1.6937 ++ N_("Volatile accesses use non-io variants of instructions (default)") }, \
1.6938 ++ { "no-cache-volatile", -CACHE_VOLATILE_FLAG, \
1.6939 ++ N_("Volatile accesses use io variants of instructions") }, \
1.6940 ++ { "bypass-cache", BYPASS_CACHE_FLAG, \
1.6941 ++ N_("All ld/st instructins use io variants") }, \
1.6942 ++ { "no-bypass-cache", -BYPASS_CACHE_FLAG, \
1.6943 ++ N_("All ld/st instructins do not use io variants (default)") }, \
1.6944 ++ { "smallc", 0, \
1.6945 ++ N_("Link with a limited version of the C library") }, \
1.6946 ++ { "ctors-in-init", 0, \
1.6947 ++ "" /* undocumented: N_("Link with static constructors and destructors in init") */ }, \
1.6948 ++ { "", TARGET_DEFAULT, 0 } \
1.6949 ++}
1.6950 ++
1.6951 ++
1.6952 ++extern const char *nios2_sys_nosys_string; /* for -msys=nosys */
1.6953 ++extern const char *nios2_sys_lib_string; /* for -msys-lib= */
1.6954 ++extern const char *nios2_sys_crt0_string; /* for -msys-crt0= */
1.6955 ++
1.6956 ++#define TARGET_OPTIONS \
1.6957 ++{ \
1.6958 ++ { "sys=nosys", &nios2_sys_nosys_string, \
1.6959 ++ N_("Use stub versions of OS library calls (default)"), 0}, \
1.6960 ++ { "sys-lib=", &nios2_sys_lib_string, \
1.6961 ++ N_("Name of System Library to link against. (Converted to a -l option)"), 0}, \
1.6962 ++ { "sys-crt0=", &nios2_sys_crt0_string, \
1.6963 ++ N_("Name of the startfile. (default is a crt0 for the ISS only)"), 0}, \
1.6964 ++}
1.6965 ++
1.6966 ++
1.6967 ++/* Default target_flags if no switches specified. */
1.6968 ++#ifndef TARGET_DEFAULT
1.6969 ++# define TARGET_DEFAULT (HAS_MUL_FLAG | CACHE_VOLATILE_FLAG)
1.6970 ++#endif
1.6971 ++
1.6972 ++/* Switch Recognition by gcc.c. Add -G xx support */
1.6973 ++#undef SWITCH_TAKES_ARG
1.6974 ++#define SWITCH_TAKES_ARG(CHAR) \
1.6975 ++ (DEFAULT_SWITCH_TAKES_ARG (CHAR) || (CHAR) == 'G')
1.6976 ++
1.6977 ++#define OVERRIDE_OPTIONS override_options ()
1.6978 ++#define OPTIMIZATION_OPTIONS(LEVEL, SIZE) optimization_options (LEVEL, SIZE)
1.6979 ++#define CAN_DEBUG_WITHOUT_FP
1.6980 ++
1.6981 ++#define CC1_SPEC "\
1.6982 ++%{G*}"
1.6983 ++
1.6984 ++#undef LIB_SPEC
1.6985 ++#define LIB_SPEC \
1.6986 ++"--start-group %{msmallc: -lsmallc} %{!msmallc: -lc} -lgcc \
1.6987 ++ %{msys-lib=*: -l%*} \
1.6988 ++ %{!msys-lib=*: -lc } \
1.6989 ++ --end-group \
1.6990 ++ %{msys-lib=: %eYou need a library name for -msys-lib=} \
1.6991 ++"
1.6992 ++
1.6993 ++
1.6994 ++#undef STARTFILE_SPEC
1.6995 ++#define STARTFILE_SPEC \
1.6996 ++"%{msys-crt0=*: %*} %{!msys-crt0=*: crt1%O%s} \
1.6997 ++ %{msys-crt0=: %eYou need a C startup file for -msys-crt0=} \
1.6998 ++ %{mctors-in-init: crti%O%s crtbegin%O%s} \
1.6999 ++"
1.7000 ++
1.7001 ++#undef ENDFILE_SPEC
1.7002 ++#define ENDFILE_SPEC \
1.7003 ++ "%{mctors-in-init: crtend%O%s crtn%O%s}"
1.7004 ++
1.7005 ++
1.7006 ++/***********************
1.7007 ++ * Storage Layout
1.7008 ++ ***********************/
1.7009 ++
1.7010 ++#define DEFAULT_SIGNED_CHAR 1
1.7011 ++#define BITS_BIG_ENDIAN 0
1.7012 ++#define BYTES_BIG_ENDIAN 0
1.7013 ++#define WORDS_BIG_ENDIAN 0
1.7014 ++#define BITS_PER_UNIT 8
1.7015 ++#define BITS_PER_WORD 32
1.7016 ++#define UNITS_PER_WORD 4
1.7017 ++#define POINTER_SIZE 32
1.7018 ++#define BIGGEST_ALIGNMENT 32
1.7019 ++#define STRICT_ALIGNMENT 1
1.7020 ++#define FUNCTION_BOUNDARY 32
1.7021 ++#define PARM_BOUNDARY 32
1.7022 ++#define STACK_BOUNDARY 32
1.7023 ++#define PREFERRED_STACK_BOUNDARY 32
1.7024 ++#define MAX_FIXED_MODE_SIZE 64
1.7025 ++
1.7026 ++#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
1.7027 ++ ((TREE_CODE (EXP) == STRING_CST) \
1.7028 ++ && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
1.7029 ++
1.7030 ++
1.7031 ++/**********************
1.7032 ++ * Layout of Source Language Data Types
1.7033 ++ **********************/
1.7034 ++
1.7035 ++#define INT_TYPE_SIZE 32
1.7036 ++#define SHORT_TYPE_SIZE 16
1.7037 ++#define LONG_TYPE_SIZE 32
1.7038 ++#define LONG_LONG_TYPE_SIZE 64
1.7039 ++#define FLOAT_TYPE_SIZE 32
1.7040 ++#define DOUBLE_TYPE_SIZE 64
1.7041 ++#define LONG_DOUBLE_TYPE_SIZE DOUBLE_TYPE_SIZE
1.7042 ++
1.7043 ++
1.7044 ++/*************************
1.7045 ++ * Condition Code Status
1.7046 ++ ************************/
1.7047 ++
1.7048 ++/* comparison type */
1.7049 ++/* ??? currently only CMP_SI is used */
1.7050 ++enum cmp_type {
1.7051 ++ CMP_SI, /* compare four byte integers */
1.7052 ++ CMP_DI, /* compare eight byte integers */
1.7053 ++ CMP_SF, /* compare single precision floats */
1.7054 ++ CMP_DF, /* compare double precision floats */
1.7055 ++ CMP_MAX /* max comparison type */
1.7056 ++};
1.7057 ++
1.7058 ++extern GTY(()) rtx branch_cmp[2]; /* operands for compare */
1.7059 ++extern enum cmp_type branch_type; /* what type of branch to use */
1.7060 ++
1.7061 ++/**********************
1.7062 ++ * Register Usage
1.7063 ++ **********************/
1.7064 ++
1.7065 ++/* ---------------------------------- *
1.7066 ++ * Basic Characteristics of Registers
1.7067 ++ * ---------------------------------- */
1.7068 ++
1.7069 ++/*
1.7070 ++Register Number
1.7071 ++ Register Name
1.7072 ++ Alternate Name
1.7073 ++ Purpose
1.7074 ++0 r0 zero always zero
1.7075 ++1 r1 at Assembler Temporary
1.7076 ++2-3 r2-r3 Return Location
1.7077 ++4-7 r4-r7 Register Arguments
1.7078 ++8-15 r8-r15 Caller Saved Registers
1.7079 ++16-22 r16-r22 Callee Saved Registers
1.7080 ++23 r23 sc Static Chain (Callee Saved)
1.7081 ++ ??? Does $sc want to be caller or callee
1.7082 ++ saved. If caller, 15, else 23.
1.7083 ++24 r24 Exception Temporary
1.7084 ++25 r25 Breakpoint Temporary
1.7085 ++26 r26 gp Global Pointer
1.7086 ++27 r27 sp Stack Pointer
1.7087 ++28 r28 fp Frame Pointer
1.7088 ++29 r29 ea Exception Return Address
1.7089 ++30 r30 ba Breakpoint Return Address
1.7090 ++31 r31 ra Return Address
1.7091 ++
1.7092 ++32 ctl0 status
1.7093 ++33 ctl1 estatus STATUS saved by exception ?
1.7094 ++34 ctl2 bstatus STATUS saved by break ?
1.7095 ++35 ctl3 ipri Interrupt Priority Mask ?
1.7096 ++36 ctl4 ecause Exception Cause ?
1.7097 ++
1.7098 ++37 pc Not an actual register
1.7099 ++
1.7100 ++38 rap Return address pointer, this does not
1.7101 ++ actually exist and will be eliminated
1.7102 ++
1.7103 ++39 fake_fp Fake Frame Pointer which will always be eliminated.
1.7104 ++40 fake_ap Fake Argument Pointer which will always be eliminated.
1.7105 ++
1.7106 ++41 First Pseudo Register
1.7107 ++
1.7108 ++
1.7109 ++The definitions for all the hard register numbers
1.7110 ++are located in nios2.md.
1.7111 ++*/
1.7112 ++
1.7113 ++#define FIRST_PSEUDO_REGISTER 41
1.7114 ++#define NUM_ARG_REGS (LAST_ARG_REGNO - FIRST_ARG_REGNO + 1)
1.7115 ++
1.7116 ++
1.7117 ++
1.7118 ++/* also see CONDITIONAL_REGISTER_USAGE */
1.7119 ++#define FIXED_REGISTERS \
1.7120 ++ { \
1.7121 ++/* +0 1 2 3 4 5 6 7 8 9 */ \
1.7122 ++/* 0 */ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, \
1.7123 ++/* 10 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
1.7124 ++/* 20 */ 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, \
1.7125 ++/* 30 */ 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, \
1.7126 ++/* 40 */ 1, \
1.7127 ++ }
1.7128 ++
1.7129 ++/* call used is the same as caller saved
1.7130 ++ + fixed regs + args + ret vals */
1.7131 ++#define CALL_USED_REGISTERS \
1.7132 ++ { \
1.7133 ++/* +0 1 2 3 4 5 6 7 8 9 */ \
1.7134 ++/* 0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1.7135 ++/* 10 */ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, \
1.7136 ++/* 20 */ 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, \
1.7137 ++/* 30 */ 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, \
1.7138 ++/* 40 */ 1, \
1.7139 ++ }
1.7140 ++
1.7141 ++#define HARD_REGNO_NREGS(REGNO, MODE) \
1.7142 ++ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \
1.7143 ++ / UNITS_PER_WORD)
1.7144 ++
1.7145 ++/* --------------------------- *
1.7146 ++ * How Values Fit in Registers
1.7147 ++ * --------------------------- */
1.7148 ++
1.7149 ++#define HARD_REGNO_MODE_OK(REGNO, MODE) 1
1.7150 ++
1.7151 ++#define MODES_TIEABLE_P(MODE1, MODE2) 1
1.7152 ++
1.7153 ++
1.7154 ++/*************************
1.7155 ++ * Register Classes
1.7156 ++ *************************/
1.7157 ++
1.7158 ++enum reg_class
1.7159 ++{
1.7160 ++ NO_REGS,
1.7161 ++ ALL_REGS,
1.7162 ++ LIM_REG_CLASSES
1.7163 ++};
1.7164 ++
1.7165 ++#define N_REG_CLASSES (int) LIM_REG_CLASSES
1.7166 ++
1.7167 ++#define REG_CLASS_NAMES \
1.7168 ++ {"NO_REGS", \
1.7169 ++ "ALL_REGS"}
1.7170 ++
1.7171 ++#define GENERAL_REGS ALL_REGS
1.7172 ++
1.7173 ++#define REG_CLASS_CONTENTS \
1.7174 ++/* NO_REGS */ {{ 0, 0}, \
1.7175 ++/* ALL_REGS */ {~0,~0}} \
1.7176 ++
1.7177 ++#define REGNO_REG_CLASS(REGNO) ALL_REGS
1.7178 ++
1.7179 ++#define BASE_REG_CLASS ALL_REGS
1.7180 ++#define INDEX_REG_CLASS ALL_REGS
1.7181 ++
1.7182 ++/* only one reg class, 'r', is handled automatically */
1.7183 ++#define REG_CLASS_FROM_LETTER(CHAR) NO_REGS
1.7184 ++
1.7185 ++#define REGNO_OK_FOR_BASE_P2(REGNO, STRICT) \
1.7186 ++ ((STRICT) \
1.7187 ++ ? (REGNO) < FIRST_PSEUDO_REGISTER \
1.7188 ++ : (REGNO) < FIRST_PSEUDO_REGISTER || (reg_renumber && reg_renumber[REGNO] < FIRST_PSEUDO_REGISTER))
1.7189 ++
1.7190 ++#define REGNO_OK_FOR_INDEX_P2(REGNO, STRICT) \
1.7191 ++ (REGNO_OK_FOR_BASE_P2 (REGNO, STRICT))
1.7192 ++
1.7193 ++#define REGNO_OK_FOR_BASE_P(REGNO) \
1.7194 ++ (REGNO_OK_FOR_BASE_P2 (REGNO, 1))
1.7195 ++
1.7196 ++#define REGNO_OK_FOR_INDEX_P(REGNO) \
1.7197 ++ (REGNO_OK_FOR_INDEX_P2 (REGNO, 1))
1.7198 ++
1.7199 ++#define REG_OK_FOR_BASE_P2(X, STRICT) \
1.7200 ++ (STRICT \
1.7201 ++ ? REGNO_OK_FOR_BASE_P2 (REGNO (X), 1) \
1.7202 ++ : REGNO_OK_FOR_BASE_P2 (REGNO (X), 1) || REGNO(X) >= FIRST_PSEUDO_REGISTER)
1.7203 ++
1.7204 ++#define REG_OK_FOR_INDEX_P2(X, STRICT) \
1.7205 ++ (STRICT \
1.7206 ++ ? REGNO_OK_FOR_INDEX_P2 (REGNO (X), 1) \
1.7207 ++ : REGNO_OK_FOR_INDEX_P2 (REGNO (X), 1) || REGNO(X) >= FIRST_PSEUDO_REGISTER)
1.7208 ++
1.7209 ++#define CLASS_MAX_NREGS(CLASS, MODE) \
1.7210 ++ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \
1.7211 ++ / UNITS_PER_WORD)
1.7212 ++
1.7213 ++
1.7214 ++#define SMALL_INT(X) ((unsigned HOST_WIDE_INT) ((X) + 0x8000) < 0x10000)
1.7215 ++#define SMALL_INT_UNSIGNED(X) ((unsigned HOST_WIDE_INT) (X) < 0x10000)
1.7216 ++#define UPPER16_INT(X) (((X) & 0xffff) == 0)
1.7217 ++#define SHIFT_INT(X) ((X) >= 0 && (X) <= 31)
1.7218 ++#define RDWRCTL_INT(X) ((X) >= 0 && (X) <= 31)
1.7219 ++#define CUSTOM_INSN_OPCODE(X) ((X) >= 0 && (X) <= 255)
1.7220 ++
1.7221 ++#define CONST_OK_FOR_LETTER_P(VALUE, C) \
1.7222 ++ ( \
1.7223 ++ (C) == 'I' ? SMALL_INT (VALUE) : \
1.7224 ++ (C) == 'J' ? SMALL_INT_UNSIGNED (VALUE) : \
1.7225 ++ (C) == 'K' ? UPPER16_INT (VALUE) : \
1.7226 ++ (C) == 'L' ? SHIFT_INT (VALUE) : \
1.7227 ++ (C) == 'M' ? (VALUE) == 0 : \
1.7228 ++ (C) == 'N' ? CUSTOM_INSN_OPCODE (VALUE) : \
1.7229 ++ (C) == 'O' ? RDWRCTL_INT (VALUE) : \
1.7230 ++ 0)
1.7231 ++
1.7232 ++#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) 0
1.7233 ++
1.7234 ++#define PREFERRED_RELOAD_CLASS(X, CLASS) \
1.7235 ++ ((CLASS) == NO_REGS ? GENERAL_REGS : (CLASS))
1.7236 ++
1.7237 ++/* 'S' matches immediates which are in small data
1.7238 ++ and therefore can be added to gp to create a
1.7239 ++ 32-bit value. */
1.7240 ++#define EXTRA_CONSTRAINT(VALUE, C) \
1.7241 ++ ((C) == 'S' \
1.7242 ++ && (GET_CODE (VALUE) == SYMBOL_REF) \
1.7243 ++ && SYMBOL_REF_IN_NIOS2_SMALL_DATA_P (VALUE))
1.7244 ++
1.7245 ++
1.7246 ++
1.7247 ++
1.7248 ++/* Say that the epilogue uses the return address register. Note that
1.7249 ++ in the case of sibcalls, the values "used by the epilogue" are
1.7250 ++ considered live at the start of the called function. */
1.7251 ++#define EPILOGUE_USES(REGNO) ((REGNO) == RA_REGNO)
1.7252 ++
1.7253 ++
1.7254 ++#define DEFAULT_MAIN_RETURN c_expand_return (integer_zero_node)
1.7255 ++
1.7256 ++/**********************************
1.7257 ++ * Trampolines for Nested Functions
1.7258 ++ ***********************************/
1.7259 ++
1.7260 ++#define TRAMPOLINE_TEMPLATE(FILE) \
1.7261 ++ error ("trampolines not yet implemented")
1.7262 ++#define TRAMPOLINE_SIZE 20
1.7263 ++#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
1.7264 ++ error ("trampolines not yet implemented")
1.7265 ++
1.7266 ++/***************************
1.7267 ++ * Stack Layout and Calling Conventions
1.7268 ++ ***************************/
1.7269 ++
1.7270 ++/* ------------------ *
1.7271 ++ * Basic Stack Layout
1.7272 ++ * ------------------ */
1.7273 ++
1.7274 ++/* The downward variants are used by the compiler,
1.7275 ++ the upward ones serve as documentation */
1.7276 ++#define STACK_GROWS_DOWNWARD
1.7277 ++#define FRAME_GROWS_UPWARD
1.7278 ++#define ARGS_GROW_UPWARD
1.7279 ++
1.7280 ++#define STARTING_FRAME_OFFSET current_function_outgoing_args_size
1.7281 ++#define FIRST_PARM_OFFSET(FUNDECL) 0
1.7282 ++
1.7283 ++/* Before the prologue, RA lives in r31. */
1.7284 ++#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (VOIDmode, RA_REGNO)
1.7285 ++
1.7286 ++/* -------------------------------------- *
1.7287 ++ * Registers That Address the Stack Frame
1.7288 ++ * -------------------------------------- */
1.7289 ++
1.7290 ++#define STACK_POINTER_REGNUM SP_REGNO
1.7291 ++#define STATIC_CHAIN_REGNUM SC_REGNO
1.7292 ++#define PC_REGNUM PC_REGNO
1.7293 ++#define DWARF_FRAME_RETURN_COLUMN RA_REGNO
1.7294 ++
1.7295 ++/* Base register for access to local variables of the function. We
1.7296 ++ pretend that the frame pointer is a non-existent hard register, and
1.7297 ++ then eliminate it to HARD_FRAME_POINTER_REGNUM. */
1.7298 ++#define FRAME_POINTER_REGNUM FAKE_FP_REGNO
1.7299 ++
1.7300 ++#define HARD_FRAME_POINTER_REGNUM FP_REGNO
1.7301 ++#define RETURN_ADDRESS_POINTER_REGNUM RAP_REGNO
1.7302 ++/* the argumnet pointer needs to always be eliminated
1.7303 ++ so it is set to a fake hard register. */
1.7304 ++#define ARG_POINTER_REGNUM FAKE_AP_REGNO
1.7305 ++
1.7306 ++/* ----------------------------------------- *
1.7307 ++ * Eliminating Frame Pointer and Arg Pointer
1.7308 ++ * ----------------------------------------- */
1.7309 ++
1.7310 ++#define FRAME_POINTER_REQUIRED 0
1.7311 ++
1.7312 ++#define ELIMINABLE_REGS \
1.7313 ++{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
1.7314 ++ { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
1.7315 ++ { RETURN_ADDRESS_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
1.7316 ++ { RETURN_ADDRESS_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
1.7317 ++ { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
1.7318 ++ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
1.7319 ++
1.7320 ++#define CAN_ELIMINATE(FROM, TO) 1
1.7321 ++
1.7322 ++#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
1.7323 ++ (OFFSET) = nios2_initial_elimination_offset ((FROM), (TO))
1.7324 ++
1.7325 ++#define MUST_SAVE_REGISTER(regno) \
1.7326 ++ ((regs_ever_live[regno] && !call_used_regs[regno]) \
1.7327 ++ || (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed) \
1.7328 ++ || (regno == RA_REGNO && regs_ever_live[RA_REGNO]))
1.7329 ++
1.7330 ++/* Treat LOC as a byte offset from the stack pointer and round it up
1.7331 ++ to the next fully-aligned offset. */
1.7332 ++#define STACK_ALIGN(LOC) \
1.7333 ++ (((LOC) + ((PREFERRED_STACK_BOUNDARY / 8) - 1)) & ~((PREFERRED_STACK_BOUNDARY / 8) - 1))
1.7334 ++
1.7335 ++
1.7336 ++/* ------------------------------ *
1.7337 ++ * Passing Arguments in Registers
1.7338 ++ * ------------------------------ */
1.7339 ++
1.7340 ++/* see nios2.c */
1.7341 ++#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
1.7342 ++ (function_arg (&CUM, MODE, TYPE, NAMED))
1.7343 ++
1.7344 ++#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
1.7345 ++ (function_arg_partial_nregs (&CUM, MODE, TYPE, NAMED))
1.7346 ++
1.7347 ++#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) 0
1.7348 ++
1.7349 ++#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) 0
1.7350 ++
1.7351 ++typedef struct nios2_args
1.7352 ++{
1.7353 ++ int regs_used;
1.7354 ++} CUMULATIVE_ARGS;
1.7355 ++
1.7356 ++/* This is to initialize the above unused CUM data type */
1.7357 ++#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \
1.7358 ++ (init_cumulative_args (&CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS))
1.7359 ++
1.7360 ++#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
1.7361 ++ (function_arg_advance (&CUM, MODE, TYPE, NAMED))
1.7362 ++
1.7363 ++#define FUNCTION_ARG_REGNO_P(REGNO) \
1.7364 ++ ((REGNO) >= FIRST_ARG_REGNO && (REGNO) <= LAST_ARG_REGNO)
1.7365 ++
1.7366 ++#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \
1.7367 ++ { \
1.7368 ++ int pret_size = nios2_setup_incoming_varargs (&(CUM), (MODE), \
1.7369 ++ (TYPE), (NO_RTL)); \
1.7370 ++ if (pret_size) \
1.7371 ++ (PRETEND_SIZE) = pret_size; \
1.7372 ++ }
1.7373 ++
1.7374 ++/* ----------------------------- *
1.7375 ++ * Generating Code for Profiling
1.7376 ++ * ----------------------------- */
1.7377 ++
1.7378 ++#define PROFILE_BEFORE_PROLOGUE
1.7379 ++
1.7380 ++#define FUNCTION_PROFILER(FILE, LABELNO) \
1.7381 ++ function_profiler ((FILE), (LABELNO))
1.7382 ++
1.7383 ++/* --------------------------------------- *
1.7384 ++ * Passing Function Arguments on the Stack
1.7385 ++ * --------------------------------------- */
1.7386 ++
1.7387 ++#define PROMOTE_PROTOTYPES 1
1.7388 ++
1.7389 ++#define PUSH_ARGS 0
1.7390 ++#define ACCUMULATE_OUTGOING_ARGS 1
1.7391 ++
1.7392 ++#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACKSIZE) 0
1.7393 ++
1.7394 ++/* --------------------------------------- *
1.7395 ++ * How Scalar Function Values Are Returned
1.7396 ++ * --------------------------------------- */
1.7397 ++
1.7398 ++#define FUNCTION_VALUE(VALTYPE, FUNC) \
1.7399 ++ gen_rtx(REG, TYPE_MODE(VALTYPE), FIRST_RETVAL_REGNO)
1.7400 ++
1.7401 ++#define LIBCALL_VALUE(MODE) \
1.7402 ++ gen_rtx(REG, MODE, FIRST_RETVAL_REGNO)
1.7403 ++
1.7404 ++#define FUNCTION_VALUE_REGNO_P(REGNO) ((REGNO) == FIRST_RETVAL_REGNO)
1.7405 ++
1.7406 ++/* ----------------------------- *
1.7407 ++ * How Large Values Are Returned
1.7408 ++ * ----------------------------- */
1.7409 ++
1.7410 ++
1.7411 ++#define RETURN_IN_MEMORY(TYPE) \
1.7412 ++ nios2_return_in_memory (TYPE)
1.7413 ++
1.7414 ++
1.7415 ++#define STRUCT_VALUE 0
1.7416 ++
1.7417 ++#define DEFAULT_PCC_STRUCT_RETURN 0
1.7418 ++
1.7419 ++/*******************
1.7420 ++ * Addressing Modes
1.7421 ++ *******************/
1.7422 ++
1.7423 ++
1.7424 ++#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)
1.7425 ++
1.7426 ++#define CONSTANT_ADDRESS_P(X) (CONSTANT_P (X))
1.7427 ++
1.7428 ++#define MAX_REGS_PER_ADDRESS 1
1.7429 ++
1.7430 ++/* Go to ADDR if X is a valid address. */
1.7431 ++#ifndef REG_OK_STRICT
1.7432 ++#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
1.7433 ++ { \
1.7434 ++ if (nios2_legitimate_address ((X), (MODE), 0)) \
1.7435 ++ goto ADDR; \
1.7436 ++ }
1.7437 ++#else
1.7438 ++#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
1.7439 ++ { \
1.7440 ++ if (nios2_legitimate_address ((X), (MODE), 1)) \
1.7441 ++ goto ADDR; \
1.7442 ++ }
1.7443 ++#endif
1.7444 ++
1.7445 ++#ifndef REG_OK_STRICT
1.7446 ++#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P2 (REGNO (X), 0)
1.7447 ++#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P2 (REGNO (X), 0)
1.7448 ++#else
1.7449 ++#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P2 (REGNO (X), 1)
1.7450 ++#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P2 (REGNO (X), 1)
1.7451 ++#endif
1.7452 ++
1.7453 ++#define LEGITIMATE_CONSTANT_P(X) 1
1.7454 ++
1.7455 ++/* Nios II has no mode dependent addresses. */
1.7456 ++#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)
1.7457 ++
1.7458 ++/* Set if this has a weak declaration */
1.7459 ++#define SYMBOL_FLAG_WEAK_DECL (1 << SYMBOL_FLAG_MACH_DEP_SHIFT)
1.7460 ++#define SYMBOL_REF_WEAK_DECL_P(RTX) \
1.7461 ++ ((SYMBOL_REF_FLAGS (RTX) & SYMBOL_FLAG_WEAK_DECL) != 0)
1.7462 ++
1.7463 ++
1.7464 ++/* true if a symbol is both small and not weak. In this case, gp
1.7465 ++ relative access can be used */
1.7466 ++#define SYMBOL_REF_IN_NIOS2_SMALL_DATA_P(RTX) \
1.7467 ++ (SYMBOL_REF_SMALL_P(RTX) && !SYMBOL_REF_WEAK_DECL_P(RTX))
1.7468 ++
1.7469 ++/*****************
1.7470 ++ * Describing Relative Costs of Operations
1.7471 ++ *****************/
1.7472 ++
1.7473 ++#define SLOW_BYTE_ACCESS 1
1.7474 ++
1.7475 ++/* It is as good to call a constant function address as to call an address
1.7476 ++ kept in a register.
1.7477 ++ ??? Not true anymore really. Now that call cannot address full range
1.7478 ++ of memory callr may need to be used */
1.7479 ++
1.7480 ++#define NO_FUNCTION_CSE
1.7481 ++#define NO_RECURSIVE_FUNCTION_CSE
1.7482 ++
1.7483 ++
1.7484 ++
1.7485 ++/*****************************************
1.7486 ++ * Defining the Output Assembler Language
1.7487 ++ *****************************************/
1.7488 ++
1.7489 ++/* ------------------------------------------ *
1.7490 ++ * The Overall Framework of an Assembler File
1.7491 ++ * ------------------------------------------ */
1.7492 ++
1.7493 ++#define ASM_APP_ON "#APP\n"
1.7494 ++#define ASM_APP_OFF "#NO_APP\n"
1.7495 ++
1.7496 ++#define ASM_COMMENT_START "# "
1.7497 ++
1.7498 ++/* ------------------------------- *
1.7499 ++ * Output and Generation of Labels
1.7500 ++ * ------------------------------- */
1.7501 ++
1.7502 ++#define GLOBAL_ASM_OP "\t.global\t"
1.7503 ++
1.7504 ++
1.7505 ++/* -------------- *
1.7506 ++ * Output of Data
1.7507 ++ * -------------- */
1.7508 ++
1.7509 ++#define DWARF2_UNWIND_INFO 0
1.7510 ++
1.7511 ++
1.7512 ++/* -------------------------------- *
1.7513 ++ * Assembler Commands for Alignment
1.7514 ++ * -------------------------------- */
1.7515 ++
1.7516 ++#define ASM_OUTPUT_ALIGN(FILE, LOG) \
1.7517 ++ do { \
1.7518 ++ fprintf ((FILE), "%s%d\n", ALIGN_ASM_OP, (LOG)); \
1.7519 ++ } while (0)
1.7520 ++
1.7521 ++
1.7522 ++/* -------------------------------- *
1.7523 ++ * Output of Assembler Instructions
1.7524 ++ * -------------------------------- */
1.7525 ++
1.7526 ++#define REGISTER_NAMES \
1.7527 ++{ \
1.7528 ++ "zero", \
1.7529 ++ "at", \
1.7530 ++ "r2", \
1.7531 ++ "r3", \
1.7532 ++ "r4", \
1.7533 ++ "r5", \
1.7534 ++ "r6", \
1.7535 ++ "r7", \
1.7536 ++ "r8", \
1.7537 ++ "r9", \
1.7538 ++ "r10", \
1.7539 ++ "r11", \
1.7540 ++ "r12", \
1.7541 ++ "r13", \
1.7542 ++ "r14", \
1.7543 ++ "r15", \
1.7544 ++ "r16", \
1.7545 ++ "r17", \
1.7546 ++ "r18", \
1.7547 ++ "r19", \
1.7548 ++ "r20", \
1.7549 ++ "r21", \
1.7550 ++ "r22", \
1.7551 ++ "r23", \
1.7552 ++ "r24", \
1.7553 ++ "r25", \
1.7554 ++ "gp", \
1.7555 ++ "sp", \
1.7556 ++ "fp", \
1.7557 ++ "ta", \
1.7558 ++ "ba", \
1.7559 ++ "ra", \
1.7560 ++ "status", \
1.7561 ++ "estatus", \
1.7562 ++ "bstatus", \
1.7563 ++ "ipri", \
1.7564 ++ "ecause", \
1.7565 ++ "pc", \
1.7566 ++ "rap", \
1.7567 ++ "fake_fp", \
1.7568 ++ "fake_ap", \
1.7569 ++}
1.7570 ++
1.7571 ++#define ASM_OUTPUT_OPCODE(STREAM, PTR)\
1.7572 ++ (PTR) = asm_output_opcode (STREAM, PTR)
1.7573 ++
1.7574 ++#define PRINT_OPERAND(STREAM, X, CODE) \
1.7575 ++ nios2_print_operand (STREAM, X, CODE)
1.7576 ++
1.7577 ++#define PRINT_OPERAND_ADDRESS(STREAM, X) \
1.7578 ++ nios2_print_operand_address (STREAM, X)
1.7579 ++
1.7580 ++#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
1.7581 ++do { fputs (integer_asm_op (POINTER_SIZE / BITS_PER_UNIT, TRUE), FILE); \
1.7582 ++ fprintf (FILE, ".L%u\n", (unsigned) (VALUE)); \
1.7583 ++ } while (0)
1.7584 ++
1.7585 ++
1.7586 ++/* ------------ *
1.7587 ++ * Label Output
1.7588 ++ * ------------ */
1.7589 ++
1.7590 ++
1.7591 ++/* ---------------------------------------------------- *
1.7592 ++ * Dividing the Output into Sections (Texts, Data, ...)
1.7593 ++ * ---------------------------------------------------- */
1.7594 ++
1.7595 ++/* Output before read-only data. */
1.7596 ++#define TEXT_SECTION_ASM_OP ("\t.section\t.text")
1.7597 ++
1.7598 ++/* Output before writable data. */
1.7599 ++#define DATA_SECTION_ASM_OP ("\t.section\t.data")
1.7600 ++
1.7601 ++
1.7602 ++/* Default the definition of "small data" to 8 bytes. */
1.7603 ++/* ??? How come I can't use HOST_WIDE_INT here? */
1.7604 ++extern unsigned long nios2_section_threshold;
1.7605 ++#define NIOS2_DEFAULT_GVALUE 8
1.7606 ++
1.7607 ++
1.7608 ++
1.7609 ++/* This says how to output assembler code to declare an
1.7610 ++ uninitialized external linkage data object. Under SVR4,
1.7611 ++ the linker seems to want the alignment of data objects
1.7612 ++ to depend on their types. We do exactly that here. */
1.7613 ++
1.7614 ++#undef COMMON_ASM_OP
1.7615 ++#define COMMON_ASM_OP "\t.comm\t"
1.7616 ++
1.7617 ++#undef ASM_OUTPUT_ALIGNED_COMMON
1.7618 ++#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
1.7619 ++do \
1.7620 ++{ \
1.7621 ++ if ((SIZE) <= nios2_section_threshold) \
1.7622 ++ { \
1.7623 ++ named_section (0, ".sbss", 0); \
1.7624 ++ (*targetm.asm_out.globalize_label) (FILE, NAME); \
1.7625 ++ ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \
1.7626 ++ if (!flag_inhibit_size_directive) \
1.7627 ++ ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE); \
1.7628 ++ ASM_OUTPUT_ALIGN ((FILE), exact_log2((ALIGN) / BITS_PER_UNIT)); \
1.7629 ++ ASM_OUTPUT_LABEL(FILE, NAME); \
1.7630 ++ ASM_OUTPUT_SKIP((FILE), (SIZE) ? (SIZE) : 1); \
1.7631 ++ } \
1.7632 ++ else \
1.7633 ++ { \
1.7634 ++ fprintf ((FILE), "%s", COMMON_ASM_OP); \
1.7635 ++ assemble_name ((FILE), (NAME)); \
1.7636 ++ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT); \
1.7637 ++ } \
1.7638 ++} \
1.7639 ++while (0)
1.7640 ++
1.7641 ++
1.7642 ++/* This says how to output assembler code to declare an
1.7643 ++ uninitialized internal linkage data object. Under SVR4,
1.7644 ++ the linker seems to want the alignment of data objects
1.7645 ++ to depend on their types. We do exactly that here. */
1.7646 ++
1.7647 ++#undef ASM_OUTPUT_ALIGNED_LOCAL
1.7648 ++#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
1.7649 ++do { \
1.7650 ++ if ((SIZE) <= nios2_section_threshold) \
1.7651 ++ named_section (0, ".sbss", 0); \
1.7652 ++ else \
1.7653 ++ named_section (0, ".bss", 0); \
1.7654 ++ ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \
1.7655 ++ if (!flag_inhibit_size_directive) \
1.7656 ++ ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE); \
1.7657 ++ ASM_OUTPUT_ALIGN ((FILE), exact_log2((ALIGN) / BITS_PER_UNIT)); \
1.7658 ++ ASM_OUTPUT_LABEL(FILE, NAME); \
1.7659 ++ ASM_OUTPUT_SKIP((FILE), (SIZE) ? (SIZE) : 1); \
1.7660 ++} while (0)
1.7661 ++
1.7662 ++
1.7663 ++
1.7664 ++/***************************
1.7665 ++ * Miscellaneous Parameters
1.7666 ++ ***************************/
1.7667 ++
1.7668 ++#define MOVE_MAX 4
1.7669 ++
1.7670 ++#define Pmode SImode
1.7671 ++#define FUNCTION_MODE QImode
1.7672 ++
1.7673 ++#define CASE_VECTOR_MODE Pmode
1.7674 ++
1.7675 ++#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
1.7676 ++
1.7677 ++#define LOAD_EXTEND_OP(MODE) (ZERO_EXTEND)
1.7678 ++
1.7679 ++#define WORD_REGISTER_OPERATIONS
1.7680 +--- gcc-3.4.3/gcc/config/nios2/nios2.md
1.7681 ++++ gcc-3.4.3-nios2/gcc/config/nios2/nios2.md
1.7682 +@@ -0,0 +1,2078 @@
1.7683 ++;; Machine Description for Altera NIOS 2G NIOS2 version.
1.7684 ++;; Copyright (C) 2003 Altera
1.7685 ++;; Contributed by Jonah Graham (jgraham@altera.com).
1.7686 ++;;
1.7687 ++;; This file is part of GNU CC.
1.7688 ++;;
1.7689 ++;; GNU CC is free software; you can redistribute it and/or modify
1.7690 ++;; it under the terms of the GNU General Public License as published by
1.7691 ++;; the Free Software Foundation; either version 2, or (at your option)
1.7692 ++;; any later version.
1.7693 ++;;
1.7694 ++;; GNU CC is distributed in the hope that it will be useful,
1.7695 ++;; but WITHOUT ANY WARRANTY; without even the implied warranty of
1.7696 ++;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.7697 ++;; GNU General Public License for more details.
1.7698 ++;;
1.7699 ++;; You should have received a copy of the GNU General Public License
1.7700 ++;; along with GNU CC; see the file COPYING. If not, write to
1.7701 ++;; the Free Software Foundation, 59 Temple Place - Suite 330,
1.7702 ++;; Boston, MA 02111-1307, USA. */
1.7703 ++
1.7704 ++
1.7705 ++
1.7706 ++;*****************************************************************************
1.7707 ++;*
1.7708 ++;* constants
1.7709 ++;*
1.7710 ++;*****************************************************************************
1.7711 ++(define_constants [
1.7712 ++ (GP_REGNO 26)
1.7713 ++ (SP_REGNO 27)
1.7714 ++ (FP_REGNO 28)
1.7715 ++ (RA_REGNO 31)
1.7716 ++ (RAP_REGNO 38)
1.7717 ++ (FIRST_RETVAL_REGNO 2)
1.7718 ++ (LAST_RETVAL_REGNO 3)
1.7719 ++ (FIRST_ARG_REGNO 4)
1.7720 ++ (LAST_ARG_REGNO 7)
1.7721 ++ (SC_REGNO 23)
1.7722 ++ (PC_REGNO 37)
1.7723 ++ (FAKE_FP_REGNO 39)
1.7724 ++ (FAKE_AP_REGNO 40)
1.7725 ++
1.7726 ++
1.7727 ++ (UNSPEC_BLOCKAGE 0)
1.7728 ++ (UNSPEC_LDBIO 1)
1.7729 ++ (UNSPEC_LDBUIO 2)
1.7730 ++ (UNSPEC_LDHIO 3)
1.7731 ++ (UNSPEC_LDHUIO 4)
1.7732 ++ (UNSPEC_LDWIO 5)
1.7733 ++ (UNSPEC_STBIO 6)
1.7734 ++ (UNSPEC_STHIO 7)
1.7735 ++ (UNSPEC_STWIO 8)
1.7736 ++ (UNSPEC_SYNC 9)
1.7737 ++ (UNSPEC_WRCTL 10)
1.7738 ++ (UNSPEC_RDCTL 11)
1.7739 ++
1.7740 ++])
1.7741 ++
1.7742 ++
1.7743 ++
1.7744 ++;*****************************************************************************
1.7745 ++;*
1.7746 ++;* instruction scheduler
1.7747 ++;*
1.7748 ++;*****************************************************************************
1.7749 ++
1.7750 ++; No schedule info is currently available, using an assumption that no
1.7751 ++; instruction can use the results of the previous instruction without
1.7752 ++; incuring a stall.
1.7753 ++
1.7754 ++; length of an instruction (in bytes)
1.7755 ++(define_attr "length" "" (const_int 4))
1.7756 ++(define_attr "type" "unknown,complex,control,alu,cond_alu,st,ld,shift,mul,div,custom" (const_string "complex"))
1.7757 ++
1.7758 ++(define_asm_attributes
1.7759 ++ [(set_attr "length" "4")
1.7760 ++ (set_attr "type" "complex")])
1.7761 ++
1.7762 ++(define_automaton "nios2")
1.7763 ++(automata_option "v")
1.7764 ++;(automata_option "no-minimization")
1.7765 ++(automata_option "ndfa")
1.7766 ++
1.7767 ++; The nios2 pipeline is fairly straightforward for the fast model.
1.7768 ++; Every alu operation is pipelined so that an instruction can
1.7769 ++; be issued every cycle. However, there are still potential
1.7770 ++; stalls which this description tries to deal with.
1.7771 ++
1.7772 ++(define_cpu_unit "cpu" "nios2")
1.7773 ++
1.7774 ++(define_insn_reservation "complex" 1
1.7775 ++ (eq_attr "type" "complex")
1.7776 ++ "cpu")
1.7777 ++
1.7778 ++(define_insn_reservation "control" 1
1.7779 ++ (eq_attr "type" "control")
1.7780 ++ "cpu")
1.7781 ++
1.7782 ++(define_insn_reservation "alu" 1
1.7783 ++ (eq_attr "type" "alu")
1.7784 ++ "cpu")
1.7785 ++
1.7786 ++(define_insn_reservation "cond_alu" 1
1.7787 ++ (eq_attr "type" "cond_alu")
1.7788 ++ "cpu")
1.7789 ++
1.7790 ++(define_insn_reservation "st" 1
1.7791 ++ (eq_attr "type" "st")
1.7792 ++ "cpu")
1.7793 ++
1.7794 ++(define_insn_reservation "custom" 1
1.7795 ++ (eq_attr "type" "custom")
1.7796 ++ "cpu")
1.7797 ++
1.7798 ++; shifts, muls and lds have three cycle latency
1.7799 ++(define_insn_reservation "ld" 3
1.7800 ++ (eq_attr "type" "ld")
1.7801 ++ "cpu")
1.7802 ++
1.7803 ++(define_insn_reservation "shift" 3
1.7804 ++ (eq_attr "type" "shift")
1.7805 ++ "cpu")
1.7806 ++
1.7807 ++(define_insn_reservation "mul" 3
1.7808 ++ (eq_attr "type" "mul")
1.7809 ++ "cpu")
1.7810 ++
1.7811 ++(define_insn_reservation "div" 1
1.7812 ++ (eq_attr "type" "div")
1.7813 ++ "cpu")
1.7814 ++
1.7815 ++
1.7816 ++;*****************************************************************************
1.7817 ++;*
1.7818 ++;* MOV Instructions
1.7819 ++;*
1.7820 ++;*****************************************************************************
1.7821 ++
1.7822 ++(define_expand "movqi"
1.7823 ++ [(set (match_operand:QI 0 "nonimmediate_operand" "")
1.7824 ++ (match_operand:QI 1 "general_operand" ""))]
1.7825 ++ ""
1.7826 ++{
1.7827 ++ if (nios2_emit_move_sequence (operands, QImode))
1.7828 ++ DONE;
1.7829 ++})
1.7830 ++
1.7831 ++(define_insn "movqi_internal"
1.7832 ++ [(set (match_operand:QI 0 "nonimmediate_operand" "=m, r,r, r")
1.7833 ++ (match_operand:QI 1 "general_operand" "rM,m,rM,I"))]
1.7834 ++ "(register_operand (operands[0], QImode)
1.7835 ++ || register_operand (operands[1], QImode)
1.7836 ++ || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
1.7837 ++ "@
1.7838 ++ stb%o0\\t%z1, %0
1.7839 ++ ldbu%o1\\t%0, %1
1.7840 ++ mov\\t%0, %z1
1.7841 ++ movi\\t%0, %1"
1.7842 ++ [(set_attr "type" "st,ld,alu,alu")])
1.7843 ++
1.7844 ++(define_insn "ldbio"
1.7845 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.7846 ++ (unspec_volatile:SI [(const_int 0)] UNSPEC_LDBIO))
1.7847 ++ (use (match_operand:SI 1 "memory_operand" "m"))]
1.7848 ++ ""
1.7849 ++ "ldbio\\t%0, %1"
1.7850 ++ [(set_attr "type" "ld")])
1.7851 ++
1.7852 ++(define_insn "ldbuio"
1.7853 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.7854 ++ (unspec_volatile:SI [(const_int 0)] UNSPEC_LDBUIO))
1.7855 ++ (use (match_operand:SI 1 "memory_operand" "m"))]
1.7856 ++ ""
1.7857 ++ "ldbuio\\t%0, %1"
1.7858 ++ [(set_attr "type" "ld")])
1.7859 ++
1.7860 ++(define_insn "stbio"
1.7861 ++ [(set (match_operand:SI 0 "memory_operand" "=m")
1.7862 ++ (match_operand:SI 1 "register_operand" "r"))
1.7863 ++ (unspec_volatile:SI [(const_int 0)] UNSPEC_STBIO)]
1.7864 ++ ""
1.7865 ++ "stbio\\t%z1, %0"
1.7866 ++ [(set_attr "type" "st")])
1.7867 ++
1.7868 ++
1.7869 ++(define_expand "movhi"
1.7870 ++ [(set (match_operand:HI 0 "nonimmediate_operand" "")
1.7871 ++ (match_operand:HI 1 "general_operand" ""))]
1.7872 ++ ""
1.7873 ++{
1.7874 ++ if (nios2_emit_move_sequence (operands, HImode))
1.7875 ++ DONE;
1.7876 ++})
1.7877 ++
1.7878 ++(define_insn "movhi_internal"
1.7879 ++ [(set (match_operand:HI 0 "nonimmediate_operand" "=m, r,r, r,r")
1.7880 ++ (match_operand:HI 1 "general_operand" "rM,m,rM,I,J"))]
1.7881 ++ "(register_operand (operands[0], HImode)
1.7882 ++ || register_operand (operands[1], HImode)
1.7883 ++ || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
1.7884 ++ "@
1.7885 ++ sth%o0\\t%z1, %0
1.7886 ++ ldhu%o1\\t%0, %1
1.7887 ++ mov\\t%0, %z1
1.7888 ++ movi\\t%0, %1
1.7889 ++ movui\\t%0, %1"
1.7890 ++ [(set_attr "type" "st,ld,alu,alu,alu")])
1.7891 ++
1.7892 ++(define_insn "ldhio"
1.7893 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.7894 ++ (unspec_volatile:SI [(const_int 0)] UNSPEC_LDHIO))
1.7895 ++ (use (match_operand:SI 1 "memory_operand" "m"))]
1.7896 ++ ""
1.7897 ++ "ldhio\\t%0, %1"
1.7898 ++ [(set_attr "type" "ld")])
1.7899 ++
1.7900 ++(define_insn "ldhuio"
1.7901 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.7902 ++ (unspec_volatile:SI [(const_int 0)] UNSPEC_LDHUIO))
1.7903 ++ (use (match_operand:SI 1 "memory_operand" "m"))]
1.7904 ++ ""
1.7905 ++ "ldhuio\\t%0, %1"
1.7906 ++ [(set_attr "type" "ld")])
1.7907 ++
1.7908 ++(define_insn "sthio"
1.7909 ++ [(set (match_operand:SI 0 "memory_operand" "=m")
1.7910 ++ (match_operand:SI 1 "register_operand" "r"))
1.7911 ++ (unspec_volatile:SI [(const_int 0)] UNSPEC_STHIO)]
1.7912 ++ ""
1.7913 ++ "sthio\\t%z1, %0"
1.7914 ++ [(set_attr "type" "st")])
1.7915 ++
1.7916 ++(define_expand "movsi"
1.7917 ++ [(set (match_operand:SI 0 "nonimmediate_operand" "")
1.7918 ++ (match_operand:SI 1 "general_operand" ""))]
1.7919 ++ ""
1.7920 ++{
1.7921 ++ if (nios2_emit_move_sequence (operands, SImode))
1.7922 ++ DONE;
1.7923 ++})
1.7924 ++
1.7925 ++(define_insn "movsi_internal"
1.7926 ++ [(set (match_operand:SI 0 "nonimmediate_operand" "=m, r,r, r,r,r,r")
1.7927 ++ (match_operand:SI 1 "general_operand" "rM,m,rM,I,J,S,i"))]
1.7928 ++ "(register_operand (operands[0], SImode)
1.7929 ++ || register_operand (operands[1], SImode)
1.7930 ++ || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
1.7931 ++ "@
1.7932 ++ stw%o0\\t%z1, %0
1.7933 ++ ldw%o1\\t%0, %1
1.7934 ++ mov\\t%0, %z1
1.7935 ++ movi\\t%0, %1
1.7936 ++ movui\\t%0, %1
1.7937 ++ addi\\t%0, gp, %%gprel(%1)
1.7938 ++ movhi\\t%0, %H1\;addi\\t%0, %0, %L1"
1.7939 ++ [(set_attr "type" "st,ld,alu,alu,alu,alu,alu")])
1.7940 ++
1.7941 ++(define_insn "ldwio"
1.7942 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.7943 ++ (unspec_volatile:SI [(const_int 0)] UNSPEC_LDWIO))
1.7944 ++ (use (match_operand:SI 1 "memory_operand" "m"))]
1.7945 ++ ""
1.7946 ++ "ldwio\\t%0, %1"
1.7947 ++ [(set_attr "type" "ld")])
1.7948 ++
1.7949 ++(define_insn "stwio"
1.7950 ++ [(set (match_operand:SI 0 "memory_operand" "=m")
1.7951 ++ (match_operand:SI 1 "register_operand" "r"))
1.7952 ++ (unspec_volatile:SI [(const_int 0)] UNSPEC_STWIO)]
1.7953 ++ ""
1.7954 ++ "stwio\\t%z1, %0"
1.7955 ++ [(set_attr "type" "st")])
1.7956 ++
1.7957 ++
1.7958 ++
1.7959 ++;*****************************************************************************
1.7960 ++;*
1.7961 ++;* zero extension
1.7962 ++;*
1.7963 ++;*****************************************************************************
1.7964 ++
1.7965 ++
1.7966 ++(define_insn "zero_extendhisi2"
1.7967 ++ [(set (match_operand:SI 0 "register_operand" "=r,r")
1.7968 ++ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
1.7969 ++ ""
1.7970 ++ "@
1.7971 ++ andi\\t%0, %1, 0xffff
1.7972 ++ ldhu%o1\\t%0, %1"
1.7973 ++ [(set_attr "type" "alu,ld")])
1.7974 ++
1.7975 ++(define_insn "zero_extendqihi2"
1.7976 ++ [(set (match_operand:HI 0 "register_operand" "=r,r")
1.7977 ++ (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1.7978 ++ ""
1.7979 ++ "@
1.7980 ++ andi\\t%0, %1, 0xff
1.7981 ++ ldbu%o1\\t%0, %1"
1.7982 ++ [(set_attr "type" "alu,ld")])
1.7983 ++
1.7984 ++(define_insn "zero_extendqisi2"
1.7985 ++ [(set (match_operand:SI 0 "register_operand" "=r,r")
1.7986 ++ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1.7987 ++ ""
1.7988 ++ "@
1.7989 ++ andi\\t%0, %1, 0xff
1.7990 ++ ldbu%o1\\t%0, %1"
1.7991 ++ [(set_attr "type" "alu,ld")])
1.7992 ++
1.7993 ++
1.7994 ++
1.7995 ++;*****************************************************************************
1.7996 ++;*
1.7997 ++;* sign extension
1.7998 ++;*
1.7999 ++;*****************************************************************************
1.8000 ++
1.8001 ++(define_expand "extendhisi2"
1.8002 ++ [(set (match_operand:SI 0 "register_operand" "")
1.8003 ++ (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
1.8004 ++ ""
1.8005 ++{
1.8006 ++ if (optimize && GET_CODE (operands[1]) == MEM)
1.8007 ++ operands[1] = force_not_mem (operands[1]);
1.8008 ++
1.8009 ++ if (GET_CODE (operands[1]) != MEM)
1.8010 ++ {
1.8011 ++ rtx op1 = gen_lowpart (SImode, operands[1]);
1.8012 ++ rtx temp = gen_reg_rtx (SImode);
1.8013 ++ rtx shift = GEN_INT (16);
1.8014 ++
1.8015 ++ emit_insn (gen_ashlsi3 (temp, op1, shift));
1.8016 ++ emit_insn (gen_ashrsi3 (operands[0], temp, shift));
1.8017 ++ DONE;
1.8018 ++ }
1.8019 ++})
1.8020 ++
1.8021 ++(define_insn "extendhisi2_internal"
1.8022 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8023 ++ (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1.8024 ++ ""
1.8025 ++ "ldh%o1\\t%0, %1"
1.8026 ++ [(set_attr "type" "ld")])
1.8027 ++
1.8028 ++(define_expand "extendqihi2"
1.8029 ++ [(set (match_operand:HI 0 "register_operand" "")
1.8030 ++ (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
1.8031 ++ ""
1.8032 ++{
1.8033 ++ if (optimize && GET_CODE (operands[1]) == MEM)
1.8034 ++ operands[1] = force_not_mem (operands[1]);
1.8035 ++
1.8036 ++ if (GET_CODE (operands[1]) != MEM)
1.8037 ++ {
1.8038 ++ rtx op0 = gen_lowpart (SImode, operands[0]);
1.8039 ++ rtx op1 = gen_lowpart (SImode, operands[1]);
1.8040 ++ rtx temp = gen_reg_rtx (SImode);
1.8041 ++ rtx shift = GEN_INT (24);
1.8042 ++
1.8043 ++ emit_insn (gen_ashlsi3 (temp, op1, shift));
1.8044 ++ emit_insn (gen_ashrsi3 (op0, temp, shift));
1.8045 ++ DONE;
1.8046 ++ }
1.8047 ++})
1.8048 ++
1.8049 ++(define_insn "extendqihi2_internal"
1.8050 ++ [(set (match_operand:HI 0 "register_operand" "=r")
1.8051 ++ (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
1.8052 ++ ""
1.8053 ++ "ldb%o1\\t%0, %1"
1.8054 ++ [(set_attr "type" "ld")])
1.8055 ++
1.8056 ++
1.8057 ++(define_expand "extendqisi2"
1.8058 ++ [(set (match_operand:SI 0 "register_operand" "")
1.8059 ++ (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1.8060 ++ ""
1.8061 ++{
1.8062 ++ if (optimize && GET_CODE (operands[1]) == MEM)
1.8063 ++ operands[1] = force_not_mem (operands[1]);
1.8064 ++
1.8065 ++ if (GET_CODE (operands[1]) != MEM)
1.8066 ++ {
1.8067 ++ rtx op1 = gen_lowpart (SImode, operands[1]);
1.8068 ++ rtx temp = gen_reg_rtx (SImode);
1.8069 ++ rtx shift = GEN_INT (24);
1.8070 ++
1.8071 ++ emit_insn (gen_ashlsi3 (temp, op1, shift));
1.8072 ++ emit_insn (gen_ashrsi3 (operands[0], temp, shift));
1.8073 ++ DONE;
1.8074 ++ }
1.8075 ++})
1.8076 ++
1.8077 ++(define_insn "extendqisi2_insn"
1.8078 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8079 ++ (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
1.8080 ++ ""
1.8081 ++ "ldb%o1\\t%0, %1"
1.8082 ++ [(set_attr "type" "ld")])
1.8083 ++
1.8084 ++
1.8085 ++
1.8086 ++;*****************************************************************************
1.8087 ++;*
1.8088 ++;* Arithmetic Operations
1.8089 ++;*
1.8090 ++;*****************************************************************************
1.8091 ++
1.8092 ++(define_insn "addsi3"
1.8093 ++ [(set (match_operand:SI 0 "register_operand" "=r,r")
1.8094 ++ (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
1.8095 ++ (match_operand:SI 2 "arith_operand" "r,I")))]
1.8096 ++ ""
1.8097 ++ "add%i2\\t%0, %1, %z2"
1.8098 ++ [(set_attr "type" "alu")])
1.8099 ++
1.8100 ++(define_insn "subsi3"
1.8101 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8102 ++ (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
1.8103 ++ (match_operand:SI 2 "register_operand" "r")))]
1.8104 ++ ""
1.8105 ++ "sub\\t%0, %z1, %2"
1.8106 ++ [(set_attr "type" "alu")])
1.8107 ++
1.8108 ++(define_insn "mulsi3"
1.8109 ++ [(set (match_operand:SI 0 "register_operand" "=r,r")
1.8110 ++ (mult:SI (match_operand:SI 1 "register_operand" "r,r")
1.8111 ++ (match_operand:SI 2 "arith_operand" "r,I")))]
1.8112 ++ "TARGET_HAS_MUL"
1.8113 ++ "mul%i2\\t%0, %1, %z2"
1.8114 ++ [(set_attr "type" "mul")])
1.8115 ++
1.8116 ++(define_expand "divsi3"
1.8117 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8118 ++ (div:SI (match_operand:SI 1 "register_operand" "r")
1.8119 ++ (match_operand:SI 2 "register_operand" "r")))]
1.8120 ++ ""
1.8121 ++{
1.8122 ++ if (!TARGET_HAS_DIV)
1.8123 ++ {
1.8124 ++ if (!TARGET_FAST_SW_DIV)
1.8125 ++ FAIL;
1.8126 ++ else
1.8127 ++ {
1.8128 ++ if (nios2_emit_expensive_div (operands, SImode))
1.8129 ++ DONE;
1.8130 ++ }
1.8131 ++ }
1.8132 ++})
1.8133 ++
1.8134 ++(define_insn "divsi3_insn"
1.8135 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8136 ++ (div:SI (match_operand:SI 1 "register_operand" "r")
1.8137 ++ (match_operand:SI 2 "register_operand" "r")))]
1.8138 ++ "TARGET_HAS_DIV"
1.8139 ++ "div\\t%0, %1, %2"
1.8140 ++ [(set_attr "type" "div")])
1.8141 ++
1.8142 ++(define_insn "udivsi3"
1.8143 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8144 ++ (udiv:SI (match_operand:SI 1 "register_operand" "r")
1.8145 ++ (match_operand:SI 2 "register_operand" "r")))]
1.8146 ++ "TARGET_HAS_DIV"
1.8147 ++ "divu\\t%0, %1, %2"
1.8148 ++ [(set_attr "type" "div")])
1.8149 ++
1.8150 ++(define_insn "smulsi3_highpart"
1.8151 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8152 ++ (truncate:SI
1.8153 ++ (lshiftrt:DI
1.8154 ++ (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
1.8155 ++ (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
1.8156 ++ (const_int 32))))]
1.8157 ++ "TARGET_HAS_MULX"
1.8158 ++ "mulxss\\t%0, %1, %2"
1.8159 ++ [(set_attr "type" "mul")])
1.8160 ++
1.8161 ++(define_insn "umulsi3_highpart"
1.8162 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8163 ++ (truncate:SI
1.8164 ++ (lshiftrt:DI
1.8165 ++ (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1.8166 ++ (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
1.8167 ++ (const_int 32))))]
1.8168 ++ "TARGET_HAS_MULX"
1.8169 ++ "mulxuu\\t%0, %1, %2"
1.8170 ++ [(set_attr "type" "mul")])
1.8171 ++
1.8172 ++
1.8173 ++(define_expand "mulsidi3"
1.8174 ++ [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 0)
1.8175 ++ (mult:SI (match_operand:SI 1 "register_operand" "")
1.8176 ++ (match_operand:SI 2 "register_operand" "")))
1.8177 ++ (set (subreg:SI (match_dup 0) 4)
1.8178 ++ (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
1.8179 ++ (sign_extend:DI (match_dup 2)))
1.8180 ++ (const_int 32))))]
1.8181 ++ "TARGET_HAS_MULX"
1.8182 ++ "")
1.8183 ++
1.8184 ++(define_expand "umulsidi3"
1.8185 ++ [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 0)
1.8186 ++ (mult:SI (match_operand:SI 1 "register_operand" "")
1.8187 ++ (match_operand:SI 2 "register_operand" "")))
1.8188 ++ (set (subreg:SI (match_dup 0) 4)
1.8189 ++ (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
1.8190 ++ (zero_extend:DI (match_dup 2)))
1.8191 ++ (const_int 32))))]
1.8192 ++ "TARGET_HAS_MULX"
1.8193 ++ "")
1.8194 ++
1.8195 ++
1.8196 ++
1.8197 ++;*****************************************************************************
1.8198 ++;*
1.8199 ++;* Negate and ones complement
1.8200 ++;*
1.8201 ++;*****************************************************************************
1.8202 ++
1.8203 ++(define_insn "negsi2"
1.8204 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8205 ++ (neg:SI (match_operand:SI 1 "register_operand" "r")))]
1.8206 ++ ""
1.8207 ++{
1.8208 ++ operands[2] = const0_rtx;
1.8209 ++ return "sub\\t%0, %z2, %1";
1.8210 ++}
1.8211 ++ [(set_attr "type" "alu")])
1.8212 ++
1.8213 ++(define_insn "one_cmplsi2"
1.8214 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8215 ++ (not:SI (match_operand:SI 1 "register_operand" "r")))]
1.8216 ++ ""
1.8217 ++{
1.8218 ++ operands[2] = const0_rtx;
1.8219 ++ return "nor\\t%0, %z2, %1";
1.8220 ++}
1.8221 ++ [(set_attr "type" "alu")])
1.8222 ++
1.8223 ++
1.8224 ++
1.8225 ++; Logical Operantions
1.8226 ++
1.8227 ++(define_insn "andsi3"
1.8228 ++ [(set (match_operand:SI 0 "register_operand" "=r, r,r")
1.8229 ++ (and:SI (match_operand:SI 1 "register_operand" "%r, r,r")
1.8230 ++ (match_operand:SI 2 "logical_operand" "rM,J,K")))]
1.8231 ++ ""
1.8232 ++ "@
1.8233 ++ and\\t%0, %1, %z2
1.8234 ++ and%i2\\t%0, %1, %2
1.8235 ++ andh%i2\\t%0, %1, %U2"
1.8236 ++ [(set_attr "type" "alu")])
1.8237 ++
1.8238 ++(define_insn "iorsi3"
1.8239 ++ [(set (match_operand:SI 0 "register_operand" "=r, r,r")
1.8240 ++ (ior:SI (match_operand:SI 1 "register_operand" "%r, r,r")
1.8241 ++ (match_operand:SI 2 "logical_operand" "rM,J,K")))]
1.8242 ++ ""
1.8243 ++ "@
1.8244 ++ or\\t%0, %1, %z2
1.8245 ++ or%i2\\t%0, %1, %2
1.8246 ++ orh%i2\\t%0, %1, %U2"
1.8247 ++ [(set_attr "type" "alu")])
1.8248 ++
1.8249 ++(define_insn "*norsi3"
1.8250 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8251 ++ (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r"))
1.8252 ++ (not:SI (match_operand:SI 2 "reg_or_0_operand" "rM"))))]
1.8253 ++ ""
1.8254 ++ "nor\\t%0, %1, %z2"
1.8255 ++ [(set_attr "type" "alu")])
1.8256 ++
1.8257 ++(define_insn "xorsi3"
1.8258 ++ [(set (match_operand:SI 0 "register_operand" "=r, r,r")
1.8259 ++ (xor:SI (match_operand:SI 1 "register_operand" "%r, r,r")
1.8260 ++ (match_operand:SI 2 "logical_operand" "rM,J,K")))]
1.8261 ++ ""
1.8262 ++ "@
1.8263 ++ xor\\t%0, %1, %z2
1.8264 ++ xor%i2\\t%0, %1, %2
1.8265 ++ xorh%i2\\t%0, %1, %U2"
1.8266 ++ [(set_attr "type" "alu")])
1.8267 ++
1.8268 ++
1.8269 ++
1.8270 ++;*****************************************************************************
1.8271 ++;*
1.8272 ++;* Shifts
1.8273 ++;*
1.8274 ++;*****************************************************************************
1.8275 ++
1.8276 ++(define_insn "ashlsi3"
1.8277 ++ [(set (match_operand:SI 0 "register_operand" "=r,r")
1.8278 ++ (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
1.8279 ++ (match_operand:SI 2 "shift_operand" "r,L")))]
1.8280 ++ ""
1.8281 ++ "sll%i2\\t%0, %1, %z2"
1.8282 ++ [(set_attr "type" "shift")])
1.8283 ++
1.8284 ++(define_insn "ashrsi3"
1.8285 ++ [(set (match_operand:SI 0 "register_operand" "=r,r")
1.8286 ++ (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1.8287 ++ (match_operand:SI 2 "shift_operand" "r,L")))]
1.8288 ++ ""
1.8289 ++ "sra%i2\\t%0, %1, %z2"
1.8290 ++ [(set_attr "type" "shift")])
1.8291 ++
1.8292 ++(define_insn "lshrsi3"
1.8293 ++ [(set (match_operand:SI 0 "register_operand" "=r,r")
1.8294 ++ (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1.8295 ++ (match_operand:SI 2 "shift_operand" "r,L")))]
1.8296 ++ ""
1.8297 ++ "srl%i2\\t%0, %1, %z2"
1.8298 ++ [(set_attr "type" "shift")])
1.8299 ++
1.8300 ++(define_insn "rotlsi3"
1.8301 ++ [(set (match_operand:SI 0 "register_operand" "=r,r")
1.8302 ++ (rotate:SI (match_operand:SI 1 "register_operand" "r,r")
1.8303 ++ (match_operand:SI 2 "shift_operand" "r,L")))]
1.8304 ++ ""
1.8305 ++ "rol%i2\\t%0, %1, %z2"
1.8306 ++ [(set_attr "type" "shift")])
1.8307 ++
1.8308 ++(define_insn "rotrsi3"
1.8309 ++ [(set (match_operand:SI 0 "register_operand" "=r,r")
1.8310 ++ (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
1.8311 ++ (match_operand:SI 2 "register_operand" "r,r")))]
1.8312 ++ ""
1.8313 ++ "ror\\t%0, %1, %2"
1.8314 ++ [(set_attr "type" "shift")])
1.8315 ++
1.8316 ++(define_insn "*shift_mul_constants"
1.8317 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8318 ++ (ashift:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
1.8319 ++ (match_operand:SI 2 "const_int_operand" "I"))
1.8320 ++ (match_operand:SI 3 "const_int_operand" "I")))]
1.8321 ++ "TARGET_HAS_MUL && SMALL_INT (INTVAL (operands[2]) << INTVAL (operands[3]))"
1.8322 ++{
1.8323 ++ HOST_WIDE_INT mul = INTVAL (operands[2]) << INTVAL (operands[3]);
1.8324 ++ rtx ops[3];
1.8325 ++
1.8326 ++ ops[0] = operands[0];
1.8327 ++ ops[1] = operands[1];
1.8328 ++ ops[2] = GEN_INT (mul);
1.8329 ++
1.8330 ++ output_asm_insn ("muli\t%0, %1, %2", ops);
1.8331 ++ return "";
1.8332 ++}
1.8333 ++ [(set_attr "type" "mul")])
1.8334 ++
1.8335 ++
1.8336 ++
1.8337 ++
1.8338 ++;*****************************************************************************
1.8339 ++;*
1.8340 ++;* Prologue, Epilogue and Return
1.8341 ++;*
1.8342 ++;*****************************************************************************
1.8343 ++
1.8344 ++(define_expand "prologue"
1.8345 ++ [(const_int 1)]
1.8346 ++ ""
1.8347 ++{
1.8348 ++ expand_prologue ();
1.8349 ++ DONE;
1.8350 ++})
1.8351 ++
1.8352 ++(define_expand "epilogue"
1.8353 ++ [(return)]
1.8354 ++ ""
1.8355 ++{
1.8356 ++ expand_epilogue (false);
1.8357 ++ DONE;
1.8358 ++})
1.8359 ++
1.8360 ++(define_expand "sibcall_epilogue"
1.8361 ++ [(return)]
1.8362 ++ ""
1.8363 ++{
1.8364 ++ expand_epilogue (true);
1.8365 ++ DONE;
1.8366 ++})
1.8367 ++
1.8368 ++(define_insn "return"
1.8369 ++ [(return)]
1.8370 ++ "reload_completed && nios2_can_use_return_insn ()"
1.8371 ++ "ret\\t"
1.8372 ++)
1.8373 ++
1.8374 ++(define_insn "return_from_epilogue"
1.8375 ++ [(use (match_operand 0 "pmode_register_operand" ""))
1.8376 ++ (return)]
1.8377 ++ "reload_completed"
1.8378 ++ "ret\\t"
1.8379 ++)
1.8380 ++
1.8381 ++;; Block any insns from being moved before this point, since the
1.8382 ++;; profiling call to mcount can use various registers that aren't
1.8383 ++;; saved or used to pass arguments.
1.8384 ++
1.8385 ++(define_insn "blockage"
1.8386 ++ [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
1.8387 ++ ""
1.8388 ++ ""
1.8389 ++ [(set_attr "type" "unknown")
1.8390 ++ (set_attr "length" "0")])
1.8391 ++
1.8392 ++
1.8393 ++
1.8394 ++;*****************************************************************************
1.8395 ++;*
1.8396 ++;* Jumps and Calls
1.8397 ++;*
1.8398 ++;*****************************************************************************
1.8399 ++
1.8400 ++(define_insn "indirect_jump"
1.8401 ++ [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
1.8402 ++ ""
1.8403 ++ "jmp\\t%0"
1.8404 ++ [(set_attr "type" "control")])
1.8405 ++
1.8406 ++(define_insn "jump"
1.8407 ++ [(set (pc)
1.8408 ++ (label_ref (match_operand 0 "" "")))]
1.8409 ++ ""
1.8410 ++ "br\\t%0"
1.8411 ++ [(set_attr "type" "control")])
1.8412 ++
1.8413 ++
1.8414 ++(define_insn "indirect_call"
1.8415 ++ [(call (mem:QI (match_operand:SI 0 "register_operand" "r"))
1.8416 ++ (match_operand 1 "" ""))
1.8417 ++ (clobber (reg:SI RA_REGNO))]
1.8418 ++ ""
1.8419 ++ "callr\\t%0"
1.8420 ++ [(set_attr "type" "control")])
1.8421 ++
1.8422 ++(define_insn "indirect_call_value"
1.8423 ++ [(set (match_operand 0 "" "")
1.8424 ++ (call (mem:QI (match_operand:SI 1 "register_operand" "r"))
1.8425 ++ (match_operand 2 "" "")))
1.8426 ++ (clobber (reg:SI RA_REGNO))]
1.8427 ++ ""
1.8428 ++ "callr\\t%1"
1.8429 ++)
1.8430 ++
1.8431 ++(define_expand "call"
1.8432 ++ [(parallel [(call (match_operand 0 "" "")
1.8433 ++ (match_operand 1 "" ""))
1.8434 ++ (clobber (reg:SI RA_REGNO))])]
1.8435 ++ ""
1.8436 ++ "")
1.8437 ++
1.8438 ++(define_expand "call_value"
1.8439 ++ [(parallel [(set (match_operand 0 "" "")
1.8440 ++ (call (match_operand 1 "" "")
1.8441 ++ (match_operand 2 "" "")))
1.8442 ++ (clobber (reg:SI RA_REGNO))])]
1.8443 ++ ""
1.8444 ++ "")
1.8445 ++
1.8446 ++(define_insn "*call"
1.8447 ++ [(call (mem:QI (match_operand:SI 0 "immediate_operand" "i"))
1.8448 ++ (match_operand 1 "" ""))
1.8449 ++ (clobber (match_operand:SI 2 "register_operand" "=r"))]
1.8450 ++ ""
1.8451 ++ "call\\t%0"
1.8452 ++ [(set_attr "type" "control")])
1.8453 ++
1.8454 ++(define_insn "*call_value"
1.8455 ++ [(set (match_operand 0 "" "")
1.8456 ++ (call (mem:QI (match_operand:SI 1 "immediate_operand" "i"))
1.8457 ++ (match_operand 2 "" "")))
1.8458 ++ (clobber (match_operand:SI 3 "register_operand" "=r"))]
1.8459 ++ ""
1.8460 ++ "call\\t%1"
1.8461 ++ [(set_attr "type" "control")])
1.8462 ++
1.8463 ++(define_expand "sibcall"
1.8464 ++ [(parallel [(call (match_operand 0 "" "")
1.8465 ++ (match_operand 1 "" ""))
1.8466 ++ (return)
1.8467 ++ (use (match_operand 2 "" ""))])]
1.8468 ++ ""
1.8469 ++ {
1.8470 ++ XEXP (operands[0], 0) = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
1.8471 ++
1.8472 ++ if (operands[2] == NULL_RTX)
1.8473 ++ operands[2] = const0_rtx;
1.8474 ++ }
1.8475 ++)
1.8476 ++
1.8477 ++(define_expand "sibcall_value"
1.8478 ++ [(parallel [(set (match_operand 0 "" "")
1.8479 ++ (call (match_operand 1 "" "")
1.8480 ++ (match_operand 2 "" "")))
1.8481 ++ (return)
1.8482 ++ (use (match_operand 3 "" ""))])]
1.8483 ++ ""
1.8484 ++ {
1.8485 ++ XEXP (operands[1], 0) = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
1.8486 ++
1.8487 ++ if (operands[3] == NULL_RTX)
1.8488 ++ operands[3] = const0_rtx;
1.8489 ++ }
1.8490 ++)
1.8491 ++
1.8492 ++(define_insn "sibcall_insn"
1.8493 ++ [(call (mem:QI (match_operand:SI 0 "register_operand" "r"))
1.8494 ++ (match_operand 1 "" ""))
1.8495 ++ (return)
1.8496 ++ (use (match_operand 2 "" ""))]
1.8497 ++ ""
1.8498 ++ "jmp\\t%0"
1.8499 ++)
1.8500 ++
1.8501 ++(define_insn "sibcall_value_insn"
1.8502 ++ [(set (match_operand 0 "register_operand" "")
1.8503 ++ (call (mem:QI (match_operand:SI 1 "register_operand" "r"))
1.8504 ++ (match_operand 2 "" "")))
1.8505 ++ (return)
1.8506 ++ (use (match_operand 3 "" ""))]
1.8507 ++ ""
1.8508 ++ "jmp\\t%1"
1.8509 ++)
1.8510 ++
1.8511 ++
1.8512 ++
1.8513 ++
1.8514 ++(define_expand "tablejump"
1.8515 ++ [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
1.8516 ++ (use (label_ref (match_operand 1 "" "")))])]
1.8517 ++ ""
1.8518 ++ ""
1.8519 ++)
1.8520 ++
1.8521 ++(define_insn "*tablejump"
1.8522 ++ [(set (pc)
1.8523 ++ (match_operand:SI 0 "register_operand" "r"))
1.8524 ++ (use (label_ref (match_operand 1 "" "")))]
1.8525 ++ ""
1.8526 ++ "jmp\\t%0"
1.8527 ++ [(set_attr "type" "control")])
1.8528 ++
1.8529 ++
1.8530 ++
1.8531 ++;*****************************************************************************
1.8532 ++;*
1.8533 ++;* Comparisons
1.8534 ++;*
1.8535 ++;*****************************************************************************
1.8536 ++;; Flow here is rather complex (based on MIPS):
1.8537 ++;;
1.8538 ++;; 1) The cmp{si,di,sf,df} routine is called. It deposits the
1.8539 ++;; arguments into the branch_cmp array, and the type into
1.8540 ++;; branch_type. No RTL is generated.
1.8541 ++;;
1.8542 ++;; 2) The appropriate branch define_expand is called, which then
1.8543 ++;; creates the appropriate RTL for the comparison and branch.
1.8544 ++;; Different CC modes are used, based on what type of branch is
1.8545 ++;; done, so that we can constrain things appropriately. There
1.8546 ++;; are assumptions in the rest of GCC that break if we fold the
1.8547 ++;; operands into the branchs for integer operations, and use cc0
1.8548 ++;; for floating point, so we use the fp status register instead.
1.8549 ++;; If needed, an appropriate temporary is created to hold the
1.8550 ++;; of the integer compare.
1.8551 ++
1.8552 ++(define_expand "cmpsi"
1.8553 ++ [(set (cc0)
1.8554 ++ (compare:CC (match_operand:SI 0 "register_operand" "")
1.8555 ++ (match_operand:SI 1 "arith_operand" "")))]
1.8556 ++ ""
1.8557 ++{
1.8558 ++ branch_cmp[0] = operands[0];
1.8559 ++ branch_cmp[1] = operands[1];
1.8560 ++ branch_type = CMP_SI;
1.8561 ++ DONE;
1.8562 ++})
1.8563 ++
1.8564 ++(define_expand "tstsi"
1.8565 ++ [(set (cc0)
1.8566 ++ (match_operand:SI 0 "register_operand" ""))]
1.8567 ++ ""
1.8568 ++{
1.8569 ++ branch_cmp[0] = operands[0];
1.8570 ++ branch_cmp[1] = const0_rtx;
1.8571 ++ branch_type = CMP_SI;
1.8572 ++ DONE;
1.8573 ++})
1.8574 ++
1.8575 ++
1.8576 ++;*****************************************************************************
1.8577 ++;*
1.8578 ++;* setting a register from a comparison
1.8579 ++;*
1.8580 ++;*****************************************************************************
1.8581 ++
1.8582 ++(define_expand "seq"
1.8583 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8584 ++ (eq:SI (match_dup 1)
1.8585 ++ (match_dup 2)))]
1.8586 ++ ""
1.8587 ++{
1.8588 ++ if (branch_type != CMP_SI)
1.8589 ++ FAIL;
1.8590 ++
1.8591 ++ /* set up operands from compare. */
1.8592 ++ operands[1] = branch_cmp[0];
1.8593 ++ operands[2] = branch_cmp[1];
1.8594 ++
1.8595 ++ gen_int_relational (EQ, operands[0], operands[1], operands[2], NULL_RTX);
1.8596 ++ DONE;
1.8597 ++})
1.8598 ++
1.8599 ++
1.8600 ++(define_insn "*seq"
1.8601 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8602 ++ (eq:SI (match_operand:SI 1 "reg_or_0_operand" "%rM")
1.8603 ++ (match_operand:SI 2 "arith_operand" "rI")))]
1.8604 ++ ""
1.8605 ++ "cmpeq%i2\\t%0, %z1, %z2"
1.8606 ++ [(set_attr "type" "alu")])
1.8607 ++
1.8608 ++
1.8609 ++(define_expand "sne"
1.8610 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8611 ++ (ne:SI (match_dup 1)
1.8612 ++ (match_dup 2)))]
1.8613 ++ ""
1.8614 ++{
1.8615 ++ if (branch_type != CMP_SI)
1.8616 ++ FAIL;
1.8617 ++
1.8618 ++ /* set up operands from compare. */
1.8619 ++ operands[1] = branch_cmp[0];
1.8620 ++ operands[2] = branch_cmp[1];
1.8621 ++
1.8622 ++ gen_int_relational (NE, operands[0], operands[1], operands[2], NULL_RTX);
1.8623 ++ DONE;
1.8624 ++})
1.8625 ++
1.8626 ++
1.8627 ++(define_insn "*sne"
1.8628 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8629 ++ (ne:SI (match_operand:SI 1 "reg_or_0_operand" "%rM")
1.8630 ++ (match_operand:SI 2 "arith_operand" "rI")))]
1.8631 ++ ""
1.8632 ++ "cmpne%i2\\t%0, %z1, %z2"
1.8633 ++ [(set_attr "type" "alu")])
1.8634 ++
1.8635 ++
1.8636 ++(define_expand "sgt"
1.8637 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8638 ++ (gt:SI (match_dup 1)
1.8639 ++ (match_dup 2)))]
1.8640 ++ ""
1.8641 ++{
1.8642 ++ if (branch_type != CMP_SI)
1.8643 ++ FAIL;
1.8644 ++
1.8645 ++ /* set up operands from compare. */
1.8646 ++ operands[1] = branch_cmp[0];
1.8647 ++ operands[2] = branch_cmp[1];
1.8648 ++
1.8649 ++ gen_int_relational (GT, operands[0], operands[1], operands[2], NULL_RTX);
1.8650 ++ DONE;
1.8651 ++})
1.8652 ++
1.8653 ++
1.8654 ++(define_insn "*sgt"
1.8655 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8656 ++ (gt:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
1.8657 ++ (match_operand:SI 2 "reg_or_0_operand" "rM")))]
1.8658 ++ ""
1.8659 ++ "cmplt\\t%0, %z2, %z1"
1.8660 ++ [(set_attr "type" "alu")])
1.8661 ++
1.8662 ++
1.8663 ++(define_expand "sge"
1.8664 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8665 ++ (ge:SI (match_dup 1)
1.8666 ++ (match_dup 2)))]
1.8667 ++ ""
1.8668 ++{
1.8669 ++ if (branch_type != CMP_SI)
1.8670 ++ FAIL;
1.8671 ++
1.8672 ++ /* set up operands from compare. */
1.8673 ++ operands[1] = branch_cmp[0];
1.8674 ++ operands[2] = branch_cmp[1];
1.8675 ++
1.8676 ++ gen_int_relational (GE, operands[0], operands[1], operands[2], NULL_RTX);
1.8677 ++ DONE;
1.8678 ++})
1.8679 ++
1.8680 ++
1.8681 ++(define_insn "*sge"
1.8682 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8683 ++ (ge:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
1.8684 ++ (match_operand:SI 2 "arith_operand" "rI")))]
1.8685 ++ ""
1.8686 ++ "cmpge%i2\\t%0, %z1, %z2"
1.8687 ++ [(set_attr "type" "alu")])
1.8688 ++
1.8689 ++(define_expand "sle"
1.8690 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8691 ++ (le:SI (match_dup 1)
1.8692 ++ (match_dup 2)))]
1.8693 ++ ""
1.8694 ++{
1.8695 ++ if (branch_type != CMP_SI)
1.8696 ++ FAIL;
1.8697 ++
1.8698 ++ /* set up operands from compare. */
1.8699 ++ operands[1] = branch_cmp[0];
1.8700 ++ operands[2] = branch_cmp[1];
1.8701 ++
1.8702 ++ gen_int_relational (LE, operands[0], operands[1], operands[2], NULL_RTX);
1.8703 ++ DONE;
1.8704 ++})
1.8705 ++
1.8706 ++
1.8707 ++(define_insn "*sle"
1.8708 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8709 ++ (le:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
1.8710 ++ (match_operand:SI 2 "reg_or_0_operand" "rM")))]
1.8711 ++ ""
1.8712 ++ "cmpge\\t%0, %z2, %z1"
1.8713 ++ [(set_attr "type" "alu")])
1.8714 ++
1.8715 ++
1.8716 ++(define_expand "slt"
1.8717 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8718 ++ (lt:SI (match_dup 1)
1.8719 ++ (match_dup 2)))]
1.8720 ++ ""
1.8721 ++{
1.8722 ++ if (branch_type != CMP_SI)
1.8723 ++ FAIL;
1.8724 ++
1.8725 ++ /* set up operands from compare. */
1.8726 ++ operands[1] = branch_cmp[0];
1.8727 ++ operands[2] = branch_cmp[1];
1.8728 ++
1.8729 ++ gen_int_relational (LT, operands[0], operands[1], operands[2], NULL_RTX);
1.8730 ++ DONE;
1.8731 ++})
1.8732 ++
1.8733 ++
1.8734 ++(define_insn "*slt"
1.8735 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8736 ++ (lt:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
1.8737 ++ (match_operand:SI 2 "arith_operand" "rI")))]
1.8738 ++ ""
1.8739 ++ "cmplt%i2\\t%0, %z1, %z2"
1.8740 ++ [(set_attr "type" "alu")])
1.8741 ++
1.8742 ++
1.8743 ++(define_expand "sgtu"
1.8744 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8745 ++ (gtu:SI (match_dup 1)
1.8746 ++ (match_dup 2)))]
1.8747 ++ ""
1.8748 ++{
1.8749 ++ if (branch_type != CMP_SI)
1.8750 ++ FAIL;
1.8751 ++
1.8752 ++ /* set up operands from compare. */
1.8753 ++ operands[1] = branch_cmp[0];
1.8754 ++ operands[2] = branch_cmp[1];
1.8755 ++
1.8756 ++ gen_int_relational (GTU, operands[0], operands[1], operands[2], NULL_RTX);
1.8757 ++ DONE;
1.8758 ++})
1.8759 ++
1.8760 ++
1.8761 ++(define_insn "*sgtu"
1.8762 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8763 ++ (gtu:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
1.8764 ++ (match_operand:SI 2 "reg_or_0_operand" "rM")))]
1.8765 ++ ""
1.8766 ++ "cmpltu\\t%0, %z2, %z1"
1.8767 ++ [(set_attr "type" "alu")])
1.8768 ++
1.8769 ++
1.8770 ++(define_expand "sgeu"
1.8771 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8772 ++ (geu:SI (match_dup 1)
1.8773 ++ (match_dup 2)))]
1.8774 ++ ""
1.8775 ++{
1.8776 ++ if (branch_type != CMP_SI)
1.8777 ++ FAIL;
1.8778 ++
1.8779 ++ /* set up operands from compare. */
1.8780 ++ operands[1] = branch_cmp[0];
1.8781 ++ operands[2] = branch_cmp[1];
1.8782 ++
1.8783 ++ gen_int_relational (GEU, operands[0], operands[1], operands[2], NULL_RTX);
1.8784 ++ DONE;
1.8785 ++})
1.8786 ++
1.8787 ++
1.8788 ++(define_insn "*sgeu"
1.8789 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8790 ++ (geu:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
1.8791 ++ (match_operand:SI 2 "uns_arith_operand" "rJ")))]
1.8792 ++ ""
1.8793 ++ "cmpgeu%i2\\t%0, %z1, %z2"
1.8794 ++ [(set_attr "type" "alu")])
1.8795 ++
1.8796 ++(define_expand "sleu"
1.8797 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8798 ++ (leu:SI (match_dup 1)
1.8799 ++ (match_dup 2)))]
1.8800 ++ ""
1.8801 ++{
1.8802 ++ if (branch_type != CMP_SI)
1.8803 ++ FAIL;
1.8804 ++
1.8805 ++ /* set up operands from compare. */
1.8806 ++ operands[1] = branch_cmp[0];
1.8807 ++ operands[2] = branch_cmp[1];
1.8808 ++
1.8809 ++ gen_int_relational (LEU, operands[0], operands[1], operands[2], NULL_RTX);
1.8810 ++ DONE;
1.8811 ++})
1.8812 ++
1.8813 ++
1.8814 ++(define_insn "*sleu"
1.8815 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8816 ++ (leu:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
1.8817 ++ (match_operand:SI 2 "reg_or_0_operand" "rM")))]
1.8818 ++ ""
1.8819 ++ "cmpgeu\\t%0, %z2, %z1"
1.8820 ++ [(set_attr "type" "alu")])
1.8821 ++
1.8822 ++
1.8823 ++(define_expand "sltu"
1.8824 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8825 ++ (ltu:SI (match_dup 1)
1.8826 ++ (match_dup 2)))]
1.8827 ++ ""
1.8828 ++{
1.8829 ++ if (branch_type != CMP_SI)
1.8830 ++ FAIL;
1.8831 ++
1.8832 ++ /* set up operands from compare. */
1.8833 ++ operands[1] = branch_cmp[0];
1.8834 ++ operands[2] = branch_cmp[1];
1.8835 ++
1.8836 ++ gen_int_relational (LTU, operands[0], operands[1], operands[2], NULL_RTX);
1.8837 ++ DONE;
1.8838 ++})
1.8839 ++
1.8840 ++
1.8841 ++(define_insn "*sltu"
1.8842 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.8843 ++ (ltu:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
1.8844 ++ (match_operand:SI 2 "uns_arith_operand" "rJ")))]
1.8845 ++ ""
1.8846 ++ "cmpltu%i2\\t%0, %z1, %z2"
1.8847 ++ [(set_attr "type" "alu")])
1.8848 ++
1.8849 ++
1.8850 ++
1.8851 ++
1.8852 ++;*****************************************************************************
1.8853 ++;*
1.8854 ++;* branches
1.8855 ++;*
1.8856 ++;*****************************************************************************
1.8857 ++
1.8858 ++(define_insn "*cbranch"
1.8859 ++ [(set (pc)
1.8860 ++ (if_then_else
1.8861 ++ (match_operator:SI 0 "comparison_operator"
1.8862 ++ [(match_operand:SI 2 "reg_or_0_operand" "rM")
1.8863 ++ (match_operand:SI 3 "reg_or_0_operand" "rM")])
1.8864 ++ (label_ref (match_operand 1 "" ""))
1.8865 ++ (pc)))]
1.8866 ++ ""
1.8867 ++ "b%0\\t%z2, %z3, %l1"
1.8868 ++ [(set_attr "type" "control")])
1.8869 ++
1.8870 ++
1.8871 ++(define_expand "beq"
1.8872 ++ [(set (pc)
1.8873 ++ (if_then_else (eq:CC (cc0)
1.8874 ++ (const_int 0))
1.8875 ++ (label_ref (match_operand 0 "" ""))
1.8876 ++ (pc)))]
1.8877 ++ ""
1.8878 ++{
1.8879 ++ gen_int_relational (EQ, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
1.8880 ++ DONE;
1.8881 ++})
1.8882 ++
1.8883 ++
1.8884 ++(define_expand "bne"
1.8885 ++ [(set (pc)
1.8886 ++ (if_then_else (ne:CC (cc0)
1.8887 ++ (const_int 0))
1.8888 ++ (label_ref (match_operand 0 "" ""))
1.8889 ++ (pc)))]
1.8890 ++ ""
1.8891 ++{
1.8892 ++ gen_int_relational (NE, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
1.8893 ++ DONE;
1.8894 ++})
1.8895 ++
1.8896 ++
1.8897 ++(define_expand "bgt"
1.8898 ++ [(set (pc)
1.8899 ++ (if_then_else (gt:CC (cc0)
1.8900 ++ (const_int 0))
1.8901 ++ (label_ref (match_operand 0 "" ""))
1.8902 ++ (pc)))]
1.8903 ++ ""
1.8904 ++{
1.8905 ++ gen_int_relational (GT, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
1.8906 ++ DONE;
1.8907 ++})
1.8908 ++
1.8909 ++(define_expand "bge"
1.8910 ++ [(set (pc)
1.8911 ++ (if_then_else (ge:CC (cc0)
1.8912 ++ (const_int 0))
1.8913 ++ (label_ref (match_operand 0 "" ""))
1.8914 ++ (pc)))]
1.8915 ++ ""
1.8916 ++{
1.8917 ++ gen_int_relational (GE, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
1.8918 ++ DONE;
1.8919 ++})
1.8920 ++
1.8921 ++(define_expand "ble"
1.8922 ++ [(set (pc)
1.8923 ++ (if_then_else (le:CC (cc0)
1.8924 ++ (const_int 0))
1.8925 ++ (label_ref (match_operand 0 "" ""))
1.8926 ++ (pc)))]
1.8927 ++ ""
1.8928 ++{
1.8929 ++ gen_int_relational (LE, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
1.8930 ++ DONE;
1.8931 ++})
1.8932 ++
1.8933 ++(define_expand "blt"
1.8934 ++ [(set (pc)
1.8935 ++ (if_then_else (lt:CC (cc0)
1.8936 ++ (const_int 0))
1.8937 ++ (label_ref (match_operand 0 "" ""))
1.8938 ++ (pc)))]
1.8939 ++ ""
1.8940 ++{
1.8941 ++ gen_int_relational (LT, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
1.8942 ++ DONE;
1.8943 ++})
1.8944 ++
1.8945 ++
1.8946 ++(define_expand "bgtu"
1.8947 ++ [(set (pc)
1.8948 ++ (if_then_else (gtu:CC (cc0)
1.8949 ++ (const_int 0))
1.8950 ++ (label_ref (match_operand 0 "" ""))
1.8951 ++ (pc)))]
1.8952 ++ ""
1.8953 ++{
1.8954 ++ gen_int_relational (GTU, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
1.8955 ++ DONE;
1.8956 ++})
1.8957 ++
1.8958 ++(define_expand "bgeu"
1.8959 ++ [(set (pc)
1.8960 ++ (if_then_else (geu:CC (cc0)
1.8961 ++ (const_int 0))
1.8962 ++ (label_ref (match_operand 0 "" ""))
1.8963 ++ (pc)))]
1.8964 ++ ""
1.8965 ++{
1.8966 ++ gen_int_relational (GEU, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
1.8967 ++ DONE;
1.8968 ++})
1.8969 ++
1.8970 ++(define_expand "bleu"
1.8971 ++ [(set (pc)
1.8972 ++ (if_then_else (leu:CC (cc0)
1.8973 ++ (const_int 0))
1.8974 ++ (label_ref (match_operand 0 "" ""))
1.8975 ++ (pc)))]
1.8976 ++ ""
1.8977 ++{
1.8978 ++ gen_int_relational (LEU, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
1.8979 ++ DONE;
1.8980 ++})
1.8981 ++
1.8982 ++(define_expand "bltu"
1.8983 ++ [(set (pc)
1.8984 ++ (if_then_else (ltu:CC (cc0)
1.8985 ++ (const_int 0))
1.8986 ++ (label_ref (match_operand 0 "" ""))
1.8987 ++ (pc)))]
1.8988 ++ ""
1.8989 ++{
1.8990 ++ gen_int_relational (LTU, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
1.8991 ++ DONE;
1.8992 ++})
1.8993 ++
1.8994 ++
1.8995 ++;*****************************************************************************
1.8996 ++;*
1.8997 ++;* String and Block Operations
1.8998 ++;*
1.8999 ++;*****************************************************************************
1.9000 ++
1.9001 ++; ??? This is all really a hack to get Dhrystone to work as fast as possible
1.9002 ++; things to be fixed:
1.9003 ++; * let the compiler core handle all of this, for that to work the extra
1.9004 ++; aliasing needs to be addressed.
1.9005 ++; * we use three temporary registers for loading and storing to ensure no
1.9006 ++; ld use stalls, this is excessive, because after the first ld/st only
1.9007 ++; two are needed. Only two would be needed all the way through if
1.9008 ++; we could schedule with other code. Consider:
1.9009 ++; 1 ld $1, 0($src)
1.9010 ++; 2 ld $2, 4($src)
1.9011 ++; 3 ld $3, 8($src)
1.9012 ++; 4 st $1, 0($dest)
1.9013 ++; 5 ld $1, 12($src)
1.9014 ++; 6 st $2, 4($src)
1.9015 ++; 7 etc.
1.9016 ++; The first store has to wait until 4. If it does not there will be one
1.9017 ++; cycle of stalling. However, if any other instruction could be placed
1.9018 ++; between 1 and 4, $3 would not be needed.
1.9019 ++; * In small we probably don't want to ever do this ourself because there
1.9020 ++; is no ld use stall.
1.9021 ++
1.9022 ++(define_expand "movstrsi"
1.9023 ++ [(parallel [(set (match_operand:BLK 0 "general_operand" "")
1.9024 ++ (match_operand:BLK 1 "general_operand" ""))
1.9025 ++ (use (match_operand:SI 2 "const_int_operand" ""))
1.9026 ++ (use (match_operand:SI 3 "const_int_operand" ""))
1.9027 ++ (clobber (match_scratch:SI 4 "=&r"))
1.9028 ++ (clobber (match_scratch:SI 5 "=&r"))
1.9029 ++ (clobber (match_scratch:SI 6 "=&r"))])]
1.9030 ++ "TARGET_INLINE_MEMCPY"
1.9031 ++{
1.9032 ++ rtx ld_addr_reg, st_addr_reg;
1.9033 ++
1.9034 ++ /* If the predicate for op2 fails in expr.c:emit_block_move_via_movstr
1.9035 ++ it trys to copy to a register, but does not re-try the predicate.
1.9036 ++ ??? Intead of fixing expr.c, I fix it here. */
1.9037 ++ if (!const_int_operand (operands[2], SImode))
1.9038 ++ FAIL;
1.9039 ++
1.9040 ++ /* ??? there are some magic numbers which need to be sorted out here.
1.9041 ++ the basis for them is not increasing code size hugely or going
1.9042 ++ out of range of offset addressing */
1.9043 ++ if (INTVAL (operands[3]) < 4)
1.9044 ++ FAIL;
1.9045 ++ if (!optimize
1.9046 ++ || (optimize_size && INTVAL (operands[2]) > 12)
1.9047 ++ || (optimize < 3 && INTVAL (operands[2]) > 100)
1.9048 ++ || INTVAL (operands[2]) > 200)
1.9049 ++ FAIL;
1.9050 ++
1.9051 ++ st_addr_reg
1.9052 ++ = replace_equiv_address (operands[0],
1.9053 ++ copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
1.9054 ++ ld_addr_reg
1.9055 ++ = replace_equiv_address (operands[1],
1.9056 ++ copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
1.9057 ++ emit_insn (gen_movstrsi_internal (st_addr_reg, ld_addr_reg,
1.9058 ++ operands[2], operands[3]));
1.9059 ++
1.9060 ++ DONE;
1.9061 ++})
1.9062 ++
1.9063 ++
1.9064 ++(define_insn "movstrsi_internal"
1.9065 ++ [(set (match_operand:BLK 0 "memory_operand" "=o")
1.9066 ++ (match_operand:BLK 1 "memory_operand" "o"))
1.9067 ++ (use (match_operand:SI 2 "const_int_operand" "i"))
1.9068 ++ (use (match_operand:SI 3 "const_int_operand" "i"))
1.9069 ++ (clobber (match_scratch:SI 4 "=&r"))
1.9070 ++ (clobber (match_scratch:SI 5 "=&r"))
1.9071 ++ (clobber (match_scratch:SI 6 "=&r"))]
1.9072 ++ "TARGET_INLINE_MEMCPY"
1.9073 ++{
1.9074 ++ int ld_offset = INTVAL (operands[2]);
1.9075 ++ int ld_len = INTVAL (operands[2]);
1.9076 ++ int ld_reg = 0;
1.9077 ++ rtx ld_addr_reg = XEXP (operands[1], 0);
1.9078 ++ int st_offset = INTVAL (operands[2]);
1.9079 ++ int st_len = INTVAL (operands[2]);
1.9080 ++ int st_reg = 0;
1.9081 ++ rtx st_addr_reg = XEXP (operands[0], 0);
1.9082 ++ int delay_count = 0;
1.9083 ++
1.9084 ++ /* ops[0] is the address used by the insn
1.9085 ++ ops[1] is the register being loaded or stored */
1.9086 ++ rtx ops[2];
1.9087 ++
1.9088 ++ if (INTVAL (operands[3]) < 4)
1.9089 ++ abort ();
1.9090 ++
1.9091 ++ while (ld_offset >= 4)
1.9092 ++ {
1.9093 ++ /* if the load use delay has been met, I can start
1.9094 ++ storing */
1.9095 ++ if (delay_count >= 3)
1.9096 ++ {
1.9097 ++ ops[0] = gen_rtx (MEM, SImode,
1.9098 ++ plus_constant (st_addr_reg, st_len - st_offset));
1.9099 ++ ops[1] = operands[st_reg + 4];
1.9100 ++ output_asm_insn ("stw\t%1, %0", ops);
1.9101 ++
1.9102 ++ st_reg = (st_reg + 1) % 3;
1.9103 ++ st_offset -= 4;
1.9104 ++ }
1.9105 ++
1.9106 ++ ops[0] = gen_rtx (MEM, SImode,
1.9107 ++ plus_constant (ld_addr_reg, ld_len - ld_offset));
1.9108 ++ ops[1] = operands[ld_reg + 4];
1.9109 ++ output_asm_insn ("ldw\t%1, %0", ops);
1.9110 ++
1.9111 ++ ld_reg = (ld_reg + 1) % 3;
1.9112 ++ ld_offset -= 4;
1.9113 ++ delay_count++;
1.9114 ++ }
1.9115 ++
1.9116 ++ if (ld_offset >= 2)
1.9117 ++ {
1.9118 ++ /* if the load use delay has been met, I can start
1.9119 ++ storing */
1.9120 ++ if (delay_count >= 3)
1.9121 ++ {
1.9122 ++ ops[0] = gen_rtx (MEM, SImode,
1.9123 ++ plus_constant (st_addr_reg, st_len - st_offset));
1.9124 ++ ops[1] = operands[st_reg + 4];
1.9125 ++ output_asm_insn ("stw\t%1, %0", ops);
1.9126 ++
1.9127 ++ st_reg = (st_reg + 1) % 3;
1.9128 ++ st_offset -= 4;
1.9129 ++ }
1.9130 ++
1.9131 ++ ops[0] = gen_rtx (MEM, HImode,
1.9132 ++ plus_constant (ld_addr_reg, ld_len - ld_offset));
1.9133 ++ ops[1] = operands[ld_reg + 4];
1.9134 ++ output_asm_insn ("ldh\t%1, %0", ops);
1.9135 ++
1.9136 ++ ld_reg = (ld_reg + 1) % 3;
1.9137 ++ ld_offset -= 2;
1.9138 ++ delay_count++;
1.9139 ++ }
1.9140 ++
1.9141 ++ if (ld_offset >= 1)
1.9142 ++ {
1.9143 ++ /* if the load use delay has been met, I can start
1.9144 ++ storing */
1.9145 ++ if (delay_count >= 3)
1.9146 ++ {
1.9147 ++ ops[0] = gen_rtx (MEM, SImode,
1.9148 ++ plus_constant (st_addr_reg, st_len - st_offset));
1.9149 ++ ops[1] = operands[st_reg + 4];
1.9150 ++ output_asm_insn ("stw\t%1, %0", ops);
1.9151 ++
1.9152 ++ st_reg = (st_reg + 1) % 3;
1.9153 ++ st_offset -= 4;
1.9154 ++ }
1.9155 ++
1.9156 ++ ops[0] = gen_rtx (MEM, QImode,
1.9157 ++ plus_constant (ld_addr_reg, ld_len - ld_offset));
1.9158 ++ ops[1] = operands[ld_reg + 4];
1.9159 ++ output_asm_insn ("ldb\t%1, %0", ops);
1.9160 ++
1.9161 ++ ld_reg = (ld_reg + 1) % 3;
1.9162 ++ ld_offset -= 1;
1.9163 ++ delay_count++;
1.9164 ++ }
1.9165 ++
1.9166 ++ while (st_offset >= 4)
1.9167 ++ {
1.9168 ++ ops[0] = gen_rtx (MEM, SImode,
1.9169 ++ plus_constant (st_addr_reg, st_len - st_offset));
1.9170 ++ ops[1] = operands[st_reg + 4];
1.9171 ++ output_asm_insn ("stw\t%1, %0", ops);
1.9172 ++
1.9173 ++ st_reg = (st_reg + 1) % 3;
1.9174 ++ st_offset -= 4;
1.9175 ++ }
1.9176 ++
1.9177 ++ while (st_offset >= 2)
1.9178 ++ {
1.9179 ++ ops[0] = gen_rtx (MEM, HImode,
1.9180 ++ plus_constant (st_addr_reg, st_len - st_offset));
1.9181 ++ ops[1] = operands[st_reg + 4];
1.9182 ++ output_asm_insn ("sth\t%1, %0", ops);
1.9183 ++
1.9184 ++ st_reg = (st_reg + 1) % 3;
1.9185 ++ st_offset -= 2;
1.9186 ++ }
1.9187 ++
1.9188 ++ while (st_offset >= 1)
1.9189 ++ {
1.9190 ++ ops[0] = gen_rtx (MEM, QImode,
1.9191 ++ plus_constant (st_addr_reg, st_len - st_offset));
1.9192 ++ ops[1] = operands[st_reg + 4];
1.9193 ++ output_asm_insn ("stb\t%1, %0", ops);
1.9194 ++
1.9195 ++ st_reg = (st_reg + 1) % 3;
1.9196 ++ st_offset -= 1;
1.9197 ++ }
1.9198 ++
1.9199 ++ return "";
1.9200 ++}
1.9201 ++; ??? lengths are not being used yet, but I will probably forget
1.9202 ++; to update this once I am using lengths, so set it to something
1.9203 ++; definetely big enough to cover it. 400 allows for 200 bytes
1.9204 ++; of motion.
1.9205 ++ [(set_attr "length" "400")])
1.9206 ++
1.9207 ++
1.9208 ++
1.9209 ++;*****************************************************************************
1.9210 ++;*
1.9211 ++;* Custom instructions
1.9212 ++;*
1.9213 ++;*****************************************************************************
1.9214 ++
1.9215 ++(define_constants [
1.9216 ++ (CUSTOM_N 100)
1.9217 ++ (CUSTOM_NI 101)
1.9218 ++ (CUSTOM_NF 102)
1.9219 ++ (CUSTOM_NP 103)
1.9220 ++ (CUSTOM_NII 104)
1.9221 ++ (CUSTOM_NIF 105)
1.9222 ++ (CUSTOM_NIP 106)
1.9223 ++ (CUSTOM_NFI 107)
1.9224 ++ (CUSTOM_NFF 108)
1.9225 ++ (CUSTOM_NFP 109)
1.9226 ++ (CUSTOM_NPI 110)
1.9227 ++ (CUSTOM_NPF 111)
1.9228 ++ (CUSTOM_NPP 112)
1.9229 ++ (CUSTOM_IN 113)
1.9230 ++ (CUSTOM_INI 114)
1.9231 ++ (CUSTOM_INF 115)
1.9232 ++ (CUSTOM_INP 116)
1.9233 ++ (CUSTOM_INII 117)
1.9234 ++ (CUSTOM_INIF 118)
1.9235 ++ (CUSTOM_INIP 119)
1.9236 ++ (CUSTOM_INFI 120)
1.9237 ++ (CUSTOM_INFF 121)
1.9238 ++ (CUSTOM_INFP 122)
1.9239 ++ (CUSTOM_INPI 123)
1.9240 ++ (CUSTOM_INPF 124)
1.9241 ++ (CUSTOM_INPP 125)
1.9242 ++ (CUSTOM_FN 126)
1.9243 ++ (CUSTOM_FNI 127)
1.9244 ++ (CUSTOM_FNF 128)
1.9245 ++ (CUSTOM_FNP 129)
1.9246 ++ (CUSTOM_FNII 130)
1.9247 ++ (CUSTOM_FNIF 131)
1.9248 ++ (CUSTOM_FNIP 132)
1.9249 ++ (CUSTOM_FNFI 133)
1.9250 ++ (CUSTOM_FNFF 134)
1.9251 ++ (CUSTOM_FNFP 135)
1.9252 ++ (CUSTOM_FNPI 136)
1.9253 ++ (CUSTOM_FNPF 137)
1.9254 ++ (CUSTOM_FNPP 138)
1.9255 ++ (CUSTOM_PN 139)
1.9256 ++ (CUSTOM_PNI 140)
1.9257 ++ (CUSTOM_PNF 141)
1.9258 ++ (CUSTOM_PNP 142)
1.9259 ++ (CUSTOM_PNII 143)
1.9260 ++ (CUSTOM_PNIF 144)
1.9261 ++ (CUSTOM_PNIP 145)
1.9262 ++ (CUSTOM_PNFI 146)
1.9263 ++ (CUSTOM_PNFF 147)
1.9264 ++ (CUSTOM_PNFP 148)
1.9265 ++ (CUSTOM_PNPI 149)
1.9266 ++ (CUSTOM_PNPF 150)
1.9267 ++ (CUSTOM_PNPP 151)
1.9268 ++])
1.9269 ++
1.9270 ++
1.9271 ++(define_insn "custom_n"
1.9272 ++ [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")] CUSTOM_N)]
1.9273 ++ ""
1.9274 ++ "custom\\t%0, zero, zero, zero"
1.9275 ++ [(set_attr "type" "custom")])
1.9276 ++
1.9277 ++(define_insn "custom_ni"
1.9278 ++ [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
1.9279 ++ (match_operand:SI 1 "register_operand" "r")] CUSTOM_NI)]
1.9280 ++ ""
1.9281 ++ "custom\\t%0, zero, %1, zero"
1.9282 ++ [(set_attr "type" "custom")])
1.9283 ++
1.9284 ++(define_insn "custom_nf"
1.9285 ++ [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
1.9286 ++ (match_operand:SF 1 "register_operand" "r")] CUSTOM_NF)]
1.9287 ++ ""
1.9288 ++ "custom\\t%0, zero, %1, zero"
1.9289 ++ [(set_attr "type" "custom")])
1.9290 ++
1.9291 ++(define_insn "custom_np"
1.9292 ++ [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
1.9293 ++ (match_operand:SI 1 "register_operand" "r")] CUSTOM_NP)]
1.9294 ++ ""
1.9295 ++ "custom\\t%0, zero, %1, zero"
1.9296 ++ [(set_attr "type" "custom")])
1.9297 ++
1.9298 ++(define_insn "custom_nii"
1.9299 ++ [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
1.9300 ++ (match_operand:SI 1 "register_operand" "r")
1.9301 ++ (match_operand:SI 2 "register_operand" "r")] CUSTOM_NII)]
1.9302 ++ ""
1.9303 ++ "custom\\t%0, zero, %1, %2"
1.9304 ++ [(set_attr "type" "custom")])
1.9305 ++
1.9306 ++(define_insn "custom_nif"
1.9307 ++ [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
1.9308 ++ (match_operand:SI 1 "register_operand" "r")
1.9309 ++ (match_operand:SF 2 "register_operand" "r")] CUSTOM_NIF)]
1.9310 ++ ""
1.9311 ++ "custom\\t%0, zero, %1, %2"
1.9312 ++ [(set_attr "type" "custom")])
1.9313 ++
1.9314 ++(define_insn "custom_nip"
1.9315 ++ [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
1.9316 ++ (match_operand:SI 1 "register_operand" "r")
1.9317 ++ (match_operand:SI 2 "register_operand" "r")] CUSTOM_NIP)]
1.9318 ++ ""
1.9319 ++ "custom\\t%0, zero, %1, %2"
1.9320 ++ [(set_attr "type" "custom")])
1.9321 ++
1.9322 ++(define_insn "custom_nfi"
1.9323 ++ [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
1.9324 ++ (match_operand:SF 1 "register_operand" "r")
1.9325 ++ (match_operand:SI 2 "register_operand" "r")] CUSTOM_NFI)]
1.9326 ++ ""
1.9327 ++ "custom\\t%0, zero, %1, %2"
1.9328 ++ [(set_attr "type" "custom")])
1.9329 ++
1.9330 ++(define_insn "custom_nff"
1.9331 ++ [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
1.9332 ++ (match_operand:SF 1 "register_operand" "r")
1.9333 ++ (match_operand:SF 2 "register_operand" "r")] CUSTOM_NFF)]
1.9334 ++ ""
1.9335 ++ "custom\\t%0, zero, %1, %2"
1.9336 ++ [(set_attr "type" "custom")])
1.9337 ++
1.9338 ++(define_insn "custom_nfp"
1.9339 ++ [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
1.9340 ++ (match_operand:SF 1 "register_operand" "r")
1.9341 ++ (match_operand:SI 2 "register_operand" "r")] CUSTOM_NFP)]
1.9342 ++ ""
1.9343 ++ "custom\\t%0, zero, %1, %2"
1.9344 ++ [(set_attr "type" "custom")])
1.9345 ++
1.9346 ++(define_insn "custom_npi"
1.9347 ++ [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
1.9348 ++ (match_operand:SI 1 "register_operand" "r")
1.9349 ++ (match_operand:SI 2 "register_operand" "r")] CUSTOM_NPI)]
1.9350 ++ ""
1.9351 ++ "custom\\t%0, zero, %1, %2"
1.9352 ++ [(set_attr "type" "custom")])
1.9353 ++
1.9354 ++(define_insn "custom_npf"
1.9355 ++ [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
1.9356 ++ (match_operand:SI 1 "register_operand" "r")
1.9357 ++ (match_operand:SF 2 "register_operand" "r")] CUSTOM_NPF)]
1.9358 ++ ""
1.9359 ++ "custom\\t%0, zero, %1, %2"
1.9360 ++ [(set_attr "type" "custom")])
1.9361 ++
1.9362 ++(define_insn "custom_npp"
1.9363 ++ [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
1.9364 ++ (match_operand:SI 1 "register_operand" "r")
1.9365 ++ (match_operand:SI 2 "register_operand" "r")] CUSTOM_NPP)]
1.9366 ++ ""
1.9367 ++ "custom\\t%0, zero, %1, %2"
1.9368 ++ [(set_attr "type" "custom")])
1.9369 ++
1.9370 ++
1.9371 ++
1.9372 ++(define_insn "custom_in"
1.9373 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.9374 ++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")] CUSTOM_IN))]
1.9375 ++ ""
1.9376 ++ "custom\\t%1, %0, zero, zero"
1.9377 ++ [(set_attr "type" "custom")])
1.9378 ++
1.9379 ++(define_insn "custom_ini"
1.9380 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.9381 ++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9382 ++ (match_operand:SI 2 "register_operand" "r")] CUSTOM_INI))]
1.9383 ++ ""
1.9384 ++ "custom\\t%1, %0, %2, zero"
1.9385 ++ [(set_attr "type" "custom")])
1.9386 ++
1.9387 ++(define_insn "custom_inf"
1.9388 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.9389 ++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9390 ++ (match_operand:SF 2 "register_operand" "r")] CUSTOM_INF))]
1.9391 ++ ""
1.9392 ++ "custom\\t%1, %0, %2, zero"
1.9393 ++ [(set_attr "type" "custom")])
1.9394 ++
1.9395 ++(define_insn "custom_inp"
1.9396 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.9397 ++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9398 ++ (match_operand:SI 2 "register_operand" "r")] CUSTOM_INP))]
1.9399 ++ ""
1.9400 ++ "custom\\t%1, %0, %2, zero"
1.9401 ++ [(set_attr "type" "custom")])
1.9402 ++
1.9403 ++(define_insn "custom_inii"
1.9404 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.9405 ++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9406 ++ (match_operand:SI 2 "register_operand" "r")
1.9407 ++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_INII))]
1.9408 ++ ""
1.9409 ++ "custom\\t%1, %0, %2, %3"
1.9410 ++ [(set_attr "type" "custom")])
1.9411 ++
1.9412 ++(define_insn "custom_inif"
1.9413 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.9414 ++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9415 ++ (match_operand:SI 2 "register_operand" "r")
1.9416 ++ (match_operand:SF 3 "register_operand" "r")] CUSTOM_INIF))]
1.9417 ++ ""
1.9418 ++ "custom\\t%1, %0, %2, %3"
1.9419 ++ [(set_attr "type" "custom")])
1.9420 ++
1.9421 ++(define_insn "custom_inip"
1.9422 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.9423 ++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9424 ++ (match_operand:SI 2 "register_operand" "r")
1.9425 ++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_INIP))]
1.9426 ++ ""
1.9427 ++ "custom\\t%1, %0, %2, %3"
1.9428 ++ [(set_attr "type" "custom")])
1.9429 ++
1.9430 ++(define_insn "custom_infi"
1.9431 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.9432 ++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9433 ++ (match_operand:SF 2 "register_operand" "r")
1.9434 ++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_INFI))]
1.9435 ++ ""
1.9436 ++ "custom\\t%1, %0, %2, %3"
1.9437 ++ [(set_attr "type" "custom")])
1.9438 ++
1.9439 ++(define_insn "custom_inff"
1.9440 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.9441 ++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9442 ++ (match_operand:SF 2 "register_operand" "r")
1.9443 ++ (match_operand:SF 3 "register_operand" "r")] CUSTOM_INFF))]
1.9444 ++ ""
1.9445 ++ "custom\\t%1, %0, %2, %3"
1.9446 ++ [(set_attr "type" "custom")])
1.9447 ++
1.9448 ++(define_insn "custom_infp"
1.9449 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.9450 ++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9451 ++ (match_operand:SF 2 "register_operand" "r")
1.9452 ++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_INFP))]
1.9453 ++ ""
1.9454 ++ "custom\\t%1, %0, %2, %3"
1.9455 ++ [(set_attr "type" "custom")])
1.9456 ++
1.9457 ++(define_insn "custom_inpi"
1.9458 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.9459 ++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9460 ++ (match_operand:SI 2 "register_operand" "r")
1.9461 ++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_INPI))]
1.9462 ++ ""
1.9463 ++ "custom\\t%1, %0, %2, %3"
1.9464 ++ [(set_attr "type" "custom")])
1.9465 ++
1.9466 ++(define_insn "custom_inpf"
1.9467 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.9468 ++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9469 ++ (match_operand:SI 2 "register_operand" "r")
1.9470 ++ (match_operand:SF 3 "register_operand" "r")] CUSTOM_INPF))]
1.9471 ++ ""
1.9472 ++ "custom\\t%1, %0, %2, %3"
1.9473 ++ [(set_attr "type" "custom")])
1.9474 ++
1.9475 ++(define_insn "custom_inpp"
1.9476 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.9477 ++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9478 ++ (match_operand:SI 2 "register_operand" "r")
1.9479 ++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_INPP))]
1.9480 ++ ""
1.9481 ++ "custom\\t%1, %0, %2, %3"
1.9482 ++ [(set_attr "type" "custom")])
1.9483 ++
1.9484 ++
1.9485 ++
1.9486 ++
1.9487 ++
1.9488 ++(define_insn "custom_fn"
1.9489 ++ [(set (match_operand:SF 0 "register_operand" "=r")
1.9490 ++ (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")] CUSTOM_FN))]
1.9491 ++ ""
1.9492 ++ "custom\\t%1, %0, zero, zero"
1.9493 ++ [(set_attr "type" "custom")])
1.9494 ++
1.9495 ++(define_insn "custom_fni"
1.9496 ++ [(set (match_operand:SF 0 "register_operand" "=r")
1.9497 ++ (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9498 ++ (match_operand:SI 2 "register_operand" "r")] CUSTOM_FNI))]
1.9499 ++ ""
1.9500 ++ "custom\\t%1, %0, %2, zero"
1.9501 ++ [(set_attr "type" "custom")])
1.9502 ++
1.9503 ++(define_insn "custom_fnf"
1.9504 ++ [(set (match_operand:SF 0 "register_operand" "=r")
1.9505 ++ (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9506 ++ (match_operand:SF 2 "register_operand" "r")] CUSTOM_FNF))]
1.9507 ++ ""
1.9508 ++ "custom\\t%1, %0, %2, zero"
1.9509 ++ [(set_attr "type" "custom")])
1.9510 ++
1.9511 ++(define_insn "custom_fnp"
1.9512 ++ [(set (match_operand:SF 0 "register_operand" "=r")
1.9513 ++ (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9514 ++ (match_operand:SI 2 "register_operand" "r")] CUSTOM_FNP))]
1.9515 ++ ""
1.9516 ++ "custom\\t%1, %0, %2, zero"
1.9517 ++ [(set_attr "type" "custom")])
1.9518 ++
1.9519 ++(define_insn "custom_fnii"
1.9520 ++ [(set (match_operand:SF 0 "register_operand" "=r")
1.9521 ++ (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9522 ++ (match_operand:SI 2 "register_operand" "r")
1.9523 ++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_FNII))]
1.9524 ++ ""
1.9525 ++ "custom\\t%1, %0, %2, %3"
1.9526 ++ [(set_attr "type" "custom")])
1.9527 ++
1.9528 ++(define_insn "custom_fnif"
1.9529 ++ [(set (match_operand:SF 0 "register_operand" "=r")
1.9530 ++ (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9531 ++ (match_operand:SI 2 "register_operand" "r")
1.9532 ++ (match_operand:SF 3 "register_operand" "r")] CUSTOM_FNIF))]
1.9533 ++ ""
1.9534 ++ "custom\\t%1, %0, %2, %3"
1.9535 ++ [(set_attr "type" "custom")])
1.9536 ++
1.9537 ++(define_insn "custom_fnip"
1.9538 ++ [(set (match_operand:SF 0 "register_operand" "=r")
1.9539 ++ (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9540 ++ (match_operand:SI 2 "register_operand" "r")
1.9541 ++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_FNIP))]
1.9542 ++ ""
1.9543 ++ "custom\\t%1, %0, %2, %3"
1.9544 ++ [(set_attr "type" "custom")])
1.9545 ++
1.9546 ++(define_insn "custom_fnfi"
1.9547 ++ [(set (match_operand:SF 0 "register_operand" "=r")
1.9548 ++ (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9549 ++ (match_operand:SF 2 "register_operand" "r")
1.9550 ++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_FNFI))]
1.9551 ++ ""
1.9552 ++ "custom\\t%1, %0, %2, %3"
1.9553 ++ [(set_attr "type" "custom")])
1.9554 ++
1.9555 ++(define_insn "custom_fnff"
1.9556 ++ [(set (match_operand:SF 0 "register_operand" "=r")
1.9557 ++ (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9558 ++ (match_operand:SF 2 "register_operand" "r")
1.9559 ++ (match_operand:SF 3 "register_operand" "r")] CUSTOM_FNFF))]
1.9560 ++ ""
1.9561 ++ "custom\\t%1, %0, %2, %3"
1.9562 ++ [(set_attr "type" "custom")])
1.9563 ++
1.9564 ++(define_insn "custom_fnfp"
1.9565 ++ [(set (match_operand:SF 0 "register_operand" "=r")
1.9566 ++ (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9567 ++ (match_operand:SF 2 "register_operand" "r")
1.9568 ++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_FNFP))]
1.9569 ++ ""
1.9570 ++ "custom\\t%1, %0, %2, %3"
1.9571 ++ [(set_attr "type" "custom")])
1.9572 ++
1.9573 ++(define_insn "custom_fnpi"
1.9574 ++ [(set (match_operand:SF 0 "register_operand" "=r")
1.9575 ++ (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9576 ++ (match_operand:SI 2 "register_operand" "r")
1.9577 ++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_FNPI))]
1.9578 ++ ""
1.9579 ++ "custom\\t%1, %0, %2, %3"
1.9580 ++ [(set_attr "type" "custom")])
1.9581 ++
1.9582 ++(define_insn "custom_fnpf"
1.9583 ++ [(set (match_operand:SF 0 "register_operand" "=r")
1.9584 ++ (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9585 ++ (match_operand:SI 2 "register_operand" "r")
1.9586 ++ (match_operand:SF 3 "register_operand" "r")] CUSTOM_FNPF))]
1.9587 ++ ""
1.9588 ++ "custom\\t%1, %0, %2, %3"
1.9589 ++ [(set_attr "type" "custom")])
1.9590 ++
1.9591 ++(define_insn "custom_fnpp"
1.9592 ++ [(set (match_operand:SF 0 "register_operand" "=r")
1.9593 ++ (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9594 ++ (match_operand:SI 2 "register_operand" "r")
1.9595 ++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_FNPP))]
1.9596 ++ ""
1.9597 ++ "custom\\t%1, %0, %2, %3"
1.9598 ++ [(set_attr "type" "custom")])
1.9599 ++
1.9600 ++
1.9601 ++
1.9602 ++(define_insn "custom_pn"
1.9603 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.9604 ++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")] CUSTOM_PN))]
1.9605 ++ ""
1.9606 ++ "custom\\t%1, %0, zero, zero"
1.9607 ++ [(set_attr "type" "custom")])
1.9608 ++
1.9609 ++(define_insn "custom_pni"
1.9610 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.9611 ++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9612 ++ (match_operand:SI 2 "register_operand" "r")] CUSTOM_PNI))]
1.9613 ++ ""
1.9614 ++ "custom\\t%1, %0, %2, zero"
1.9615 ++ [(set_attr "type" "custom")])
1.9616 ++
1.9617 ++(define_insn "custom_pnf"
1.9618 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.9619 ++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9620 ++ (match_operand:SF 2 "register_operand" "r")] CUSTOM_PNF))]
1.9621 ++ ""
1.9622 ++ "custom\\t%1, %0, %2, zero"
1.9623 ++ [(set_attr "type" "custom")])
1.9624 ++
1.9625 ++(define_insn "custom_pnp"
1.9626 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.9627 ++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9628 ++ (match_operand:SI 2 "register_operand" "r")] CUSTOM_PNP))]
1.9629 ++ ""
1.9630 ++ "custom\\t%1, %0, %2, zero"
1.9631 ++ [(set_attr "type" "custom")])
1.9632 ++
1.9633 ++(define_insn "custom_pnii"
1.9634 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.9635 ++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9636 ++ (match_operand:SI 2 "register_operand" "r")
1.9637 ++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_PNII))]
1.9638 ++ ""
1.9639 ++ "custom\\t%1, %0, %2, %3"
1.9640 ++ [(set_attr "type" "custom")])
1.9641 ++
1.9642 ++(define_insn "custom_pnif"
1.9643 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.9644 ++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9645 ++ (match_operand:SI 2 "register_operand" "r")
1.9646 ++ (match_operand:SF 3 "register_operand" "r")] CUSTOM_PNIF))]
1.9647 ++ ""
1.9648 ++ "custom\\t%1, %0, %2, %3"
1.9649 ++ [(set_attr "type" "custom")])
1.9650 ++
1.9651 ++(define_insn "custom_pnip"
1.9652 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.9653 ++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9654 ++ (match_operand:SI 2 "register_operand" "r")
1.9655 ++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_PNIP))]
1.9656 ++ ""
1.9657 ++ "custom\\t%1, %0, %2, %3"
1.9658 ++ [(set_attr "type" "custom")])
1.9659 ++
1.9660 ++(define_insn "custom_pnfi"
1.9661 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.9662 ++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9663 ++ (match_operand:SF 2 "register_operand" "r")
1.9664 ++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_PNFI))]
1.9665 ++ ""
1.9666 ++ "custom\\t%1, %0, %2, %3"
1.9667 ++ [(set_attr "type" "custom")])
1.9668 ++
1.9669 ++(define_insn "custom_pnff"
1.9670 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.9671 ++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9672 ++ (match_operand:SF 2 "register_operand" "r")
1.9673 ++ (match_operand:SF 3 "register_operand" "r")] CUSTOM_PNFF))]
1.9674 ++ ""
1.9675 ++ "custom\\t%1, %0, %2, %3"
1.9676 ++ [(set_attr "type" "custom")])
1.9677 ++
1.9678 ++(define_insn "custom_pnfp"
1.9679 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.9680 ++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9681 ++ (match_operand:SF 2 "register_operand" "r")
1.9682 ++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_PNFP))]
1.9683 ++ ""
1.9684 ++ "custom\\t%1, %0, %2, %3"
1.9685 ++ [(set_attr "type" "custom")])
1.9686 ++
1.9687 ++(define_insn "custom_pnpi"
1.9688 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.9689 ++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9690 ++ (match_operand:SI 2 "register_operand" "r")
1.9691 ++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_PNPI))]
1.9692 ++ ""
1.9693 ++ "custom\\t%1, %0, %2, %3"
1.9694 ++ [(set_attr "type" "custom")])
1.9695 ++
1.9696 ++(define_insn "custom_pnpf"
1.9697 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.9698 ++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9699 ++ (match_operand:SI 2 "register_operand" "r")
1.9700 ++ (match_operand:SF 3 "register_operand" "r")] CUSTOM_PNPF))]
1.9701 ++ ""
1.9702 ++ "custom\\t%1, %0, %2, %3"
1.9703 ++ [(set_attr "type" "custom")])
1.9704 ++
1.9705 ++(define_insn "custom_pnpp"
1.9706 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.9707 ++ (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
1.9708 ++ (match_operand:SI 2 "register_operand" "r")
1.9709 ++ (match_operand:SI 3 "register_operand" "r")] CUSTOM_PNPP))]
1.9710 ++ ""
1.9711 ++ "custom\\t%1, %0, %2, %3"
1.9712 ++ [(set_attr "type" "custom")])
1.9713 ++
1.9714 ++
1.9715 ++
1.9716 ++
1.9717 ++
1.9718 ++
1.9719 ++;*****************************************************************************
1.9720 ++;*
1.9721 ++;* Misc
1.9722 ++;*
1.9723 ++;*****************************************************************************
1.9724 ++
1.9725 ++(define_insn "nop"
1.9726 ++ [(const_int 0)]
1.9727 ++ ""
1.9728 ++ "nop\\t"
1.9729 ++ [(set_attr "type" "alu")])
1.9730 ++
1.9731 ++(define_insn "sync"
1.9732 ++ [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)]
1.9733 ++ ""
1.9734 ++ "sync\\t"
1.9735 ++ [(set_attr "type" "control")])
1.9736 ++
1.9737 ++
1.9738 ++(define_insn "rdctl"
1.9739 ++ [(set (match_operand:SI 0 "register_operand" "=r")
1.9740 ++ (unspec_volatile:SI [(match_operand:SI 1 "rdwrctl_operand" "O")] UNSPEC_RDCTL))]
1.9741 ++ ""
1.9742 ++ "rdctl\\t%0, ctl%1"
1.9743 ++ [(set_attr "type" "control")])
1.9744 ++
1.9745 ++(define_insn "wrctl"
1.9746 ++ [(unspec_volatile:SI [(match_operand:SI 0 "rdwrctl_operand" "O")
1.9747 ++ (match_operand:SI 1 "register_operand" "r")] UNSPEC_WRCTL)]
1.9748 ++ ""
1.9749 ++ "wrctl\\tctl%0, %1"
1.9750 ++ [(set_attr "type" "control")])
1.9751 ++
1.9752 ++
1.9753 ++
1.9754 ++;*****************************************************************************
1.9755 ++;*
1.9756 ++;* Peepholes
1.9757 ++;*
1.9758 ++;*****************************************************************************
1.9759 ++
1.9760 ++
1.9761 +--- gcc-3.4.3/gcc/config/nios2/t-nios2
1.9762 ++++ gcc-3.4.3-nios2/gcc/config/nios2/t-nios2
1.9763 +@@ -0,0 +1,123 @@
1.9764 ++##
1.9765 ++## Compiler flags to use when compiling libgcc2.c.
1.9766 ++##
1.9767 ++## LIB2FUNCS_EXTRA
1.9768 ++## A list of source file names to be compiled or assembled and inserted into libgcc.a.
1.9769 ++
1.9770 ++LIB2FUNCS_EXTRA=$(srcdir)/config/nios2/lib2-divmod.c \
1.9771 ++ $(srcdir)/config/nios2/lib2-divmod-hi.c \
1.9772 ++ $(srcdir)/config/nios2/lib2-divtable.c \
1.9773 ++ $(srcdir)/config/nios2/lib2-mul.c
1.9774 ++
1.9775 ++##
1.9776 ++## Floating Point Emulation
1.9777 ++## To have GCC include software floating point libraries in libgcc.a define FPBIT
1.9778 ++## and DPBIT along with a few rules as follows:
1.9779 ++##
1.9780 ++## # We want fine grained libraries, so use the new code
1.9781 ++## # to build the floating point emulation libraries.
1.9782 ++FPBIT=$(srcdir)/config/nios2/nios2-fp-bit.c
1.9783 ++DPBIT=$(srcdir)/config/nios2/nios2-dp-bit.c
1.9784 ++
1.9785 ++TARGET_LIBGCC2_CFLAGS = -O2
1.9786 ++
1.9787 ++# FLOAT_ONLY - no doubles
1.9788 ++# SMALL_MACHINE - QI/HI is faster than SI
1.9789 ++# Actually SMALL_MACHINE uses chars and shorts instead of ints
1.9790 ++# since ints (16-bit ones as they are today) are at least as fast
1.9791 ++# as chars and shorts, don't define SMALL_MACHINE
1.9792 ++# CMPtype - type returned by FP compare, i.e. INT (hard coded in fp-bit - see code )
1.9793 ++
1.9794 ++$(FPBIT): $(srcdir)/config/fp-bit.c Makefile
1.9795 ++ echo '#define FLOAT' > ${FPBIT}
1.9796 ++ cat $(srcdir)/config/fp-bit.c >> ${FPBIT}
1.9797 ++
1.9798 ++$(DPBIT): $(srcdir)/config/fp-bit.c Makefile
1.9799 ++ echo '' > ${DPBIT}
1.9800 ++ cat $(srcdir)/config/fp-bit.c >> ${DPBIT}
1.9801 ++
1.9802 ++EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crti.o crtn.o
1.9803 ++
1.9804 ++# Assemble startup files.
1.9805 ++$(T)crti.o: $(srcdir)/config/nios2/crti.asm $(GCC_PASSES)
1.9806 ++ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
1.9807 ++ -c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/nios2/crti.asm
1.9808 ++
1.9809 ++$(T)crtn.o: $(srcdir)/config/nios2/crtn.asm $(GCC_PASSES)
1.9810 ++ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
1.9811 ++ -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/nios2/crtn.asm
1.9812 ++
1.9813 ++
1.9814 ++## You may need to provide additional #defines at the beginning of
1.9815 ++## fp-bit.c and dp-bit.c to control target endianness and other options
1.9816 ++##
1.9817 ++## CRTSTUFF_T_CFLAGS
1.9818 ++## Special flags used when compiling crtstuff.c. See Initialization.
1.9819 ++##
1.9820 ++## CRTSTUFF_T_CFLAGS_S
1.9821 ++## Special flags used when compiling crtstuff.c for shared linking. Used
1.9822 ++## if you use crtbeginS.o and crtendS.o in EXTRA-PARTS. See Initialization.
1.9823 ++##
1.9824 ++## MULTILIB_OPTIONS
1.9825 ++## For some targets, invoking GCC in different ways produces objects that
1.9826 ++## can not be linked together. For example, for some targets GCC produces
1.9827 ++## both big and little endian code. For these targets, you must arrange
1.9828 ++## for multiple versions of libgcc.a to be compiled, one for each set of
1.9829 ++## incompatible options. When GCC invokes the linker, it arranges to link
1.9830 ++## in the right version of libgcc.a, based on the command line options
1.9831 ++## used.
1.9832 ++## The MULTILIB_OPTIONS macro lists the set of options for which special
1.9833 ++## versions of libgcc.a must be built. Write options that are mutually
1.9834 ++## incompatible side by side, separated by a slash. Write options that may
1.9835 ++## be used together separated by a space. The build procedure will build
1.9836 ++## all combinations of compatible options.
1.9837 ++##
1.9838 ++## For example, if you set MULTILIB_OPTIONS to m68000/m68020 msoft-float,
1.9839 ++## Makefile will build special versions of libgcc.a using the following
1.9840 ++## sets of options: -m68000, -m68020, -msoft-float, -m68000 -msoft-float,
1.9841 ++## and -m68020 -msoft-float.
1.9842 ++
1.9843 ++MULTILIB_OPTIONS = mno-hw-mul mhw-mulx
1.9844 ++
1.9845 ++## MULTILIB_DIRNAMES
1.9846 ++## If MULTILIB_OPTIONS is used, this variable specifies the directory names
1.9847 ++## that should be used to hold the various libraries. Write one element in
1.9848 ++## MULTILIB_DIRNAMES for each element in MULTILIB_OPTIONS. If
1.9849 ++## MULTILIB_DIRNAMES is not used, the default value will be
1.9850 ++## MULTILIB_OPTIONS, with all slashes treated as spaces.
1.9851 ++## For example, if MULTILIB_OPTIONS is set to m68000/m68020 msoft-float,
1.9852 ++## then the default value of MULTILIB_DIRNAMES is m68000 m68020
1.9853 ++## msoft-float. You may specify a different value if you desire a
1.9854 ++## different set of directory names.
1.9855 ++
1.9856 ++# MULTILIB_DIRNAMES =
1.9857 ++
1.9858 ++## MULTILIB_MATCHES
1.9859 ++## Sometimes the same option may be written in two different ways. If an
1.9860 ++## option is listed in MULTILIB_OPTIONS, GCC needs to know about any
1.9861 ++## synonyms. In that case, set MULTILIB_MATCHES to a list of items of the
1.9862 ++## form option=option to describe all relevant synonyms. For example,
1.9863 ++## m68000=mc68000 m68020=mc68020.
1.9864 ++##
1.9865 ++## MULTILIB_EXCEPTIONS
1.9866 ++## Sometimes when there are multiple sets of MULTILIB_OPTIONS being
1.9867 ++## specified, there are combinations that should not be built. In that
1.9868 ++## case, set MULTILIB_EXCEPTIONS to be all of the switch exceptions in
1.9869 ++## shell case syntax that should not be built.
1.9870 ++## For example, in the PowerPC embedded ABI support, it is not desirable to
1.9871 ++## build libraries compiled with the -mcall-aix option and either of the
1.9872 ++## -fleading-underscore or -mlittle options at the same time. Therefore
1.9873 ++## MULTILIB_EXCEPTIONS is set to
1.9874 ++##
1.9875 ++## *mcall-aix/*fleading-underscore* *mlittle/*mcall-aix*
1.9876 ++##
1.9877 ++
1.9878 ++MULTILIB_EXCEPTIONS = *mno-hw-mul/*mhw-mulx*
1.9879 ++
1.9880 ++##
1.9881 ++## MULTILIB_EXTRA_OPTS Sometimes it is desirable that when building
1.9882 ++## multiple versions of libgcc.a certain options should always be passed on
1.9883 ++## to the compiler. In that case, set MULTILIB_EXTRA_OPTS to be the list
1.9884 ++## of options to be used for all builds.
1.9885 ++##
1.9886 ++
1.9887 +--- gcc-3.4.3/gcc/config.gcc
1.9888 ++++ gcc-3.4.3-nios2/gcc/config.gcc
1.9889 +@@ -1321,6 +1321,10 @@ m32rle-*-linux*)
1.9890 + thread_file='posix'
1.9891 + fi
1.9892 + ;;
1.9893 ++# JBG
1.9894 ++nios2-*-* | nios2-*-*)
1.9895 ++ tm_file="elfos.h ${tm_file}"
1.9896 ++ ;;
1.9897 + # m68hc11 and m68hc12 share the same machine description.
1.9898 + m68hc11-*-*|m6811-*-*)
1.9899 + tm_file="dbxelf.h elfos.h m68hc11/m68hc11.h"
1.9900 +--- gcc-3.4.3/gcc/cse.c
1.9901 ++++ gcc-3.4.3-nios2/gcc/cse.c
1.9902 +@@ -3134,6 +3134,10 @@ find_comparison_args (enum rtx_code code
1.9903 + #ifdef FLOAT_STORE_FLAG_VALUE
1.9904 + REAL_VALUE_TYPE fsfv;
1.9905 + #endif
1.9906 ++#ifdef __nios2__
1.9907 ++ if (p->is_const)
1.9908 ++ break;
1.9909 ++#endif
1.9910 +
1.9911 + /* If the entry isn't valid, skip it. */
1.9912 + if (! exp_equiv_p (p->exp, p->exp, 1, 0))
1.9913 +--- gcc-3.4.3/gcc/doc/extend.texi
1.9914 ++++ gcc-3.4.3-nios2/gcc/doc/extend.texi
1.9915 +@@ -5636,12 +5636,118 @@ to those machines. Generally these gene
1.9916 + instructions, but allow the compiler to schedule those calls.
1.9917 +
1.9918 + @menu
1.9919 ++* Altera Nios II Built-in Functions::
1.9920 + * Alpha Built-in Functions::
1.9921 + * ARM Built-in Functions::
1.9922 + * X86 Built-in Functions::
1.9923 + * PowerPC AltiVec Built-in Functions::
1.9924 + @end menu
1.9925 +
1.9926 ++@node Altera Nios II Built-in Functions
1.9927 ++@subsection Altera Nios II Built-in Functions
1.9928 ++
1.9929 ++These built-in functions are available for the Altera Nios II
1.9930 ++family of processors.
1.9931 ++
1.9932 ++The following built-in functions are always available. They
1.9933 ++all generate the machine instruction that is part of the name.
1.9934 ++
1.9935 ++@example
1.9936 ++int __builtin_ldbio (volatile const void *)
1.9937 ++int __builtin_ldbuio (volatile const void *)
1.9938 ++int __builtin_ldhio (volatile const void *)
1.9939 ++int __builtin_ldhuio (volatile const void *)
1.9940 ++int __builtin_ldwio (volatile const void *)
1.9941 ++void __builtin_stbio (volatile void *, int)
1.9942 ++void __builtin_sthio (volatile void *, int)
1.9943 ++void __builtin_stwio (volatile void *, int)
1.9944 ++void __builtin_sync (void)
1.9945 ++int __builtin_rdctl (int)
1.9946 ++void __builtin_wrctl (int, int)
1.9947 ++@end example
1.9948 ++
1.9949 ++The following built-in functions are always available. They
1.9950 ++all generate a Nios II Custom Instruction. The name of the
1.9951 ++function represents the types that the function takes and
1.9952 ++returns. The letter before the @code{n} is the return type
1.9953 ++or void if absent. The @code{n} represnts the first parameter
1.9954 ++to all the custom instructions, the custom instruction number.
1.9955 ++The two letters after the @code{n} represent the up to two
1.9956 ++parameters to the function.
1.9957 ++
1.9958 ++The letters reprsent the following data types:
1.9959 ++@table @code
1.9960 ++@item <no letter>
1.9961 ++@code{void} for return type and no parameter for parameter types.
1.9962 ++
1.9963 ++@item i
1.9964 ++@code{int} for return type and parameter type
1.9965 ++
1.9966 ++@item f
1.9967 ++@code{float} for return type and parameter type
1.9968 ++
1.9969 ++@item p
1.9970 ++@code{void *} for return type and parameter type
1.9971 ++
1.9972 ++@end table
1.9973 ++
1.9974 ++And the function names are:
1.9975 ++@example
1.9976 ++void __builtin_custom_n (void)
1.9977 ++void __builtin_custom_ni (int)
1.9978 ++void __builtin_custom_nf (float)
1.9979 ++void __builtin_custom_np (void *)
1.9980 ++void __builtin_custom_nii (int, int)
1.9981 ++void __builtin_custom_nif (int, float)
1.9982 ++void __builtin_custom_nip (int, void *)
1.9983 ++void __builtin_custom_nfi (float, int)
1.9984 ++void __builtin_custom_nff (float, float)
1.9985 ++void __builtin_custom_nfp (float, void *)
1.9986 ++void __builtin_custom_npi (void *, int)
1.9987 ++void __builtin_custom_npf (void *, float)
1.9988 ++void __builtin_custom_npp (void *, void *)
1.9989 ++int __builtin_custom_in (void)
1.9990 ++int __builtin_custom_ini (int)
1.9991 ++int __builtin_custom_inf (float)
1.9992 ++int __builtin_custom_inp (void *)
1.9993 ++int __builtin_custom_inii (int, int)
1.9994 ++int __builtin_custom_inif (int, float)
1.9995 ++int __builtin_custom_inip (int, void *)
1.9996 ++int __builtin_custom_infi (float, int)
1.9997 ++int __builtin_custom_inff (float, float)
1.9998 ++int __builtin_custom_infp (float, void *)
1.9999 ++int __builtin_custom_inpi (void *, int)
1.10000 ++int __builtin_custom_inpf (void *, float)
1.10001 ++int __builtin_custom_inpp (void *, void *)
1.10002 ++float __builtin_custom_fn (void)
1.10003 ++float __builtin_custom_fni (int)
1.10004 ++float __builtin_custom_fnf (float)
1.10005 ++float __builtin_custom_fnp (void *)
1.10006 ++float __builtin_custom_fnii (int, int)
1.10007 ++float __builtin_custom_fnif (int, float)
1.10008 ++float __builtin_custom_fnip (int, void *)
1.10009 ++float __builtin_custom_fnfi (float, int)
1.10010 ++float __builtin_custom_fnff (float, float)
1.10011 ++float __builtin_custom_fnfp (float, void *)
1.10012 ++float __builtin_custom_fnpi (void *, int)
1.10013 ++float __builtin_custom_fnpf (void *, float)
1.10014 ++float __builtin_custom_fnpp (void *, void *)
1.10015 ++void * __builtin_custom_pn (void)
1.10016 ++void * __builtin_custom_pni (int)
1.10017 ++void * __builtin_custom_pnf (float)
1.10018 ++void * __builtin_custom_pnp (void *)
1.10019 ++void * __builtin_custom_pnii (int, int)
1.10020 ++void * __builtin_custom_pnif (int, float)
1.10021 ++void * __builtin_custom_pnip (int, void *)
1.10022 ++void * __builtin_custom_pnfi (float, int)
1.10023 ++void * __builtin_custom_pnff (float, float)
1.10024 ++void * __builtin_custom_pnfp (float, void *)
1.10025 ++void * __builtin_custom_pnpi (void *, int)
1.10026 ++void * __builtin_custom_pnpf (void *, float)
1.10027 ++void * __builtin_custom_pnpp (void *, void *)
1.10028 ++@end example
1.10029 ++
1.10030 ++
1.10031 + @node Alpha Built-in Functions
1.10032 + @subsection Alpha Built-in Functions
1.10033 +
1.10034 +--- gcc-3.4.3/gcc/doc/invoke.texi
1.10035 ++++ gcc-3.4.3-nios2/gcc/doc/invoke.texi
1.10036 +@@ -337,6 +337,14 @@ in the following sections.
1.10037 + @item Machine Dependent Options
1.10038 + @xref{Submodel Options,,Hardware Models and Configurations}.
1.10039 +
1.10040 ++@emph{Altera Nios II Options}
1.10041 ++@gccoptlist{-msmallc -mno-bypass-cache -mbypass-cache @gol
1.10042 ++-mno-cache-volatile -mcache-volatile -mno-inline-memcpy @gol
1.10043 ++-minline-memcpy -mno-fast-sw-div -mfast-sw-div @gol
1.10044 ++-mhw-mul -mno-hw-mul -mhw-mulx -mno-hw-mulx @gol
1.10045 ++-mno-hw-div -mhw-div @gol
1.10046 ++-msys-crt0= -msys-lib= -msys=nosys }
1.10047 ++
1.10048 + @emph{M680x0 Options}
1.10049 + @gccoptlist{-m68000 -m68020 -m68020-40 -m68020-60 -m68030 -m68040 @gol
1.10050 + -m68060 -mcpu32 -m5200 -m68881 -mbitfield -mc68000 -mc68020 @gol
1.10051 +@@ -5836,6 +5844,7 @@ machine description. The default for th
1.10052 + that macro, which enables you to change the defaults.
1.10053 +
1.10054 + @menu
1.10055 ++* Altera Nios II Options::
1.10056 + * M680x0 Options::
1.10057 + * M68hc1x Options::
1.10058 + * VAX Options::
1.10059 +@@ -5871,6 +5880,103 @@ that macro, which enables you to change
1.10060 + * FRV Options::
1.10061 + @end menu
1.10062 +
1.10063 ++
1.10064 ++@node Altera Nios II Options
1.10065 ++@subsection Altera Nios II Options
1.10066 ++@cindex Altera Nios II options
1.10067 ++
1.10068 ++These are the @samp{-m} options defined for the Altera Nios II
1.10069 ++processor.
1.10070 ++
1.10071 ++@table @gcctabopt
1.10072 ++
1.10073 ++@item -msmallc
1.10074 ++@opindex msmallc
1.10075 ++
1.10076 ++Link with a limited version of the C library, -lsmallc. For more
1.10077 ++information see the C Library Documentation.
1.10078 ++
1.10079 ++
1.10080 ++@item -mbypass-cache
1.10081 ++@itemx -mno-bypass-cache
1.10082 ++@opindex mno-bypass-cache
1.10083 ++@opindex mbypass-cache
1.10084 ++
1.10085 ++Force all load and store instructions to always bypass cache by
1.10086 ++using io variants of the instructions. The default is to not
1.10087 ++bypass the cache.
1.10088 ++
1.10089 ++@item -mno-cache-volatile
1.10090 ++@itemx -mcache-volatile
1.10091 ++@opindex mcache-volatile
1.10092 ++@opindex mno-cache-volatile
1.10093 ++
1.10094 ++Volatile memory access bypass the cache using the io variants of
1.10095 ++the ld and st instructions. The default is to cache volatile
1.10096 ++accesses.
1.10097 ++
1.10098 ++-mno-cache-volatile is deprecated and will be deleted in a
1.10099 ++future GCC release.
1.10100 ++
1.10101 ++
1.10102 ++@item -mno-inline-memcpy
1.10103 ++@itemx -minline-memcpy
1.10104 ++@opindex mno-inline-memcpy
1.10105 ++@opindex minline-memcpy
1.10106 ++
1.10107 ++Do not inline memcpy. The default is to inline when -O is on.
1.10108 ++
1.10109 ++
1.10110 ++@item -mno-fast-sw-div
1.10111 ++@itemx -mfast-sw-div
1.10112 ++@opindex mno-fast-sw-div
1.10113 ++@opindex mfast-sw-div
1.10114 ++
1.10115 ++Do no use table based fast divide for small numbers. The default
1.10116 ++is to use the fast divide at -O3 and above.
1.10117 ++
1.10118 ++
1.10119 ++@item -mno-hw-mul
1.10120 ++@itemx -mhw-mul
1.10121 ++@itemx -mno-hw-mulx
1.10122 ++@itemx -mhw-mulx
1.10123 ++@itemx -mno-hw-div
1.10124 ++@itemx -mhw-div
1.10125 ++@opindex mno-hw-mul
1.10126 ++@opindex mhw-mul
1.10127 ++@opindex mno-hw-mulx
1.10128 ++@opindex mhw-mulx
1.10129 ++@opindex mno-hw-div
1.10130 ++@opindex mhw-div
1.10131 ++
1.10132 ++Enable or disable emitting @code{mul}, @code{mulx} and @code{div} family of
1.10133 ++instructions by the compiler. The default is to emit @code{mul}
1.10134 ++and not emit @code{div} and @code{mulx}.
1.10135 ++
1.10136 ++The different combinations of @code{mul} and @code{mulx} instructions
1.10137 ++generate a different multilib options.
1.10138 ++
1.10139 ++
1.10140 ++@item -msys-crt0=@var{startfile}
1.10141 ++@opindex msys-crt0
1.10142 ++
1.10143 ++@var{startfile} is the file name of the startfile (crt0) to use
1.10144 ++when linking. The default is crt0.o that comes with libgloss
1.10145 ++and is only suitable for use with the instruction set
1.10146 ++simulator.
1.10147 ++
1.10148 ++@item -msys-lib=@var{systemlib}
1.10149 ++@itemx -msys-lib=nosys
1.10150 ++@opindex msys-lib
1.10151 ++
1.10152 ++@var{systemlib} is the library name of the library which provides
1.10153 ++the system calls required by the C library, e.g. @code{read}, @code{write}
1.10154 ++etc. The default is to use nosys, this library provides
1.10155 ++stub implementations of the calls and is part of libgloss.
1.10156 ++
1.10157 ++@end table
1.10158 ++
1.10159 ++
1.10160 + @node M680x0 Options
1.10161 + @subsection M680x0 Options
1.10162 + @cindex M680x0 options
1.10163 +--- gcc-3.4.3/gcc/doc/md.texi
1.10164 ++++ gcc-3.4.3-nios2/gcc/doc/md.texi
1.10165 +@@ -1335,6 +1335,49 @@ However, here is a summary of the machin
1.10166 + available on some particular machines.
1.10167 +
1.10168 + @table @emph
1.10169 ++
1.10170 ++@item Altera Nios II family---@file{nios2.h}
1.10171 ++@table @code
1.10172 ++
1.10173 ++@item I
1.10174 ++Integer that is valid as an immediate operand in an
1.10175 ++instruction taking a signed 16-bit number. Range
1.10176 ++@minus{}32768 to 32767.
1.10177 ++
1.10178 ++@item J
1.10179 ++Integer that is valid as an immediate operand in an
1.10180 ++instruction taking an unsigned 16-bit number. Range
1.10181 ++0 to 65535.
1.10182 ++
1.10183 ++@item K
1.10184 ++Integer that is valid as an immediate operand in an
1.10185 ++instruction taking only the upper 16-bits of a
1.10186 ++32-bit number. Range 32-bit numbers with the lower
1.10187 ++16-bits being 0.
1.10188 ++
1.10189 ++@item L
1.10190 ++Integer that is valid as an immediate operand for a
1.10191 ++shift instruction. Range 0 to 31.
1.10192 ++
1.10193 ++
1.10194 ++@item M
1.10195 ++Integer that is valid as an immediate operand for
1.10196 ++only the value 0. Can be used in conjunction with
1.10197 ++the format modifier @code{z} to use @code{r0}
1.10198 ++instead of @code{0} in the assembly output.
1.10199 ++
1.10200 ++@item N
1.10201 ++Integer that is valid as an immediate operand for
1.10202 ++a custom instruction opcode. Range 0 to 255.
1.10203 ++
1.10204 ++@item S
1.10205 ++Matches immediates which are addresses in the small
1.10206 ++data section and therefore can be added to @code{gp}
1.10207 ++as a 16-bit immediate to re-create their 32-bit value.
1.10208 ++
1.10209 ++@end table
1.10210 ++
1.10211 ++
1.10212 + @item ARM family---@file{arm.h}
1.10213 + @table @code
1.10214 + @item f