patches/gcc/3.4.4/900-nios2.patch
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Sat Feb 24 11:00:05 2007 +0000 (2007-02-24)
changeset 1 eeea35fbf182
permissions -rw-r--r--
Add the full crosstool-NG sources to the new repository of its own.
You might just say: 'Yeah! crosstool-NG's got its own repo!".
Unfortunately, that's because the previous repo got damaged beyond repair and I had no backup.
That means I'm putting backups in place in the afternoon.
That also means we've lost history... :-(
     1 --- gcc-3.4.3/gcc/Makefile.in
     2 +++ gcc-3.4.3-nios2/gcc/Makefile.in
     3 @@ -3085,7 +3085,7 @@ install-mkheaders: stmp-int-hdrs $(STMP_
     4  	  $(INSTALL_DATA) $(srcdir)/README-fixinc \
     5  	    $(DESTDIR)$(itoolsdatadir)/include/README ; \
     6  	  $(INSTALL_SCRIPT) fixinc.sh $(DESTDIR)$(itoolsdir)/fixinc.sh ; \
     7 -	  $(INSTALL_PROGRAM) fixinc/fixincl $(DESTDIR)$(itoolsdir)/fixincl ; \
     8 +	  $(INSTALL_PROGRAM) fixinc/fixincl$(build_exeext) $(DESTDIR)$(itoolsdir)/fixincl$(build_exeext) ; \
     9  	  $(INSTALL_DATA) $(srcdir)/gsyslimits.h \
    10  	    $(DESTDIR)$(itoolsdatadir)/gsyslimits.h ; \
    11  	else :; fi
    12 --- gcc-3.4.3/gcc/combine.c
    13 +++ gcc-3.4.3-nios2/gcc/combine.c
    14 @@ -4380,6 +4380,14 @@ combine_simplify_rtx (rtx x, enum machin
    15  					 mode);
    16  	    }
    17  
    18 +#ifndef __nios2__
    19 +/* This screws up Nios II in this test case:
    20 +
    21 +if (x & 1)
    22 +  return 2;
    23 +else
    24 +  return 3;
    25 +*/
    26  	  else if (STORE_FLAG_VALUE == 1
    27  		   && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT
    28  		   && op1 == const0_rtx
    29 @@ -4391,6 +4399,7 @@ combine_simplify_rtx (rtx x, enum machin
    30  				 gen_lowpart_for_combine (mode, op0),
    31  				 const1_rtx);
    32  	    }
    33 +#endif
    34  
    35  	  else if (STORE_FLAG_VALUE == 1
    36  		   && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT
    37 --- gcc-3.4.3/gcc/config/nios2/crti.asm
    38 +++ gcc-3.4.3-nios2/gcc/config/nios2/crti.asm
    39 @@ -0,0 +1,88 @@
    40 +/*
    41 +  Copyright (C) 2003 
    42 + by Jonah Graham (jgraham@altera.com)
    43 +
    44 +This file is free software; you can redistribute it and/or modify it
    45 +under the terms of the GNU General Public License as published by the
    46 +Free Software Foundation; either version 2, or (at your option) any
    47 +later version.
    48 +
    49 +In addition to the permissions in the GNU General Public License, the
    50 +Free Software Foundation gives you unlimited permission to link the
    51 +compiled version of this file with other programs, and to distribute
    52 +those programs without any restriction coming from the use of this
    53 +file.  (The General Public License restrictions do apply in other
    54 +respects; for example, they cover modification of the file, and
    55 +distribution when not linked into another program.)
    56 +
    57 +This file is distributed in the hope that it will be useful, but
    58 +WITHOUT ANY WARRANTY; without even the implied warranty of
    59 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    60 +General Public License for more details.
    61 +
    62 +You should have received a copy of the GNU General Public License
    63 +along with this program; see the file COPYING.  If not, write to
    64 +the Free Software Foundation, 59 Temple Place - Suite 330,
    65 +Boston, MA 02111-1307, USA.
    66 +
    67 +   As a special exception, if you link this library with files
    68 +   compiled with GCC to produce an executable, this does not cause
    69 +   the resulting executable to be covered by the GNU General Public License.
    70 +   This exception does not however invalidate any other reasons why
    71 +   the executable file might be covered by the GNU General Public License.
    72 +
    73 +
    74 +This file just make a stack frame for the contents of the .fini and
    75 +.init sections.  Users may put any desired instructions in those
    76 +sections.
    77 +
    78 +
    79 +While technically any code can be put in the init and fini sections
    80 +most stuff will not work other than stuff which obeys the call frame
    81 +and ABI. All the call-preserved registers are saved, the call clobbered
    82 +registers should have been saved by the code calling init and fini.
    83 +
    84 +See crtstuff.c for an example of code that inserts itself in the 
    85 +init and fini sections. 
    86 +
    87 +See crt0.s for the code that calls init and fini.
    88 +*/
    89 +
    90 +	.file	"crti.asm"
    91 +
    92 +	.section	".init"
    93 +	.align 2
    94 +	.global	_init
    95 +_init:
    96 +	addi	sp, sp, -48
    97 +	stw	ra, 44(sp)
    98 +	stw	r23, 40(sp)
    99 +	stw	r22, 36(sp)
   100 +	stw	r21, 32(sp)
   101 +	stw	r20, 28(sp)
   102 +	stw	r19, 24(sp)
   103 +	stw	r18, 20(sp)
   104 +	stw	r17, 16(sp)
   105 +	stw	r16, 12(sp)
   106 +	stw	fp, 8(sp)
   107 +	mov	fp, sp
   108 +	
   109 +	
   110 +	.section	".fini"
   111 +	.align	2
   112 +	.global	_fini
   113 +_fini:
   114 +	addi	sp, sp, -48
   115 +	stw	ra, 44(sp)
   116 +	stw	r23, 40(sp)
   117 +	stw	r22, 36(sp)
   118 +	stw	r21, 32(sp)
   119 +	stw	r20, 28(sp)
   120 +	stw	r19, 24(sp)
   121 +	stw	r18, 20(sp)
   122 +	stw	r17, 16(sp)
   123 +	stw	r16, 12(sp)
   124 +	stw	fp, 8(sp)
   125 +	mov	fp, sp
   126 +	
   127 +
   128 --- gcc-3.4.3/gcc/config/nios2/crtn.asm
   129 +++ gcc-3.4.3-nios2/gcc/config/nios2/crtn.asm
   130 @@ -0,0 +1,70 @@
   131 +/*
   132 +  Copyright (C) 2003 
   133 + by Jonah Graham (jgraham@altera.com)
   134 +
   135 +This file is free software; you can redistribute it and/or modify it
   136 +under the terms of the GNU General Public License as published by the
   137 +Free Software Foundation; either version 2, or (at your option) any
   138 +later version.
   139 +
   140 +In addition to the permissions in the GNU General Public License, the
   141 +Free Software Foundation gives you unlimited permission to link the
   142 +compiled version of this file with other programs, and to distribute
   143 +those programs without any restriction coming from the use of this
   144 +file.  (The General Public License restrictions do apply in other
   145 +respects; for example, they cover modification of the file, and
   146 +distribution when not linked into another program.)
   147 +
   148 +This file is distributed in the hope that it will be useful, but
   149 +WITHOUT ANY WARRANTY; without even the implied warranty of
   150 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   151 +General Public License for more details.
   152 +
   153 +You should have received a copy of the GNU General Public License
   154 +along with this program; see the file COPYING.  If not, write to
   155 +the Free Software Foundation, 59 Temple Place - Suite 330,
   156 +Boston, MA 02111-1307, USA.
   157 +
   158 +   As a special exception, if you link this library with files
   159 +   compiled with GCC to produce an executable, this does not cause
   160 +   the resulting executable to be covered by the GNU General Public License.
   161 +   This exception does not however invalidate any other reasons why
   162 +   the executable file might be covered by the GNU General Public License.
   163 +
   164 +
   165 +This file just makes sure that the .fini and .init sections do in
   166 +fact return.  Users may put any desired instructions in those sections.
   167 +This file is the last thing linked into any executable.
   168 +*/	
   169 +	.file	"crtn.asm"
   170 +
   171 +
   172 +
   173 +	.section	".init"
   174 +	ldw	ra, 44(sp)
   175 +	ldw	r23, 40(sp)
   176 +	ldw	r22, 36(sp)
   177 +	ldw	r21, 32(sp)
   178 +	ldw	r20, 28(sp)
   179 +	ldw	r19, 24(sp)
   180 +	ldw	r18, 20(sp)
   181 +	ldw	r17, 16(sp)
   182 +	ldw	r16, 12(sp)
   183 +	ldw	fp, 8(sp)
   184 +	addi	sp, sp, -48
   185 +	ret
   186 +	
   187 +	.section	".fini"
   188 +	ldw	ra, 44(sp)
   189 +	ldw	r23, 40(sp)
   190 +	ldw	r22, 36(sp)
   191 +	ldw	r21, 32(sp)
   192 +	ldw	r20, 28(sp)
   193 +	ldw	r19, 24(sp)
   194 +	ldw	r18, 20(sp)
   195 +	ldw	r17, 16(sp)
   196 +	ldw	r16, 12(sp)
   197 +	ldw	fp, 8(sp)
   198 +	addi	sp, sp, -48
   199 +	ret
   200 +	
   201 --- gcc-3.4.3/gcc/config/nios2/lib2-divmod-hi.c
   202 +++ gcc-3.4.3-nios2/gcc/config/nios2/lib2-divmod-hi.c
   203 @@ -0,0 +1,123 @@
   204 +
   205 +/* We include auto-host.h here to get HAVE_GAS_HIDDEN.  This is
   206 +   supposedly valid even though this is a "target" file.  */
   207 +#include "auto-host.h"
   208 +
   209 +
   210 +#include "tconfig.h"
   211 +#include "tsystem.h"
   212 +#include "coretypes.h"
   213 +#include "tm.h"
   214 +
   215 +
   216 +/* Don't use `fancy_abort' here even if config.h says to use it.  */
   217 +#ifdef abort
   218 +#undef abort
   219 +#endif
   220 +
   221 +
   222 +#ifdef HAVE_GAS_HIDDEN
   223 +#define ATTRIBUTE_HIDDEN  __attribute__ ((__visibility__ ("hidden")))
   224 +#else
   225 +#define ATTRIBUTE_HIDDEN
   226 +#endif
   227 +
   228 +#include "libgcc2.h"
   229 +
   230 +extern HItype __modhi3 (HItype, HItype);
   231 +extern HItype __divhi3 (HItype, HItype);
   232 +extern HItype __umodhi3 (HItype, HItype);
   233 +extern HItype __udivhi3 (HItype, HItype);
   234 +
   235 +static UHItype udivmodhi4(UHItype, UHItype, word_type);
   236 +
   237 +static UHItype
   238 +udivmodhi4(UHItype num, UHItype den, word_type modwanted)
   239 +{
   240 +  UHItype bit = 1;
   241 +  UHItype res = 0;
   242 +
   243 +  while (den < num && bit && !(den & (1L<<15)))
   244 +    {
   245 +      den <<=1;
   246 +      bit <<=1;
   247 +    }
   248 +  while (bit)
   249 +    {
   250 +      if (num >= den)
   251 +	{
   252 +	  num -= den;
   253 +	  res |= bit;
   254 +	}
   255 +      bit >>=1;
   256 +      den >>=1;
   257 +    }
   258 +  if (modwanted) return num;
   259 +  return res;
   260 +}
   261 +
   262 +
   263 +HItype
   264 +__divhi3 (HItype a, HItype b)
   265 +{
   266 +  word_type neg = 0;
   267 +  HItype res;
   268 +
   269 +  if (a < 0)
   270 +    {
   271 +      a = -a;
   272 +      neg = !neg;
   273 +    }
   274 +
   275 +  if (b < 0)
   276 +    {
   277 +      b = -b;
   278 +      neg = !neg;
   279 +    }
   280 +
   281 +  res = udivmodhi4 (a, b, 0);
   282 +
   283 +  if (neg)
   284 +    res = -res;
   285 +
   286 +  return res;
   287 +}
   288 +
   289 +
   290 +HItype
   291 +__modhi3 (HItype a, HItype b)
   292 +{
   293 +  word_type neg = 0;
   294 +  HItype res;
   295 +
   296 +  if (a < 0)
   297 +    {
   298 +      a = -a;
   299 +      neg = 1;
   300 +    }
   301 +
   302 +  if (b < 0)
   303 +    b = -b;
   304 +
   305 +  res = udivmodhi4 (a, b, 1);
   306 +
   307 +  if (neg)
   308 +    res = -res;
   309 +
   310 +  return res;
   311 +}
   312 +
   313 +
   314 +HItype
   315 +__udivhi3 (HItype a, HItype b)
   316 +{
   317 +  return udivmodhi4 (a, b, 0);
   318 +}
   319 +
   320 +
   321 +HItype
   322 +__umodhi3 (HItype a, HItype b)
   323 +{
   324 +  return udivmodhi4 (a, b, 1);
   325 +}
   326 +
   327 --- gcc-3.4.3/gcc/config/nios2/lib2-divmod.c
   328 +++ gcc-3.4.3-nios2/gcc/config/nios2/lib2-divmod.c
   329 @@ -0,0 +1,126 @@
   330 +
   331 +/* We include auto-host.h here to get HAVE_GAS_HIDDEN.  This is
   332 +   supposedly valid even though this is a "target" file.  */
   333 +#include "auto-host.h"
   334 +
   335 +
   336 +#include "tconfig.h"
   337 +#include "tsystem.h"
   338 +#include "coretypes.h"
   339 +#include "tm.h"
   340 +
   341 +
   342 +/* Don't use `fancy_abort' here even if config.h says to use it.  */
   343 +#ifdef abort
   344 +#undef abort
   345 +#endif
   346 +
   347 +
   348 +#ifdef HAVE_GAS_HIDDEN
   349 +#define ATTRIBUTE_HIDDEN  __attribute__ ((__visibility__ ("hidden")))
   350 +#else
   351 +#define ATTRIBUTE_HIDDEN
   352 +#endif
   353 +
   354 +#include "libgcc2.h"
   355 +
   356 +extern SItype __modsi3 (SItype, SItype);
   357 +extern SItype __divsi3 (SItype, SItype);
   358 +extern SItype __umodsi3 (SItype, SItype);
   359 +extern SItype __udivsi3 (SItype, SItype);
   360 +
   361 +static USItype udivmodsi4(USItype, USItype, word_type);
   362 +
   363 +/* 16-bit SI divide and modulo as used in NIOS */
   364 +
   365 +
   366 +static USItype
   367 +udivmodsi4(USItype num, USItype den, word_type modwanted)
   368 +{
   369 +  USItype bit = 1;
   370 +  USItype res = 0;
   371 +
   372 +  while (den < num && bit && !(den & (1L<<31)))
   373 +    {
   374 +      den <<=1;
   375 +      bit <<=1;
   376 +    }
   377 +  while (bit)
   378 +    {
   379 +      if (num >= den)
   380 +	{
   381 +	  num -= den;
   382 +	  res |= bit;
   383 +	}
   384 +      bit >>=1;
   385 +      den >>=1;
   386 +    }
   387 +  if (modwanted) return num;
   388 +  return res;
   389 +}
   390 +
   391 +
   392 +SItype
   393 +__divsi3 (SItype a, SItype b)
   394 +{
   395 +  word_type neg = 0;
   396 +  SItype res;
   397 +
   398 +  if (a < 0)
   399 +    {
   400 +      a = -a;
   401 +      neg = !neg;
   402 +    }
   403 +
   404 +  if (b < 0)
   405 +    {
   406 +      b = -b;
   407 +      neg = !neg;
   408 +    }
   409 +
   410 +  res = udivmodsi4 (a, b, 0);
   411 +
   412 +  if (neg)
   413 +    res = -res;
   414 +
   415 +  return res;
   416 +}
   417 +
   418 +
   419 +SItype
   420 +__modsi3 (SItype a, SItype b)
   421 +{
   422 +  word_type neg = 0;
   423 +  SItype res;
   424 +
   425 +  if (a < 0)
   426 +    {
   427 +      a = -a;
   428 +      neg = 1;
   429 +    }
   430 +
   431 +  if (b < 0)
   432 +    b = -b;
   433 +
   434 +  res = udivmodsi4 (a, b, 1);
   435 +
   436 +  if (neg)
   437 +    res = -res;
   438 +
   439 +  return res;
   440 +}
   441 +
   442 +
   443 +SItype
   444 +__udivsi3 (SItype a, SItype b)
   445 +{
   446 +  return udivmodsi4 (a, b, 0);
   447 +}
   448 +
   449 +
   450 +SItype
   451 +__umodsi3 (SItype a, SItype b)
   452 +{
   453 +  return udivmodsi4 (a, b, 1);
   454 +}
   455 +
   456 --- gcc-3.4.3/gcc/config/nios2/lib2-divtable.c
   457 +++ gcc-3.4.3-nios2/gcc/config/nios2/lib2-divtable.c
   458 @@ -0,0 +1,46 @@
   459 +
   460 +/* We include auto-host.h here to get HAVE_GAS_HIDDEN.  This is
   461 +   supposedly valid even though this is a "target" file.  */
   462 +#include "auto-host.h"
   463 +
   464 +
   465 +#include "tconfig.h"
   466 +#include "tsystem.h"
   467 +#include "coretypes.h"
   468 +#include "tm.h"
   469 +
   470 +
   471 +/* Don't use `fancy_abort' here even if config.h says to use it.  */
   472 +#ifdef abort
   473 +#undef abort
   474 +#endif
   475 +
   476 +
   477 +#ifdef HAVE_GAS_HIDDEN
   478 +#define ATTRIBUTE_HIDDEN  __attribute__ ((__visibility__ ("hidden")))
   479 +#else
   480 +#define ATTRIBUTE_HIDDEN
   481 +#endif
   482 +
   483 +#include "libgcc2.h"
   484 +
   485 +UQItype __divsi3_table[] =
   486 +{
   487 +  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,
   488 +  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,
   489 +  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,
   490 +  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,
   491 +  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,
   492 +  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,
   493 +  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,
   494 +  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,
   495 +  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,
   496 +  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,
   497 +  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,
   498 +  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,
   499 +  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,
   500 +  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,
   501 +  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,
   502 +  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,
   503 +};
   504 +
   505 --- gcc-3.4.3/gcc/config/nios2/lib2-mul.c
   506 +++ gcc-3.4.3-nios2/gcc/config/nios2/lib2-mul.c
   507 @@ -0,0 +1,103 @@
   508 +/* while we are debugging (ie compile outside of gcc build) 
   509 +   disable gcc specific headers */
   510 +#ifndef DEBUG_MULSI3
   511 +
   512 +
   513 +/* We include auto-host.h here to get HAVE_GAS_HIDDEN.  This is
   514 +   supposedly valid even though this is a "target" file.  */
   515 +#include "auto-host.h"
   516 +
   517 +
   518 +#include "tconfig.h"
   519 +#include "tsystem.h"
   520 +#include "coretypes.h"
   521 +#include "tm.h"
   522 +
   523 +
   524 +/* Don't use `fancy_abort' here even if config.h says to use it.  */
   525 +#ifdef abort
   526 +#undef abort
   527 +#endif
   528 +
   529 +
   530 +#ifdef HAVE_GAS_HIDDEN
   531 +#define ATTRIBUTE_HIDDEN  __attribute__ ((__visibility__ ("hidden")))
   532 +#else
   533 +#define ATTRIBUTE_HIDDEN
   534 +#endif
   535 +
   536 +#include "libgcc2.h"
   537 +
   538 +#else
   539 +#define SItype int
   540 +#define USItype unsigned int
   541 +#endif
   542 +
   543 +
   544 +extern SItype __mulsi3 (SItype, SItype);
   545 +
   546 +SItype
   547 +__mulsi3 (SItype a, SItype b)
   548 +{
   549 +  SItype res = 0;
   550 +  USItype cnt = a;
   551 +  
   552 +  while (cnt)
   553 +    {
   554 +      if (cnt & 1)
   555 +        {
   556 +	  res += b;	  
   557 +	}
   558 +      b <<= 1;
   559 +      cnt >>= 1;
   560 +    }
   561 +    
   562 +  return res;
   563 +}
   564 +/*
   565 +TODO: Choose best alternative implementation.
   566 +
   567 +SItype
   568 +__divsi3 (SItype a, SItype b)
   569 +{
   570 +  SItype res = 0;
   571 +  USItype cnt = 0;
   572 +  
   573 +  while (cnt < 32)
   574 +    {
   575 +      if (a & (1L << cnt))
   576 +        {
   577 +	  res += b;	  
   578 +	}
   579 +      b <<= 1;
   580 +      cnt++;
   581 +    }
   582 +    
   583 +  return res;
   584 +}
   585 +*/
   586 +
   587 +
   588 +#ifdef DEBUG_MULSI3
   589 +
   590 +int
   591 +main ()
   592 +{
   593 +  int i, j;
   594 +  int error = 0;
   595 +  
   596 +  for (i = -1000; i < 1000; i++)
   597 +    for (j = -1000; j < 1000; j++)
   598 +      {
   599 +	int expect = i * j;
   600 +	int actual = A__divsi3 (i, j);
   601 +	if (expect != actual)
   602 +	  {
   603 +	    printf ("error: %d * %d = %d not %d\n", i, j, expect, actual);
   604 +	    error = 1;
   605 +	  }
   606 +      }
   607 +
   608 +  return error;
   609 +}
   610 +#endif
   611 --- gcc-3.4.3/gcc/config/nios2/nios2-dp-bit.c
   612 +++ gcc-3.4.3-nios2/gcc/config/nios2/nios2-dp-bit.c
   613 @@ -0,0 +1,1652 @@
   614 +
   615 +/* This is a software floating point library which can be used
   616 +   for targets without hardware floating point. 
   617 +   Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004
   618 +   Free Software Foundation, Inc.
   619 +
   620 +This file is free software; you can redistribute it and/or modify it
   621 +under the terms of the GNU General Public License as published by the
   622 +Free Software Foundation; either version 2, or (at your option) any
   623 +later version.
   624 +
   625 +In addition to the permissions in the GNU General Public License, the
   626 +Free Software Foundation gives you unlimited permission to link the
   627 +compiled version of this file with other programs, and to distribute
   628 +those programs without any restriction coming from the use of this
   629 +file.  (The General Public License restrictions do apply in other
   630 +respects; for example, they cover modification of the file, and
   631 +distribution when not linked into another program.)
   632 +
   633 +This file is distributed in the hope that it will be useful, but
   634 +WITHOUT ANY WARRANTY; without even the implied warranty of
   635 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   636 +General Public License for more details.
   637 +
   638 +You should have received a copy of the GNU General Public License
   639 +along with this program; see the file COPYING.  If not, write to
   640 +the Free Software Foundation, 59 Temple Place - Suite 330,
   641 +Boston, MA 02111-1307, USA.  */
   642 +
   643 +/* As a special exception, if you link this library with other files,
   644 +   some of which are compiled with GCC, to produce an executable,
   645 +   this library does not by itself cause the resulting executable
   646 +   to be covered by the GNU General Public License.
   647 +   This exception does not however invalidate any other reasons why
   648 +   the executable file might be covered by the GNU General Public License.  */
   649 +
   650 +/* This implements IEEE 754 format arithmetic, but does not provide a
   651 +   mechanism for setting the rounding mode, or for generating or handling
   652 +   exceptions.
   653 +
   654 +   The original code by Steve Chamberlain, hacked by Mark Eichin and Jim
   655 +   Wilson, all of Cygnus Support.  */
   656 +
   657 +/* The intended way to use this file is to make two copies, add `#define FLOAT'
   658 +   to one copy, then compile both copies and add them to libgcc.a.  */
   659 +
   660 +#include "tconfig.h"
   661 +#include "coretypes.h"
   662 +#include "tm.h"
   663 +#include "config/fp-bit.h"
   664 +
   665 +/* The following macros can be defined to change the behavior of this file:
   666 +   FLOAT: Implement a `float', aka SFmode, fp library.  If this is not
   667 +     defined, then this file implements a `double', aka DFmode, fp library.
   668 +   FLOAT_ONLY: Used with FLOAT, to implement a `float' only library, i.e.
   669 +     don't include float->double conversion which requires the double library.
   670 +     This is useful only for machines which can't support doubles, e.g. some
   671 +     8-bit processors.
   672 +   CMPtype: Specify the type that floating point compares should return.
   673 +     This defaults to SItype, aka int.
   674 +   US_SOFTWARE_GOFAST: This makes all entry points use the same names as the
   675 +     US Software goFast library.
   676 +   _DEBUG_BITFLOAT: This makes debugging the code a little easier, by adding
   677 +     two integers to the FLO_union_type.
   678 +   NO_DENORMALS: Disable handling of denormals.
   679 +   NO_NANS: Disable nan and infinity handling
   680 +   SMALL_MACHINE: Useful when operations on QIs and HIs are faster
   681 +     than on an SI */
   682 +
   683 +/* We don't currently support extended floats (long doubles) on machines
   684 +   without hardware to deal with them.
   685 +
   686 +   These stubs are just to keep the linker from complaining about unresolved
   687 +   references which can be pulled in from libio & libstdc++, even if the
   688 +   user isn't using long doubles.  However, they may generate an unresolved
   689 +   external to abort if abort is not used by the function, and the stubs
   690 +   are referenced from within libc, since libgcc goes before and after the
   691 +   system library.  */
   692 +
   693 +#ifdef DECLARE_LIBRARY_RENAMES
   694 +  DECLARE_LIBRARY_RENAMES
   695 +#endif
   696 +
   697 +#ifdef EXTENDED_FLOAT_STUBS
   698 +extern void abort (void);
   699 +void __extendsfxf2 (void) { abort(); }
   700 +void __extenddfxf2 (void) { abort(); }
   701 +void __truncxfdf2 (void) { abort(); }
   702 +void __truncxfsf2 (void) { abort(); }
   703 +void __fixxfsi (void) { abort(); }
   704 +void __floatsixf (void) { abort(); }
   705 +void __addxf3 (void) { abort(); }
   706 +void __subxf3 (void) { abort(); }
   707 +void __mulxf3 (void) { abort(); }
   708 +void __divxf3 (void) { abort(); }
   709 +void __negxf2 (void) { abort(); }
   710 +void __eqxf2 (void) { abort(); }
   711 +void __nexf2 (void) { abort(); }
   712 +void __gtxf2 (void) { abort(); }
   713 +void __gexf2 (void) { abort(); }
   714 +void __lexf2 (void) { abort(); }
   715 +void __ltxf2 (void) { abort(); }
   716 +
   717 +void __extendsftf2 (void) { abort(); }
   718 +void __extenddftf2 (void) { abort(); }
   719 +void __trunctfdf2 (void) { abort(); }
   720 +void __trunctfsf2 (void) { abort(); }
   721 +void __fixtfsi (void) { abort(); }
   722 +void __floatsitf (void) { abort(); }
   723 +void __addtf3 (void) { abort(); }
   724 +void __subtf3 (void) { abort(); }
   725 +void __multf3 (void) { abort(); }
   726 +void __divtf3 (void) { abort(); }
   727 +void __negtf2 (void) { abort(); }
   728 +void __eqtf2 (void) { abort(); }
   729 +void __netf2 (void) { abort(); }
   730 +void __gttf2 (void) { abort(); }
   731 +void __getf2 (void) { abort(); }
   732 +void __letf2 (void) { abort(); }
   733 +void __lttf2 (void) { abort(); }
   734 +#else	/* !EXTENDED_FLOAT_STUBS, rest of file */
   735 +
   736 +/* IEEE "special" number predicates */
   737 +
   738 +#ifdef NO_NANS
   739 +
   740 +#define nan() 0
   741 +#define isnan(x) 0
   742 +#define isinf(x) 0
   743 +#else
   744 +
   745 +#if   defined L_thenan_sf
   746 +const fp_number_type __thenan_sf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
   747 +#elif defined L_thenan_df
   748 +const fp_number_type __thenan_df = { CLASS_SNAN, 0, 0, {(fractype) 0} };
   749 +#elif defined L_thenan_tf
   750 +const fp_number_type __thenan_tf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
   751 +#elif defined TFLOAT
   752 +extern const fp_number_type __thenan_tf;
   753 +#elif defined FLOAT
   754 +extern const fp_number_type __thenan_sf;
   755 +#else
   756 +extern const fp_number_type __thenan_df;
   757 +#endif
   758 +
   759 +INLINE
   760 +static fp_number_type *
   761 +nan (void)
   762 +{
   763 +  /* Discard the const qualifier...  */
   764 +#ifdef TFLOAT
   765 +  return (fp_number_type *) (& __thenan_tf);
   766 +#elif defined FLOAT  
   767 +  return (fp_number_type *) (& __thenan_sf);
   768 +#else
   769 +  return (fp_number_type *) (& __thenan_df);
   770 +#endif
   771 +}
   772 +
   773 +INLINE
   774 +static int
   775 +isnan ( fp_number_type *  x)
   776 +{
   777 +  return x->class == CLASS_SNAN || x->class == CLASS_QNAN;
   778 +}
   779 +
   780 +INLINE
   781 +static int
   782 +isinf ( fp_number_type *  x)
   783 +{
   784 +  return x->class == CLASS_INFINITY;
   785 +}
   786 +
   787 +#endif /* NO_NANS */
   788 +
   789 +INLINE
   790 +static int
   791 +iszero ( fp_number_type *  x)
   792 +{
   793 +  return x->class == CLASS_ZERO;
   794 +}
   795 +
   796 +INLINE 
   797 +static void
   798 +flip_sign ( fp_number_type *  x)
   799 +{
   800 +  x->sign = !x->sign;
   801 +}
   802 +
   803 +extern FLO_type pack_d ( fp_number_type * );
   804 +
   805 +#if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf)
   806 +FLO_type
   807 +pack_d ( fp_number_type *  src)
   808 +{
   809 +  FLO_union_type dst;
   810 +  fractype fraction = src->fraction.ll;	/* wasn't unsigned before? */
   811 +  int sign = src->sign;
   812 +  int exp = 0;
   813 +
   814 +  if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && (isnan (src) || isinf (src)))
   815 +    {
   816 +      /* We can't represent these values accurately.  By using the
   817 +	 largest possible magnitude, we guarantee that the conversion
   818 +	 of infinity is at least as big as any finite number.  */
   819 +      exp = EXPMAX;
   820 +      fraction = ((fractype) 1 << FRACBITS) - 1;
   821 +    }
   822 +  else if (isnan (src))
   823 +    {
   824 +      exp = EXPMAX;
   825 +      if (src->class == CLASS_QNAN || 1)
   826 +	{
   827 +#ifdef QUIET_NAN_NEGATED
   828 +	  fraction |= QUIET_NAN - 1;
   829 +#else
   830 +	  fraction |= QUIET_NAN;
   831 +#endif
   832 +	}
   833 +    }
   834 +  else if (isinf (src))
   835 +    {
   836 +      exp = EXPMAX;
   837 +      fraction = 0;
   838 +    }
   839 +  else if (iszero (src))
   840 +    {
   841 +      exp = 0;
   842 +      fraction = 0;
   843 +    }
   844 +  else if (fraction == 0)
   845 +    {
   846 +      exp = 0;
   847 +    }
   848 +  else
   849 +    {
   850 +      if (src->normal_exp < NORMAL_EXPMIN)
   851 +	{
   852 +#ifdef NO_DENORMALS
   853 +	  /* Go straight to a zero representation if denormals are not
   854 + 	     supported.  The denormal handling would be harmless but
   855 + 	     isn't unnecessary.  */
   856 +	  exp = 0;
   857 +	  fraction = 0;
   858 +#else /* NO_DENORMALS */
   859 +	  /* This number's exponent is too low to fit into the bits
   860 +	     available in the number, so we'll store 0 in the exponent and
   861 +	     shift the fraction to the right to make up for it.  */
   862 +
   863 +	  int shift = NORMAL_EXPMIN - src->normal_exp;
   864 +
   865 +	  exp = 0;
   866 +
   867 +	  if (shift > FRAC_NBITS - NGARDS)
   868 +	    {
   869 +	      /* No point shifting, since it's more that 64 out.  */
   870 +	      fraction = 0;
   871 +	    }
   872 +	  else
   873 +	    {
   874 +	      int lowbit = (fraction & (((fractype)1 << shift) - 1)) ? 1 : 0;
   875 +	      fraction = (fraction >> shift) | lowbit;
   876 +	    }
   877 +	  if ((fraction & GARDMASK) == GARDMSB)
   878 +	    {
   879 +	      if ((fraction & (1 << NGARDS)))
   880 +		fraction += GARDROUND + 1;
   881 +	    }
   882 +	  else
   883 +	    {
   884 +	      /* Add to the guards to round up.  */
   885 +	      fraction += GARDROUND;
   886 +	    }
   887 +	  /* Perhaps the rounding means we now need to change the
   888 +             exponent, because the fraction is no longer denormal.  */
   889 +	  if (fraction >= IMPLICIT_1)
   890 +	    {
   891 +	      exp += 1;
   892 +	    }
   893 +	  fraction >>= NGARDS;
   894 +#endif /* NO_DENORMALS */
   895 +	}
   896 +      else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS)
   897 +	       && src->normal_exp > EXPBIAS)
   898 +	{
   899 +	  exp = EXPMAX;
   900 +	  fraction = 0;
   901 +	}
   902 +      else
   903 +	{
   904 +	  exp = src->normal_exp + EXPBIAS;
   905 +	  if (!ROUND_TOWARDS_ZERO)
   906 +	    {
   907 +	      /* IF the gard bits are the all zero, but the first, then we're
   908 +		 half way between two numbers, choose the one which makes the
   909 +		 lsb of the answer 0.  */
   910 +	      if ((fraction & GARDMASK) == GARDMSB)
   911 +		{
   912 +		  if (fraction & (1 << NGARDS))
   913 +		    fraction += GARDROUND + 1;
   914 +		}
   915 +	      else
   916 +		{
   917 +		  /* Add a one to the guards to round up */
   918 +		  fraction += GARDROUND;
   919 +		}
   920 +	      if (fraction >= IMPLICIT_2)
   921 +		{
   922 +		  fraction >>= 1;
   923 +		  exp += 1;
   924 +		}
   925 +	    }
   926 +	  fraction >>= NGARDS;
   927 +
   928 +	  if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp > EXPMAX)
   929 +	    {
   930 +	      /* Saturate on overflow.  */
   931 +	      exp = EXPMAX;
   932 +	      fraction = ((fractype) 1 << FRACBITS) - 1;
   933 +	    }
   934 +	}
   935 +    }
   936 +
   937 +  /* We previously used bitfields to store the number, but this doesn't
   938 +     handle little/big endian systems conveniently, so use shifts and
   939 +     masks */
   940 +#ifdef FLOAT_BIT_ORDER_MISMATCH
   941 +  dst.bits.fraction = fraction;
   942 +  dst.bits.exp = exp;
   943 +  dst.bits.sign = sign;
   944 +#else
   945 +# if defined TFLOAT && defined HALFFRACBITS
   946 + {
   947 +   halffractype high, low, unity;
   948 +   int lowsign, lowexp;
   949 +
   950 +   unity = (halffractype) 1 << HALFFRACBITS;
   951 +
   952 +   /* Set HIGH to the high double's significand, masking out the implicit 1.
   953 +      Set LOW to the low double's full significand.  */
   954 +   high = (fraction >> (FRACBITS - HALFFRACBITS)) & (unity - 1);
   955 +   low = fraction & (unity * 2 - 1);
   956 +
   957 +   /* Get the initial sign and exponent of the low double.  */
   958 +   lowexp = exp - HALFFRACBITS - 1;
   959 +   lowsign = sign;
   960 +
   961 +   /* HIGH should be rounded like a normal double, making |LOW| <=
   962 +      0.5 ULP of HIGH.  Assume round-to-nearest.  */
   963 +   if (exp < EXPMAX)
   964 +     if (low > unity || (low == unity && (high & 1) == 1))
   965 +       {
   966 +	 /* Round HIGH up and adjust LOW to match.  */
   967 +	 high++;
   968 +	 if (high == unity)
   969 +	   {
   970 +	     /* May make it infinite, but that's OK.  */
   971 +	     high = 0;
   972 +	     exp++;
   973 +	   }
   974 +	 low = unity * 2 - low;
   975 +	 lowsign ^= 1;
   976 +       }
   977 +
   978 +   high |= (halffractype) exp << HALFFRACBITS;
   979 +   high |= (halffractype) sign << (HALFFRACBITS + EXPBITS);
   980 +
   981 +   if (exp == EXPMAX || exp == 0 || low == 0)
   982 +     low = 0;
   983 +   else
   984 +     {
   985 +       while (lowexp > 0 && low < unity)
   986 +	 {
   987 +	   low <<= 1;
   988 +	   lowexp--;
   989 +	 }
   990 +
   991 +       if (lowexp <= 0)
   992 +	 {
   993 +	   halffractype roundmsb, round;
   994 +	   int shift;
   995 +
   996 +	   shift = 1 - lowexp;
   997 +	   roundmsb = (1 << (shift - 1));
   998 +	   round = low & ((roundmsb << 1) - 1);
   999 +
  1000 +	   low >>= shift;
  1001 +	   lowexp = 0;
  1002 +
  1003 +	   if (round > roundmsb || (round == roundmsb && (low & 1) == 1))
  1004 +	     {
  1005 +	       low++;
  1006 +	       if (low == unity)
  1007 +		 /* LOW rounds up to the smallest normal number.  */
  1008 +		 lowexp++;
  1009 +	     }
  1010 +	 }
  1011 +
  1012 +       low &= unity - 1;
  1013 +       low |= (halffractype) lowexp << HALFFRACBITS;
  1014 +       low |= (halffractype) lowsign << (HALFFRACBITS + EXPBITS);
  1015 +     }
  1016 +   dst.value_raw = ((fractype) high << HALFSHIFT) | low;
  1017 + }
  1018 +# else
  1019 +  dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1);
  1020 +  dst.value_raw |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << FRACBITS;
  1021 +  dst.value_raw |= ((fractype) (sign & 1)) << (FRACBITS | EXPBITS);
  1022 +# endif
  1023 +#endif
  1024 +
  1025 +#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
  1026 +#ifdef TFLOAT
  1027 +  {
  1028 +    qrtrfractype tmp1 = dst.words[0];
  1029 +    qrtrfractype tmp2 = dst.words[1];
  1030 +    dst.words[0] = dst.words[3];
  1031 +    dst.words[1] = dst.words[2];
  1032 +    dst.words[2] = tmp2;
  1033 +    dst.words[3] = tmp1;
  1034 +  }
  1035 +#else
  1036 +  {
  1037 +    halffractype tmp = dst.words[0];
  1038 +    dst.words[0] = dst.words[1];
  1039 +    dst.words[1] = tmp;
  1040 +  }
  1041 +#endif
  1042 +#endif
  1043 +
  1044 +  return dst.value;
  1045 +}
  1046 +#endif
  1047 +
  1048 +#if defined(L_unpack_df) || defined(L_unpack_sf) || defined(L_unpack_tf)
  1049 +void
  1050 +unpack_d (FLO_union_type * src, fp_number_type * dst)
  1051 +{
  1052 +  /* We previously used bitfields to store the number, but this doesn't
  1053 +     handle little/big endian systems conveniently, so use shifts and
  1054 +     masks */
  1055 +  fractype fraction;
  1056 +  int exp;
  1057 +  int sign;
  1058 +
  1059 +#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
  1060 +  FLO_union_type swapped;
  1061 +
  1062 +#ifdef TFLOAT
  1063 +  swapped.words[0] = src->words[3];
  1064 +  swapped.words[1] = src->words[2];
  1065 +  swapped.words[2] = src->words[1];
  1066 +  swapped.words[3] = src->words[0];
  1067 +#else
  1068 +  swapped.words[0] = src->words[1];
  1069 +  swapped.words[1] = src->words[0];
  1070 +#endif
  1071 +  src = &swapped;
  1072 +#endif
  1073 +  
  1074 +#ifdef FLOAT_BIT_ORDER_MISMATCH
  1075 +  fraction = src->bits.fraction;
  1076 +  exp = src->bits.exp;
  1077 +  sign = src->bits.sign;
  1078 +#else
  1079 +# if defined TFLOAT && defined HALFFRACBITS
  1080 + {
  1081 +   halffractype high, low;
  1082 +   
  1083 +   high = src->value_raw >> HALFSHIFT;
  1084 +   low = src->value_raw & (((fractype)1 << HALFSHIFT) - 1);
  1085 +
  1086 +   fraction = high & ((((fractype)1) << HALFFRACBITS) - 1);
  1087 +   fraction <<= FRACBITS - HALFFRACBITS;
  1088 +   exp = ((int)(high >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
  1089 +   sign = ((int)(high >> (((HALFFRACBITS + EXPBITS))))) & 1;
  1090 +
  1091 +   if (exp != EXPMAX && exp != 0 && low != 0)
  1092 +     {
  1093 +       int lowexp = ((int)(low >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
  1094 +       int lowsign = ((int)(low >> (((HALFFRACBITS + EXPBITS))))) & 1;
  1095 +       int shift;
  1096 +       fractype xlow;
  1097 +
  1098 +       xlow = low & ((((fractype)1) << HALFFRACBITS) - 1);
  1099 +       if (lowexp)
  1100 +	 xlow |= (((halffractype)1) << HALFFRACBITS);
  1101 +       else
  1102 +	 lowexp = 1;
  1103 +       shift = (FRACBITS - HALFFRACBITS) - (exp - lowexp);
  1104 +       if (shift > 0)
  1105 +	 xlow <<= shift;
  1106 +       else if (shift < 0)
  1107 +	 xlow >>= -shift;
  1108 +       if (sign == lowsign)
  1109 +	 fraction += xlow;
  1110 +       else if (fraction >= xlow)
  1111 +	 fraction -= xlow;
  1112 +       else
  1113 +	 {
  1114 +	   /* The high part is a power of two but the full number is lower.
  1115 +	      This code will leave the implicit 1 in FRACTION, but we'd
  1116 +	      have added that below anyway.  */
  1117 +	   fraction = (((fractype) 1 << FRACBITS) - xlow) << 1;
  1118 +	   exp--;
  1119 +	 }
  1120 +     }
  1121 + }
  1122 +# else
  1123 +  fraction = src->value_raw & ((((fractype)1) << FRACBITS) - 1);
  1124 +  exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1);
  1125 +  sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1;
  1126 +# endif
  1127 +#endif
  1128 +
  1129 +  dst->sign = sign;
  1130 +  if (exp == 0)
  1131 +    {
  1132 +      /* Hmm.  Looks like 0 */
  1133 +      if (fraction == 0
  1134 +#ifdef NO_DENORMALS
  1135 +	  || 1
  1136 +#endif
  1137 +	  )
  1138 +	{
  1139 +	  /* tastes like zero */
  1140 +	  dst->class = CLASS_ZERO;
  1141 +	}
  1142 +      else
  1143 +	{
  1144 +	  /* Zero exponent with nonzero fraction - it's denormalized,
  1145 +	     so there isn't a leading implicit one - we'll shift it so
  1146 +	     it gets one.  */
  1147 +	  dst->normal_exp = exp - EXPBIAS + 1;
  1148 +	  fraction <<= NGARDS;
  1149 +
  1150 +	  dst->class = CLASS_NUMBER;
  1151 +#if 1
  1152 +	  while (fraction < IMPLICIT_1)
  1153 +	    {
  1154 +	      fraction <<= 1;
  1155 +	      dst->normal_exp--;
  1156 +	    }
  1157 +#endif
  1158 +	  dst->fraction.ll = fraction;
  1159 +	}
  1160 +    }
  1161 +  else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp == EXPMAX)
  1162 +    {
  1163 +      /* Huge exponent*/
  1164 +      if (fraction == 0)
  1165 +	{
  1166 +	  /* Attached to a zero fraction - means infinity */
  1167 +	  dst->class = CLASS_INFINITY;
  1168 +	}
  1169 +      else
  1170 +	{
  1171 +	  /* Nonzero fraction, means nan */
  1172 +#ifdef QUIET_NAN_NEGATED
  1173 +	  if ((fraction & QUIET_NAN) == 0)
  1174 +#else
  1175 +	  if (fraction & QUIET_NAN)
  1176 +#endif
  1177 +	    {
  1178 +	      dst->class = CLASS_QNAN;
  1179 +	    }
  1180 +	  else
  1181 +	    {
  1182 +	      dst->class = CLASS_SNAN;
  1183 +	    }
  1184 +	  /* Keep the fraction part as the nan number */
  1185 +	  dst->fraction.ll = fraction;
  1186 +	}
  1187 +    }
  1188 +  else
  1189 +    {
  1190 +      /* Nothing strange about this number */
  1191 +      dst->normal_exp = exp - EXPBIAS;
  1192 +      dst->class = CLASS_NUMBER;
  1193 +      dst->fraction.ll = (fraction << NGARDS) | IMPLICIT_1;
  1194 +    }
  1195 +}
  1196 +#endif /* L_unpack_df || L_unpack_sf */
  1197 +
  1198 +#if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf)
  1199 +static fp_number_type *
  1200 +_fpadd_parts (fp_number_type * a,
  1201 +	      fp_number_type * b,
  1202 +	      fp_number_type * tmp)
  1203 +{
  1204 +  intfrac tfraction;
  1205 +
  1206 +  /* Put commonly used fields in local variables.  */
  1207 +  int a_normal_exp;
  1208 +  int b_normal_exp;
  1209 +  fractype a_fraction;
  1210 +  fractype b_fraction;
  1211 +
  1212 +  if (isnan (a))
  1213 +    {
  1214 +      return a;
  1215 +    }
  1216 +  if (isnan (b))
  1217 +    {
  1218 +      return b;
  1219 +    }
  1220 +  if (isinf (a))
  1221 +    {
  1222 +      /* Adding infinities with opposite signs yields a NaN.  */
  1223 +      if (isinf (b) && a->sign != b->sign)
  1224 +	return nan ();
  1225 +      return a;
  1226 +    }
  1227 +  if (isinf (b))
  1228 +    {
  1229 +      return b;
  1230 +    }
  1231 +  if (iszero (b))
  1232 +    {
  1233 +      if (iszero (a))
  1234 +	{
  1235 +	  *tmp = *a;
  1236 +	  tmp->sign = a->sign & b->sign;
  1237 +	  return tmp;
  1238 +	}
  1239 +      return a;
  1240 +    }
  1241 +  if (iszero (a))
  1242 +    {
  1243 +      return b;
  1244 +    }
  1245 +
  1246 +  /* Got two numbers. shift the smaller and increment the exponent till
  1247 +     they're the same */
  1248 +  {
  1249 +    int diff;
  1250 +
  1251 +    a_normal_exp = a->normal_exp;
  1252 +    b_normal_exp = b->normal_exp;
  1253 +    a_fraction = a->fraction.ll;
  1254 +    b_fraction = b->fraction.ll;
  1255 +
  1256 +    diff = a_normal_exp - b_normal_exp;
  1257 +
  1258 +    if (diff < 0)
  1259 +      diff = -diff;
  1260 +    if (diff < FRAC_NBITS)
  1261 +      {
  1262 +	/* ??? This does shifts one bit at a time.  Optimize.  */
  1263 +	while (a_normal_exp > b_normal_exp)
  1264 +	  {
  1265 +	    b_normal_exp++;
  1266 +	    LSHIFT (b_fraction);
  1267 +	  }
  1268 +	while (b_normal_exp > a_normal_exp)
  1269 +	  {
  1270 +	    a_normal_exp++;
  1271 +	    LSHIFT (a_fraction);
  1272 +	  }
  1273 +      }
  1274 +    else
  1275 +      {
  1276 +	/* Somethings's up.. choose the biggest */
  1277 +	if (a_normal_exp > b_normal_exp)
  1278 +	  {
  1279 +	    b_normal_exp = a_normal_exp;
  1280 +	    b_fraction = 0;
  1281 +	  }
  1282 +	else
  1283 +	  {
  1284 +	    a_normal_exp = b_normal_exp;
  1285 +	    a_fraction = 0;
  1286 +	  }
  1287 +      }
  1288 +  }
  1289 +
  1290 +  if (a->sign != b->sign)
  1291 +    {
  1292 +      if (a->sign)
  1293 +	{
  1294 +	  tfraction = -a_fraction + b_fraction;
  1295 +	}
  1296 +      else
  1297 +	{
  1298 +	  tfraction = a_fraction - b_fraction;
  1299 +	}
  1300 +      if (tfraction >= 0)
  1301 +	{
  1302 +	  tmp->sign = 0;
  1303 +	  tmp->normal_exp = a_normal_exp;
  1304 +	  tmp->fraction.ll = tfraction;
  1305 +	}
  1306 +      else
  1307 +	{
  1308 +	  tmp->sign = 1;
  1309 +	  tmp->normal_exp = a_normal_exp;
  1310 +	  tmp->fraction.ll = -tfraction;
  1311 +	}
  1312 +      /* and renormalize it */
  1313 +
  1314 +      while (tmp->fraction.ll < IMPLICIT_1 && tmp->fraction.ll)
  1315 +	{
  1316 +	  tmp->fraction.ll <<= 1;
  1317 +	  tmp->normal_exp--;
  1318 +	}
  1319 +    }
  1320 +  else
  1321 +    {
  1322 +      tmp->sign = a->sign;
  1323 +      tmp->normal_exp = a_normal_exp;
  1324 +      tmp->fraction.ll = a_fraction + b_fraction;
  1325 +    }
  1326 +  tmp->class = CLASS_NUMBER;
  1327 +  /* Now the fraction is added, we have to shift down to renormalize the
  1328 +     number */
  1329 +
  1330 +  if (tmp->fraction.ll >= IMPLICIT_2)
  1331 +    {
  1332 +      LSHIFT (tmp->fraction.ll);
  1333 +      tmp->normal_exp++;
  1334 +    }
  1335 +  return tmp;
  1336 +
  1337 +}
  1338 +
  1339 +FLO_type
  1340 +add (FLO_type arg_a, FLO_type arg_b)
  1341 +{
  1342 +  fp_number_type a;
  1343 +  fp_number_type b;
  1344 +  fp_number_type tmp;
  1345 +  fp_number_type *res;
  1346 +  FLO_union_type au, bu;
  1347 +
  1348 +  au.value = arg_a;
  1349 +  bu.value = arg_b;
  1350 +
  1351 +  unpack_d (&au, &a);
  1352 +  unpack_d (&bu, &b);
  1353 +
  1354 +  res = _fpadd_parts (&a, &b, &tmp);
  1355 +
  1356 +  return pack_d (res);
  1357 +}
  1358 +
  1359 +FLO_type
  1360 +sub (FLO_type arg_a, FLO_type arg_b)
  1361 +{
  1362 +  fp_number_type a;
  1363 +  fp_number_type b;
  1364 +  fp_number_type tmp;
  1365 +  fp_number_type *res;
  1366 +  FLO_union_type au, bu;
  1367 +
  1368 +  au.value = arg_a;
  1369 +  bu.value = arg_b;
  1370 +
  1371 +  unpack_d (&au, &a);
  1372 +  unpack_d (&bu, &b);
  1373 +
  1374 +  b.sign ^= 1;
  1375 +
  1376 +  res = _fpadd_parts (&a, &b, &tmp);
  1377 +
  1378 +  return pack_d (res);
  1379 +}
  1380 +#endif /* L_addsub_sf || L_addsub_df */
  1381 +
  1382 +#if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf)
  1383 +static inline __attribute__ ((__always_inline__)) fp_number_type *
  1384 +_fpmul_parts ( fp_number_type *  a,
  1385 +	       fp_number_type *  b,
  1386 +	       fp_number_type * tmp)
  1387 +{
  1388 +  fractype low = 0;
  1389 +  fractype high = 0;
  1390 +
  1391 +  if (isnan (a))
  1392 +    {
  1393 +      a->sign = a->sign != b->sign;
  1394 +      return a;
  1395 +    }
  1396 +  if (isnan (b))
  1397 +    {
  1398 +      b->sign = a->sign != b->sign;
  1399 +      return b;
  1400 +    }
  1401 +  if (isinf (a))
  1402 +    {
  1403 +      if (iszero (b))
  1404 +	return nan ();
  1405 +      a->sign = a->sign != b->sign;
  1406 +      return a;
  1407 +    }
  1408 +  if (isinf (b))
  1409 +    {
  1410 +      if (iszero (a))
  1411 +	{
  1412 +	  return nan ();
  1413 +	}
  1414 +      b->sign = a->sign != b->sign;
  1415 +      return b;
  1416 +    }
  1417 +  if (iszero (a))
  1418 +    {
  1419 +      a->sign = a->sign != b->sign;
  1420 +      return a;
  1421 +    }
  1422 +  if (iszero (b))
  1423 +    {
  1424 +      b->sign = a->sign != b->sign;
  1425 +      return b;
  1426 +    }
  1427 +
  1428 +  /* Calculate the mantissa by multiplying both numbers to get a
  1429 +     twice-as-wide number.  */
  1430 +  {
  1431 +#if defined(NO_DI_MODE) || defined(TFLOAT)
  1432 +    {
  1433 +      fractype x = a->fraction.ll;
  1434 +      fractype ylow = b->fraction.ll;
  1435 +      fractype yhigh = 0;
  1436 +      int bit;
  1437 +
  1438 +      /* ??? This does multiplies one bit at a time.  Optimize.  */
  1439 +      for (bit = 0; bit < FRAC_NBITS; bit++)
  1440 +	{
  1441 +	  int carry;
  1442 +
  1443 +	  if (x & 1)
  1444 +	    {
  1445 +	      carry = (low += ylow) < ylow;
  1446 +	      high += yhigh + carry;
  1447 +	    }
  1448 +	  yhigh <<= 1;
  1449 +	  if (ylow & FRACHIGH)
  1450 +	    {
  1451 +	      yhigh |= 1;
  1452 +	    }
  1453 +	  ylow <<= 1;
  1454 +	  x >>= 1;
  1455 +	}
  1456 +    }
  1457 +#elif defined(FLOAT) 
  1458 +    /* Multiplying two USIs to get a UDI, we're safe.  */
  1459 +    {
  1460 +      UDItype answer = (UDItype)a->fraction.ll * (UDItype)b->fraction.ll;
  1461 +      
  1462 +      high = answer >> BITS_PER_SI;
  1463 +      low = answer;
  1464 +    }
  1465 +#else
  1466 +    /* fractype is DImode, but we need the result to be twice as wide.
  1467 +       Assuming a widening multiply from DImode to TImode is not
  1468 +       available, build one by hand.  */
  1469 +    {
  1470 +      USItype nl = a->fraction.ll;
  1471 +      USItype nh = a->fraction.ll >> BITS_PER_SI;
  1472 +      USItype ml = b->fraction.ll;
  1473 +      USItype mh = b->fraction.ll >> BITS_PER_SI;
  1474 +      UDItype pp_ll = (UDItype) ml * nl;
  1475 +      UDItype pp_hl = (UDItype) mh * nl;
  1476 +      UDItype pp_lh = (UDItype) ml * nh;
  1477 +      UDItype pp_hh = (UDItype) mh * nh;
  1478 +      UDItype res2 = 0;
  1479 +      UDItype res0 = 0;
  1480 +      UDItype ps_hh__ = pp_hl + pp_lh;
  1481 +      if (ps_hh__ < pp_hl)
  1482 +	res2 += (UDItype)1 << BITS_PER_SI;
  1483 +      pp_hl = (UDItype)(USItype)ps_hh__ << BITS_PER_SI;
  1484 +      res0 = pp_ll + pp_hl;
  1485 +      if (res0 < pp_ll)
  1486 +	res2++;
  1487 +      res2 += (ps_hh__ >> BITS_PER_SI) + pp_hh;
  1488 +      high = res2;
  1489 +      low = res0;
  1490 +    }
  1491 +#endif
  1492 +  }
  1493 +
  1494 +  tmp->normal_exp = a->normal_exp + b->normal_exp
  1495 +    + FRAC_NBITS - (FRACBITS + NGARDS);
  1496 +  tmp->sign = a->sign != b->sign;
  1497 +  while (high >= IMPLICIT_2)
  1498 +    {
  1499 +      tmp->normal_exp++;
  1500 +      if (high & 1)
  1501 +	{
  1502 +	  low >>= 1;
  1503 +	  low |= FRACHIGH;
  1504 +	}
  1505 +      high >>= 1;
  1506 +    }
  1507 +  while (high < IMPLICIT_1)
  1508 +    {
  1509 +      tmp->normal_exp--;
  1510 +
  1511 +      high <<= 1;
  1512 +      if (low & FRACHIGH)
  1513 +	high |= 1;
  1514 +      low <<= 1;
  1515 +    }
  1516 +  /* rounding is tricky. if we only round if it won't make us round later.  */
  1517 +#if 0
  1518 +  if (low & FRACHIGH2)
  1519 +    {
  1520 +      if (((high & GARDMASK) != GARDMSB)
  1521 +	  && (((high + 1) & GARDMASK) == GARDMSB))
  1522 +	{
  1523 +	  /* don't round, it gets done again later.  */
  1524 +	}
  1525 +      else
  1526 +	{
  1527 +	  high++;
  1528 +	}
  1529 +    }
  1530 +#endif
  1531 +  if (!ROUND_TOWARDS_ZERO && (high & GARDMASK) == GARDMSB)
  1532 +    {
  1533 +      if (high & (1 << NGARDS))
  1534 +	{
  1535 +	  /* half way, so round to even */
  1536 +	  high += GARDROUND + 1;
  1537 +	}
  1538 +      else if (low)
  1539 +	{
  1540 +	  /* but we really weren't half way */
  1541 +	  high += GARDROUND + 1;
  1542 +	}
  1543 +    }
  1544 +  tmp->fraction.ll = high;
  1545 +  tmp->class = CLASS_NUMBER;
  1546 +  return tmp;
  1547 +}
  1548 +
  1549 +FLO_type
  1550 +multiply (FLO_type arg_a, FLO_type arg_b)
  1551 +{
  1552 +  fp_number_type a;
  1553 +  fp_number_type b;
  1554 +  fp_number_type tmp;
  1555 +  fp_number_type *res;
  1556 +  FLO_union_type au, bu;
  1557 +
  1558 +  au.value = arg_a;
  1559 +  bu.value = arg_b;
  1560 +
  1561 +  unpack_d (&au, &a);
  1562 +  unpack_d (&bu, &b);
  1563 +
  1564 +  res = _fpmul_parts (&a, &b, &tmp);
  1565 +
  1566 +  return pack_d (res);
  1567 +}
  1568 +#endif /* L_mul_sf || L_mul_df */
  1569 +
  1570 +#if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf)
  1571 +static inline __attribute__ ((__always_inline__)) fp_number_type *
  1572 +_fpdiv_parts (fp_number_type * a,
  1573 +	      fp_number_type * b)
  1574 +{
  1575 +  fractype bit;
  1576 +  fractype numerator;
  1577 +  fractype denominator;
  1578 +  fractype quotient;
  1579 +
  1580 +  if (isnan (a))
  1581 +    {
  1582 +      return a;
  1583 +    }
  1584 +  if (isnan (b))
  1585 +    {
  1586 +      return b;
  1587 +    }
  1588 +
  1589 +  a->sign = a->sign ^ b->sign;
  1590 +
  1591 +  if (isinf (a) || iszero (a))
  1592 +    {
  1593 +      if (a->class == b->class)
  1594 +	return nan ();
  1595 +      return a;
  1596 +    }
  1597 +
  1598 +  if (isinf (b))
  1599 +    {
  1600 +      a->fraction.ll = 0;
  1601 +      a->normal_exp = 0;
  1602 +      return a;
  1603 +    }
  1604 +  if (iszero (b))
  1605 +    {
  1606 +      a->class = CLASS_INFINITY;
  1607 +      return a;
  1608 +    }
  1609 +
  1610 +  /* Calculate the mantissa by multiplying both 64bit numbers to get a
  1611 +     128 bit number */
  1612 +  {
  1613 +    /* quotient =
  1614 +       ( numerator / denominator) * 2^(numerator exponent -  denominator exponent)
  1615 +     */
  1616 +
  1617 +    a->normal_exp = a->normal_exp - b->normal_exp;
  1618 +    numerator = a->fraction.ll;
  1619 +    denominator = b->fraction.ll;
  1620 +
  1621 +    if (numerator < denominator)
  1622 +      {
  1623 +	/* Fraction will be less than 1.0 */
  1624 +	numerator *= 2;
  1625 +	a->normal_exp--;
  1626 +      }
  1627 +    bit = IMPLICIT_1;
  1628 +    quotient = 0;
  1629 +    /* ??? Does divide one bit at a time.  Optimize.  */
  1630 +    while (bit)
  1631 +      {
  1632 +	if (numerator >= denominator)
  1633 +	  {
  1634 +	    quotient |= bit;
  1635 +	    numerator -= denominator;
  1636 +	  }
  1637 +	bit >>= 1;
  1638 +	numerator *= 2;
  1639 +      }
  1640 +
  1641 +    if (!ROUND_TOWARDS_ZERO && (quotient & GARDMASK) == GARDMSB)
  1642 +      {
  1643 +	if (quotient & (1 << NGARDS))
  1644 +	  {
  1645 +	    /* half way, so round to even */
  1646 +	    quotient += GARDROUND + 1;
  1647 +	  }
  1648 +	else if (numerator)
  1649 +	  {
  1650 +	    /* but we really weren't half way, more bits exist */
  1651 +	    quotient += GARDROUND + 1;
  1652 +	  }
  1653 +      }
  1654 +
  1655 +    a->fraction.ll = quotient;
  1656 +    return (a);
  1657 +  }
  1658 +}
  1659 +
  1660 +FLO_type
  1661 +divide (FLO_type arg_a, FLO_type arg_b)
  1662 +{
  1663 +  fp_number_type a;
  1664 +  fp_number_type b;
  1665 +  fp_number_type *res;
  1666 +  FLO_union_type au, bu;
  1667 +
  1668 +  au.value = arg_a;
  1669 +  bu.value = arg_b;
  1670 +
  1671 +  unpack_d (&au, &a);
  1672 +  unpack_d (&bu, &b);
  1673 +
  1674 +  res = _fpdiv_parts (&a, &b);
  1675 +
  1676 +  return pack_d (res);
  1677 +}
  1678 +#endif /* L_div_sf || L_div_df */
  1679 +
  1680 +#if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) \
  1681 +    || defined(L_fpcmp_parts_tf)
  1682 +/* according to the demo, fpcmp returns a comparison with 0... thus
  1683 +   a<b -> -1
  1684 +   a==b -> 0
  1685 +   a>b -> +1
  1686 + */
  1687 +
  1688 +int
  1689 +__fpcmp_parts (fp_number_type * a, fp_number_type * b)
  1690 +{
  1691 +#if 0
  1692 +  /* either nan -> unordered. Must be checked outside of this routine.  */
  1693 +  if (isnan (a) && isnan (b))
  1694 +    {
  1695 +      return 1;			/* still unordered! */
  1696 +    }
  1697 +#endif
  1698 +
  1699 +  if (isnan (a) || isnan (b))
  1700 +    {
  1701 +      return 1;			/* how to indicate unordered compare? */
  1702 +    }
  1703 +  if (isinf (a) && isinf (b))
  1704 +    {
  1705 +      /* +inf > -inf, but +inf != +inf */
  1706 +      /* b    \a| +inf(0)| -inf(1)
  1707 +       ______\+--------+--------
  1708 +       +inf(0)| a==b(0)| a<b(-1)
  1709 +       -------+--------+--------
  1710 +       -inf(1)| a>b(1) | a==b(0)
  1711 +       -------+--------+--------
  1712 +       So since unordered must be nonzero, just line up the columns...
  1713 +       */
  1714 +      return b->sign - a->sign;
  1715 +    }
  1716 +  /* but not both...  */
  1717 +  if (isinf (a))
  1718 +    {
  1719 +      return a->sign ? -1 : 1;
  1720 +    }
  1721 +  if (isinf (b))
  1722 +    {
  1723 +      return b->sign ? 1 : -1;
  1724 +    }
  1725 +  if (iszero (a) && iszero (b))
  1726 +    {
  1727 +      return 0;
  1728 +    }
  1729 +  if (iszero (a))
  1730 +    {
  1731 +      return b->sign ? 1 : -1;
  1732 +    }
  1733 +  if (iszero (b))
  1734 +    {
  1735 +      return a->sign ? -1 : 1;
  1736 +    }
  1737 +  /* now both are "normal".  */
  1738 +  if (a->sign != b->sign)
  1739 +    {
  1740 +      /* opposite signs */
  1741 +      return a->sign ? -1 : 1;
  1742 +    }
  1743 +  /* same sign; exponents? */
  1744 +  if (a->normal_exp > b->normal_exp)
  1745 +    {
  1746 +      return a->sign ? -1 : 1;
  1747 +    }
  1748 +  if (a->normal_exp < b->normal_exp)
  1749 +    {
  1750 +      return a->sign ? 1 : -1;
  1751 +    }
  1752 +  /* same exponents; check size.  */
  1753 +  if (a->fraction.ll > b->fraction.ll)
  1754 +    {
  1755 +      return a->sign ? -1 : 1;
  1756 +    }
  1757 +  if (a->fraction.ll < b->fraction.ll)
  1758 +    {
  1759 +      return a->sign ? 1 : -1;
  1760 +    }
  1761 +  /* after all that, they're equal.  */
  1762 +  return 0;
  1763 +}
  1764 +#endif
  1765 +
  1766 +#if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compoare_tf)
  1767 +CMPtype
  1768 +compare (FLO_type arg_a, FLO_type arg_b)
  1769 +{
  1770 +  fp_number_type a;
  1771 +  fp_number_type b;
  1772 +  FLO_union_type au, bu;
  1773 +
  1774 +  au.value = arg_a;
  1775 +  bu.value = arg_b;
  1776 +
  1777 +  unpack_d (&au, &a);
  1778 +  unpack_d (&bu, &b);
  1779 +
  1780 +  return __fpcmp_parts (&a, &b);
  1781 +}
  1782 +#endif /* L_compare_sf || L_compare_df */
  1783 +
  1784 +#ifndef US_SOFTWARE_GOFAST
  1785 +
  1786 +/* These should be optimized for their specific tasks someday.  */
  1787 +
  1788 +#if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf)
  1789 +CMPtype
  1790 +_eq_f2 (FLO_type arg_a, FLO_type arg_b)
  1791 +{
  1792 +  fp_number_type a;
  1793 +  fp_number_type b;
  1794 +  FLO_union_type au, bu;
  1795 +
  1796 +  au.value = arg_a;
  1797 +  bu.value = arg_b;
  1798 +
  1799 +  unpack_d (&au, &a);
  1800 +  unpack_d (&bu, &b);
  1801 +
  1802 +  if (isnan (&a) || isnan (&b))
  1803 +    return 1;			/* false, truth == 0 */
  1804 +
  1805 +  return __fpcmp_parts (&a, &b) ;
  1806 +}
  1807 +#endif /* L_eq_sf || L_eq_df */
  1808 +
  1809 +#if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf)
  1810 +CMPtype
  1811 +_ne_f2 (FLO_type arg_a, FLO_type arg_b)
  1812 +{
  1813 +  fp_number_type a;
  1814 +  fp_number_type b;
  1815 +  FLO_union_type au, bu;
  1816 +
  1817 +  au.value = arg_a;
  1818 +  bu.value = arg_b;
  1819 +
  1820 +  unpack_d (&au, &a);
  1821 +  unpack_d (&bu, &b);
  1822 +
  1823 +  if (isnan (&a) || isnan (&b))
  1824 +    return 1;			/* true, truth != 0 */
  1825 +
  1826 +  return  __fpcmp_parts (&a, &b) ;
  1827 +}
  1828 +#endif /* L_ne_sf || L_ne_df */
  1829 +
  1830 +#if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf)
  1831 +CMPtype
  1832 +_gt_f2 (FLO_type arg_a, FLO_type arg_b)
  1833 +{
  1834 +  fp_number_type a;
  1835 +  fp_number_type b;
  1836 +  FLO_union_type au, bu;
  1837 +
  1838 +  au.value = arg_a;
  1839 +  bu.value = arg_b;
  1840 +
  1841 +  unpack_d (&au, &a);
  1842 +  unpack_d (&bu, &b);
  1843 +
  1844 +  if (isnan (&a) || isnan (&b))
  1845 +    return -1;			/* false, truth > 0 */
  1846 +
  1847 +  return __fpcmp_parts (&a, &b);
  1848 +}
  1849 +#endif /* L_gt_sf || L_gt_df */
  1850 +
  1851 +#if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf)
  1852 +CMPtype
  1853 +_ge_f2 (FLO_type arg_a, FLO_type arg_b)
  1854 +{
  1855 +  fp_number_type a;
  1856 +  fp_number_type b;
  1857 +  FLO_union_type au, bu;
  1858 +
  1859 +  au.value = arg_a;
  1860 +  bu.value = arg_b;
  1861 +
  1862 +  unpack_d (&au, &a);
  1863 +  unpack_d (&bu, &b);
  1864 +
  1865 +  if (isnan (&a) || isnan (&b))
  1866 +    return -1;			/* false, truth >= 0 */
  1867 +  return __fpcmp_parts (&a, &b) ;
  1868 +}
  1869 +#endif /* L_ge_sf || L_ge_df */
  1870 +
  1871 +#if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf)
  1872 +CMPtype
  1873 +_lt_f2 (FLO_type arg_a, FLO_type arg_b)
  1874 +{
  1875 +  fp_number_type a;
  1876 +  fp_number_type b;
  1877 +  FLO_union_type au, bu;
  1878 +
  1879 +  au.value = arg_a;
  1880 +  bu.value = arg_b;
  1881 +
  1882 +  unpack_d (&au, &a);
  1883 +  unpack_d (&bu, &b);
  1884 +
  1885 +  if (isnan (&a) || isnan (&b))
  1886 +    return 1;			/* false, truth < 0 */
  1887 +
  1888 +  return __fpcmp_parts (&a, &b);
  1889 +}
  1890 +#endif /* L_lt_sf || L_lt_df */
  1891 +
  1892 +#if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf)
  1893 +CMPtype
  1894 +_le_f2 (FLO_type arg_a, FLO_type arg_b)
  1895 +{
  1896 +  fp_number_type a;
  1897 +  fp_number_type b;
  1898 +  FLO_union_type au, bu;
  1899 +
  1900 +  au.value = arg_a;
  1901 +  bu.value = arg_b;
  1902 +
  1903 +  unpack_d (&au, &a);
  1904 +  unpack_d (&bu, &b);
  1905 +
  1906 +  if (isnan (&a) || isnan (&b))
  1907 +    return 1;			/* false, truth <= 0 */
  1908 +
  1909 +  return __fpcmp_parts (&a, &b) ;
  1910 +}
  1911 +#endif /* L_le_sf || L_le_df */
  1912 +
  1913 +#endif /* ! US_SOFTWARE_GOFAST */
  1914 +
  1915 +#if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf)
  1916 +CMPtype
  1917 +_unord_f2 (FLO_type arg_a, FLO_type arg_b)
  1918 +{
  1919 +  fp_number_type a;
  1920 +  fp_number_type b;
  1921 +  FLO_union_type au, bu;
  1922 +
  1923 +  au.value = arg_a;
  1924 +  bu.value = arg_b;
  1925 +
  1926 +  unpack_d (&au, &a);
  1927 +  unpack_d (&bu, &b);
  1928 +
  1929 +  return (isnan (&a) || isnan (&b));
  1930 +}
  1931 +#endif /* L_unord_sf || L_unord_df */
  1932 +
  1933 +#if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf)
  1934 +FLO_type
  1935 +si_to_float (SItype arg_a)
  1936 +{
  1937 +  fp_number_type in;
  1938 +
  1939 +  in.class = CLASS_NUMBER;
  1940 +  in.sign = arg_a < 0;
  1941 +  if (!arg_a)
  1942 +    {
  1943 +      in.class = CLASS_ZERO;
  1944 +    }
  1945 +  else
  1946 +    {
  1947 +      in.normal_exp = FRACBITS + NGARDS;
  1948 +      if (in.sign) 
  1949 +	{
  1950 +	  /* Special case for minint, since there is no +ve integer
  1951 +	     representation for it */
  1952 +	  if (arg_a == (- MAX_SI_INT - 1))
  1953 +	    {
  1954 +	      return (FLO_type)(- MAX_SI_INT - 1);
  1955 +	    }
  1956 +	  in.fraction.ll = (-arg_a);
  1957 +	}
  1958 +      else
  1959 +	in.fraction.ll = arg_a;
  1960 +
  1961 +      while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS)))
  1962 +	{
  1963 +	  in.fraction.ll <<= 1;
  1964 +	  in.normal_exp -= 1;
  1965 +	}
  1966 +    }
  1967 +  return pack_d (&in);
  1968 +}
  1969 +#endif /* L_si_to_sf || L_si_to_df */
  1970 +
  1971 +#if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf)
  1972 +FLO_type
  1973 +usi_to_float (USItype arg_a)
  1974 +{
  1975 +  fp_number_type in;
  1976 +
  1977 +  in.sign = 0;
  1978 +  if (!arg_a)
  1979 +    {
  1980 +      in.class = CLASS_ZERO;
  1981 +    }
  1982 +  else
  1983 +    {
  1984 +      in.class = CLASS_NUMBER;
  1985 +      in.normal_exp = FRACBITS + NGARDS;
  1986 +      in.fraction.ll = arg_a;
  1987 +
  1988 +      while (in.fraction.ll > ((fractype)1 << (FRACBITS + NGARDS)))
  1989 +        {
  1990 +          in.fraction.ll >>= 1;
  1991 +          in.normal_exp += 1;
  1992 +        }
  1993 +      while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS)))
  1994 +	{
  1995 +	  in.fraction.ll <<= 1;
  1996 +	  in.normal_exp -= 1;
  1997 +	}
  1998 +    }
  1999 +  return pack_d (&in);
  2000 +}
  2001 +#endif
  2002 +
  2003 +#if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si)
  2004 +SItype
  2005 +float_to_si (FLO_type arg_a)
  2006 +{
  2007 +  fp_number_type a;
  2008 +  SItype tmp;
  2009 +  FLO_union_type au;
  2010 +
  2011 +  au.value = arg_a;
  2012 +  unpack_d (&au, &a);
  2013 +
  2014 +  if (iszero (&a))
  2015 +    return 0;
  2016 +  if (isnan (&a))
  2017 +    return 0;
  2018 +  /* get reasonable MAX_SI_INT...  */
  2019 +  if (isinf (&a))
  2020 +    return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
  2021 +  /* it is a number, but a small one */
  2022 +  if (a.normal_exp < 0)
  2023 +    return 0;
  2024 +  if (a.normal_exp > BITS_PER_SI - 2)
  2025 +    return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
  2026 +  tmp = a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
  2027 +  return a.sign ? (-tmp) : (tmp);
  2028 +}
  2029 +#endif /* L_sf_to_si || L_df_to_si */
  2030 +
  2031 +#if defined(L_sf_to_usi) || defined(L_df_to_usi) || defined(L_tf_to_usi)
  2032 +#if defined US_SOFTWARE_GOFAST || defined(L_tf_to_usi)
  2033 +/* While libgcc2.c defines its own __fixunssfsi and __fixunsdfsi routines,
  2034 +   we also define them for GOFAST because the ones in libgcc2.c have the
  2035 +   wrong names and I'd rather define these here and keep GOFAST CYG-LOC's
  2036 +   out of libgcc2.c.  We can't define these here if not GOFAST because then
  2037 +   there'd be duplicate copies.  */
  2038 +
  2039 +USItype
  2040 +float_to_usi (FLO_type arg_a)
  2041 +{
  2042 +  fp_number_type a;
  2043 +  FLO_union_type au;
  2044 +
  2045 +  au.value = arg_a;
  2046 +  unpack_d (&au, &a);
  2047 +
  2048 +  if (iszero (&a))
  2049 +    return 0;
  2050 +  if (isnan (&a))
  2051 +    return 0;
  2052 +  /* it is a negative number */
  2053 +  if (a.sign)
  2054 +    return 0;
  2055 +  /* get reasonable MAX_USI_INT...  */
  2056 +  if (isinf (&a))
  2057 +    return MAX_USI_INT;
  2058 +  /* it is a number, but a small one */
  2059 +  if (a.normal_exp < 0)
  2060 +    return 0;
  2061 +  if (a.normal_exp > BITS_PER_SI - 1)
  2062 +    return MAX_USI_INT;
  2063 +  else if (a.normal_exp > (FRACBITS + NGARDS))
  2064 +    return a.fraction.ll << (a.normal_exp - (FRACBITS + NGARDS));
  2065 +  else
  2066 +    return a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
  2067 +}
  2068 +#endif /* US_SOFTWARE_GOFAST */
  2069 +#endif /* L_sf_to_usi || L_df_to_usi */
  2070 +
  2071 +#if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf)
  2072 +FLO_type
  2073 +negate (FLO_type arg_a)
  2074 +{
  2075 +  fp_number_type a;
  2076 +  FLO_union_type au;
  2077 +
  2078 +  au.value = arg_a;
  2079 +  unpack_d (&au, &a);
  2080 +
  2081 +  flip_sign (&a);
  2082 +  return pack_d (&a);
  2083 +}
  2084 +#endif /* L_negate_sf || L_negate_df */
  2085 +
  2086 +#ifdef FLOAT
  2087 +
  2088 +#if defined(L_make_sf)
  2089 +SFtype
  2090 +__make_fp(fp_class_type class,
  2091 +	     unsigned int sign,
  2092 +	     int exp, 
  2093 +	     USItype frac)
  2094 +{
  2095 +  fp_number_type in;
  2096 +
  2097 +  in.class = class;
  2098 +  in.sign = sign;
  2099 +  in.normal_exp = exp;
  2100 +  in.fraction.ll = frac;
  2101 +  return pack_d (&in);
  2102 +}
  2103 +#endif /* L_make_sf */
  2104 +
  2105 +#ifndef FLOAT_ONLY
  2106 +
  2107 +/* This enables one to build an fp library that supports float but not double.
  2108 +   Otherwise, we would get an undefined reference to __make_dp.
  2109 +   This is needed for some 8-bit ports that can't handle well values that
  2110 +   are 8-bytes in size, so we just don't support double for them at all.  */
  2111 +
  2112 +#if defined(L_sf_to_df)
  2113 +DFtype
  2114 +sf_to_df (SFtype arg_a)
  2115 +{
  2116 +  fp_number_type in;
  2117 +  FLO_union_type au;
  2118 +
  2119 +  au.value = arg_a;
  2120 +  unpack_d (&au, &in);
  2121 +
  2122 +  return __make_dp (in.class, in.sign, in.normal_exp,
  2123 +		    ((UDItype) in.fraction.ll) << F_D_BITOFF);
  2124 +}
  2125 +#endif /* L_sf_to_df */
  2126 +
  2127 +#if defined(L_sf_to_tf) && defined(TMODES)
  2128 +TFtype
  2129 +sf_to_tf (SFtype arg_a)
  2130 +{
  2131 +  fp_number_type in;
  2132 +  FLO_union_type au;
  2133 +
  2134 +  au.value = arg_a;
  2135 +  unpack_d (&au, &in);
  2136 +
  2137 +  return __make_tp (in.class, in.sign, in.normal_exp,
  2138 +		    ((UTItype) in.fraction.ll) << F_T_BITOFF);
  2139 +}
  2140 +#endif /* L_sf_to_df */
  2141 +
  2142 +#endif /* ! FLOAT_ONLY */
  2143 +#endif /* FLOAT */
  2144 +
  2145 +#ifndef FLOAT
  2146 +
  2147 +extern SFtype __make_fp (fp_class_type, unsigned int, int, USItype);
  2148 +
  2149 +#if defined(L_make_df)
  2150 +DFtype
  2151 +__make_dp (fp_class_type class, unsigned int sign, int exp, UDItype frac)
  2152 +{
  2153 +  fp_number_type in;
  2154 +
  2155 +  in.class = class;
  2156 +  in.sign = sign;
  2157 +  in.normal_exp = exp;
  2158 +  in.fraction.ll = frac;
  2159 +  return pack_d (&in);
  2160 +}
  2161 +#endif /* L_make_df */
  2162 +
  2163 +#if defined(L_df_to_sf)
  2164 +SFtype
  2165 +df_to_sf (DFtype arg_a)
  2166 +{
  2167 +  fp_number_type in;
  2168 +  USItype sffrac;
  2169 +  FLO_union_type au;
  2170 +
  2171 +  au.value = arg_a;
  2172 +  unpack_d (&au, &in);
  2173 +
  2174 +  sffrac = in.fraction.ll >> F_D_BITOFF;
  2175 +
  2176 +  /* We set the lowest guard bit in SFFRAC if we discarded any non
  2177 +     zero bits.  */
  2178 +  if ((in.fraction.ll & (((USItype) 1 << F_D_BITOFF) - 1)) != 0)
  2179 +    sffrac |= 1;
  2180 +
  2181 +  return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
  2182 +}
  2183 +#endif /* L_df_to_sf */
  2184 +
  2185 +#if defined(L_df_to_tf) && defined(TMODES) \
  2186 +    && !defined(FLOAT) && !defined(TFLOAT)
  2187 +TFtype
  2188 +df_to_tf (DFtype arg_a)
  2189 +{
  2190 +  fp_number_type in;
  2191 +  FLO_union_type au;
  2192 +
  2193 +  au.value = arg_a;
  2194 +  unpack_d (&au, &in);
  2195 +
  2196 +  return __make_tp (in.class, in.sign, in.normal_exp,
  2197 +		    ((UTItype) in.fraction.ll) << D_T_BITOFF);
  2198 +}
  2199 +#endif /* L_sf_to_df */
  2200 +
  2201 +#ifdef TFLOAT
  2202 +#if defined(L_make_tf)
  2203 +TFtype
  2204 +__make_tp(fp_class_type class,
  2205 +	     unsigned int sign,
  2206 +	     int exp, 
  2207 +	     UTItype frac)
  2208 +{
  2209 +  fp_number_type in;
  2210 +
  2211 +  in.class = class;
  2212 +  in.sign = sign;
  2213 +  in.normal_exp = exp;
  2214 +  in.fraction.ll = frac;
  2215 +  return pack_d (&in);
  2216 +}
  2217 +#endif /* L_make_tf */
  2218 +
  2219 +#if defined(L_tf_to_df)
  2220 +DFtype
  2221 +tf_to_df (TFtype arg_a)
  2222 +{
  2223 +  fp_number_type in;
  2224 +  UDItype sffrac;
  2225 +  FLO_union_type au;
  2226 +
  2227 +  au.value = arg_a;
  2228 +  unpack_d (&au, &in);
  2229 +
  2230 +  sffrac = in.fraction.ll >> D_T_BITOFF;
  2231 +
  2232 +  /* We set the lowest guard bit in SFFRAC if we discarded any non
  2233 +     zero bits.  */
  2234 +  if ((in.fraction.ll & (((UTItype) 1 << D_T_BITOFF) - 1)) != 0)
  2235 +    sffrac |= 1;
  2236 +
  2237 +  return __make_dp (in.class, in.sign, in.normal_exp, sffrac);
  2238 +}
  2239 +#endif /* L_tf_to_df */
  2240 +
  2241 +#if defined(L_tf_to_sf)
  2242 +SFtype
  2243 +tf_to_sf (TFtype arg_a)
  2244 +{
  2245 +  fp_number_type in;
  2246 +  USItype sffrac;
  2247 +  FLO_union_type au;
  2248 +
  2249 +  au.value = arg_a;
  2250 +  unpack_d (&au, &in);
  2251 +
  2252 +  sffrac = in.fraction.ll >> F_T_BITOFF;
  2253 +
  2254 +  /* We set the lowest guard bit in SFFRAC if we discarded any non
  2255 +     zero bits.  */
  2256 +  if ((in.fraction.ll & (((UTItype) 1 << F_T_BITOFF) - 1)) != 0)
  2257 +    sffrac |= 1;
  2258 +
  2259 +  return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
  2260 +}
  2261 +#endif /* L_tf_to_sf */
  2262 +#endif /* TFLOAT */
  2263 +
  2264 +#endif /* ! FLOAT */
  2265 +#endif /* !EXTENDED_FLOAT_STUBS */
  2266 --- gcc-3.4.3/gcc/config/nios2/nios2-fp-bit.c
  2267 +++ gcc-3.4.3-nios2/gcc/config/nios2/nios2-fp-bit.c
  2268 @@ -0,0 +1,1652 @@
  2269 +#define FLOAT
  2270 +/* This is a software floating point library which can be used
  2271 +   for targets without hardware floating point. 
  2272 +   Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004
  2273 +   Free Software Foundation, Inc.
  2274 +
  2275 +This file is free software; you can redistribute it and/or modify it
  2276 +under the terms of the GNU General Public License as published by the
  2277 +Free Software Foundation; either version 2, or (at your option) any
  2278 +later version.
  2279 +
  2280 +In addition to the permissions in the GNU General Public License, the
  2281 +Free Software Foundation gives you unlimited permission to link the
  2282 +compiled version of this file with other programs, and to distribute
  2283 +those programs without any restriction coming from the use of this
  2284 +file.  (The General Public License restrictions do apply in other
  2285 +respects; for example, they cover modification of the file, and
  2286 +distribution when not linked into another program.)
  2287 +
  2288 +This file is distributed in the hope that it will be useful, but
  2289 +WITHOUT ANY WARRANTY; without even the implied warranty of
  2290 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  2291 +General Public License for more details.
  2292 +
  2293 +You should have received a copy of the GNU General Public License
  2294 +along with this program; see the file COPYING.  If not, write to
  2295 +the Free Software Foundation, 59 Temple Place - Suite 330,
  2296 +Boston, MA 02111-1307, USA.  */
  2297 +
  2298 +/* As a special exception, if you link this library with other files,
  2299 +   some of which are compiled with GCC, to produce an executable,
  2300 +   this library does not by itself cause the resulting executable
  2301 +   to be covered by the GNU General Public License.
  2302 +   This exception does not however invalidate any other reasons why
  2303 +   the executable file might be covered by the GNU General Public License.  */
  2304 +
  2305 +/* This implements IEEE 754 format arithmetic, but does not provide a
  2306 +   mechanism for setting the rounding mode, or for generating or handling
  2307 +   exceptions.
  2308 +
  2309 +   The original code by Steve Chamberlain, hacked by Mark Eichin and Jim
  2310 +   Wilson, all of Cygnus Support.  */
  2311 +
  2312 +/* The intended way to use this file is to make two copies, add `#define FLOAT'
  2313 +   to one copy, then compile both copies and add them to libgcc.a.  */
  2314 +
  2315 +#include "tconfig.h"
  2316 +#include "coretypes.h"
  2317 +#include "tm.h"
  2318 +#include "config/fp-bit.h"
  2319 +
  2320 +/* The following macros can be defined to change the behavior of this file:
  2321 +   FLOAT: Implement a `float', aka SFmode, fp library.  If this is not
  2322 +     defined, then this file implements a `double', aka DFmode, fp library.
  2323 +   FLOAT_ONLY: Used with FLOAT, to implement a `float' only library, i.e.
  2324 +     don't include float->double conversion which requires the double library.
  2325 +     This is useful only for machines which can't support doubles, e.g. some
  2326 +     8-bit processors.
  2327 +   CMPtype: Specify the type that floating point compares should return.
  2328 +     This defaults to SItype, aka int.
  2329 +   US_SOFTWARE_GOFAST: This makes all entry points use the same names as the
  2330 +     US Software goFast library.
  2331 +   _DEBUG_BITFLOAT: This makes debugging the code a little easier, by adding
  2332 +     two integers to the FLO_union_type.
  2333 +   NO_DENORMALS: Disable handling of denormals.
  2334 +   NO_NANS: Disable nan and infinity handling
  2335 +   SMALL_MACHINE: Useful when operations on QIs and HIs are faster
  2336 +     than on an SI */
  2337 +
  2338 +/* We don't currently support extended floats (long doubles) on machines
  2339 +   without hardware to deal with them.
  2340 +
  2341 +   These stubs are just to keep the linker from complaining about unresolved
  2342 +   references which can be pulled in from libio & libstdc++, even if the
  2343 +   user isn't using long doubles.  However, they may generate an unresolved
  2344 +   external to abort if abort is not used by the function, and the stubs
  2345 +   are referenced from within libc, since libgcc goes before and after the
  2346 +   system library.  */
  2347 +
  2348 +#ifdef DECLARE_LIBRARY_RENAMES
  2349 +  DECLARE_LIBRARY_RENAMES
  2350 +#endif
  2351 +
  2352 +#ifdef EXTENDED_FLOAT_STUBS
  2353 +extern void abort (void);
  2354 +void __extendsfxf2 (void) { abort(); }
  2355 +void __extenddfxf2 (void) { abort(); }
  2356 +void __truncxfdf2 (void) { abort(); }
  2357 +void __truncxfsf2 (void) { abort(); }
  2358 +void __fixxfsi (void) { abort(); }
  2359 +void __floatsixf (void) { abort(); }
  2360 +void __addxf3 (void) { abort(); }
  2361 +void __subxf3 (void) { abort(); }
  2362 +void __mulxf3 (void) { abort(); }
  2363 +void __divxf3 (void) { abort(); }
  2364 +void __negxf2 (void) { abort(); }
  2365 +void __eqxf2 (void) { abort(); }
  2366 +void __nexf2 (void) { abort(); }
  2367 +void __gtxf2 (void) { abort(); }
  2368 +void __gexf2 (void) { abort(); }
  2369 +void __lexf2 (void) { abort(); }
  2370 +void __ltxf2 (void) { abort(); }
  2371 +
  2372 +void __extendsftf2 (void) { abort(); }
  2373 +void __extenddftf2 (void) { abort(); }
  2374 +void __trunctfdf2 (void) { abort(); }
  2375 +void __trunctfsf2 (void) { abort(); }
  2376 +void __fixtfsi (void) { abort(); }
  2377 +void __floatsitf (void) { abort(); }
  2378 +void __addtf3 (void) { abort(); }
  2379 +void __subtf3 (void) { abort(); }
  2380 +void __multf3 (void) { abort(); }
  2381 +void __divtf3 (void) { abort(); }
  2382 +void __negtf2 (void) { abort(); }
  2383 +void __eqtf2 (void) { abort(); }
  2384 +void __netf2 (void) { abort(); }
  2385 +void __gttf2 (void) { abort(); }
  2386 +void __getf2 (void) { abort(); }
  2387 +void __letf2 (void) { abort(); }
  2388 +void __lttf2 (void) { abort(); }
  2389 +#else	/* !EXTENDED_FLOAT_STUBS, rest of file */
  2390 +
  2391 +/* IEEE "special" number predicates */
  2392 +
  2393 +#ifdef NO_NANS
  2394 +
  2395 +#define nan() 0
  2396 +#define isnan(x) 0
  2397 +#define isinf(x) 0
  2398 +#else
  2399 +
  2400 +#if   defined L_thenan_sf
  2401 +const fp_number_type __thenan_sf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
  2402 +#elif defined L_thenan_df
  2403 +const fp_number_type __thenan_df = { CLASS_SNAN, 0, 0, {(fractype) 0} };
  2404 +#elif defined L_thenan_tf
  2405 +const fp_number_type __thenan_tf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
  2406 +#elif defined TFLOAT
  2407 +extern const fp_number_type __thenan_tf;
  2408 +#elif defined FLOAT
  2409 +extern const fp_number_type __thenan_sf;
  2410 +#else
  2411 +extern const fp_number_type __thenan_df;
  2412 +#endif
  2413 +
  2414 +INLINE
  2415 +static fp_number_type *
  2416 +nan (void)
  2417 +{
  2418 +  /* Discard the const qualifier...  */
  2419 +#ifdef TFLOAT
  2420 +  return (fp_number_type *) (& __thenan_tf);
  2421 +#elif defined FLOAT  
  2422 +  return (fp_number_type *) (& __thenan_sf);
  2423 +#else
  2424 +  return (fp_number_type *) (& __thenan_df);
  2425 +#endif
  2426 +}
  2427 +
  2428 +INLINE
  2429 +static int
  2430 +isnan ( fp_number_type *  x)
  2431 +{
  2432 +  return x->class == CLASS_SNAN || x->class == CLASS_QNAN;
  2433 +}
  2434 +
  2435 +INLINE
  2436 +static int
  2437 +isinf ( fp_number_type *  x)
  2438 +{
  2439 +  return x->class == CLASS_INFINITY;
  2440 +}
  2441 +
  2442 +#endif /* NO_NANS */
  2443 +
  2444 +INLINE
  2445 +static int
  2446 +iszero ( fp_number_type *  x)
  2447 +{
  2448 +  return x->class == CLASS_ZERO;
  2449 +}
  2450 +
  2451 +INLINE 
  2452 +static void
  2453 +flip_sign ( fp_number_type *  x)
  2454 +{
  2455 +  x->sign = !x->sign;
  2456 +}
  2457 +
  2458 +extern FLO_type pack_d ( fp_number_type * );
  2459 +
  2460 +#if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf)
  2461 +FLO_type
  2462 +pack_d ( fp_number_type *  src)
  2463 +{
  2464 +  FLO_union_type dst;
  2465 +  fractype fraction = src->fraction.ll;	/* wasn't unsigned before? */
  2466 +  int sign = src->sign;
  2467 +  int exp = 0;
  2468 +
  2469 +  if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && (isnan (src) || isinf (src)))
  2470 +    {
  2471 +      /* We can't represent these values accurately.  By using the
  2472 +	 largest possible magnitude, we guarantee that the conversion
  2473 +	 of infinity is at least as big as any finite number.  */
  2474 +      exp = EXPMAX;
  2475 +      fraction = ((fractype) 1 << FRACBITS) - 1;
  2476 +    }
  2477 +  else if (isnan (src))
  2478 +    {
  2479 +      exp = EXPMAX;
  2480 +      if (src->class == CLASS_QNAN || 1)
  2481 +	{
  2482 +#ifdef QUIET_NAN_NEGATED
  2483 +	  fraction |= QUIET_NAN - 1;
  2484 +#else
  2485 +	  fraction |= QUIET_NAN;
  2486 +#endif
  2487 +	}
  2488 +    }
  2489 +  else if (isinf (src))
  2490 +    {
  2491 +      exp = EXPMAX;
  2492 +      fraction = 0;
  2493 +    }
  2494 +  else if (iszero (src))
  2495 +    {
  2496 +      exp = 0;
  2497 +      fraction = 0;
  2498 +    }
  2499 +  else if (fraction == 0)
  2500 +    {
  2501 +      exp = 0;
  2502 +    }
  2503 +  else
  2504 +    {
  2505 +      if (src->normal_exp < NORMAL_EXPMIN)
  2506 +	{
  2507 +#ifdef NO_DENORMALS
  2508 +	  /* Go straight to a zero representation if denormals are not
  2509 + 	     supported.  The denormal handling would be harmless but
  2510 + 	     isn't unnecessary.  */
  2511 +	  exp = 0;
  2512 +	  fraction = 0;
  2513 +#else /* NO_DENORMALS */
  2514 +	  /* This number's exponent is too low to fit into the bits
  2515 +	     available in the number, so we'll store 0 in the exponent and
  2516 +	     shift the fraction to the right to make up for it.  */
  2517 +
  2518 +	  int shift = NORMAL_EXPMIN - src->normal_exp;
  2519 +
  2520 +	  exp = 0;
  2521 +
  2522 +	  if (shift > FRAC_NBITS - NGARDS)
  2523 +	    {
  2524 +	      /* No point shifting, since it's more that 64 out.  */
  2525 +	      fraction = 0;
  2526 +	    }
  2527 +	  else
  2528 +	    {
  2529 +	      int lowbit = (fraction & (((fractype)1 << shift) - 1)) ? 1 : 0;
  2530 +	      fraction = (fraction >> shift) | lowbit;
  2531 +	    }
  2532 +	  if ((fraction & GARDMASK) == GARDMSB)
  2533 +	    {
  2534 +	      if ((fraction & (1 << NGARDS)))
  2535 +		fraction += GARDROUND + 1;
  2536 +	    }
  2537 +	  else
  2538 +	    {
  2539 +	      /* Add to the guards to round up.  */
  2540 +	      fraction += GARDROUND;
  2541 +	    }
  2542 +	  /* Perhaps the rounding means we now need to change the
  2543 +             exponent, because the fraction is no longer denormal.  */
  2544 +	  if (fraction >= IMPLICIT_1)
  2545 +	    {
  2546 +	      exp += 1;
  2547 +	    }
  2548 +	  fraction >>= NGARDS;
  2549 +#endif /* NO_DENORMALS */
  2550 +	}
  2551 +      else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS)
  2552 +	       && src->normal_exp > EXPBIAS)
  2553 +	{
  2554 +	  exp = EXPMAX;
  2555 +	  fraction = 0;
  2556 +	}
  2557 +      else
  2558 +	{
  2559 +	  exp = src->normal_exp + EXPBIAS;
  2560 +	  if (!ROUND_TOWARDS_ZERO)
  2561 +	    {
  2562 +	      /* IF the gard bits are the all zero, but the first, then we're
  2563 +		 half way between two numbers, choose the one which makes the
  2564 +		 lsb of the answer 0.  */
  2565 +	      if ((fraction & GARDMASK) == GARDMSB)
  2566 +		{
  2567 +		  if (fraction & (1 << NGARDS))
  2568 +		    fraction += GARDROUND + 1;
  2569 +		}
  2570 +	      else
  2571 +		{
  2572 +		  /* Add a one to the guards to round up */
  2573 +		  fraction += GARDROUND;
  2574 +		}
  2575 +	      if (fraction >= IMPLICIT_2)
  2576 +		{
  2577 +		  fraction >>= 1;
  2578 +		  exp += 1;
  2579 +		}
  2580 +	    }
  2581 +	  fraction >>= NGARDS;
  2582 +
  2583 +	  if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp > EXPMAX)
  2584 +	    {
  2585 +	      /* Saturate on overflow.  */
  2586 +	      exp = EXPMAX;
  2587 +	      fraction = ((fractype) 1 << FRACBITS) - 1;
  2588 +	    }
  2589 +	}
  2590 +    }
  2591 +
  2592 +  /* We previously used bitfields to store the number, but this doesn't
  2593 +     handle little/big endian systems conveniently, so use shifts and
  2594 +     masks */
  2595 +#ifdef FLOAT_BIT_ORDER_MISMATCH
  2596 +  dst.bits.fraction = fraction;
  2597 +  dst.bits.exp = exp;
  2598 +  dst.bits.sign = sign;
  2599 +#else
  2600 +# if defined TFLOAT && defined HALFFRACBITS
  2601 + {
  2602 +   halffractype high, low, unity;
  2603 +   int lowsign, lowexp;
  2604 +
  2605 +   unity = (halffractype) 1 << HALFFRACBITS;
  2606 +
  2607 +   /* Set HIGH to the high double's significand, masking out the implicit 1.
  2608 +      Set LOW to the low double's full significand.  */
  2609 +   high = (fraction >> (FRACBITS - HALFFRACBITS)) & (unity - 1);
  2610 +   low = fraction & (unity * 2 - 1);
  2611 +
  2612 +   /* Get the initial sign and exponent of the low double.  */
  2613 +   lowexp = exp - HALFFRACBITS - 1;
  2614 +   lowsign = sign;
  2615 +
  2616 +   /* HIGH should be rounded like a normal double, making |LOW| <=
  2617 +      0.5 ULP of HIGH.  Assume round-to-nearest.  */
  2618 +   if (exp < EXPMAX)
  2619 +     if (low > unity || (low == unity && (high & 1) == 1))
  2620 +       {
  2621 +	 /* Round HIGH up and adjust LOW to match.  */
  2622 +	 high++;
  2623 +	 if (high == unity)
  2624 +	   {
  2625 +	     /* May make it infinite, but that's OK.  */
  2626 +	     high = 0;
  2627 +	     exp++;
  2628 +	   }
  2629 +	 low = unity * 2 - low;
  2630 +	 lowsign ^= 1;
  2631 +       }
  2632 +
  2633 +   high |= (halffractype) exp << HALFFRACBITS;
  2634 +   high |= (halffractype) sign << (HALFFRACBITS + EXPBITS);
  2635 +
  2636 +   if (exp == EXPMAX || exp == 0 || low == 0)
  2637 +     low = 0;
  2638 +   else
  2639 +     {
  2640 +       while (lowexp > 0 && low < unity)
  2641 +	 {
  2642 +	   low <<= 1;
  2643 +	   lowexp--;
  2644 +	 }
  2645 +
  2646 +       if (lowexp <= 0)
  2647 +	 {
  2648 +	   halffractype roundmsb, round;
  2649 +	   int shift;
  2650 +
  2651 +	   shift = 1 - lowexp;
  2652 +	   roundmsb = (1 << (shift - 1));
  2653 +	   round = low & ((roundmsb << 1) - 1);
  2654 +
  2655 +	   low >>= shift;
  2656 +	   lowexp = 0;
  2657 +
  2658 +	   if (round > roundmsb || (round == roundmsb && (low & 1) == 1))
  2659 +	     {
  2660 +	       low++;
  2661 +	       if (low == unity)
  2662 +		 /* LOW rounds up to the smallest normal number.  */
  2663 +		 lowexp++;
  2664 +	     }
  2665 +	 }
  2666 +
  2667 +       low &= unity - 1;
  2668 +       low |= (halffractype) lowexp << HALFFRACBITS;
  2669 +       low |= (halffractype) lowsign << (HALFFRACBITS + EXPBITS);
  2670 +     }
  2671 +   dst.value_raw = ((fractype) high << HALFSHIFT) | low;
  2672 + }
  2673 +# else
  2674 +  dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1);
  2675 +  dst.value_raw |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << FRACBITS;
  2676 +  dst.value_raw |= ((fractype) (sign & 1)) << (FRACBITS | EXPBITS);
  2677 +# endif
  2678 +#endif
  2679 +
  2680 +#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
  2681 +#ifdef TFLOAT
  2682 +  {
  2683 +    qrtrfractype tmp1 = dst.words[0];
  2684 +    qrtrfractype tmp2 = dst.words[1];
  2685 +    dst.words[0] = dst.words[3];
  2686 +    dst.words[1] = dst.words[2];
  2687 +    dst.words[2] = tmp2;
  2688 +    dst.words[3] = tmp1;
  2689 +  }
  2690 +#else
  2691 +  {
  2692 +    halffractype tmp = dst.words[0];
  2693 +    dst.words[0] = dst.words[1];
  2694 +    dst.words[1] = tmp;
  2695 +  }
  2696 +#endif
  2697 +#endif
  2698 +
  2699 +  return dst.value;
  2700 +}
  2701 +#endif
  2702 +
  2703 +#if defined(L_unpack_df) || defined(L_unpack_sf) || defined(L_unpack_tf)
  2704 +void
  2705 +unpack_d (FLO_union_type * src, fp_number_type * dst)
  2706 +{
  2707 +  /* We previously used bitfields to store the number, but this doesn't
  2708 +     handle little/big endian systems conveniently, so use shifts and
  2709 +     masks */
  2710 +  fractype fraction;
  2711 +  int exp;
  2712 +  int sign;
  2713 +
  2714 +#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
  2715 +  FLO_union_type swapped;
  2716 +
  2717 +#ifdef TFLOAT
  2718 +  swapped.words[0] = src->words[3];
  2719 +  swapped.words[1] = src->words[2];
  2720 +  swapped.words[2] = src->words[1];
  2721 +  swapped.words[3] = src->words[0];
  2722 +#else
  2723 +  swapped.words[0] = src->words[1];
  2724 +  swapped.words[1] = src->words[0];
  2725 +#endif
  2726 +  src = &swapped;
  2727 +#endif
  2728 +  
  2729 +#ifdef FLOAT_BIT_ORDER_MISMATCH
  2730 +  fraction = src->bits.fraction;
  2731 +  exp = src->bits.exp;
  2732 +  sign = src->bits.sign;
  2733 +#else
  2734 +# if defined TFLOAT && defined HALFFRACBITS
  2735 + {
  2736 +   halffractype high, low;
  2737 +   
  2738 +   high = src->value_raw >> HALFSHIFT;
  2739 +   low = src->value_raw & (((fractype)1 << HALFSHIFT) - 1);
  2740 +
  2741 +   fraction = high & ((((fractype)1) << HALFFRACBITS) - 1);
  2742 +   fraction <<= FRACBITS - HALFFRACBITS;
  2743 +   exp = ((int)(high >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
  2744 +   sign = ((int)(high >> (((HALFFRACBITS + EXPBITS))))) & 1;
  2745 +
  2746 +   if (exp != EXPMAX && exp != 0 && low != 0)
  2747 +     {
  2748 +       int lowexp = ((int)(low >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
  2749 +       int lowsign = ((int)(low >> (((HALFFRACBITS + EXPBITS))))) & 1;
  2750 +       int shift;
  2751 +       fractype xlow;
  2752 +
  2753 +       xlow = low & ((((fractype)1) << HALFFRACBITS) - 1);
  2754 +       if (lowexp)
  2755 +	 xlow |= (((halffractype)1) << HALFFRACBITS);
  2756 +       else
  2757 +	 lowexp = 1;
  2758 +       shift = (FRACBITS - HALFFRACBITS) - (exp - lowexp);
  2759 +       if (shift > 0)
  2760 +	 xlow <<= shift;
  2761 +       else if (shift < 0)
  2762 +	 xlow >>= -shift;
  2763 +       if (sign == lowsign)
  2764 +	 fraction += xlow;
  2765 +       else if (fraction >= xlow)
  2766 +	 fraction -= xlow;
  2767 +       else
  2768 +	 {
  2769 +	   /* The high part is a power of two but the full number is lower.
  2770 +	      This code will leave the implicit 1 in FRACTION, but we'd
  2771 +	      have added that below anyway.  */
  2772 +	   fraction = (((fractype) 1 << FRACBITS) - xlow) << 1;
  2773 +	   exp--;
  2774 +	 }
  2775 +     }
  2776 + }
  2777 +# else
  2778 +  fraction = src->value_raw & ((((fractype)1) << FRACBITS) - 1);
  2779 +  exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1);
  2780 +  sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1;
  2781 +# endif
  2782 +#endif
  2783 +
  2784 +  dst->sign = sign;
  2785 +  if (exp == 0)
  2786 +    {
  2787 +      /* Hmm.  Looks like 0 */
  2788 +      if (fraction == 0
  2789 +#ifdef NO_DENORMALS
  2790 +	  || 1
  2791 +#endif
  2792 +	  )
  2793 +	{
  2794 +	  /* tastes like zero */
  2795 +	  dst->class = CLASS_ZERO;
  2796 +	}
  2797 +      else
  2798 +	{
  2799 +	  /* Zero exponent with nonzero fraction - it's denormalized,
  2800 +	     so there isn't a leading implicit one - we'll shift it so
  2801 +	     it gets one.  */
  2802 +	  dst->normal_exp = exp - EXPBIAS + 1;
  2803 +	  fraction <<= NGARDS;
  2804 +
  2805 +	  dst->class = CLASS_NUMBER;
  2806 +#if 1
  2807 +	  while (fraction < IMPLICIT_1)
  2808 +	    {
  2809 +	      fraction <<= 1;
  2810 +	      dst->normal_exp--;
  2811 +	    }
  2812 +#endif
  2813 +	  dst->fraction.ll = fraction;
  2814 +	}
  2815 +    }
  2816 +  else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp == EXPMAX)
  2817 +    {
  2818 +      /* Huge exponent*/
  2819 +      if (fraction == 0)
  2820 +	{
  2821 +	  /* Attached to a zero fraction - means infinity */
  2822 +	  dst->class = CLASS_INFINITY;
  2823 +	}
  2824 +      else
  2825 +	{
  2826 +	  /* Nonzero fraction, means nan */
  2827 +#ifdef QUIET_NAN_NEGATED
  2828 +	  if ((fraction & QUIET_NAN) == 0)
  2829 +#else
  2830 +	  if (fraction & QUIET_NAN)
  2831 +#endif
  2832 +	    {
  2833 +	      dst->class = CLASS_QNAN;
  2834 +	    }
  2835 +	  else
  2836 +	    {
  2837 +	      dst->class = CLASS_SNAN;
  2838 +	    }
  2839 +	  /* Keep the fraction part as the nan number */
  2840 +	  dst->fraction.ll = fraction;
  2841 +	}
  2842 +    }
  2843 +  else
  2844 +    {
  2845 +      /* Nothing strange about this number */
  2846 +      dst->normal_exp = exp - EXPBIAS;
  2847 +      dst->class = CLASS_NUMBER;
  2848 +      dst->fraction.ll = (fraction << NGARDS) | IMPLICIT_1;
  2849 +    }
  2850 +}
  2851 +#endif /* L_unpack_df || L_unpack_sf */
  2852 +
  2853 +#if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf)
  2854 +static fp_number_type *
  2855 +_fpadd_parts (fp_number_type * a,
  2856 +	      fp_number_type * b,
  2857 +	      fp_number_type * tmp)
  2858 +{
  2859 +  intfrac tfraction;
  2860 +
  2861 +  /* Put commonly used fields in local variables.  */
  2862 +  int a_normal_exp;
  2863 +  int b_normal_exp;
  2864 +  fractype a_fraction;
  2865 +  fractype b_fraction;
  2866 +
  2867 +  if (isnan (a))
  2868 +    {
  2869 +      return a;
  2870 +    }
  2871 +  if (isnan (b))
  2872 +    {
  2873 +      return b;
  2874 +    }
  2875 +  if (isinf (a))
  2876 +    {
  2877 +      /* Adding infinities with opposite signs yields a NaN.  */
  2878 +      if (isinf (b) && a->sign != b->sign)
  2879 +	return nan ();
  2880 +      return a;
  2881 +    }
  2882 +  if (isinf (b))
  2883 +    {
  2884 +      return b;
  2885 +    }
  2886 +  if (iszero (b))
  2887 +    {
  2888 +      if (iszero (a))
  2889 +	{
  2890 +	  *tmp = *a;
  2891 +	  tmp->sign = a->sign & b->sign;
  2892 +	  return tmp;
  2893 +	}
  2894 +      return a;
  2895 +    }
  2896 +  if (iszero (a))
  2897 +    {
  2898 +      return b;
  2899 +    }
  2900 +
  2901 +  /* Got two numbers. shift the smaller and increment the exponent till
  2902 +     they're the same */
  2903 +  {
  2904 +    int diff;
  2905 +
  2906 +    a_normal_exp = a->normal_exp;
  2907 +    b_normal_exp = b->normal_exp;
  2908 +    a_fraction = a->fraction.ll;
  2909 +    b_fraction = b->fraction.ll;
  2910 +
  2911 +    diff = a_normal_exp - b_normal_exp;
  2912 +
  2913 +    if (diff < 0)
  2914 +      diff = -diff;
  2915 +    if (diff < FRAC_NBITS)
  2916 +      {
  2917 +	/* ??? This does shifts one bit at a time.  Optimize.  */
  2918 +	while (a_normal_exp > b_normal_exp)
  2919 +	  {
  2920 +	    b_normal_exp++;
  2921 +	    LSHIFT (b_fraction);
  2922 +	  }
  2923 +	while (b_normal_exp > a_normal_exp)
  2924 +	  {
  2925 +	    a_normal_exp++;
  2926 +	    LSHIFT (a_fraction);
  2927 +	  }
  2928 +      }
  2929 +    else
  2930 +      {
  2931 +	/* Somethings's up.. choose the biggest */
  2932 +	if (a_normal_exp > b_normal_exp)
  2933 +	  {
  2934 +	    b_normal_exp = a_normal_exp;
  2935 +	    b_fraction = 0;
  2936 +	  }
  2937 +	else
  2938 +	  {
  2939 +	    a_normal_exp = b_normal_exp;
  2940 +	    a_fraction = 0;
  2941 +	  }
  2942 +      }
  2943 +  }
  2944 +
  2945 +  if (a->sign != b->sign)
  2946 +    {
  2947 +      if (a->sign)
  2948 +	{
  2949 +	  tfraction = -a_fraction + b_fraction;
  2950 +	}
  2951 +      else
  2952 +	{
  2953 +	  tfraction = a_fraction - b_fraction;
  2954 +	}
  2955 +      if (tfraction >= 0)
  2956 +	{
  2957 +	  tmp->sign = 0;
  2958 +	  tmp->normal_exp = a_normal_exp;
  2959 +	  tmp->fraction.ll = tfraction;
  2960 +	}
  2961 +      else
  2962 +	{
  2963 +	  tmp->sign = 1;
  2964 +	  tmp->normal_exp = a_normal_exp;
  2965 +	  tmp->fraction.ll = -tfraction;
  2966 +	}
  2967 +      /* and renormalize it */
  2968 +
  2969 +      while (tmp->fraction.ll < IMPLICIT_1 && tmp->fraction.ll)
  2970 +	{
  2971 +	  tmp->fraction.ll <<= 1;
  2972 +	  tmp->normal_exp--;
  2973 +	}
  2974 +    }
  2975 +  else
  2976 +    {
  2977 +      tmp->sign = a->sign;
  2978 +      tmp->normal_exp = a_normal_exp;
  2979 +      tmp->fraction.ll = a_fraction + b_fraction;
  2980 +    }
  2981 +  tmp->class = CLASS_NUMBER;
  2982 +  /* Now the fraction is added, we have to shift down to renormalize the
  2983 +     number */
  2984 +
  2985 +  if (tmp->fraction.ll >= IMPLICIT_2)
  2986 +    {
  2987 +      LSHIFT (tmp->fraction.ll);
  2988 +      tmp->normal_exp++;
  2989 +    }
  2990 +  return tmp;
  2991 +
  2992 +}
  2993 +
  2994 +FLO_type
  2995 +add (FLO_type arg_a, FLO_type arg_b)
  2996 +{
  2997 +  fp_number_type a;
  2998 +  fp_number_type b;
  2999 +  fp_number_type tmp;
  3000 +  fp_number_type *res;
  3001 +  FLO_union_type au, bu;
  3002 +
  3003 +  au.value = arg_a;
  3004 +  bu.value = arg_b;
  3005 +
  3006 +  unpack_d (&au, &a);
  3007 +  unpack_d (&bu, &b);
  3008 +
  3009 +  res = _fpadd_parts (&a, &b, &tmp);
  3010 +
  3011 +  return pack_d (res);
  3012 +}
  3013 +
  3014 +FLO_type
  3015 +sub (FLO_type arg_a, FLO_type arg_b)
  3016 +{
  3017 +  fp_number_type a;
  3018 +  fp_number_type b;
  3019 +  fp_number_type tmp;
  3020 +  fp_number_type *res;
  3021 +  FLO_union_type au, bu;
  3022 +
  3023 +  au.value = arg_a;
  3024 +  bu.value = arg_b;
  3025 +
  3026 +  unpack_d (&au, &a);
  3027 +  unpack_d (&bu, &b);
  3028 +
  3029 +  b.sign ^= 1;
  3030 +
  3031 +  res = _fpadd_parts (&a, &b, &tmp);
  3032 +
  3033 +  return pack_d (res);
  3034 +}
  3035 +#endif /* L_addsub_sf || L_addsub_df */
  3036 +
  3037 +#if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf)
  3038 +static inline __attribute__ ((__always_inline__)) fp_number_type *
  3039 +_fpmul_parts ( fp_number_type *  a,
  3040 +	       fp_number_type *  b,
  3041 +	       fp_number_type * tmp)
  3042 +{
  3043 +  fractype low = 0;
  3044 +  fractype high = 0;
  3045 +
  3046 +  if (isnan (a))
  3047 +    {
  3048 +      a->sign = a->sign != b->sign;
  3049 +      return a;
  3050 +    }
  3051 +  if (isnan (b))
  3052 +    {
  3053 +      b->sign = a->sign != b->sign;
  3054 +      return b;
  3055 +    }
  3056 +  if (isinf (a))
  3057 +    {
  3058 +      if (iszero (b))
  3059 +	return nan ();
  3060 +      a->sign = a->sign != b->sign;
  3061 +      return a;
  3062 +    }
  3063 +  if (isinf (b))
  3064 +    {
  3065 +      if (iszero (a))
  3066 +	{
  3067 +	  return nan ();
  3068 +	}
  3069 +      b->sign = a->sign != b->sign;
  3070 +      return b;
  3071 +    }
  3072 +  if (iszero (a))
  3073 +    {
  3074 +      a->sign = a->sign != b->sign;
  3075 +      return a;
  3076 +    }
  3077 +  if (iszero (b))
  3078 +    {
  3079 +      b->sign = a->sign != b->sign;
  3080 +      return b;
  3081 +    }
  3082 +
  3083 +  /* Calculate the mantissa by multiplying both numbers to get a
  3084 +     twice-as-wide number.  */
  3085 +  {
  3086 +#if defined(NO_DI_MODE) || defined(TFLOAT)
  3087 +    {
  3088 +      fractype x = a->fraction.ll;
  3089 +      fractype ylow = b->fraction.ll;
  3090 +      fractype yhigh = 0;
  3091 +      int bit;
  3092 +
  3093 +      /* ??? This does multiplies one bit at a time.  Optimize.  */
  3094 +      for (bit = 0; bit < FRAC_NBITS; bit++)
  3095 +	{
  3096 +	  int carry;
  3097 +
  3098 +	  if (x & 1)
  3099 +	    {
  3100 +	      carry = (low += ylow) < ylow;
  3101 +	      high += yhigh + carry;
  3102 +	    }
  3103 +	  yhigh <<= 1;
  3104 +	  if (ylow & FRACHIGH)
  3105 +	    {
  3106 +	      yhigh |= 1;
  3107 +	    }
  3108 +	  ylow <<= 1;
  3109 +	  x >>= 1;
  3110 +	}
  3111 +    }
  3112 +#elif defined(FLOAT) 
  3113 +    /* Multiplying two USIs to get a UDI, we're safe.  */
  3114 +    {
  3115 +      UDItype answer = (UDItype)a->fraction.ll * (UDItype)b->fraction.ll;
  3116 +      
  3117 +      high = answer >> BITS_PER_SI;
  3118 +      low = answer;
  3119 +    }
  3120 +#else
  3121 +    /* fractype is DImode, but we need the result to be twice as wide.
  3122 +       Assuming a widening multiply from DImode to TImode is not
  3123 +       available, build one by hand.  */
  3124 +    {
  3125 +      USItype nl = a->fraction.ll;
  3126 +      USItype nh = a->fraction.ll >> BITS_PER_SI;
  3127 +      USItype ml = b->fraction.ll;
  3128 +      USItype mh = b->fraction.ll >> BITS_PER_SI;
  3129 +      UDItype pp_ll = (UDItype) ml * nl;
  3130 +      UDItype pp_hl = (UDItype) mh * nl;
  3131 +      UDItype pp_lh = (UDItype) ml * nh;
  3132 +      UDItype pp_hh = (UDItype) mh * nh;
  3133 +      UDItype res2 = 0;
  3134 +      UDItype res0 = 0;
  3135 +      UDItype ps_hh__ = pp_hl + pp_lh;
  3136 +      if (ps_hh__ < pp_hl)
  3137 +	res2 += (UDItype)1 << BITS_PER_SI;
  3138 +      pp_hl = (UDItype)(USItype)ps_hh__ << BITS_PER_SI;
  3139 +      res0 = pp_ll + pp_hl;
  3140 +      if (res0 < pp_ll)
  3141 +	res2++;
  3142 +      res2 += (ps_hh__ >> BITS_PER_SI) + pp_hh;
  3143 +      high = res2;
  3144 +      low = res0;
  3145 +    }
  3146 +#endif
  3147 +  }
  3148 +
  3149 +  tmp->normal_exp = a->normal_exp + b->normal_exp
  3150 +    + FRAC_NBITS - (FRACBITS + NGARDS);
  3151 +  tmp->sign = a->sign != b->sign;
  3152 +  while (high >= IMPLICIT_2)
  3153 +    {
  3154 +      tmp->normal_exp++;
  3155 +      if (high & 1)
  3156 +	{
  3157 +	  low >>= 1;
  3158 +	  low |= FRACHIGH;
  3159 +	}
  3160 +      high >>= 1;
  3161 +    }
  3162 +  while (high < IMPLICIT_1)
  3163 +    {
  3164 +      tmp->normal_exp--;
  3165 +
  3166 +      high <<= 1;
  3167 +      if (low & FRACHIGH)
  3168 +	high |= 1;
  3169 +      low <<= 1;
  3170 +    }
  3171 +  /* rounding is tricky. if we only round if it won't make us round later.  */
  3172 +#if 0
  3173 +  if (low & FRACHIGH2)
  3174 +    {
  3175 +      if (((high & GARDMASK) != GARDMSB)
  3176 +	  && (((high + 1) & GARDMASK) == GARDMSB))
  3177 +	{
  3178 +	  /* don't round, it gets done again later.  */
  3179 +	}
  3180 +      else
  3181 +	{
  3182 +	  high++;
  3183 +	}
  3184 +    }
  3185 +#endif
  3186 +  if (!ROUND_TOWARDS_ZERO && (high & GARDMASK) == GARDMSB)
  3187 +    {
  3188 +      if (high & (1 << NGARDS))
  3189 +	{
  3190 +	  /* half way, so round to even */
  3191 +	  high += GARDROUND + 1;
  3192 +	}
  3193 +      else if (low)
  3194 +	{
  3195 +	  /* but we really weren't half way */
  3196 +	  high += GARDROUND + 1;
  3197 +	}
  3198 +    }
  3199 +  tmp->fraction.ll = high;
  3200 +  tmp->class = CLASS_NUMBER;
  3201 +  return tmp;
  3202 +}
  3203 +
  3204 +FLO_type
  3205 +multiply (FLO_type arg_a, FLO_type arg_b)
  3206 +{
  3207 +  fp_number_type a;
  3208 +  fp_number_type b;
  3209 +  fp_number_type tmp;
  3210 +  fp_number_type *res;
  3211 +  FLO_union_type au, bu;
  3212 +
  3213 +  au.value = arg_a;
  3214 +  bu.value = arg_b;
  3215 +
  3216 +  unpack_d (&au, &a);
  3217 +  unpack_d (&bu, &b);
  3218 +
  3219 +  res = _fpmul_parts (&a, &b, &tmp);
  3220 +
  3221 +  return pack_d (res);
  3222 +}
  3223 +#endif /* L_mul_sf || L_mul_df */
  3224 +
  3225 +#if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf)
  3226 +static inline __attribute__ ((__always_inline__)) fp_number_type *
  3227 +_fpdiv_parts (fp_number_type * a,
  3228 +	      fp_number_type * b)
  3229 +{
  3230 +  fractype bit;
  3231 +  fractype numerator;
  3232 +  fractype denominator;
  3233 +  fractype quotient;
  3234 +
  3235 +  if (isnan (a))
  3236 +    {
  3237 +      return a;
  3238 +    }
  3239 +  if (isnan (b))
  3240 +    {
  3241 +      return b;
  3242 +    }
  3243 +
  3244 +  a->sign = a->sign ^ b->sign;
  3245 +
  3246 +  if (isinf (a) || iszero (a))
  3247 +    {
  3248 +      if (a->class == b->class)
  3249 +	return nan ();
  3250 +      return a;
  3251 +    }
  3252 +
  3253 +  if (isinf (b))
  3254 +    {
  3255 +      a->fraction.ll = 0;
  3256 +      a->normal_exp = 0;
  3257 +      return a;
  3258 +    }
  3259 +  if (iszero (b))
  3260 +    {
  3261 +      a->class = CLASS_INFINITY;
  3262 +      return a;
  3263 +    }
  3264 +
  3265 +  /* Calculate the mantissa by multiplying both 64bit numbers to get a
  3266 +     128 bit number */
  3267 +  {
  3268 +    /* quotient =
  3269 +       ( numerator / denominator) * 2^(numerator exponent -  denominator exponent)
  3270 +     */
  3271 +
  3272 +    a->normal_exp = a->normal_exp - b->normal_exp;
  3273 +    numerator = a->fraction.ll;
  3274 +    denominator = b->fraction.ll;
  3275 +
  3276 +    if (numerator < denominator)
  3277 +      {
  3278 +	/* Fraction will be less than 1.0 */
  3279 +	numerator *= 2;
  3280 +	a->normal_exp--;
  3281 +      }
  3282 +    bit = IMPLICIT_1;
  3283 +    quotient = 0;
  3284 +    /* ??? Does divide one bit at a time.  Optimize.  */
  3285 +    while (bit)
  3286 +      {
  3287 +	if (numerator >= denominator)
  3288 +	  {
  3289 +	    quotient |= bit;
  3290 +	    numerator -= denominator;
  3291 +	  }
  3292 +	bit >>= 1;
  3293 +	numerator *= 2;
  3294 +      }
  3295 +
  3296 +    if (!ROUND_TOWARDS_ZERO && (quotient & GARDMASK) == GARDMSB)
  3297 +      {
  3298 +	if (quotient & (1 << NGARDS))
  3299 +	  {
  3300 +	    /* half way, so round to even */
  3301 +	    quotient += GARDROUND + 1;
  3302 +	  }
  3303 +	else if (numerator)
  3304 +	  {
  3305 +	    /* but we really weren't half way, more bits exist */
  3306 +	    quotient += GARDROUND + 1;
  3307 +	  }
  3308 +      }
  3309 +
  3310 +    a->fraction.ll = quotient;
  3311 +    return (a);
  3312 +  }
  3313 +}
  3314 +
  3315 +FLO_type
  3316 +divide (FLO_type arg_a, FLO_type arg_b)
  3317 +{
  3318 +  fp_number_type a;
  3319 +  fp_number_type b;
  3320 +  fp_number_type *res;
  3321 +  FLO_union_type au, bu;
  3322 +
  3323 +  au.value = arg_a;
  3324 +  bu.value = arg_b;
  3325 +
  3326 +  unpack_d (&au, &a);
  3327 +  unpack_d (&bu, &b);
  3328 +
  3329 +  res = _fpdiv_parts (&a, &b);
  3330 +
  3331 +  return pack_d (res);
  3332 +}
  3333 +#endif /* L_div_sf || L_div_df */
  3334 +
  3335 +#if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) \
  3336 +    || defined(L_fpcmp_parts_tf)
  3337 +/* according to the demo, fpcmp returns a comparison with 0... thus
  3338 +   a<b -> -1
  3339 +   a==b -> 0
  3340 +   a>b -> +1
  3341 + */
  3342 +
  3343 +int
  3344 +__fpcmp_parts (fp_number_type * a, fp_number_type * b)
  3345 +{
  3346 +#if 0
  3347 +  /* either nan -> unordered. Must be checked outside of this routine.  */
  3348 +  if (isnan (a) && isnan (b))
  3349 +    {
  3350 +      return 1;			/* still unordered! */
  3351 +    }
  3352 +#endif
  3353 +
  3354 +  if (isnan (a) || isnan (b))
  3355 +    {
  3356 +      return 1;			/* how to indicate unordered compare? */
  3357 +    }
  3358 +  if (isinf (a) && isinf (b))
  3359 +    {
  3360 +      /* +inf > -inf, but +inf != +inf */
  3361 +      /* b    \a| +inf(0)| -inf(1)
  3362 +       ______\+--------+--------
  3363 +       +inf(0)| a==b(0)| a<b(-1)
  3364 +       -------+--------+--------
  3365 +       -inf(1)| a>b(1) | a==b(0)
  3366 +       -------+--------+--------
  3367 +       So since unordered must be nonzero, just line up the columns...
  3368 +       */
  3369 +      return b->sign - a->sign;
  3370 +    }
  3371 +  /* but not both...  */
  3372 +  if (isinf (a))
  3373 +    {
  3374 +      return a->sign ? -1 : 1;
  3375 +    }
  3376 +  if (isinf (b))
  3377 +    {
  3378 +      return b->sign ? 1 : -1;
  3379 +    }
  3380 +  if (iszero (a) && iszero (b))
  3381 +    {
  3382 +      return 0;
  3383 +    }
  3384 +  if (iszero (a))
  3385 +    {
  3386 +      return b->sign ? 1 : -1;
  3387 +    }
  3388 +  if (iszero (b))
  3389 +    {
  3390 +      return a->sign ? -1 : 1;
  3391 +    }
  3392 +  /* now both are "normal".  */
  3393 +  if (a->sign != b->sign)
  3394 +    {
  3395 +      /* opposite signs */
  3396 +      return a->sign ? -1 : 1;
  3397 +    }
  3398 +  /* same sign; exponents? */
  3399 +  if (a->normal_exp > b->normal_exp)
  3400 +    {
  3401 +      return a->sign ? -1 : 1;
  3402 +    }
  3403 +  if (a->normal_exp < b->normal_exp)
  3404 +    {
  3405 +      return a->sign ? 1 : -1;
  3406 +    }
  3407 +  /* same exponents; check size.  */
  3408 +  if (a->fraction.ll > b->fraction.ll)
  3409 +    {
  3410 +      return a->sign ? -1 : 1;
  3411 +    }
  3412 +  if (a->fraction.ll < b->fraction.ll)
  3413 +    {
  3414 +      return a->sign ? 1 : -1;
  3415 +    }
  3416 +  /* after all that, they're equal.  */
  3417 +  return 0;
  3418 +}
  3419 +#endif
  3420 +
  3421 +#if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compoare_tf)
  3422 +CMPtype
  3423 +compare (FLO_type arg_a, FLO_type arg_b)
  3424 +{
  3425 +  fp_number_type a;
  3426 +  fp_number_type b;
  3427 +  FLO_union_type au, bu;
  3428 +
  3429 +  au.value = arg_a;
  3430 +  bu.value = arg_b;
  3431 +
  3432 +  unpack_d (&au, &a);
  3433 +  unpack_d (&bu, &b);
  3434 +
  3435 +  return __fpcmp_parts (&a, &b);
  3436 +}
  3437 +#endif /* L_compare_sf || L_compare_df */
  3438 +
  3439 +#ifndef US_SOFTWARE_GOFAST
  3440 +
  3441 +/* These should be optimized for their specific tasks someday.  */
  3442 +
  3443 +#if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf)
  3444 +CMPtype
  3445 +_eq_f2 (FLO_type arg_a, FLO_type arg_b)
  3446 +{
  3447 +  fp_number_type a;
  3448 +  fp_number_type b;
  3449 +  FLO_union_type au, bu;
  3450 +
  3451 +  au.value = arg_a;
  3452 +  bu.value = arg_b;
  3453 +
  3454 +  unpack_d (&au, &a);
  3455 +  unpack_d (&bu, &b);
  3456 +
  3457 +  if (isnan (&a) || isnan (&b))
  3458 +    return 1;			/* false, truth == 0 */
  3459 +
  3460 +  return __fpcmp_parts (&a, &b) ;
  3461 +}
  3462 +#endif /* L_eq_sf || L_eq_df */
  3463 +
  3464 +#if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf)
  3465 +CMPtype
  3466 +_ne_f2 (FLO_type arg_a, FLO_type arg_b)
  3467 +{
  3468 +  fp_number_type a;
  3469 +  fp_number_type b;
  3470 +  FLO_union_type au, bu;
  3471 +
  3472 +  au.value = arg_a;
  3473 +  bu.value = arg_b;
  3474 +
  3475 +  unpack_d (&au, &a);
  3476 +  unpack_d (&bu, &b);
  3477 +
  3478 +  if (isnan (&a) || isnan (&b))
  3479 +    return 1;			/* true, truth != 0 */
  3480 +
  3481 +  return  __fpcmp_parts (&a, &b) ;
  3482 +}
  3483 +#endif /* L_ne_sf || L_ne_df */
  3484 +
  3485 +#if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf)
  3486 +CMPtype
  3487 +_gt_f2 (FLO_type arg_a, FLO_type arg_b)
  3488 +{
  3489 +  fp_number_type a;
  3490 +  fp_number_type b;
  3491 +  FLO_union_type au, bu;
  3492 +
  3493 +  au.value = arg_a;
  3494 +  bu.value = arg_b;
  3495 +
  3496 +  unpack_d (&au, &a);
  3497 +  unpack_d (&bu, &b);
  3498 +
  3499 +  if (isnan (&a) || isnan (&b))
  3500 +    return -1;			/* false, truth > 0 */
  3501 +
  3502 +  return __fpcmp_parts (&a, &b);
  3503 +}
  3504 +#endif /* L_gt_sf || L_gt_df */
  3505 +
  3506 +#if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf)
  3507 +CMPtype
  3508 +_ge_f2 (FLO_type arg_a, FLO_type arg_b)
  3509 +{
  3510 +  fp_number_type a;
  3511 +  fp_number_type b;
  3512 +  FLO_union_type au, bu;
  3513 +
  3514 +  au.value = arg_a;
  3515 +  bu.value = arg_b;
  3516 +
  3517 +  unpack_d (&au, &a);
  3518 +  unpack_d (&bu, &b);
  3519 +
  3520 +  if (isnan (&a) || isnan (&b))
  3521 +    return -1;			/* false, truth >= 0 */
  3522 +  return __fpcmp_parts (&a, &b) ;
  3523 +}
  3524 +#endif /* L_ge_sf || L_ge_df */
  3525 +
  3526 +#if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf)
  3527 +CMPtype
  3528 +_lt_f2 (FLO_type arg_a, FLO_type arg_b)
  3529 +{
  3530 +  fp_number_type a;
  3531 +  fp_number_type b;
  3532 +  FLO_union_type au, bu;
  3533 +
  3534 +  au.value = arg_a;
  3535 +  bu.value = arg_b;
  3536 +
  3537 +  unpack_d (&au, &a);
  3538 +  unpack_d (&bu, &b);
  3539 +
  3540 +  if (isnan (&a) || isnan (&b))
  3541 +    return 1;			/* false, truth < 0 */
  3542 +
  3543 +  return __fpcmp_parts (&a, &b);
  3544 +}
  3545 +#endif /* L_lt_sf || L_lt_df */
  3546 +
  3547 +#if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf)
  3548 +CMPtype
  3549 +_le_f2 (FLO_type arg_a, FLO_type arg_b)
  3550 +{
  3551 +  fp_number_type a;
  3552 +  fp_number_type b;
  3553 +  FLO_union_type au, bu;
  3554 +
  3555 +  au.value = arg_a;
  3556 +  bu.value = arg_b;
  3557 +
  3558 +  unpack_d (&au, &a);
  3559 +  unpack_d (&bu, &b);
  3560 +
  3561 +  if (isnan (&a) || isnan (&b))
  3562 +    return 1;			/* false, truth <= 0 */
  3563 +
  3564 +  return __fpcmp_parts (&a, &b) ;
  3565 +}
  3566 +#endif /* L_le_sf || L_le_df */
  3567 +
  3568 +#endif /* ! US_SOFTWARE_GOFAST */
  3569 +
  3570 +#if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf)
  3571 +CMPtype
  3572 +_unord_f2 (FLO_type arg_a, FLO_type arg_b)
  3573 +{
  3574 +  fp_number_type a;
  3575 +  fp_number_type b;
  3576 +  FLO_union_type au, bu;
  3577 +
  3578 +  au.value = arg_a;
  3579 +  bu.value = arg_b;
  3580 +
  3581 +  unpack_d (&au, &a);
  3582 +  unpack_d (&bu, &b);
  3583 +
  3584 +  return (isnan (&a) || isnan (&b));
  3585 +}
  3586 +#endif /* L_unord_sf || L_unord_df */
  3587 +
  3588 +#if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf)
  3589 +FLO_type
  3590 +si_to_float (SItype arg_a)
  3591 +{
  3592 +  fp_number_type in;
  3593 +
  3594 +  in.class = CLASS_NUMBER;
  3595 +  in.sign = arg_a < 0;
  3596 +  if (!arg_a)
  3597 +    {
  3598 +      in.class = CLASS_ZERO;
  3599 +    }
  3600 +  else
  3601 +    {
  3602 +      in.normal_exp = FRACBITS + NGARDS;
  3603 +      if (in.sign) 
  3604 +	{
  3605 +	  /* Special case for minint, since there is no +ve integer
  3606 +	     representation for it */
  3607 +	  if (arg_a == (- MAX_SI_INT - 1))
  3608 +	    {
  3609 +	      return (FLO_type)(- MAX_SI_INT - 1);
  3610 +	    }
  3611 +	  in.fraction.ll = (-arg_a);
  3612 +	}
  3613 +      else
  3614 +	in.fraction.ll = arg_a;
  3615 +
  3616 +      while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS)))
  3617 +	{
  3618 +	  in.fraction.ll <<= 1;
  3619 +	  in.normal_exp -= 1;
  3620 +	}
  3621 +    }
  3622 +  return pack_d (&in);
  3623 +}
  3624 +#endif /* L_si_to_sf || L_si_to_df */
  3625 +
  3626 +#if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf)
  3627 +FLO_type
  3628 +usi_to_float (USItype arg_a)
  3629 +{
  3630 +  fp_number_type in;
  3631 +
  3632 +  in.sign = 0;
  3633 +  if (!arg_a)
  3634 +    {
  3635 +      in.class = CLASS_ZERO;
  3636 +    }
  3637 +  else
  3638 +    {
  3639 +      in.class = CLASS_NUMBER;
  3640 +      in.normal_exp = FRACBITS + NGARDS;
  3641 +      in.fraction.ll = arg_a;
  3642 +
  3643 +      while (in.fraction.ll > ((fractype)1 << (FRACBITS + NGARDS)))
  3644 +        {
  3645 +          in.fraction.ll >>= 1;
  3646 +          in.normal_exp += 1;
  3647 +        }
  3648 +      while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS)))
  3649 +	{
  3650 +	  in.fraction.ll <<= 1;
  3651 +	  in.normal_exp -= 1;
  3652 +	}
  3653 +    }
  3654 +  return pack_d (&in);
  3655 +}
  3656 +#endif
  3657 +
  3658 +#if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si)
  3659 +SItype
  3660 +float_to_si (FLO_type arg_a)
  3661 +{
  3662 +  fp_number_type a;
  3663 +  SItype tmp;
  3664 +  FLO_union_type au;
  3665 +
  3666 +  au.value = arg_a;
  3667 +  unpack_d (&au, &a);
  3668 +
  3669 +  if (iszero (&a))
  3670 +    return 0;
  3671 +  if (isnan (&a))
  3672 +    return 0;
  3673 +  /* get reasonable MAX_SI_INT...  */
  3674 +  if (isinf (&a))
  3675 +    return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
  3676 +  /* it is a number, but a small one */
  3677 +  if (a.normal_exp < 0)
  3678 +    return 0;
  3679 +  if (a.normal_exp > BITS_PER_SI - 2)
  3680 +    return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
  3681 +  tmp = a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
  3682 +  return a.sign ? (-tmp) : (tmp);
  3683 +}
  3684 +#endif /* L_sf_to_si || L_df_to_si */
  3685 +
  3686 +#if defined(L_sf_to_usi) || defined(L_df_to_usi) || defined(L_tf_to_usi)
  3687 +#if defined US_SOFTWARE_GOFAST || defined(L_tf_to_usi)
  3688 +/* While libgcc2.c defines its own __fixunssfsi and __fixunsdfsi routines,
  3689 +   we also define them for GOFAST because the ones in libgcc2.c have the
  3690 +   wrong names and I'd rather define these here and keep GOFAST CYG-LOC's
  3691 +   out of libgcc2.c.  We can't define these here if not GOFAST because then
  3692 +   there'd be duplicate copies.  */
  3693 +
  3694 +USItype
  3695 +float_to_usi (FLO_type arg_a)
  3696 +{
  3697 +  fp_number_type a;
  3698 +  FLO_union_type au;
  3699 +
  3700 +  au.value = arg_a;
  3701 +  unpack_d (&au, &a);
  3702 +
  3703 +  if (iszero (&a))
  3704 +    return 0;
  3705 +  if (isnan (&a))
  3706 +    return 0;
  3707 +  /* it is a negative number */
  3708 +  if (a.sign)
  3709 +    return 0;
  3710 +  /* get reasonable MAX_USI_INT...  */
  3711 +  if (isinf (&a))
  3712 +    return MAX_USI_INT;
  3713 +  /* it is a number, but a small one */
  3714 +  if (a.normal_exp < 0)
  3715 +    return 0;
  3716 +  if (a.normal_exp > BITS_PER_SI - 1)
  3717 +    return MAX_USI_INT;
  3718 +  else if (a.normal_exp > (FRACBITS + NGARDS))
  3719 +    return a.fraction.ll << (a.normal_exp - (FRACBITS + NGARDS));
  3720 +  else
  3721 +    return a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
  3722 +}
  3723 +#endif /* US_SOFTWARE_GOFAST */
  3724 +#endif /* L_sf_to_usi || L_df_to_usi */
  3725 +
  3726 +#if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf)
  3727 +FLO_type
  3728 +negate (FLO_type arg_a)
  3729 +{
  3730 +  fp_number_type a;
  3731 +  FLO_union_type au;
  3732 +
  3733 +  au.value = arg_a;
  3734 +  unpack_d (&au, &a);
  3735 +
  3736 +  flip_sign (&a);
  3737 +  return pack_d (&a);
  3738 +}
  3739 +#endif /* L_negate_sf || L_negate_df */
  3740 +
  3741 +#ifdef FLOAT
  3742 +
  3743 +#if defined(L_make_sf)
  3744 +SFtype
  3745 +__make_fp(fp_class_type class,
  3746 +	     unsigned int sign,
  3747 +	     int exp, 
  3748 +	     USItype frac)
  3749 +{
  3750 +  fp_number_type in;
  3751 +
  3752 +  in.class = class;
  3753 +  in.sign = sign;
  3754 +  in.normal_exp = exp;
  3755 +  in.fraction.ll = frac;
  3756 +  return pack_d (&in);
  3757 +}
  3758 +#endif /* L_make_sf */
  3759 +
  3760 +#ifndef FLOAT_ONLY
  3761 +
  3762 +/* This enables one to build an fp library that supports float but not double.
  3763 +   Otherwise, we would get an undefined reference to __make_dp.
  3764 +   This is needed for some 8-bit ports that can't handle well values that
  3765 +   are 8-bytes in size, so we just don't support double for them at all.  */
  3766 +
  3767 +#if defined(L_sf_to_df)
  3768 +DFtype
  3769 +sf_to_df (SFtype arg_a)
  3770 +{
  3771 +  fp_number_type in;
  3772 +  FLO_union_type au;
  3773 +
  3774 +  au.value = arg_a;
  3775 +  unpack_d (&au, &in);
  3776 +
  3777 +  return __make_dp (in.class, in.sign, in.normal_exp,
  3778 +		    ((UDItype) in.fraction.ll) << F_D_BITOFF);
  3779 +}
  3780 +#endif /* L_sf_to_df */
  3781 +
  3782 +#if defined(L_sf_to_tf) && defined(TMODES)
  3783 +TFtype
  3784 +sf_to_tf (SFtype arg_a)
  3785 +{
  3786 +  fp_number_type in;
  3787 +  FLO_union_type au;
  3788 +
  3789 +  au.value = arg_a;
  3790 +  unpack_d (&au, &in);
  3791 +
  3792 +  return __make_tp (in.class, in.sign, in.normal_exp,
  3793 +		    ((UTItype) in.fraction.ll) << F_T_BITOFF);
  3794 +}
  3795 +#endif /* L_sf_to_df */
  3796 +
  3797 +#endif /* ! FLOAT_ONLY */
  3798 +#endif /* FLOAT */
  3799 +
  3800 +#ifndef FLOAT
  3801 +
  3802 +extern SFtype __make_fp (fp_class_type, unsigned int, int, USItype);
  3803 +
  3804 +#if defined(L_make_df)
  3805 +DFtype
  3806 +__make_dp (fp_class_type class, unsigned int sign, int exp, UDItype frac)
  3807 +{
  3808 +  fp_number_type in;
  3809 +
  3810 +  in.class = class;
  3811 +  in.sign = sign;
  3812 +  in.normal_exp = exp;
  3813 +  in.fraction.ll = frac;
  3814 +  return pack_d (&in);
  3815 +}
  3816 +#endif /* L_make_df */
  3817 +
  3818 +#if defined(L_df_to_sf)
  3819 +SFtype
  3820 +df_to_sf (DFtype arg_a)
  3821 +{
  3822 +  fp_number_type in;
  3823 +  USItype sffrac;
  3824 +  FLO_union_type au;
  3825 +
  3826 +  au.value = arg_a;
  3827 +  unpack_d (&au, &in);
  3828 +
  3829 +  sffrac = in.fraction.ll >> F_D_BITOFF;
  3830 +
  3831 +  /* We set the lowest guard bit in SFFRAC if we discarded any non
  3832 +     zero bits.  */
  3833 +  if ((in.fraction.ll & (((USItype) 1 << F_D_BITOFF) - 1)) != 0)
  3834 +    sffrac |= 1;
  3835 +
  3836 +  return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
  3837 +}
  3838 +#endif /* L_df_to_sf */
  3839 +
  3840 +#if defined(L_df_to_tf) && defined(TMODES) \
  3841 +    && !defined(FLOAT) && !defined(TFLOAT)
  3842 +TFtype
  3843 +df_to_tf (DFtype arg_a)
  3844 +{
  3845 +  fp_number_type in;
  3846 +  FLO_union_type au;
  3847 +
  3848 +  au.value = arg_a;
  3849 +  unpack_d (&au, &in);
  3850 +
  3851 +  return __make_tp (in.class, in.sign, in.normal_exp,
  3852 +		    ((UTItype) in.fraction.ll) << D_T_BITOFF);
  3853 +}
  3854 +#endif /* L_sf_to_df */
  3855 +
  3856 +#ifdef TFLOAT
  3857 +#if defined(L_make_tf)
  3858 +TFtype
  3859 +__make_tp(fp_class_type class,
  3860 +	     unsigned int sign,
  3861 +	     int exp, 
  3862 +	     UTItype frac)
  3863 +{
  3864 +  fp_number_type in;
  3865 +
  3866 +  in.class = class;
  3867 +  in.sign = sign;
  3868 +  in.normal_exp = exp;
  3869 +  in.fraction.ll = frac;
  3870 +  return pack_d (&in);
  3871 +}
  3872 +#endif /* L_make_tf */
  3873 +
  3874 +#if defined(L_tf_to_df)
  3875 +DFtype
  3876 +tf_to_df (TFtype arg_a)
  3877 +{
  3878 +  fp_number_type in;
  3879 +  UDItype sffrac;
  3880 +  FLO_union_type au;
  3881 +
  3882 +  au.value = arg_a;
  3883 +  unpack_d (&au, &in);
  3884 +
  3885 +  sffrac = in.fraction.ll >> D_T_BITOFF;
  3886 +
  3887 +  /* We set the lowest guard bit in SFFRAC if we discarded any non
  3888 +     zero bits.  */
  3889 +  if ((in.fraction.ll & (((UTItype) 1 << D_T_BITOFF) - 1)) != 0)
  3890 +    sffrac |= 1;
  3891 +
  3892 +  return __make_dp (in.class, in.sign, in.normal_exp, sffrac);
  3893 +}
  3894 +#endif /* L_tf_to_df */
  3895 +
  3896 +#if defined(L_tf_to_sf)
  3897 +SFtype
  3898 +tf_to_sf (TFtype arg_a)
  3899 +{
  3900 +  fp_number_type in;
  3901 +  USItype sffrac;
  3902 +  FLO_union_type au;
  3903 +
  3904 +  au.value = arg_a;
  3905 +  unpack_d (&au, &in);
  3906 +
  3907 +  sffrac = in.fraction.ll >> F_T_BITOFF;
  3908 +
  3909 +  /* We set the lowest guard bit in SFFRAC if we discarded any non
  3910 +     zero bits.  */
  3911 +  if ((in.fraction.ll & (((UTItype) 1 << F_T_BITOFF) - 1)) != 0)
  3912 +    sffrac |= 1;
  3913 +
  3914 +  return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
  3915 +}
  3916 +#endif /* L_tf_to_sf */
  3917 +#endif /* TFLOAT */
  3918 +
  3919 +#endif /* ! FLOAT */
  3920 +#endif /* !EXTENDED_FLOAT_STUBS */
  3921 --- gcc-3.4.3/gcc/config/nios2/nios2-protos.h
  3922 +++ gcc-3.4.3-nios2/gcc/config/nios2/nios2-protos.h
  3923 @@ -0,0 +1,70 @@
  3924 +/* Subroutines for assembler code output for Altera NIOS 2G NIOS2 version.
  3925 +   Copyright (C) 2003 Altera 
  3926 +   Contributed by Jonah Graham (jgraham@altera.com).
  3927 +
  3928 +This file is part of GNU CC.
  3929 +
  3930 +GNU CC is free software; you can redistribute it and/or modify
  3931 +it under the terms of the GNU General Public License as published by
  3932 +the Free Software Foundation; either version 2, or (at your option)
  3933 +any later version.
  3934 +
  3935 +GNU CC is distributed in the hope that it will be useful,
  3936 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  3937 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  3938 +GNU General Public License for more details.
  3939 +
  3940 +You should have received a copy of the GNU General Public License
  3941 +along with GNU CC; see the file COPYING.  If not, write to
  3942 +the Free Software Foundation, 59 Temple Place - Suite 330,
  3943 +Boston, MA 02111-1307, USA.  */
  3944 +
  3945 +extern void dump_frame_size (FILE *);
  3946 +extern HOST_WIDE_INT compute_frame_size (void);
  3947 +extern int nios2_initial_elimination_offset (int, int);
  3948 +extern void override_options (void);
  3949 +extern void optimization_options (int, int);
  3950 +extern int nios2_can_use_return_insn (void);
  3951 +extern void expand_prologue (void);
  3952 +extern void expand_epilogue (bool);
  3953 +extern void function_profiler (FILE *, int);
  3954 +
  3955 +
  3956 +#ifdef RTX_CODE
  3957 +extern int nios2_legitimate_address (rtx, enum machine_mode, int);
  3958 +extern void nios2_print_operand (FILE *, rtx, int);
  3959 +extern void nios2_print_operand_address (FILE *, rtx);
  3960 +
  3961 +extern int nios2_emit_move_sequence (rtx *, enum machine_mode);
  3962 +extern int nios2_emit_expensive_div (rtx *, enum machine_mode);
  3963 +
  3964 +extern void gen_int_relational (enum rtx_code, rtx, rtx, rtx, rtx);
  3965 +extern void gen_conditional_move (rtx *, enum machine_mode);
  3966 +extern const char *asm_output_opcode (FILE *, const char *);
  3967 +
  3968 +/* predicates */
  3969 +extern int arith_operand (rtx, enum machine_mode);
  3970 +extern int uns_arith_operand (rtx, enum machine_mode);
  3971 +extern int logical_operand (rtx, enum machine_mode);
  3972 +extern int shift_operand (rtx, enum machine_mode);
  3973 +extern int reg_or_0_operand (rtx, enum machine_mode);
  3974 +extern int equality_op (rtx, enum machine_mode);
  3975 +extern int custom_insn_opcode (rtx, enum machine_mode);
  3976 +extern int rdwrctl_operand (rtx, enum machine_mode);
  3977 +
  3978 +# ifdef HAVE_MACHINE_MODES
  3979 +#  if defined TREE_CODE
  3980 +extern void function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
  3981 +extern rtx function_arg (const CUMULATIVE_ARGS *, enum machine_mode, tree, int);
  3982 +extern int function_arg_partial_nregs (const CUMULATIVE_ARGS *, enum machine_mode, tree, int);
  3983 +extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree, int);
  3984 +extern int nios2_setup_incoming_varargs (const CUMULATIVE_ARGS *, enum machine_mode, tree, int);
  3985 +
  3986 +#  endif /* TREE_CODE */
  3987 +# endif	/* HAVE_MACHINE_MODES */
  3988 +#endif
  3989 +
  3990 +#ifdef TREE_CODE
  3991 +extern int nios2_return_in_memory (tree);
  3992 +
  3993 +#endif /* TREE_CODE */
  3994 --- gcc-3.4.3/gcc/config/nios2/nios2.c
  3995 +++ gcc-3.4.3-nios2/gcc/config/nios2/nios2.c
  3996 @@ -0,0 +1,2853 @@
  3997 +/* Subroutines for assembler code output for Altera NIOS 2G NIOS2 version.
  3998 +   Copyright (C) 2003 Altera
  3999 +   Contributed by Jonah Graham (jgraham@altera.com).
  4000 +
  4001 +This file is part of GNU CC.
  4002 +
  4003 +GNU CC is free software; you can redistribute it and/or modify
  4004 +it under the terms of the GNU General Public License as published by
  4005 +the Free Software Foundation; either version 2, or (at your option)
  4006 +any later version.
  4007 +
  4008 +GNU CC is distributed in the hope that it will be useful,
  4009 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  4010 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  4011 +GNU General Public License for more details.
  4012 +
  4013 +You should have received a copy of the GNU General Public License
  4014 +along with GNU CC; see the file COPYING.  If not, write to
  4015 +the Free Software Foundation, 59 Temple Place - Suite 330,
  4016 +Boston, MA 02111-1307, USA.  */
  4017 +
  4018 +
  4019 +#include <stdio.h>
  4020 +#include "config.h"
  4021 +#include "system.h"
  4022 +#include "coretypes.h"
  4023 +#include "tm.h"
  4024 +#include "rtl.h"
  4025 +#include "tree.h"
  4026 +#include "tm_p.h"
  4027 +#include "regs.h"
  4028 +#include "hard-reg-set.h"
  4029 +#include "real.h"
  4030 +#include "insn-config.h"
  4031 +#include "conditions.h"
  4032 +#include "output.h"
  4033 +#include "insn-attr.h"
  4034 +#include "flags.h"
  4035 +#include "recog.h"
  4036 +#include "expr.h"
  4037 +#include "toplev.h"
  4038 +#include "basic-block.h"
  4039 +#include "function.h"
  4040 +#include "ggc.h"
  4041 +#include "reload.h"
  4042 +#include "debug.h"
  4043 +#include "optabs.h"
  4044 +#include "target.h"
  4045 +#include "target-def.h"
  4046 +
  4047 +/* local prototypes */
  4048 +static bool nios2_rtx_costs (rtx, int, int, int *);
  4049 +
  4050 +static void nios2_asm_function_prologue (FILE *, HOST_WIDE_INT);
  4051 +static int nios2_use_dfa_pipeline_interface (void);
  4052 +static int nios2_issue_rate (void);
  4053 +static struct machine_function *nios2_init_machine_status (void);
  4054 +static bool nios2_in_small_data_p (tree);
  4055 +static rtx save_reg (int, HOST_WIDE_INT, rtx);
  4056 +static rtx restore_reg (int, HOST_WIDE_INT);
  4057 +static unsigned int nios2_section_type_flags (tree, const char *, int);
  4058 +static void nios2_init_builtins (void);
  4059 +static rtx nios2_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
  4060 +static bool nios2_function_ok_for_sibcall (tree, tree);
  4061 +static void nios2_encode_section_info (tree, rtx, int);
  4062 +
  4063 +/* Initialize the GCC target structure.  */
  4064 +#undef TARGET_ASM_FUNCTION_PROLOGUE
  4065 +#define TARGET_ASM_FUNCTION_PROLOGUE nios2_asm_function_prologue
  4066 +
  4067 +#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
  4068 +#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE \
  4069 + nios2_use_dfa_pipeline_interface
  4070 +#undef TARGET_SCHED_ISSUE_RATE
  4071 +#define TARGET_SCHED_ISSUE_RATE nios2_issue_rate
  4072 +#undef TARGET_IN_SMALL_DATA_P
  4073 +#define TARGET_IN_SMALL_DATA_P nios2_in_small_data_p
  4074 +#undef  TARGET_ENCODE_SECTION_INFO
  4075 +#define TARGET_ENCODE_SECTION_INFO nios2_encode_section_info
  4076 +#undef  TARGET_SECTION_TYPE_FLAGS
  4077 +#define TARGET_SECTION_TYPE_FLAGS  nios2_section_type_flags
  4078 +
  4079 +#undef TARGET_INIT_BUILTINS
  4080 +#define TARGET_INIT_BUILTINS nios2_init_builtins
  4081 +#undef TARGET_EXPAND_BUILTIN
  4082 +#define TARGET_EXPAND_BUILTIN nios2_expand_builtin
  4083 +
  4084 +#undef TARGET_FUNCTION_OK_FOR_SIBCALL
  4085 +#define TARGET_FUNCTION_OK_FOR_SIBCALL nios2_function_ok_for_sibcall
  4086 +
  4087 +#undef TARGET_RTX_COSTS
  4088 +#define TARGET_RTX_COSTS nios2_rtx_costs
  4089 +
  4090 +
  4091 +struct gcc_target targetm = TARGET_INITIALIZER;
  4092 +
  4093 +
  4094 +
  4095 +/* Threshold for data being put into the small data/bss area, instead
  4096 +   of the normal data area (references to the small data/bss area take
  4097 +   1 instruction, and use the global pointer, references to the normal
  4098 +   data area takes 2 instructions).  */
  4099 +unsigned HOST_WIDE_INT nios2_section_threshold = NIOS2_DEFAULT_GVALUE;
  4100 +
  4101 +
  4102 +/* Structure to be filled in by compute_frame_size with register
  4103 +   save masks, and offsets for the current function.  */
  4104 +
  4105 +struct nios2_frame_info
  4106 +GTY (())
  4107 +{
  4108 +  long total_size;		/* # bytes that the entire frame takes up */
  4109 +  long var_size;		/* # bytes that variables take up */
  4110 +  long args_size;		/* # bytes that outgoing arguments take up */
  4111 +  int save_reg_size;		/* # bytes needed to store gp regs */
  4112 +  int save_reg_rounded;		/* # bytes needed to store gp regs */
  4113 +  long save_regs_offset;	/* offset from new sp to store gp registers */
  4114 +  int initialized;		/* != 0 if frame size already calculated */
  4115 +  int num_regs;			/* number of gp registers saved */
  4116 +};
  4117 +
  4118 +struct machine_function
  4119 +GTY (())
  4120 +{
  4121 +
  4122 +  /* Current frame information, calculated by compute_frame_size.  */
  4123 +  struct nios2_frame_info frame;
  4124 +};
  4125 +
  4126 +
  4127 +/***************************************
  4128 + * Section encodings
  4129 + ***************************************/
  4130 +
  4131 +
  4132 +
  4133 +
  4134 +
  4135 +/***************************************
  4136 + * Stack Layout and Calling Conventions
  4137 + ***************************************/
  4138 +
  4139 +
  4140 +#define TOO_BIG_OFFSET(X) ((X) > ((1 << 15) - 1))
  4141 +#define TEMP_REG_NUM 8
  4142 +
  4143 +static void
  4144 +nios2_asm_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
  4145 +{
  4146 +  if (flag_verbose_asm || flag_debug_asm)
  4147 +    {
  4148 +      compute_frame_size ();
  4149 +      dump_frame_size (file);
  4150 +    }
  4151 +}
  4152 +
  4153 +static rtx
  4154 +save_reg (int regno, HOST_WIDE_INT offset, rtx cfa_store_reg)
  4155 +{
  4156 +  rtx insn, stack_slot;
  4157 +
  4158 +  stack_slot = gen_rtx_PLUS (SImode,
  4159 +			     cfa_store_reg,
  4160 +			     GEN_INT (offset));
  4161 +
  4162 +  insn = emit_insn (gen_rtx_SET (SImode,
  4163 +				 gen_rtx_MEM (SImode, stack_slot),
  4164 +				 gen_rtx_REG (SImode, regno)));
  4165 +
  4166 +  RTX_FRAME_RELATED_P (insn) = 1;
  4167 +
  4168 +  return insn;
  4169 +}
  4170 +
  4171 +static rtx
  4172 +restore_reg (int regno, HOST_WIDE_INT offset)
  4173 +{
  4174 +  rtx insn, stack_slot;
  4175 +
  4176 +  if (TOO_BIG_OFFSET (offset))
  4177 +    {
  4178 +      stack_slot = gen_rtx_REG (SImode, TEMP_REG_NUM);
  4179 +      insn = emit_insn (gen_rtx_SET (SImode,
  4180 +				     stack_slot,
  4181 +				     GEN_INT (offset)));
  4182 +
  4183 +      insn = emit_insn (gen_rtx_SET (SImode,
  4184 +				     stack_slot,
  4185 +                                     gen_rtx_PLUS (SImode,
  4186 +				                   stack_slot,
  4187 +				                   stack_pointer_rtx)));
  4188 +    }
  4189 +  else
  4190 +    {
  4191 +      stack_slot = gen_rtx_PLUS (SImode,
  4192 +			         stack_pointer_rtx,
  4193 +				 GEN_INT (offset));
  4194 +    }
  4195 +
  4196 +  stack_slot = gen_rtx_MEM (SImode, stack_slot);
  4197 +
  4198 +  insn = emit_move_insn (gen_rtx_REG (SImode, regno), stack_slot);
  4199 +
  4200 +  return insn;
  4201 +}
  4202 +
  4203 +
  4204 +/* There are two possible paths for prologue expansion,
  4205 +- the first is if the total frame size is < 2^15-1. In that
  4206 +case all the immediates will fit into the 16-bit immediate
  4207 +fields.
  4208 +- the second is when the frame size is too big, in that
  4209 +case an additional temporary register is used, first 
  4210 +as a cfa_temp to offset the sp, second as the cfa_store
  4211 +register.
  4212 +
  4213 +See the comment above dwarf2out_frame_debug_expr in 
  4214 +dwarf2out.c for more explanation of the "rules."
  4215 +
  4216 +
  4217 +Case 1:
  4218 +Rule #  Example Insn                       Effect
  4219 +2  	addi	sp, sp, -total_frame_size  cfa.reg=sp, cfa.offset=total_frame_size
  4220 +                                           cfa_store.reg=sp, cfa_store.offset=total_frame_size
  4221 +12  	stw	ra, offset(sp)		   
  4222 +12  	stw	r16, offset(sp)
  4223 +1  	mov	fp, sp
  4224 +  
  4225 +Case 2: 
  4226 +Rule #  Example Insn                       Effect
  4227 +6 	movi	r8, total_frame_size       cfa_temp.reg=r8, cfa_temp.offset=total_frame_size
  4228 +2  	sub	sp, sp, r8                 cfa.reg=sp, cfa.offset=total_frame_size
  4229 +                                           cfa_store.reg=sp, cfa_store.offset=total_frame_size
  4230 +5   	add	r8, r8, sp                 cfa_store.reg=r8, cfa_store.offset=0
  4231 +12  	stw	ra, offset(r8)
  4232 +12  	stw	r16, offset(r8)
  4233 +1  	mov	fp, sp
  4234 +
  4235 +*/
  4236 +
  4237 +void
  4238 +expand_prologue ()
  4239 +{
  4240 +  int i;
  4241 +  HOST_WIDE_INT total_frame_size;
  4242 +  int cfa_store_offset;
  4243 +  rtx insn;
  4244 +  rtx cfa_store_reg = 0;
  4245 +
  4246 +  total_frame_size = compute_frame_size ();
  4247 +
  4248 +  if (total_frame_size)
  4249 +    {
  4250 +
  4251 +      if (TOO_BIG_OFFSET (total_frame_size)) 
  4252 +	{
  4253 +	    /* cfa_temp and cfa_store_reg are the same register,
  4254 +	       cfa_store_reg overwrites cfa_temp */
  4255 +	    cfa_store_reg = gen_rtx_REG (SImode, TEMP_REG_NUM);
  4256 +	    insn = emit_insn (gen_rtx_SET (SImode,
  4257 +					   cfa_store_reg,
  4258 +					   GEN_INT (total_frame_size)));
  4259 +
  4260 +	    RTX_FRAME_RELATED_P (insn) = 1;
  4261 +
  4262 +
  4263 +	    insn = gen_rtx_SET (SImode,
  4264 +				stack_pointer_rtx,
  4265 +				gen_rtx_MINUS (SImode,
  4266 +					       stack_pointer_rtx,
  4267 +					       cfa_store_reg));
  4268 +
  4269 +	    insn = emit_insn (insn);
  4270 +	    RTX_FRAME_RELATED_P (insn) = 1;
  4271 +
  4272 +
  4273 +	    /* if there are no registers to save, I don't need to
  4274 +	       create a cfa_store */
  4275 +	    if (cfun->machine->frame.save_reg_size) 
  4276 +	      {
  4277 +		insn = gen_rtx_SET (SImode,
  4278 +				    cfa_store_reg,
  4279 +				    gen_rtx_PLUS (SImode,
  4280 +						  cfa_store_reg,
  4281 +						  stack_pointer_rtx));
  4282 +
  4283 +		insn = emit_insn (insn);
  4284 +		RTX_FRAME_RELATED_P (insn) = 1;
  4285 +	      }
  4286 +
  4287 +	    cfa_store_offset 
  4288 +	      = total_frame_size 
  4289 +		- (cfun->machine->frame.save_regs_offset
  4290 +		   + cfun->machine->frame.save_reg_rounded);
  4291 +	}
  4292 +      else
  4293 +	{
  4294 +	    insn = gen_rtx_SET (SImode,
  4295 +				stack_pointer_rtx,
  4296 +				gen_rtx_PLUS (SImode,
  4297 +					      stack_pointer_rtx,
  4298 +					      GEN_INT (-total_frame_size)));
  4299 +	    insn = emit_insn (insn);
  4300 +	    RTX_FRAME_RELATED_P (insn) = 1;
  4301 +
  4302 +	    cfa_store_reg = stack_pointer_rtx;
  4303 +	    cfa_store_offset 
  4304 +	      = cfun->machine->frame.save_regs_offset
  4305 +		+ cfun->machine->frame.save_reg_rounded;
  4306 +	}
  4307 +    }
  4308 +
  4309 +  if (MUST_SAVE_REGISTER (RA_REGNO))
  4310 +    {
  4311 +      cfa_store_offset -= 4;
  4312 +      save_reg (RA_REGNO, cfa_store_offset, cfa_store_reg);
  4313 +    }
  4314 +  if (MUST_SAVE_REGISTER (FP_REGNO))
  4315 +    {
  4316 +      cfa_store_offset -= 4;
  4317 +      save_reg (FP_REGNO, cfa_store_offset, cfa_store_reg);
  4318 +    }
  4319 +
  4320 +  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  4321 +    {
  4322 +      if (MUST_SAVE_REGISTER (i) && i != FP_REGNO && i != RA_REGNO)
  4323 +	{
  4324 +	  cfa_store_offset -= 4;
  4325 +	  save_reg (i, cfa_store_offset, cfa_store_reg);
  4326 +	}
  4327 +    }
  4328 +
  4329 +  if (frame_pointer_needed)
  4330 +    {
  4331 +      insn = emit_insn (gen_rtx_SET (SImode,
  4332 +				     gen_rtx_REG (SImode, FP_REGNO),
  4333 +				     gen_rtx_REG (SImode, SP_REGNO)));
  4334 +
  4335 +      RTX_FRAME_RELATED_P (insn) = 1;
  4336 +    }
  4337 +
  4338 +  /* If we are profiling, make sure no instructions are scheduled before
  4339 +     the call to mcount.  */
  4340 +  if (current_function_profile)
  4341 +    emit_insn (gen_blockage ());
  4342 +}
  4343 +
  4344 +void
  4345 +expand_epilogue (bool sibcall_p)
  4346 +{
  4347 +  rtx insn;
  4348 +  int i;
  4349 +  HOST_WIDE_INT total_frame_size;
  4350 +  int register_store_offset;
  4351 +
  4352 +  total_frame_size = compute_frame_size ();
  4353 +
  4354 +  if (!sibcall_p && nios2_can_use_return_insn ())
  4355 +    {
  4356 +      insn = emit_jump_insn (gen_return ());
  4357 +      return;
  4358 +    }
  4359 +
  4360 +  emit_insn (gen_blockage ());
  4361 +
  4362 +  register_store_offset =
  4363 +    cfun->machine->frame.save_regs_offset +
  4364 +    cfun->machine->frame.save_reg_rounded;
  4365 +
  4366 +  if (MUST_SAVE_REGISTER (RA_REGNO))
  4367 +    {
  4368 +      register_store_offset -= 4;
  4369 +      restore_reg (RA_REGNO, register_store_offset);
  4370 +    }
  4371 +
  4372 +  if (MUST_SAVE_REGISTER (FP_REGNO))
  4373 +    {
  4374 +      register_store_offset -= 4;
  4375 +      restore_reg (FP_REGNO, register_store_offset);
  4376 +    }
  4377 +
  4378 +  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  4379 +    {
  4380 +      if (MUST_SAVE_REGISTER (i) && i != FP_REGNO && i != RA_REGNO)
  4381 +	{
  4382 +	  register_store_offset -= 4;
  4383 +	  restore_reg (i, register_store_offset);
  4384 +	}
  4385 +    }
  4386 +
  4387 +  if (total_frame_size)
  4388 +    {
  4389 +      rtx sp_adjust;
  4390 +
  4391 +      if (TOO_BIG_OFFSET (total_frame_size))
  4392 +        {
  4393 +	  sp_adjust = gen_rtx_REG (SImode, TEMP_REG_NUM);
  4394 +	  insn = emit_insn (gen_rtx_SET (SImode,
  4395 +					 sp_adjust,
  4396 +					 GEN_INT (total_frame_size)));
  4397 +
  4398 +      	}
  4399 +      else
  4400 +        {
  4401 +	  sp_adjust = GEN_INT (total_frame_size);
  4402 +	}
  4403 +
  4404 +      insn = gen_rtx_SET (SImode,
  4405 +			  stack_pointer_rtx,
  4406 +			  gen_rtx_PLUS (SImode,
  4407 +					stack_pointer_rtx,
  4408 +					sp_adjust));
  4409 +      insn = emit_insn (insn);
  4410 +    }
  4411 +
  4412 +
  4413 +  if (!sibcall_p)
  4414 +    {
  4415 +      insn = emit_jump_insn (gen_return_from_epilogue (gen_rtx (REG, Pmode,
  4416 +								RA_REGNO)));
  4417 +    }
  4418 +}
  4419 +
  4420 +
  4421 +bool
  4422 +nios2_function_ok_for_sibcall (tree a ATTRIBUTE_UNUSED, tree b ATTRIBUTE_UNUSED)
  4423 +{
  4424 +  return true;
  4425 +}
  4426 +
  4427 +
  4428 +
  4429 +
  4430 +
  4431 +/* ----------------------- *
  4432 + * Profiling
  4433 + * ----------------------- */
  4434 +
  4435 +void
  4436 +function_profiler (FILE *file, int labelno)
  4437 +{
  4438 +  fprintf (file, "\t%s mcount begin, label: .LP%d\n", 
  4439 +           ASM_COMMENT_START, labelno);
  4440 +  fprintf (file, "\tnextpc\tr8\n");
  4441 +  fprintf (file, "\tmov\tr9, ra\n");
  4442 +  fprintf (file, "\tmovhi\tr10, %%hiadj(.LP%d)\n", labelno);
  4443 +  fprintf (file, "\taddi\tr10, r10, %%lo(.LP%d)\n", labelno);
  4444 +  fprintf (file, "\tcall\tmcount\n");
  4445 +  fprintf (file, "\tmov\tra, r9\n");
  4446 +  fprintf (file, "\t%s mcount end\n", ASM_COMMENT_START);
  4447 +}
  4448 +
  4449 +
  4450 +/***************************************
  4451 + * Stack Layout
  4452 + ***************************************/
  4453 +
  4454 +
  4455 +void
  4456 +dump_frame_size (FILE *file)
  4457 +{
  4458 +  fprintf (file, "\t%s Current Frame Info\n", ASM_COMMENT_START);
  4459 +
  4460 +  fprintf (file, "\t%s total_size = %ld\n", ASM_COMMENT_START,
  4461 +	   cfun->machine->frame.total_size);
  4462 +  fprintf (file, "\t%s var_size = %ld\n", ASM_COMMENT_START,
  4463 +	   cfun->machine->frame.var_size);
  4464 +  fprintf (file, "\t%s args_size = %ld\n", ASM_COMMENT_START,
  4465 +	   cfun->machine->frame.args_size);
  4466 +  fprintf (file, "\t%s save_reg_size = %d\n", ASM_COMMENT_START,
  4467 +	   cfun->machine->frame.save_reg_size);
  4468 +  fprintf (file, "\t%s save_reg_rounded = %d\n", ASM_COMMENT_START,
  4469 +	   cfun->machine->frame.save_reg_rounded);
  4470 +  fprintf (file, "\t%s initialized = %d\n", ASM_COMMENT_START,
  4471 +	   cfun->machine->frame.initialized);
  4472 +  fprintf (file, "\t%s num_regs = %d\n", ASM_COMMENT_START,
  4473 +	   cfun->machine->frame.num_regs);
  4474 +  fprintf (file, "\t%s save_regs_offset = %ld\n", ASM_COMMENT_START,
  4475 +	   cfun->machine->frame.save_regs_offset);
  4476 +  fprintf (file, "\t%s current_function_is_leaf = %d\n", ASM_COMMENT_START,
  4477 +	   current_function_is_leaf);
  4478 +  fprintf (file, "\t%s frame_pointer_needed = %d\n", ASM_COMMENT_START,
  4479 +	   frame_pointer_needed);
  4480 +  fprintf (file, "\t%s pretend_args_size = %d\n", ASM_COMMENT_START,
  4481 +	   current_function_pretend_args_size);
  4482 +
  4483 +}
  4484 +
  4485 +
  4486 +/* Return the bytes needed to compute the frame pointer from the current
  4487 +   stack pointer.
  4488 +*/
  4489 +
  4490 +HOST_WIDE_INT
  4491 +compute_frame_size ()
  4492 +{
  4493 +  unsigned int regno;
  4494 +  HOST_WIDE_INT var_size;	/* # of var. bytes allocated */
  4495 +  HOST_WIDE_INT total_size;	/* # bytes that the entire frame takes up */
  4496 +  HOST_WIDE_INT save_reg_size;	/* # bytes needed to store callee save regs */
  4497 +  HOST_WIDE_INT save_reg_rounded;	
  4498 +    /* # bytes needed to store callee save regs (rounded) */
  4499 +  HOST_WIDE_INT out_args_size;	/* # bytes needed for outgoing args */
  4500 +
  4501 +  save_reg_size = 0;
  4502 +  var_size = STACK_ALIGN (get_frame_size ());
  4503 +  out_args_size = STACK_ALIGN (current_function_outgoing_args_size);
  4504 +
  4505 +  total_size = var_size + out_args_size;
  4506 +
  4507 +  /* Calculate space needed for gp registers.  */
  4508 +  for (regno = 0; regno <= FIRST_PSEUDO_REGISTER; regno++)
  4509 +    {
  4510 +      if (MUST_SAVE_REGISTER (regno))
  4511 +	{
  4512 +	  save_reg_size += 4;
  4513 +	}
  4514 +    }
  4515 +
  4516 +  save_reg_rounded = STACK_ALIGN (save_reg_size);
  4517 +  total_size += save_reg_rounded;
  4518 +
  4519 +  total_size += STACK_ALIGN (current_function_pretend_args_size);
  4520 +
  4521 +  /* Save other computed information.  */
  4522 +  cfun->machine->frame.total_size = total_size;
  4523 +  cfun->machine->frame.var_size = var_size;
  4524 +  cfun->machine->frame.args_size = current_function_outgoing_args_size;
  4525 +  cfun->machine->frame.save_reg_size = save_reg_size;
  4526 +  cfun->machine->frame.save_reg_rounded = save_reg_rounded;
  4527 +  cfun->machine->frame.initialized = reload_completed;
  4528 +  cfun->machine->frame.num_regs = save_reg_size / UNITS_PER_WORD;
  4529 +
  4530 +  cfun->machine->frame.save_regs_offset
  4531 +    = save_reg_rounded ? current_function_outgoing_args_size + var_size : 0;
  4532 +
  4533 +  return total_size;
  4534 +}
  4535 +
  4536 +
  4537 +int
  4538 +nios2_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED)
  4539 +{
  4540 +  int offset;
  4541 +
  4542 +  /* Set OFFSET to the offset from the stack pointer.  */
  4543 +  switch (from)
  4544 +    {
  4545 +    case FRAME_POINTER_REGNUM:
  4546 +      offset = 0;
  4547 +      break;
  4548 +
  4549 +    case ARG_POINTER_REGNUM:
  4550 +      compute_frame_size ();
  4551 +      offset = cfun->machine->frame.total_size;
  4552 +      offset -= current_function_pretend_args_size;
  4553 +      break;
  4554 +
  4555 +    case RETURN_ADDRESS_POINTER_REGNUM:
  4556 +      compute_frame_size ();
  4557 +      /* since the return address is always the first of the
  4558 +         saved registers, return the offset to the beginning
  4559 +         of the saved registers block */
  4560 +      offset = cfun->machine->frame.save_regs_offset;
  4561 +      break;
  4562 +
  4563 +    default:
  4564 +      abort ();
  4565 +    }
  4566 +
  4567 +  return offset;
  4568 +}
  4569 +
  4570 +/* Return nonzero if this function is known to have a null epilogue.
  4571 +   This allows the optimizer to omit jumps to jumps if no stack
  4572 +   was created.  */
  4573 +int
  4574 +nios2_can_use_return_insn ()
  4575 +{
  4576 +  if (!reload_completed)
  4577 +    return 0;
  4578 +
  4579 +  if (regs_ever_live[RA_REGNO] || current_function_profile)
  4580 +    return 0;
  4581 +
  4582 +  if (cfun->machine->frame.initialized)
  4583 +    return cfun->machine->frame.total_size == 0;
  4584 +
  4585 +  return compute_frame_size () == 0;
  4586 +}
  4587 +
  4588 +
  4589 +
  4590 +
  4591 +
  4592 +/***************************************
  4593 + *
  4594 + ***************************************/
  4595 +
  4596 +const char *nios2_sys_nosys_string;    /* for -msys=nosys */
  4597 +const char *nios2_sys_lib_string;    /* for -msys-lib= */
  4598 +const char *nios2_sys_crt0_string;    /* for -msys-crt0= */
  4599 +
  4600 +void
  4601 +override_options ()
  4602 +{
  4603 +  /* Function to allocate machine-dependent function status.  */
  4604 +  init_machine_status = &nios2_init_machine_status;
  4605 +
  4606 +  nios2_section_threshold 
  4607 +    = g_switch_set ? g_switch_value : NIOS2_DEFAULT_GVALUE;
  4608 +
  4609 +  if (nios2_sys_nosys_string && *nios2_sys_nosys_string)
  4610 +    {
  4611 +      error ("invalid option '-msys=nosys%s'", nios2_sys_nosys_string);
  4612 +    }
  4613 +
  4614 +  /* If we don't have mul, we don't have mulx either! */
  4615 +  if (!TARGET_HAS_MUL && TARGET_HAS_MULX) 
  4616 +    {
  4617 +      target_flags &= ~HAS_MULX_FLAG;
  4618 +    }
  4619 +
  4620 +}
  4621 +
  4622 +void
  4623 +optimization_options (int level, int size)
  4624 +{
  4625 +  if (level || size)
  4626 +    {
  4627 +      target_flags |= INLINE_MEMCPY_FLAG;
  4628 +    }
  4629 +
  4630 +  if (level >= 3 && !size)
  4631 +    {
  4632 +      target_flags |= FAST_SW_DIV_FLAG;
  4633 +    }
  4634 +}
  4635 +
  4636 +/* Allocate a chunk of memory for per-function machine-dependent data.  */
  4637 +static struct machine_function *
  4638 +nios2_init_machine_status ()
  4639 +{
  4640 +  return ((struct machine_function *)
  4641 +	  ggc_alloc_cleared (sizeof (struct machine_function)));
  4642 +}
  4643 +
  4644 +
  4645 +
  4646 +/*****************
  4647 + * Describing Relative Costs of Operations
  4648 + *****************/
  4649 +
  4650 +/* Compute a (partial) cost for rtx X.  Return true if the complete
  4651 +   cost has been computed, and false if subexpressions should be
  4652 +   scanned.  In either case, *TOTAL contains the cost result.  */
  4653 +
  4654 +
  4655 +
  4656 +static bool
  4657 +nios2_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total)
  4658 +{
  4659 +  switch (code)
  4660 +    {
  4661 +      case CONST_INT:
  4662 +	if (INTVAL (x) == 0)
  4663 +	  {
  4664 +	    *total = COSTS_N_INSNS (0);
  4665 +	    return true;
  4666 +	  }
  4667 +	else if (SMALL_INT (INTVAL (x))
  4668 +		|| SMALL_INT_UNSIGNED (INTVAL (x))
  4669 +		|| UPPER16_INT (INTVAL (x)))
  4670 +	  {
  4671 +	    *total = COSTS_N_INSNS (2);
  4672 +	    return true;
  4673 +	  }
  4674 +	else
  4675 +	  {
  4676 +	    *total = COSTS_N_INSNS (4);
  4677 +	    return true;
  4678 +	  }
  4679 +
  4680 +      case LABEL_REF:
  4681 +      case SYMBOL_REF:
  4682 +	/* ??? gp relative stuff will fit in here */
  4683 +	/* fall through */
  4684 +      case CONST:
  4685 +      case CONST_DOUBLE:
  4686 +	{
  4687 +	  *total = COSTS_N_INSNS (4);
  4688 +	  return true;
  4689 +	}
  4690 +
  4691 +      case MULT:
  4692 +	{
  4693 +	  *total = COSTS_N_INSNS (1);
  4694 +	  return false;
  4695 +	}
  4696 +      case SIGN_EXTEND:
  4697 +	{
  4698 +	  *total = COSTS_N_INSNS (3);
  4699 +	  return false;
  4700 +	}
  4701 +      case ZERO_EXTEND:
  4702 +	{
  4703 +	  *total = COSTS_N_INSNS (1);
  4704 +	  return false;
  4705 +	}
  4706 +
  4707 +    default:
  4708 +      return false;
  4709 +    }
  4710 +}
  4711 +
  4712 +
  4713 +/***************************************
  4714 + * INSTRUCTION SUPPORT
  4715 + *
  4716 + * These functions are used within the Machine Description to
  4717 + * handle common or complicated output and expansions from
  4718 + * instructions.
  4719 + ***************************************/
  4720 +
  4721 +int
  4722 +nios2_emit_move_sequence (rtx *operands, enum machine_mode mode)
  4723 +{
  4724 +  rtx to = operands[0];
  4725 +  rtx from = operands[1];
  4726 +
  4727 +  if (!register_operand (to, mode) && !reg_or_0_operand (from, mode))
  4728 +    {
  4729 +      if (no_new_pseudos)
  4730 +	internal_error ("Trying to force_reg no_new_pseudos == 1");
  4731 +      from = copy_to_mode_reg (mode, from);
  4732 +    }
  4733 +
  4734 +  operands[0] = to;
  4735 +  operands[1] = from;
  4736 +  return 0;
  4737 +}
  4738 +
  4739 +/* Divide Support */
  4740 +
  4741 +/*
  4742 +  If -O3 is used, we want to output a table lookup for
  4743 +  divides between small numbers (both num and den >= 0
  4744 +  and < 0x10). The overhead of this method in the worse
  4745 +  case is 40 bytes in the text section (10 insns) and
  4746 +  256 bytes in the data section. Additional divides do
  4747 +  not incur additional penalties in the data section.
  4748 +
  4749 +  Code speed is improved for small divides by about 5x
  4750 +  when using this method in the worse case (~9 cycles
  4751 +  vs ~45). And in the worse case divides not within the
  4752 +  table are penalized by about 10% (~5 cycles vs ~45).
  4753 +  However in the typical case the penalty is not as bad
  4754 +  because doing the long divide in only 45 cycles is
  4755 +  quite optimistic.
  4756 +
  4757 +  ??? It would be nice to have some benchmarks other
  4758 +  than Dhrystone to back this up.
  4759 +
  4760 +  This bit of expansion is to create this instruction
  4761 +  sequence as rtl.
  4762 +	or	$8, $4, $5
  4763 +	slli	$9, $4, 4
  4764 +	cmpgeui	$3, $8, 16
  4765 +	beq	$3, $0, .L3
  4766 +	or	$10, $9, $5
  4767 +	add	$12, $11, divide_table
  4768 +	ldbu	$2, 0($12)
  4769 +	br	.L1
  4770 +.L3:
  4771 +	call	slow_div
  4772 +.L1:
  4773 +#	continue here with result in $2
  4774 +
  4775 +  ??? Ideally I would like the emit libcall block to contain
  4776 +  all of this code, but I don't know how to do that. What it
  4777 +  means is that if the divide can be eliminated, it may not
  4778 +  completely disappear.
  4779 +
  4780 +  ??? The __divsi3_table label should ideally be moved out
  4781 +  of this block and into a global. If it is placed into the
  4782 +  sdata section we can save even more cycles by doing things
  4783 +  gp relative.
  4784 +*/
  4785 +int
  4786 +nios2_emit_expensive_div (rtx *operands, enum machine_mode mode)
  4787 +{
  4788 +  rtx or_result, shift_left_result;
  4789 +  rtx lookup_value;
  4790 +  rtx lab1, lab3;
  4791 +  rtx insns;
  4792 +  rtx libfunc;
  4793 +  rtx final_result;
  4794 +  rtx tmp;
  4795 +
  4796 +  /* it may look a little generic, but only SImode
  4797 +     is supported for now */
  4798 +  if (mode != SImode)
  4799 +    abort ();
  4800 +
  4801 +  libfunc = sdiv_optab->handlers[(int) SImode].libfunc;
  4802 +
  4803 +
  4804 +
  4805 +  lab1 = gen_label_rtx ();
  4806 +  lab3 = gen_label_rtx ();
  4807 +
  4808 +  or_result = expand_simple_binop (SImode, IOR,
  4809 +				   operands[1], operands[2],
  4810 +				   0, 0, OPTAB_LIB_WIDEN);
  4811 +
  4812 +  emit_cmp_and_jump_insns (or_result, GEN_INT (15), GTU, 0,
  4813 +			   GET_MODE (or_result), 0, lab3);
  4814 +  JUMP_LABEL (get_last_insn ()) = lab3;
  4815 +
  4816 +  shift_left_result = expand_simple_binop (SImode, ASHIFT,
  4817 +					   operands[1], GEN_INT (4),
  4818 +					   0, 0, OPTAB_LIB_WIDEN);
  4819 +
  4820 +  lookup_value = expand_simple_binop (SImode, IOR,
  4821 +				      shift_left_result, operands[2],
  4822 +				      0, 0, OPTAB_LIB_WIDEN);
  4823 +
  4824 +  convert_move (operands[0],
  4825 +		gen_rtx (MEM, QImode,
  4826 +			 gen_rtx (PLUS, SImode,
  4827 +				  lookup_value,
  4828 +				  gen_rtx_SYMBOL_REF (SImode, "__divsi3_table"))),
  4829 +		1);
  4830 +
  4831 +
  4832 +  tmp = emit_jump_insn (gen_jump (lab1));
  4833 +  JUMP_LABEL (tmp) = lab1;
  4834 +  emit_barrier ();
  4835 +
  4836 +  emit_label (lab3);
  4837 +  LABEL_NUSES (lab3) = 1;
  4838 +
  4839 +  start_sequence ();
  4840 +  final_result = emit_library_call_value (libfunc, NULL_RTX,
  4841 +					  LCT_CONST, SImode, 2,
  4842 +					  operands[1], SImode,
  4843 +					  operands[2], SImode);
  4844 +
  4845 +
  4846 +  insns = get_insns ();
  4847 +  end_sequence ();
  4848 +  emit_libcall_block (insns, operands[0], final_result,
  4849 +		      gen_rtx (DIV, SImode, operands[1], operands[2]));
  4850 +
  4851 +  emit_label (lab1);
  4852 +  LABEL_NUSES (lab1) = 1;
  4853 +  return 1;
  4854 +}
  4855 +
  4856 +/* Branches/Compares */
  4857 +
  4858 +/* the way of handling branches/compares
  4859 +   in gcc is heavily borrowed from MIPS */
  4860 +
  4861 +enum internal_test
  4862 +{
  4863 +  ITEST_EQ,
  4864 +  ITEST_NE,
  4865 +  ITEST_GT,
  4866 +  ITEST_GE,
  4867 +  ITEST_LT,
  4868 +  ITEST_LE,
  4869 +  ITEST_GTU,
  4870 +  ITEST_GEU,
  4871 +  ITEST_LTU,
  4872 +  ITEST_LEU,
  4873 +  ITEST_MAX
  4874 +};
  4875 +
  4876 +static enum internal_test map_test_to_internal_test (enum rtx_code);
  4877 +
  4878 +/* Cached operands, and operator to compare for use in set/branch/trap
  4879 +   on condition codes.  */
  4880 +rtx branch_cmp[2];
  4881 +enum cmp_type branch_type;
  4882 +
  4883 +/* Make normal rtx_code into something we can index from an array */
  4884 +
  4885 +static enum internal_test
  4886 +map_test_to_internal_test (enum rtx_code test_code)
  4887 +{
  4888 +  enum internal_test test = ITEST_MAX;
  4889 +
  4890 +  switch (test_code)
  4891 +    {
  4892 +    case EQ:
  4893 +      test = ITEST_EQ;
  4894 +      break;
  4895 +    case NE:
  4896 +      test = ITEST_NE;
  4897 +      break;
  4898 +    case GT:
  4899 +      test = ITEST_GT;
  4900 +      break;
  4901 +    case GE:
  4902 +      test = ITEST_GE;
  4903 +      break;
  4904 +    case LT:
  4905 +      test = ITEST_LT;
  4906 +      break;
  4907 +    case LE:
  4908 +      test = ITEST_LE;
  4909 +      break;
  4910 +    case GTU:
  4911 +      test = ITEST_GTU;
  4912 +      break;
  4913 +    case GEU:
  4914 +      test = ITEST_GEU;
  4915 +      break;
  4916 +    case LTU:
  4917 +      test = ITEST_LTU;
  4918 +      break;
  4919 +    case LEU:
  4920 +      test = ITEST_LEU;
  4921 +      break;
  4922 +    default:
  4923 +      break;
  4924 +    }
  4925 +
  4926 +  return test;
  4927 +}
  4928 +
  4929 +/* Generate the code to compare (and possibly branch) two integer values
  4930 +   TEST_CODE is the comparison code we are trying to emulate 
  4931 +     (or implement directly)
  4932 +   RESULT is where to store the result of the comparison, 
  4933 +     or null to emit a branch
  4934 +   CMP0 CMP1 are the two comparison operands
  4935 +   DESTINATION is the destination of the branch, or null to only compare
  4936 +   */
  4937 +
  4938 +void
  4939 +gen_int_relational (enum rtx_code test_code, /* relational test (EQ, etc) */
  4940 +		    rtx result,		/* result to store comp. or 0 if branch */
  4941 +		    rtx cmp0,		/* first operand to compare */
  4942 +		    rtx cmp1,		/* second operand to compare */
  4943 +		    rtx destination)	/* destination of the branch, or 0 if compare */
  4944 +{
  4945 +  struct cmp_info
  4946 +  {
  4947 +    /* for register (or 0) compares */
  4948 +    enum rtx_code test_code_reg;	/* code to use in instruction (LT vs. LTU) */
  4949 +    int reverse_regs;		/* reverse registers in test */
  4950 +
  4951 +    /* for immediate compares */
  4952 +    enum rtx_code test_code_const;	
  4953 +         /* code to use in instruction (LT vs. LTU) */
  4954 +    int const_low;		/* low bound of constant we can accept */
  4955 +    int const_high;		/* high bound of constant we can accept */
  4956 +    int const_add;		/* constant to add */
  4957 +
  4958 +    /* generic info */
  4959 +    int unsignedp;		/* != 0 for unsigned comparisons.  */
  4960 +  };
  4961 +
  4962 +  static const struct cmp_info info[(int) ITEST_MAX] = {
  4963 +
  4964 +    {EQ, 0, EQ, -32768, 32767, 0, 0}, /* EQ  */
  4965 +    {NE, 0, NE, -32768, 32767, 0, 0}, /* NE  */
  4966 +
  4967 +    {LT, 1, GE, -32769, 32766, 1, 0}, /* GT  */
  4968 +    {GE, 0, GE, -32768, 32767, 0, 0}, /* GE  */
  4969 +    {LT, 0, LT, -32768, 32767, 0, 0}, /* LT  */
  4970 +    {GE, 1, LT, -32769, 32766, 1, 0}, /* LE  */
  4971 +
  4972 +    {LTU, 1, GEU, 0, 65534, 1, 0}, /* GTU */
  4973 +    {GEU, 0, GEU, 0, 65535, 0, 0}, /* GEU */
  4974 +    {LTU, 0, LTU, 0, 65535, 0, 0}, /* LTU */
  4975 +    {GEU, 1, LTU, 0, 65534, 1, 0}, /* LEU */
  4976 +  };
  4977 +
  4978 +  enum internal_test test;
  4979 +  enum machine_mode mode;
  4980 +  const struct cmp_info *p_info;
  4981 +  int branch_p;
  4982 +
  4983 +
  4984 +
  4985 +
  4986 +  test = map_test_to_internal_test (test_code);
  4987 +  if (test == ITEST_MAX)
  4988 +    abort ();
  4989 +
  4990 +  p_info = &info[(int) test];
  4991 +
  4992 +  mode = GET_MODE (cmp0);
  4993 +  if (mode == VOIDmode)
  4994 +    mode = GET_MODE (cmp1);
  4995 +
  4996 +  branch_p = (destination != 0);
  4997 +
  4998 +  /* We can't, under any circumstances, have const_ints in cmp0
  4999 +     ??? Actually we could have const0 */
  5000 +  if (GET_CODE (cmp0) == CONST_INT)
  5001 +    cmp0 = force_reg (mode, cmp0);
  5002 +
  5003 +  /* if the comparison is against an int not in legal range
  5004 +     move it into a register */
  5005 +  if (GET_CODE (cmp1) == CONST_INT)
  5006 +    {
  5007 +      HOST_WIDE_INT value = INTVAL (cmp1);
  5008 +
  5009 +      if (value < p_info->const_low || value > p_info->const_high)
  5010 +	cmp1 = force_reg (mode, cmp1);
  5011 +    }
  5012 +
  5013 +  /* Comparison to constants, may involve adding 1 to change a GT into GE.
  5014 +     Comparison between two registers, may involve switching operands.  */
  5015 +  if (GET_CODE (cmp1) == CONST_INT)
  5016 +    {
  5017 +      if (p_info->const_add != 0)
  5018 +	{
  5019 +	  HOST_WIDE_INT new = INTVAL (cmp1) + p_info->const_add;
  5020 +
  5021 +	  /* If modification of cmp1 caused overflow,
  5022 +	     we would get the wrong answer if we follow the usual path;
  5023 +	     thus, x > 0xffffffffU would turn into x > 0U.  */
  5024 +	  if ((p_info->unsignedp
  5025 +	       ? (unsigned HOST_WIDE_INT) new >
  5026 +	       (unsigned HOST_WIDE_INT) INTVAL (cmp1)
  5027 +	       : new > INTVAL (cmp1)) != (p_info->const_add > 0))
  5028 +	    {
  5029 +	      /* ??? This case can never happen with the current numbers,
  5030 +	         but I am paranoid and would rather an abort than
  5031 +	         a bug I will never find */
  5032 +	      abort ();
  5033 +	    }
  5034 +	  else
  5035 +	    cmp1 = GEN_INT (new);
  5036 +	}
  5037 +    }
  5038 +
  5039 +  else if (p_info->reverse_regs)
  5040 +    {
  5041 +      rtx temp = cmp0;
  5042 +      cmp0 = cmp1;
  5043 +      cmp1 = temp;
  5044 +    }
  5045 +
  5046 +
  5047 +
  5048 +  if (branch_p)
  5049 +    {
  5050 +      if (register_operand (cmp0, mode) && register_operand (cmp1, mode))
  5051 +	{
  5052 +	  rtx insn;
  5053 +	  rtx cond = gen_rtx (p_info->test_code_reg, mode, cmp0, cmp1);
  5054 +	  rtx label = gen_rtx_LABEL_REF (VOIDmode, destination);
  5055 +
  5056 +	  insn = gen_rtx_SET (VOIDmode, pc_rtx,
  5057 +			      gen_rtx_IF_THEN_ELSE (VOIDmode,
  5058 +						    cond, label, pc_rtx));
  5059 +	  emit_jump_insn (insn);
  5060 +	}
  5061 +      else
  5062 +	{
  5063 +	  rtx cond, label;
  5064 +
  5065 +	  result = gen_reg_rtx (mode);
  5066 +
  5067 +	  emit_move_insn (result,
  5068 +			  gen_rtx (p_info->test_code_const, mode, cmp0,
  5069 +				   cmp1));
  5070 +
  5071 +	  cond = gen_rtx (NE, mode, result, const0_rtx);
  5072 +	  label = gen_rtx_LABEL_REF (VOIDmode, destination);
  5073 +
  5074 +	  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
  5075 +				       gen_rtx_IF_THEN_ELSE (VOIDmode,
  5076 +							     cond,
  5077 +							     label, pc_rtx)));
  5078 +	}
  5079 +    }
  5080 +  else
  5081 +    {
  5082 +      if (register_operand (cmp0, mode) && register_operand (cmp1, mode))
  5083 +	{
  5084 +	  emit_move_insn (result,
  5085 +			  gen_rtx (p_info->test_code_reg, mode, cmp0, cmp1));
  5086 +	}
  5087 +      else
  5088 +	{
  5089 +	  emit_move_insn (result,
  5090 +			  gen_rtx (p_info->test_code_const, mode, cmp0,
  5091 +				   cmp1));
  5092 +	}
  5093 +    }
  5094 +
  5095 +}
  5096 +
  5097 +
  5098 +/* ??? For now conditional moves are only supported
  5099 +   when the mode of the operands being compared are
  5100 +   the same as the ones being moved */
  5101 +
  5102 +void
  5103 +gen_conditional_move (rtx *operands, enum machine_mode mode)
  5104 +{
  5105 +  rtx insn, cond;
  5106 +  rtx cmp_reg = gen_reg_rtx (mode);
  5107 +  enum rtx_code cmp_code = GET_CODE (operands[1]);
  5108 +  enum rtx_code move_code = EQ;
  5109 +
  5110 +  /* emit a comparison if it is not "simple".
  5111 +     Simple comparisons are X eq 0 and X ne 0 */
  5112 +  if ((cmp_code == EQ || cmp_code == NE) && branch_cmp[1] == const0_rtx)
  5113 +    {
  5114 +      cmp_reg = branch_cmp[0];
  5115 +      move_code = cmp_code;
  5116 +    }
  5117 +  else if ((cmp_code == EQ || cmp_code == NE) && branch_cmp[0] == const0_rtx)
  5118 +    {
  5119 +      cmp_reg = branch_cmp[1];
  5120 +      move_code = cmp_code == EQ ? NE : EQ;
  5121 +    }
  5122 +  else
  5123 +    gen_int_relational (cmp_code, cmp_reg, branch_cmp[0], branch_cmp[1],
  5124 +			NULL_RTX);
  5125 +
  5126 +  cond = gen_rtx (move_code, VOIDmode, cmp_reg, CONST0_RTX (mode));
  5127 +  insn = gen_rtx_SET (mode, operands[0],
  5128 +		      gen_rtx_IF_THEN_ELSE (mode,
  5129 +					    cond, operands[2], operands[3]));
  5130 +  emit_insn (insn);
  5131 +}
  5132 +
  5133 +/*******************
  5134 + * Addressing Modes
  5135 + *******************/
  5136 +
  5137 +int
  5138 +nios2_legitimate_address (rtx operand, enum machine_mode mode ATTRIBUTE_UNUSED, 
  5139 +                          int strict)
  5140 +{
  5141 +  int ret_val = 0;
  5142 +
  5143 +  switch (GET_CODE (operand))
  5144 +    {
  5145 +      /* direct.  */
  5146 +    case SYMBOL_REF:
  5147 +      if (SYMBOL_REF_IN_NIOS2_SMALL_DATA_P (operand))
  5148 +        {
  5149 +          ret_val = 1;
  5150 +          break;
  5151 +	}
  5152 +      /* else, fall through */
  5153 +    case LABEL_REF:
  5154 +    case CONST_INT:
  5155 +    case CONST:
  5156 +    case CONST_DOUBLE:
  5157 +      /* ??? In here I need to add gp addressing */
  5158 +      ret_val = 0;
  5159 +
  5160 +      break;
  5161 +
  5162 +      /* Register indirect.  */
  5163 +    case REG:
  5164 +      ret_val = REG_OK_FOR_BASE_P2 (operand, strict);
  5165 +      break;
  5166 +
  5167 +      /* Register indirect with displacement */
  5168 +    case PLUS:
  5169 +      {
  5170 +	rtx op0 = XEXP (operand, 0);
  5171 +	rtx op1 = XEXP (operand, 1);
  5172 +
  5173 +	if (REG_P (op0) && REG_P (op1))
  5174 +	  ret_val = 0;
  5175 +	else if (REG_P (op0) && CONSTANT_P (op1))
  5176 +	  ret_val = REG_OK_FOR_BASE_P2 (op0, strict)
  5177 +	    && SMALL_INT (INTVAL (op1));
  5178 +	else if (REG_P (op1) && CONSTANT_P (op0))
  5179 +	  ret_val = REG_OK_FOR_BASE_P2 (op1, strict)
  5180 +	    && SMALL_INT (INTVAL (op0));
  5181 +	else
  5182 +	  ret_val = 0;
  5183 +      }
  5184 +      break;
  5185 +
  5186 +    default:
  5187 +      ret_val = 0;
  5188 +      break;
  5189 +    }
  5190 +
  5191 +  return ret_val;
  5192 +}
  5193 +
  5194 +/* Return true if EXP should be placed in the small data section.  */
  5195 +
  5196 +static bool
  5197 +nios2_in_small_data_p (tree exp)
  5198 +{
  5199 +  /* We want to merge strings, so we never consider them small data.  */
  5200 +  if (TREE_CODE (exp) == STRING_CST)
  5201 +    return false;
  5202 +
  5203 +  if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
  5204 +    {
  5205 +      const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
  5206 +      /* ??? these string names need moving into 
  5207 +         an array in some header file */
  5208 +      if (nios2_section_threshold > 0
  5209 +          && (strcmp (section, ".sbss") == 0
  5210 +	      || strncmp (section, ".sbss.", 6) == 0
  5211 +	      || strcmp (section, ".sdata") == 0
  5212 +	      || strncmp (section, ".sdata.", 7) == 0))
  5213 +	return true;
  5214 +    }
  5215 +  else if (TREE_CODE (exp) == VAR_DECL)
  5216 +    {
  5217 +      HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
  5218 +
  5219 +      /* If this is an incomplete type with size 0, then we can't put it
  5220 +         in sdata because it might be too big when completed.  */
  5221 +      if (size > 0 && size <= nios2_section_threshold)
  5222 +	return true;
  5223 +    }
  5224 +
  5225 +  return false;
  5226 +}
  5227 +
  5228 +static void
  5229 +nios2_encode_section_info (tree decl, rtx rtl, int first)
  5230 +{
  5231 +
  5232 +  rtx symbol;
  5233 +  int flags;
  5234 +
  5235 +  default_encode_section_info (decl, rtl, first);
  5236 +  
  5237 +  /* Careful not to prod global register variables.  */
  5238 +  if (GET_CODE (rtl) != MEM)
  5239 +    return;
  5240 +  symbol = XEXP (rtl, 0);
  5241 +  if (GET_CODE (symbol) != SYMBOL_REF)
  5242 +    return;
  5243 +
  5244 +  flags = SYMBOL_REF_FLAGS (symbol);
  5245 +    
  5246 +  /* We don't want weak variables to be addressed with gp in case they end up with
  5247 +     value 0 which is not within 2^15 of $gp */
  5248 +  if (DECL_P (decl) && DECL_WEAK (decl))
  5249 +    flags |= SYMBOL_FLAG_WEAK_DECL;
  5250 +
  5251 +  SYMBOL_REF_FLAGS (symbol) = flags;
  5252 +}
  5253 +
  5254 +
  5255 +static unsigned int
  5256 +nios2_section_type_flags (tree decl, const char *name, int reloc)
  5257 +{
  5258 +  unsigned int flags;
  5259 +
  5260 +  flags = default_section_type_flags (decl, name, reloc);
  5261 +
  5262 +  /* ??? these string names need moving into an array in some header file */
  5263 +  if (strcmp (name, ".sbss") == 0
  5264 +      || strncmp (name, ".sbss.", 6) == 0
  5265 +      || strcmp (name, ".sdata") == 0
  5266 +      || strncmp (name, ".sdata.", 7) == 0)
  5267 +    flags |= SECTION_SMALL;
  5268 +
  5269 +  return flags;
  5270 +}
  5271 +
  5272 +
  5273 +
  5274 +
  5275 +/*****************************************
  5276 + * Defining the Output Assembler Language
  5277 + *****************************************/
  5278 +
  5279 +/* -------------- *
  5280 + * Output of Data
  5281 + * -------------- */
  5282 +
  5283 +
  5284 +/* -------------------------------- *
  5285 + * Output of Assembler Instructions
  5286 + * -------------------------------- */
  5287 +
  5288 +
  5289 +/* print the operand OP to file stream
  5290 +   FILE modified by LETTER. LETTER
  5291 +   can be one of:
  5292 +     i: print "i" if OP is an immediate, except 0
  5293 +     o: print "io" if OP is volatile
  5294 +
  5295 +     z: for const0_rtx print $0 instead of 0
  5296 +     H: for %hiadj
  5297 +     L: for %lo
  5298 +     U: for upper half of 32 bit value
  5299 + */
  5300 +
  5301 +void
  5302 +nios2_print_operand (FILE *file, rtx op, int letter)
  5303 +{
  5304 +
  5305 +  switch (letter)
  5306 +    {
  5307 +    case 'i':
  5308 +      if (CONSTANT_P (op) && (op != const0_rtx))
  5309 +	fprintf (file, "i");
  5310 +      return;
  5311 +
  5312 +    case 'o':
  5313 +      if (GET_CODE (op) == MEM
  5314 +          && ((MEM_VOLATILE_P (op) && !TARGET_CACHE_VOLATILE)
  5315 +              || TARGET_BYPASS_CACHE))
  5316 +	fprintf (file, "io");
  5317 +      return;
  5318 +
  5319 +    default:
  5320 +      break;
  5321 +    }
  5322 +
  5323 +  if (comparison_operator (op, VOIDmode))
  5324 +    {
  5325 +      if (letter == 0)
  5326 +	{
  5327 +	  fprintf (file, "%s", GET_RTX_NAME (GET_CODE (op)));
  5328 +	  return;
  5329 +	}
  5330 +    }
  5331 +
  5332 +
  5333 +  switch (GET_CODE (op))
  5334 +    {
  5335 +    case REG:
  5336 +      if (letter == 0 || letter == 'z')
  5337 +	{
  5338 +	  fprintf (file, "%s", reg_names[REGNO (op)]);
  5339 +	  return;
  5340 +	}
  5341 +
  5342 +    case CONST_INT:
  5343 +      if (INTVAL (op) == 0 && letter == 'z')
  5344 +	{
  5345 +	  fprintf (file, "zero");
  5346 +	  return;
  5347 +	}
  5348 +      else if (letter == 'U')
  5349 +	{
  5350 +	  HOST_WIDE_INT val = INTVAL (op);
  5351 +	  rtx new_op;
  5352 +	  val = (val / 65536) & 0xFFFF;
  5353 +	  new_op = GEN_INT (val);
  5354 +	  output_addr_const (file, new_op);
  5355 +	  return;
  5356 +	}
  5357 +
  5358 +      /* else, fall through */
  5359 +    case CONST:
  5360 +    case LABEL_REF:
  5361 +    case SYMBOL_REF:
  5362 +    case CONST_DOUBLE:
  5363 +      if (letter == 0 || letter == 'z')
  5364 +	{
  5365 +	  output_addr_const (file, op);
  5366 +	  return;
  5367 +	}
  5368 +      else if (letter == 'H')
  5369 +	{
  5370 +	  fprintf (file, "%%hiadj(");
  5371 +	  output_addr_const (file, op);
  5372 +	  fprintf (file, ")");
  5373 +	  return;
  5374 +	}
  5375 +      else if (letter == 'L')
  5376 +	{
  5377 +	  fprintf (file, "%%lo(");
  5378 +	  output_addr_const (file, op);
  5379 +	  fprintf (file, ")");
  5380 +	  return;
  5381 +	}
  5382 +
  5383 +
  5384 +    case SUBREG:
  5385 +    case MEM:
  5386 +      if (letter == 0)
  5387 +	{
  5388 +	  output_address (op);
  5389 +	  return;
  5390 +	}
  5391 +
  5392 +    case CODE_LABEL:
  5393 +      if (letter == 0)
  5394 +	{
  5395 +	  output_addr_const (file, op);
  5396 +	  return;
  5397 +	}
  5398 +
  5399 +    default:
  5400 +      break;
  5401 +    }
  5402 +
  5403 +  fprintf (stderr, "Missing way to print (%c) ", letter);
  5404 +  debug_rtx (op);
  5405 +  abort ();
  5406 +}
  5407 +
  5408 +static int gprel_constant (rtx);
  5409 +
  5410 +static int
  5411 +gprel_constant (rtx op)
  5412 +{
  5413 +  if (GET_CODE (op) == SYMBOL_REF
  5414 +      && SYMBOL_REF_IN_NIOS2_SMALL_DATA_P (op))
  5415 +    {
  5416 +      return 1;
  5417 +    }
  5418 +  else if (GET_CODE (op) == CONST
  5419 +           && GET_CODE (XEXP (op, 0)) == PLUS)
  5420 +    {
  5421 +      return gprel_constant (XEXP (XEXP (op, 0), 0));
  5422 +    }
  5423 +  else
  5424 +    {
  5425 +      return 0;
  5426 +    }
  5427 +}
  5428 +
  5429 +void
  5430 +nios2_print_operand_address (FILE *file, rtx op)
  5431 +{
  5432 +  switch (GET_CODE (op))
  5433 +    {
  5434 +    case CONST:
  5435 +    case CONST_INT:
  5436 +    case LABEL_REF:
  5437 +    case CONST_DOUBLE:
  5438 +    case SYMBOL_REF:
  5439 +      if (gprel_constant (op))
  5440 +        {
  5441 +          fprintf (file, "%%gprel(");
  5442 +          output_addr_const (file, op);
  5443 +          fprintf (file, ")(%s)", reg_names[GP_REGNO]);
  5444 +          return;
  5445 +        }
  5446 +
  5447 +      break;
  5448 +
  5449 +    case PLUS:
  5450 +      {
  5451 +	rtx op0 = XEXP (op, 0);
  5452 +	rtx op1 = XEXP (op, 1);
  5453 +
  5454 +	if (REG_P (op0) && CONSTANT_P (op1))
  5455 +	  {
  5456 +	    output_addr_const (file, op1);
  5457 +	    fprintf (file, "(%s)", reg_names[REGNO (op0)]);
  5458 +	    return;
  5459 +	  }
  5460 +	else if (REG_P (op1) && CONSTANT_P (op0))
  5461 +	  {
  5462 +	    output_addr_const (file, op0);
  5463 +	    fprintf (file, "(%s)", reg_names[REGNO (op1)]);
  5464 +	    return;
  5465 +	  }
  5466 +      }
  5467 +      break;
  5468 +
  5469 +    case REG:
  5470 +      fprintf (file, "0(%s)", reg_names[REGNO (op)]);
  5471 +      return;
  5472 +
  5473 +    case MEM:
  5474 +      {
  5475 +	rtx base = XEXP (op, 0);
  5476 +	PRINT_OPERAND_ADDRESS (file, base);
  5477 +	return;
  5478 +      }
  5479 +    default:
  5480 +      break;
  5481 +    }
  5482 +
  5483 +  fprintf (stderr, "Missing way to print address\n");
  5484 +  debug_rtx (op);
  5485 +  abort ();
  5486 +}
  5487 +
  5488 +
  5489 +
  5490 +
  5491 +
  5492 +/****************************
  5493 + * Predicates
  5494 + ****************************/
  5495 +
  5496 +int
  5497 +arith_operand (rtx op, enum machine_mode mode)
  5498 +{
  5499 +  if (GET_CODE (op) == CONST_INT && SMALL_INT (INTVAL (op)))
  5500 +    return 1;
  5501 +
  5502 +  return register_operand (op, mode);
  5503 +}
  5504 +
  5505 +int
  5506 +uns_arith_operand (rtx op, enum machine_mode mode)
  5507 +{
  5508 +  if (GET_CODE (op) == CONST_INT && SMALL_INT_UNSIGNED (INTVAL (op)))
  5509 +    return 1;
  5510 +
  5511 +  return register_operand (op, mode);
  5512 +}
  5513 +
  5514 +int
  5515 +logical_operand (rtx op, enum machine_mode mode)
  5516 +{
  5517 +  if (GET_CODE (op) == CONST_INT
  5518 +      && (SMALL_INT_UNSIGNED (INTVAL (op)) || UPPER16_INT (INTVAL (op))))
  5519 +    return 1;
  5520 +
  5521 +  return register_operand (op, mode);
  5522 +}
  5523 +
  5524 +int
  5525 +shift_operand (rtx op, enum machine_mode mode)
  5526 +{
  5527 +  if (GET_CODE (op) == CONST_INT && SHIFT_INT (INTVAL (op)))
  5528 +    return 1;
  5529 +
  5530 +  return register_operand (op, mode);
  5531 +}
  5532 +
  5533 +int
  5534 +rdwrctl_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
  5535 +{
  5536 +  return GET_CODE (op) == CONST_INT && RDWRCTL_INT (INTVAL (op));
  5537 +}
  5538 +
  5539 +/* Return truth value of whether OP is a register or the constant 0. */
  5540 +
  5541 +int
  5542 +reg_or_0_operand (rtx op, enum machine_mode mode)
  5543 +{
  5544 +  switch (GET_CODE (op))
  5545 +    {
  5546 +    case CONST_INT:
  5547 +      return INTVAL (op) == 0;
  5548 +
  5549 +    case CONST_DOUBLE:
  5550 +      return op == CONST0_RTX (mode);
  5551 +
  5552 +    default:
  5553 +      break;
  5554 +    }
  5555 +
  5556 +  return register_operand (op, mode);
  5557 +}
  5558 +
  5559 +
  5560 +int
  5561 +equality_op (rtx op, enum machine_mode mode)
  5562 +{
  5563 +  if (mode != GET_MODE (op))
  5564 +    return 0;
  5565 +
  5566 +  return GET_CODE (op) == EQ || GET_CODE (op) == NE;
  5567 +}
  5568 +
  5569 +int
  5570 +custom_insn_opcode (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
  5571 +{
  5572 +  return GET_CODE (op) == CONST_INT && CUSTOM_INSN_OPCODE (INTVAL (op));
  5573 +}
  5574 +
  5575 +
  5576 +
  5577 +
  5578 +
  5579 +
  5580 +
  5581 +/*****************************************************************************
  5582 +**
  5583 +** instruction scheduler
  5584 +**
  5585 +*****************************************************************************/
  5586 +static int
  5587 +nios2_use_dfa_pipeline_interface ()
  5588 +{
  5589 +  return 1;
  5590 +}
  5591 +
  5592 +
  5593 +static int
  5594 +nios2_issue_rate ()
  5595 +{
  5596 +#ifdef MAX_DFA_ISSUE_RATE
  5597 +  return MAX_DFA_ISSUE_RATE;
  5598 +#else
  5599 +  return 1;
  5600 +#endif
  5601 +}
  5602 +
  5603 +
  5604 +const char *
  5605 +asm_output_opcode (FILE *file ATTRIBUTE_UNUSED, 
  5606 +                   const char *ptr ATTRIBUTE_UNUSED)
  5607 +{
  5608 +  const char *p;
  5609 +
  5610 +  p = ptr;
  5611 +  return ptr;
  5612 +}
  5613 +
  5614 +
  5615 +
  5616 +/*****************************************************************************
  5617 +**
  5618 +** function arguments
  5619 +**
  5620 +*****************************************************************************/
  5621 +
  5622 +void
  5623 +init_cumulative_args (CUMULATIVE_ARGS *cum, 
  5624 +                      tree fntype ATTRIBUTE_UNUSED, 
  5625 +                      rtx libname ATTRIBUTE_UNUSED, 
  5626 +                      tree fndecl ATTRIBUTE_UNUSED, 
  5627 +                      int n_named_args ATTRIBUTE_UNUSED)
  5628 +{
  5629 +  cum->regs_used = 0;
  5630 +}
  5631 +
  5632 +
  5633 +/* Update the data in CUM to advance over an argument
  5634 +   of mode MODE and data type TYPE.
  5635 +   (TYPE is null for libcalls where that information may not be available.)  */
  5636 +
  5637 +void
  5638 +function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, 
  5639 +                      tree type ATTRIBUTE_UNUSED, int named ATTRIBUTE_UNUSED)
  5640 +{
  5641 +  HOST_WIDE_INT param_size;
  5642 +
  5643 +  if (mode == BLKmode)
  5644 +    {
  5645 +      param_size = int_size_in_bytes (type);
  5646 +      if (param_size < 0)
  5647 +	internal_error
  5648 +	  ("Do not know how to handle large structs or variable length types");
  5649 +    }
  5650 +  else
  5651 +    {
  5652 +      param_size = GET_MODE_SIZE (mode);
  5653 +    }
  5654 +
  5655 +  /* convert to words (round up) */
  5656 +  param_size = (3 + param_size) / 4;
  5657 +
  5658 +  if (cum->regs_used + param_size > NUM_ARG_REGS)
  5659 +    {
  5660 +      cum->regs_used = NUM_ARG_REGS;
  5661 +    }
  5662 +  else
  5663 +    {
  5664 +      cum->regs_used += param_size;
  5665 +    }
  5666 +
  5667 +  return;
  5668 +}
  5669 +
  5670 +/* Define where to put the arguments to a function.  Value is zero to
  5671 +   push the argument on the stack, or a hard register in which to
  5672 +   store the argument.
  5673 +
  5674 +   MODE is the argument's machine mode.
  5675 +   TYPE is the data type of the argument (as a tree).
  5676 +   This is null for libcalls where that information may
  5677 +   not be available.
  5678 +   CUM is a variable of type CUMULATIVE_ARGS which gives info about
  5679 +   the preceding args and about the function being called.
  5680 +   NAMED is nonzero if this argument is a named parameter
  5681 +   (otherwise it is an extra parameter matching an ellipsis).  */
  5682 +rtx
  5683 +function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode, 
  5684 +              tree type ATTRIBUTE_UNUSED, int named ATTRIBUTE_UNUSED)
  5685 +{
  5686 +  rtx return_rtx = NULL_RTX;
  5687 +
  5688 +  if (cum->regs_used < NUM_ARG_REGS)
  5689 +    {
  5690 +      return_rtx = gen_rtx_REG (mode, FIRST_ARG_REGNO + cum->regs_used);
  5691 +    }
  5692 +
  5693 +  return return_rtx;
  5694 +}
  5695 +
  5696 +int
  5697 +function_arg_partial_nregs (const CUMULATIVE_ARGS *cum,
  5698 +                            enum machine_mode mode, tree type, 
  5699 +                            int named ATTRIBUTE_UNUSED)
  5700 +{
  5701 +  HOST_WIDE_INT param_size;
  5702 +
  5703 +  if (mode == BLKmode)
  5704 +    {
  5705 +      param_size = int_size_in_bytes (type);
  5706 +      if (param_size < 0)
  5707 +	internal_error
  5708 +	  ("Do not know how to handle large structs or variable length types");
  5709 +    }
  5710 +  else
  5711 +    {
  5712 +      param_size = GET_MODE_SIZE (mode);
  5713 +    }
  5714 +
  5715 +  /* convert to words (round up) */
  5716 +  param_size = (3 + param_size) / 4;
  5717 +
  5718 +  if (cum->regs_used < NUM_ARG_REGS
  5719 +      && cum->regs_used + param_size > NUM_ARG_REGS)
  5720 +    {
  5721 +      return NUM_ARG_REGS - cum->regs_used;
  5722 +    }
  5723 +  else
  5724 +    {
  5725 +      return 0;
  5726 +    }
  5727 +}
  5728 +
  5729 +
  5730 +int
  5731 +nios2_return_in_memory (tree type)
  5732 +{
  5733 +  int res = ((int_size_in_bytes (type) > (2 * UNITS_PER_WORD))
  5734 +  	     || (int_size_in_bytes (type) == -1));
  5735 +
  5736 +  return res;
  5737 +}
  5738 +
  5739 +/* ??? It may be possible to eliminate the copyback and implement
  5740 +       my own va_arg type, but that is more work for now. */
  5741 +int
  5742 +nios2_setup_incoming_varargs (const CUMULATIVE_ARGS *cum, 
  5743 +                              enum machine_mode mode, tree type, 
  5744 +                              int no_rtl)
  5745 +{
  5746 +  CUMULATIVE_ARGS local_cum;
  5747 +  int regs_to_push;
  5748 +
  5749 +  local_cum = *cum;
  5750 +  FUNCTION_ARG_ADVANCE (local_cum, mode, type, 1);
  5751 +
  5752 +  regs_to_push = NUM_ARG_REGS - local_cum.regs_used;
  5753 +
  5754 +  if (!no_rtl)
  5755 +    {
  5756 +      if (regs_to_push > 0)
  5757 +	{
  5758 +	  rtx ptr, mem;
  5759 +
  5760 +	  ptr = virtual_incoming_args_rtx;
  5761 +	  mem = gen_rtx_MEM (BLKmode, ptr);
  5762 +
  5763 +	  /* va_arg is an array access in this case, which causes
  5764 +	     it to get MEM_IN_STRUCT_P set.  We must set it here
  5765 +	     so that the insn scheduler won't assume that these
  5766 +	     stores can't possibly overlap with the va_arg loads.  */
  5767 +	  MEM_SET_IN_STRUCT_P (mem, 1);
  5768 +
  5769 +	  emit_insn (gen_blockage ());
  5770 +	  move_block_from_reg (local_cum.regs_used + FIRST_ARG_REGNO, mem,
  5771 +			       regs_to_push);
  5772 +	  emit_insn (gen_blockage ());
  5773 +	}
  5774 +    }
  5775 +
  5776 +  return regs_to_push * UNITS_PER_WORD;
  5777 +
  5778 +}
  5779 +
  5780 +
  5781 +
  5782 +/*****************************************************************************
  5783 +**
  5784 +** builtins
  5785 +**
  5786 +** This method for handling builtins is from CSP where _many_ more types of
  5787 +** expanders have already been written. Check there first before writing
  5788 +** new ones.
  5789 +**
  5790 +*****************************************************************************/
  5791 +
  5792 +enum nios2_builtins
  5793 +{
  5794 +  NIOS2_BUILTIN_LDBIO,
  5795 +  NIOS2_BUILTIN_LDBUIO,
  5796 +  NIOS2_BUILTIN_LDHIO,
  5797 +  NIOS2_BUILTIN_LDHUIO,
  5798 +  NIOS2_BUILTIN_LDWIO,
  5799 +  NIOS2_BUILTIN_STBIO,
  5800 +  NIOS2_BUILTIN_STHIO,
  5801 +  NIOS2_BUILTIN_STWIO,
  5802 +  NIOS2_BUILTIN_SYNC,
  5803 +  NIOS2_BUILTIN_RDCTL,
  5804 +  NIOS2_BUILTIN_WRCTL,
  5805 +
  5806 +  NIOS2_BUILTIN_CUSTOM_N,
  5807 +  NIOS2_BUILTIN_CUSTOM_NI,
  5808 +  NIOS2_BUILTIN_CUSTOM_NF,
  5809 +  NIOS2_BUILTIN_CUSTOM_NP,
  5810 +  NIOS2_BUILTIN_CUSTOM_NII,
  5811 +  NIOS2_BUILTIN_CUSTOM_NIF,
  5812 +  NIOS2_BUILTIN_CUSTOM_NIP,
  5813 +  NIOS2_BUILTIN_CUSTOM_NFI,
  5814 +  NIOS2_BUILTIN_CUSTOM_NFF,
  5815 +  NIOS2_BUILTIN_CUSTOM_NFP,
  5816 +  NIOS2_BUILTIN_CUSTOM_NPI,
  5817 +  NIOS2_BUILTIN_CUSTOM_NPF,
  5818 +  NIOS2_BUILTIN_CUSTOM_NPP,
  5819 +  NIOS2_BUILTIN_CUSTOM_IN,
  5820 +  NIOS2_BUILTIN_CUSTOM_INI,
  5821 +  NIOS2_BUILTIN_CUSTOM_INF,
  5822 +  NIOS2_BUILTIN_CUSTOM_INP,
  5823 +  NIOS2_BUILTIN_CUSTOM_INII,
  5824 +  NIOS2_BUILTIN_CUSTOM_INIF,
  5825 +  NIOS2_BUILTIN_CUSTOM_INIP,
  5826 +  NIOS2_BUILTIN_CUSTOM_INFI,
  5827 +  NIOS2_BUILTIN_CUSTOM_INFF,
  5828 +  NIOS2_BUILTIN_CUSTOM_INFP,
  5829 +  NIOS2_BUILTIN_CUSTOM_INPI,
  5830 +  NIOS2_BUILTIN_CUSTOM_INPF,
  5831 +  NIOS2_BUILTIN_CUSTOM_INPP,
  5832 +  NIOS2_BUILTIN_CUSTOM_FN,
  5833 +  NIOS2_BUILTIN_CUSTOM_FNI,
  5834 +  NIOS2_BUILTIN_CUSTOM_FNF,
  5835 +  NIOS2_BUILTIN_CUSTOM_FNP,
  5836 +  NIOS2_BUILTIN_CUSTOM_FNII,
  5837 +  NIOS2_BUILTIN_CUSTOM_FNIF,
  5838 +  NIOS2_BUILTIN_CUSTOM_FNIP,
  5839 +  NIOS2_BUILTIN_CUSTOM_FNFI,
  5840 +  NIOS2_BUILTIN_CUSTOM_FNFF,
  5841 +  NIOS2_BUILTIN_CUSTOM_FNFP,
  5842 +  NIOS2_BUILTIN_CUSTOM_FNPI,
  5843 +  NIOS2_BUILTIN_CUSTOM_FNPF,
  5844 +  NIOS2_BUILTIN_CUSTOM_FNPP,
  5845 +  NIOS2_BUILTIN_CUSTOM_PN,
  5846 +  NIOS2_BUILTIN_CUSTOM_PNI,
  5847 +  NIOS2_BUILTIN_CUSTOM_PNF,
  5848 +  NIOS2_BUILTIN_CUSTOM_PNP,
  5849 +  NIOS2_BUILTIN_CUSTOM_PNII,
  5850 +  NIOS2_BUILTIN_CUSTOM_PNIF,
  5851 +  NIOS2_BUILTIN_CUSTOM_PNIP,
  5852 +  NIOS2_BUILTIN_CUSTOM_PNFI,
  5853 +  NIOS2_BUILTIN_CUSTOM_PNFF,
  5854 +  NIOS2_BUILTIN_CUSTOM_PNFP,
  5855 +  NIOS2_BUILTIN_CUSTOM_PNPI,
  5856 +  NIOS2_BUILTIN_CUSTOM_PNPF,
  5857 +  NIOS2_BUILTIN_CUSTOM_PNPP,
  5858 +
  5859 +
  5860 +  LIM_NIOS2_BUILTINS
  5861 +};
  5862 +
  5863 +struct builtin_description
  5864 +{
  5865 +    const enum insn_code icode;
  5866 +    const char *const name;
  5867 +    const enum nios2_builtins code;
  5868 +    const tree *type;
  5869 +    rtx (* expander) PARAMS ((const struct builtin_description *,
  5870 +                              tree, rtx, rtx, enum machine_mode, int));
  5871 +};
  5872 +
  5873 +static rtx nios2_expand_STXIO (const struct builtin_description *, 
  5874 +                               tree, rtx, rtx, enum machine_mode, int);
  5875 +static rtx nios2_expand_LDXIO (const struct builtin_description *, 
  5876 +                               tree, rtx, rtx, enum machine_mode, int);
  5877 +static rtx nios2_expand_sync (const struct builtin_description *, 
  5878 +                              tree, rtx, rtx, enum machine_mode, int);
  5879 +static rtx nios2_expand_rdctl (const struct builtin_description *, 
  5880 +                               tree, rtx, rtx, enum machine_mode, int);
  5881 +static rtx nios2_expand_wrctl (const struct builtin_description *, 
  5882 +                               tree, rtx, rtx, enum machine_mode, int);
  5883 +
  5884 +static rtx nios2_expand_custom_n (const struct builtin_description *, 
  5885 +                                  tree, rtx, rtx, enum machine_mode, int);
  5886 +static rtx nios2_expand_custom_Xn (const struct builtin_description *, 
  5887 +                                   tree, rtx, rtx, enum machine_mode, int);
  5888 +static rtx nios2_expand_custom_nX (const struct builtin_description *, 
  5889 +                                   tree, rtx, rtx, enum machine_mode, int);
  5890 +static rtx nios2_expand_custom_XnX (const struct builtin_description *, 
  5891 +                                    tree, rtx, rtx, enum machine_mode, int);
  5892 +static rtx nios2_expand_custom_nXX (const struct builtin_description *, 
  5893 +                                    tree, rtx, rtx, enum machine_mode, int);
  5894 +static rtx nios2_expand_custom_XnXX (const struct builtin_description *, 
  5895 +                                     tree, rtx, rtx, enum machine_mode, int);
  5896 +
  5897 +static tree endlink;
  5898 +
  5899 +/* int fn (volatile const void *)
  5900 + */
  5901 +static tree int_ftype_volatile_const_void_p;
  5902 +
  5903 +/* int fn (int)
  5904 + */
  5905 +static tree int_ftype_int;
  5906 +
  5907 +/* void fn (int, int)
  5908 + */
  5909 +static tree void_ftype_int_int;
  5910 +
  5911 +/* void fn (volatile void *, int)
  5912 + */
  5913 +static tree void_ftype_volatile_void_p_int;
  5914 +
  5915 +/* void fn (void)
  5916 + */
  5917 +static tree void_ftype_void;
  5918 +
  5919 +static tree custom_n;
  5920 +static tree custom_ni;
  5921 +static tree custom_nf;
  5922 +static tree custom_np;
  5923 +static tree custom_nii;
  5924 +static tree custom_nif;
  5925 +static tree custom_nip;
  5926 +static tree custom_nfi;
  5927 +static tree custom_nff;
  5928 +static tree custom_nfp;
  5929 +static tree custom_npi;
  5930 +static tree custom_npf;
  5931 +static tree custom_npp;
  5932 +static tree custom_in;
  5933 +static tree custom_ini;
  5934 +static tree custom_inf;
  5935 +static tree custom_inp;
  5936 +static tree custom_inii;
  5937 +static tree custom_inif;
  5938 +static tree custom_inip;
  5939 +static tree custom_infi;
  5940 +static tree custom_inff;
  5941 +static tree custom_infp;
  5942 +static tree custom_inpi;
  5943 +static tree custom_inpf;
  5944 +static tree custom_inpp;
  5945 +static tree custom_fn;
  5946 +static tree custom_fni;
  5947 +static tree custom_fnf;
  5948 +static tree custom_fnp;
  5949 +static tree custom_fnii;
  5950 +static tree custom_fnif;
  5951 +static tree custom_fnip;
  5952 +static tree custom_fnfi;
  5953 +static tree custom_fnff;
  5954 +static tree custom_fnfp;
  5955 +static tree custom_fnpi;
  5956 +static tree custom_fnpf;
  5957 +static tree custom_fnpp;
  5958 +static tree custom_pn;
  5959 +static tree custom_pni;
  5960 +static tree custom_pnf;
  5961 +static tree custom_pnp;
  5962 +static tree custom_pnii;
  5963 +static tree custom_pnif;
  5964 +static tree custom_pnip;
  5965 +static tree custom_pnfi;
  5966 +static tree custom_pnff;
  5967 +static tree custom_pnfp;
  5968 +static tree custom_pnpi;
  5969 +static tree custom_pnpf;
  5970 +static tree custom_pnpp;
  5971 +
  5972 +
  5973 +static const struct builtin_description bdesc[] = {
  5974 +    {CODE_FOR_ldbio, "__builtin_ldbio", NIOS2_BUILTIN_LDBIO, &int_ftype_volatile_const_void_p, nios2_expand_LDXIO},
  5975 +    {CODE_FOR_ldbuio, "__builtin_ldbuio", NIOS2_BUILTIN_LDBUIO, &int_ftype_volatile_const_void_p, nios2_expand_LDXIO},
  5976 +    {CODE_FOR_ldhio, "__builtin_ldhio", NIOS2_BUILTIN_LDHIO, &int_ftype_volatile_const_void_p, nios2_expand_LDXIO},
  5977 +    {CODE_FOR_ldhuio, "__builtin_ldhuio", NIOS2_BUILTIN_LDHUIO, &int_ftype_volatile_const_void_p, nios2_expand_LDXIO},
  5978 +    {CODE_FOR_ldwio, "__builtin_ldwio", NIOS2_BUILTIN_LDWIO, &int_ftype_volatile_const_void_p, nios2_expand_LDXIO},
  5979 +
  5980 +    {CODE_FOR_stbio, "__builtin_stbio", NIOS2_BUILTIN_STBIO, &void_ftype_volatile_void_p_int, nios2_expand_STXIO},
  5981 +    {CODE_FOR_sthio, "__builtin_sthio", NIOS2_BUILTIN_STHIO, &void_ftype_volatile_void_p_int, nios2_expand_STXIO},
  5982 +    {CODE_FOR_stwio, "__builtin_stwio", NIOS2_BUILTIN_STWIO, &void_ftype_volatile_void_p_int, nios2_expand_STXIO},
  5983 +
  5984 +    {CODE_FOR_sync, "__builtin_sync", NIOS2_BUILTIN_SYNC, &void_ftype_void, nios2_expand_sync},
  5985 +    {CODE_FOR_rdctl, "__builtin_rdctl", NIOS2_BUILTIN_RDCTL, &int_ftype_int, nios2_expand_rdctl},
  5986 +    {CODE_FOR_wrctl, "__builtin_wrctl", NIOS2_BUILTIN_WRCTL, &void_ftype_int_int, nios2_expand_wrctl},
  5987 +
  5988 +    {CODE_FOR_custom_n, "__builtin_custom_n", NIOS2_BUILTIN_CUSTOM_N, &custom_n, nios2_expand_custom_n},
  5989 +    {CODE_FOR_custom_ni, "__builtin_custom_ni", NIOS2_BUILTIN_CUSTOM_NI, &custom_ni, nios2_expand_custom_nX},
  5990 +    {CODE_FOR_custom_nf, "__builtin_custom_nf", NIOS2_BUILTIN_CUSTOM_NF, &custom_nf, nios2_expand_custom_nX},
  5991 +    {CODE_FOR_custom_np, "__builtin_custom_np", NIOS2_BUILTIN_CUSTOM_NP, &custom_np, nios2_expand_custom_nX},
  5992 +    {CODE_FOR_custom_nii, "__builtin_custom_nii", NIOS2_BUILTIN_CUSTOM_NII, &custom_nii, nios2_expand_custom_nXX},
  5993 +    {CODE_FOR_custom_nif, "__builtin_custom_nif", NIOS2_BUILTIN_CUSTOM_NIF, &custom_nif, nios2_expand_custom_nXX},
  5994 +    {CODE_FOR_custom_nip, "__builtin_custom_nip", NIOS2_BUILTIN_CUSTOM_NIP, &custom_nip, nios2_expand_custom_nXX},
  5995 +    {CODE_FOR_custom_nfi, "__builtin_custom_nfi", NIOS2_BUILTIN_CUSTOM_NFI, &custom_nfi, nios2_expand_custom_nXX},
  5996 +    {CODE_FOR_custom_nff, "__builtin_custom_nff", NIOS2_BUILTIN_CUSTOM_NFF, &custom_nff, nios2_expand_custom_nXX},
  5997 +    {CODE_FOR_custom_nfp, "__builtin_custom_nfp", NIOS2_BUILTIN_CUSTOM_NFP, &custom_nfp, nios2_expand_custom_nXX},
  5998 +    {CODE_FOR_custom_npi, "__builtin_custom_npi", NIOS2_BUILTIN_CUSTOM_NPI, &custom_npi, nios2_expand_custom_nXX},
  5999 +    {CODE_FOR_custom_npf, "__builtin_custom_npf", NIOS2_BUILTIN_CUSTOM_NPF, &custom_npf, nios2_expand_custom_nXX},
  6000 +    {CODE_FOR_custom_npp, "__builtin_custom_npp", NIOS2_BUILTIN_CUSTOM_NPP, &custom_npp, nios2_expand_custom_nXX},
  6001 +    {CODE_FOR_custom_in, "__builtin_custom_in", NIOS2_BUILTIN_CUSTOM_IN, &custom_in, nios2_expand_custom_Xn},
  6002 +    {CODE_FOR_custom_ini, "__builtin_custom_ini", NIOS2_BUILTIN_CUSTOM_INI, &custom_ini, nios2_expand_custom_XnX},
  6003 +    {CODE_FOR_custom_inf, "__builtin_custom_inf", NIOS2_BUILTIN_CUSTOM_INF, &custom_inf, nios2_expand_custom_XnX},
  6004 +    {CODE_FOR_custom_inp, "__builtin_custom_inp", NIOS2_BUILTIN_CUSTOM_INP, &custom_inp, nios2_expand_custom_XnX},
  6005 +    {CODE_FOR_custom_inii, "__builtin_custom_inii", NIOS2_BUILTIN_CUSTOM_INII, &custom_inii, nios2_expand_custom_XnXX},
  6006 +    {CODE_FOR_custom_inif, "__builtin_custom_inif", NIOS2_BUILTIN_CUSTOM_INIF, &custom_inif, nios2_expand_custom_XnXX},
  6007 +    {CODE_FOR_custom_inip, "__builtin_custom_inip", NIOS2_BUILTIN_CUSTOM_INIP, &custom_inip, nios2_expand_custom_XnXX},
  6008 +    {CODE_FOR_custom_infi, "__builtin_custom_infi", NIOS2_BUILTIN_CUSTOM_INFI, &custom_infi, nios2_expand_custom_XnXX},
  6009 +    {CODE_FOR_custom_inff, "__builtin_custom_inff", NIOS2_BUILTIN_CUSTOM_INFF, &custom_inff, nios2_expand_custom_XnXX},
  6010 +    {CODE_FOR_custom_infp, "__builtin_custom_infp", NIOS2_BUILTIN_CUSTOM_INFP, &custom_infp, nios2_expand_custom_XnXX},
  6011 +    {CODE_FOR_custom_inpi, "__builtin_custom_inpi", NIOS2_BUILTIN_CUSTOM_INPI, &custom_inpi, nios2_expand_custom_XnXX},
  6012 +    {CODE_FOR_custom_inpf, "__builtin_custom_inpf", NIOS2_BUILTIN_CUSTOM_INPF, &custom_inpf, nios2_expand_custom_XnXX},
  6013 +    {CODE_FOR_custom_inpp, "__builtin_custom_inpp", NIOS2_BUILTIN_CUSTOM_INPP, &custom_inpp, nios2_expand_custom_XnXX},
  6014 +    {CODE_FOR_custom_fn, "__builtin_custom_fn", NIOS2_BUILTIN_CUSTOM_FN, &custom_fn, nios2_expand_custom_Xn},
  6015 +    {CODE_FOR_custom_fni, "__builtin_custom_fni", NIOS2_BUILTIN_CUSTOM_FNI, &custom_fni, nios2_expand_custom_XnX},
  6016 +    {CODE_FOR_custom_fnf, "__builtin_custom_fnf", NIOS2_BUILTIN_CUSTOM_FNF, &custom_fnf, nios2_expand_custom_XnX},
  6017 +    {CODE_FOR_custom_fnp, "__builtin_custom_fnp", NIOS2_BUILTIN_CUSTOM_FNP, &custom_fnp, nios2_expand_custom_XnX},
  6018 +    {CODE_FOR_custom_fnii, "__builtin_custom_fnii", NIOS2_BUILTIN_CUSTOM_FNII, &custom_fnii, nios2_expand_custom_XnXX},
  6019 +    {CODE_FOR_custom_fnif, "__builtin_custom_fnif", NIOS2_BUILTIN_CUSTOM_FNIF, &custom_fnif, nios2_expand_custom_XnXX},
  6020 +    {CODE_FOR_custom_fnip, "__builtin_custom_fnip", NIOS2_BUILTIN_CUSTOM_FNIP, &custom_fnip, nios2_expand_custom_XnXX},
  6021 +    {CODE_FOR_custom_fnfi, "__builtin_custom_fnfi", NIOS2_BUILTIN_CUSTOM_FNFI, &custom_fnfi, nios2_expand_custom_XnXX},
  6022 +    {CODE_FOR_custom_fnff, "__builtin_custom_fnff", NIOS2_BUILTIN_CUSTOM_FNFF, &custom_fnff, nios2_expand_custom_XnXX},
  6023 +    {CODE_FOR_custom_fnfp, "__builtin_custom_fnfp", NIOS2_BUILTIN_CUSTOM_FNFP, &custom_fnfp, nios2_expand_custom_XnXX},
  6024 +    {CODE_FOR_custom_fnpi, "__builtin_custom_fnpi", NIOS2_BUILTIN_CUSTOM_FNPI, &custom_fnpi, nios2_expand_custom_XnXX},
  6025 +    {CODE_FOR_custom_fnpf, "__builtin_custom_fnpf", NIOS2_BUILTIN_CUSTOM_FNPF, &custom_fnpf, nios2_expand_custom_XnXX},
  6026 +    {CODE_FOR_custom_fnpp, "__builtin_custom_fnpp", NIOS2_BUILTIN_CUSTOM_FNPP, &custom_fnpp, nios2_expand_custom_XnXX},
  6027 +    {CODE_FOR_custom_pn, "__builtin_custom_pn", NIOS2_BUILTIN_CUSTOM_PN, &custom_pn, nios2_expand_custom_Xn},
  6028 +    {CODE_FOR_custom_pni, "__builtin_custom_pni", NIOS2_BUILTIN_CUSTOM_PNI, &custom_pni, nios2_expand_custom_XnX},
  6029 +    {CODE_FOR_custom_pnf, "__builtin_custom_pnf", NIOS2_BUILTIN_CUSTOM_PNF, &custom_pnf, nios2_expand_custom_XnX},
  6030 +    {CODE_FOR_custom_pnp, "__builtin_custom_pnp", NIOS2_BUILTIN_CUSTOM_PNP, &custom_pnp, nios2_expand_custom_XnX},
  6031 +    {CODE_FOR_custom_pnii, "__builtin_custom_pnii", NIOS2_BUILTIN_CUSTOM_PNII, &custom_pnii, nios2_expand_custom_XnXX},
  6032 +    {CODE_FOR_custom_pnif, "__builtin_custom_pnif", NIOS2_BUILTIN_CUSTOM_PNIF, &custom_pnif, nios2_expand_custom_XnXX},
  6033 +    {CODE_FOR_custom_pnip, "__builtin_custom_pnip", NIOS2_BUILTIN_CUSTOM_PNIP, &custom_pnip, nios2_expand_custom_XnXX},
  6034 +    {CODE_FOR_custom_pnfi, "__builtin_custom_pnfi", NIOS2_BUILTIN_CUSTOM_PNFI, &custom_pnfi, nios2_expand_custom_XnXX},
  6035 +    {CODE_FOR_custom_pnff, "__builtin_custom_pnff", NIOS2_BUILTIN_CUSTOM_PNFF, &custom_pnff, nios2_expand_custom_XnXX},
  6036 +    {CODE_FOR_custom_pnfp, "__builtin_custom_pnfp", NIOS2_BUILTIN_CUSTOM_PNFP, &custom_pnfp, nios2_expand_custom_XnXX},
  6037 +    {CODE_FOR_custom_pnpi, "__builtin_custom_pnpi", NIOS2_BUILTIN_CUSTOM_PNPI, &custom_pnpi, nios2_expand_custom_XnXX},
  6038 +    {CODE_FOR_custom_pnpf, "__builtin_custom_pnpf", NIOS2_BUILTIN_CUSTOM_PNPF, &custom_pnpf, nios2_expand_custom_XnXX},
  6039 +    {CODE_FOR_custom_pnpp, "__builtin_custom_pnpp", NIOS2_BUILTIN_CUSTOM_PNPP, &custom_pnpp, nios2_expand_custom_XnXX},
  6040 +
  6041 +
  6042 +    {0, 0, 0, 0, 0},
  6043 +};
  6044 +
  6045 +/* This does not have a closing bracket on purpose (see use) */
  6046 +#define def_param(TYPE) \
  6047 +  tree_cons (NULL_TREE, TYPE,
  6048 +
  6049 +static void
  6050 +nios2_init_builtins ()
  6051 +{
  6052 +  const struct builtin_description *d;
  6053 +
  6054 +
  6055 +  endlink = void_list_node;
  6056 +
  6057 +  /* Special indenting here because one of the brackets is in def_param */
  6058 +  /* *INDENT-OFF* */
  6059 +
  6060 +  /* int fn (volatile const void *)
  6061 +   */
  6062 +  int_ftype_volatile_const_void_p
  6063 +    = build_function_type (integer_type_node,
  6064 +			   def_param (build_qualified_type (ptr_type_node,
  6065 +			                                    TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE))
  6066 +			   endlink));
  6067 +
  6068 +
  6069 +  /* void fn (volatile void *, int)
  6070 +   */
  6071 +  void_ftype_volatile_void_p_int
  6072 +    = build_function_type (void_type_node,
  6073 +			   def_param (build_qualified_type (ptr_type_node,
  6074 +			                                    TYPE_QUAL_VOLATILE))
  6075 +			   def_param (integer_type_node)
  6076 +			   endlink)));
  6077 +
  6078 +  /* void fn (void)
  6079 +   */
  6080 +  void_ftype_void
  6081 +      = build_function_type (void_type_node,
  6082 +                             endlink);
  6083 +
  6084 +  /* int fn (int)
  6085 +   */
  6086 +  int_ftype_int
  6087 +      = build_function_type (integer_type_node,
  6088 +                             def_param (integer_type_node)
  6089 +                             endlink));
  6090 +
  6091 +  /* void fn (int, int)
  6092 +   */
  6093 +  void_ftype_int_int
  6094 +      = build_function_type (void_type_node,
  6095 +                             def_param (integer_type_node)
  6096 +                             def_param (integer_type_node)
  6097 +                             endlink)));
  6098 +
  6099 +
  6100 +#define CUSTOM_NUM def_param (integer_type_node)
  6101 +
  6102 +  custom_n
  6103 +      = build_function_type (void_type_node,
  6104 +  			     CUSTOM_NUM
  6105 +  			     endlink));
  6106 +  custom_ni
  6107 +      = build_function_type (void_type_node,
  6108 +  			     CUSTOM_NUM
  6109 +  			     def_param (integer_type_node)
  6110 +  			     endlink)));
  6111 +  custom_nf
  6112 +      = build_function_type (void_type_node,
  6113 +  			     CUSTOM_NUM
  6114 +  			     def_param (float_type_node)
  6115 +  			     endlink)));
  6116 +  custom_np
  6117 +      = build_function_type (void_type_node,
  6118 +  			     CUSTOM_NUM
  6119 +  			     def_param (ptr_type_node)
  6120 +  			     endlink)));
  6121 +  custom_nii
  6122 +      = build_function_type (void_type_node,
  6123 +  			     CUSTOM_NUM
  6124 +  			     def_param (integer_type_node)
  6125 +  			     def_param (integer_type_node)
  6126 +  			     endlink))));
  6127 +  custom_nif
  6128 +      = build_function_type (void_type_node,
  6129 +  			     CUSTOM_NUM
  6130 +  			     def_param (integer_type_node)
  6131 +  			     def_param (float_type_node)
  6132 +  			     endlink))));
  6133 +  custom_nip
  6134 +      = build_function_type (void_type_node,
  6135 +  			     CUSTOM_NUM
  6136 +  			     def_param (integer_type_node)
  6137 +  			     def_param (ptr_type_node)
  6138 +  			     endlink))));
  6139 +  custom_nfi
  6140 +      = build_function_type (void_type_node,
  6141 +  			     CUSTOM_NUM
  6142 +  			     def_param (float_type_node)
  6143 +  			     def_param (integer_type_node)
  6144 +  			     endlink))));
  6145 +  custom_nff
  6146 +      = build_function_type (void_type_node,
  6147 +  			     CUSTOM_NUM
  6148 +  			     def_param (float_type_node)
  6149 +  			     def_param (float_type_node)
  6150 +  			     endlink))));
  6151 +  custom_nfp
  6152 +      = build_function_type (void_type_node,
  6153 +  			     CUSTOM_NUM
  6154 +  			     def_param (float_type_node)
  6155 +  			     def_param (ptr_type_node)
  6156 +  			     endlink))));
  6157 +  custom_npi
  6158 +      = build_function_type (void_type_node,
  6159 +  			     CUSTOM_NUM
  6160 +  			     def_param (ptr_type_node)
  6161 +  			     def_param (integer_type_node)
  6162 +  			     endlink))));
  6163 +  custom_npf
  6164 +      = build_function_type (void_type_node,
  6165 +  			     CUSTOM_NUM
  6166 +  			     def_param (ptr_type_node)
  6167 +  			     def_param (float_type_node)
  6168 +  			     endlink))));
  6169 +  custom_npp
  6170 +      = build_function_type (void_type_node,
  6171 +  			     CUSTOM_NUM
  6172 +  			     def_param (ptr_type_node)
  6173 +  			     def_param (ptr_type_node)
  6174 +  			     endlink))));
  6175 +
  6176 +  custom_in
  6177 +      = build_function_type (integer_type_node,
  6178 +  			     CUSTOM_NUM
  6179 +  			     endlink));
  6180 +  custom_ini
  6181 +      = build_function_type (integer_type_node,
  6182 +  			     CUSTOM_NUM
  6183 +  			     def_param (integer_type_node)
  6184 +  			     endlink)));
  6185 +  custom_inf
  6186 +      = build_function_type (integer_type_node,
  6187 +  			     CUSTOM_NUM
  6188 +  			     def_param (float_type_node)
  6189 +  			     endlink)));
  6190 +  custom_inp
  6191 +      = build_function_type (integer_type_node,
  6192 +  			     CUSTOM_NUM
  6193 +  			     def_param (ptr_type_node)
  6194 +  			     endlink)));
  6195 +  custom_inii
  6196 +      = build_function_type (integer_type_node,
  6197 +  			     CUSTOM_NUM
  6198 +  			     def_param (integer_type_node)
  6199 +  			     def_param (integer_type_node)
  6200 +  			     endlink))));
  6201 +  custom_inif
  6202 +      = build_function_type (integer_type_node,
  6203 +  			     CUSTOM_NUM
  6204 +  			     def_param (integer_type_node)
  6205 +  			     def_param (float_type_node)
  6206 +  			     endlink))));
  6207 +  custom_inip
  6208 +      = build_function_type (integer_type_node,
  6209 +  			     CUSTOM_NUM
  6210 +  			     def_param (integer_type_node)
  6211 +  			     def_param (ptr_type_node)
  6212 +  			     endlink))));
  6213 +  custom_infi
  6214 +      = build_function_type (integer_type_node,
  6215 +  			     CUSTOM_NUM
  6216 +  			     def_param (float_type_node)
  6217 +  			     def_param (integer_type_node)
  6218 +  			     endlink))));
  6219 +  custom_inff
  6220 +      = build_function_type (integer_type_node,
  6221 +  			     CUSTOM_NUM
  6222 +  			     def_param (float_type_node)
  6223 +  			     def_param (float_type_node)
  6224 +  			     endlink))));
  6225 +  custom_infp
  6226 +      = build_function_type (integer_type_node,
  6227 +  			     CUSTOM_NUM
  6228 +  			     def_param (float_type_node)
  6229 +  			     def_param (ptr_type_node)
  6230 +  			     endlink))));
  6231 +  custom_inpi
  6232 +      = build_function_type (integer_type_node,
  6233 +  			     CUSTOM_NUM
  6234 +  			     def_param (ptr_type_node)
  6235 +  			     def_param (integer_type_node)
  6236 +  			     endlink))));
  6237 +  custom_inpf
  6238 +      = build_function_type (integer_type_node,
  6239 +  			     CUSTOM_NUM
  6240 +  			     def_param (ptr_type_node)
  6241 +  			     def_param (float_type_node)
  6242 +  			     endlink))));
  6243 +  custom_inpp
  6244 +      = build_function_type (integer_type_node,
  6245 +  			     CUSTOM_NUM
  6246 +  			     def_param (ptr_type_node)
  6247 +  			     def_param (ptr_type_node)
  6248 +  			     endlink))));
  6249 +
  6250 +  custom_fn
  6251 +      = build_function_type (float_type_node,
  6252 +  			     CUSTOM_NUM
  6253 +  			     endlink));
  6254 +  custom_fni
  6255 +      = build_function_type (float_type_node,
  6256 +  			     CUSTOM_NUM
  6257 +  			     def_param (integer_type_node)
  6258 +  			     endlink)));
  6259 +  custom_fnf
  6260 +      = build_function_type (float_type_node,
  6261 +  			     CUSTOM_NUM
  6262 +  			     def_param (float_type_node)
  6263 +  			     endlink)));
  6264 +  custom_fnp
  6265 +      = build_function_type (float_type_node,
  6266 +  			     CUSTOM_NUM
  6267 +  			     def_param (ptr_type_node)
  6268 +  			     endlink)));
  6269 +  custom_fnii
  6270 +      = build_function_type (float_type_node,
  6271 +  			     CUSTOM_NUM
  6272 +  			     def_param (integer_type_node)
  6273 +  			     def_param (integer_type_node)
  6274 +  			     endlink))));
  6275 +  custom_fnif
  6276 +      = build_function_type (float_type_node,
  6277 +  			     CUSTOM_NUM
  6278 +  			     def_param (integer_type_node)
  6279 +  			     def_param (float_type_node)
  6280 +  			     endlink))));
  6281 +  custom_fnip
  6282 +      = build_function_type (float_type_node,
  6283 +  			     CUSTOM_NUM
  6284 +  			     def_param (integer_type_node)
  6285 +  			     def_param (ptr_type_node)
  6286 +  			     endlink))));
  6287 +  custom_fnfi
  6288 +      = build_function_type (float_type_node,
  6289 +  			     CUSTOM_NUM
  6290 +  			     def_param (float_type_node)
  6291 +  			     def_param (integer_type_node)
  6292 +  			     endlink))));
  6293 +  custom_fnff
  6294 +      = build_function_type (float_type_node,
  6295 +  			     CUSTOM_NUM
  6296 +  			     def_param (float_type_node)
  6297 +  			     def_param (float_type_node)
  6298 +  			     endlink))));
  6299 +  custom_fnfp
  6300 +      = build_function_type (float_type_node,
  6301 +  			     CUSTOM_NUM
  6302 +  			     def_param (float_type_node)
  6303 +  			     def_param (ptr_type_node)
  6304 +  			     endlink))));
  6305 +  custom_fnpi
  6306 +      = build_function_type (float_type_node,
  6307 +  			     CUSTOM_NUM
  6308 +  			     def_param (ptr_type_node)
  6309 +  			     def_param (integer_type_node)
  6310 +  			     endlink))));
  6311 +  custom_fnpf
  6312 +      = build_function_type (float_type_node,
  6313 +  			     CUSTOM_NUM
  6314 +  			     def_param (ptr_type_node)
  6315 +  			     def_param (float_type_node)
  6316 +  			     endlink))));
  6317 +  custom_fnpp
  6318 +      = build_function_type (float_type_node,
  6319 +  			     CUSTOM_NUM
  6320 +  			     def_param (ptr_type_node)
  6321 +  			     def_param (ptr_type_node)
  6322 +  			     endlink))));
  6323 +
  6324 +
  6325 +  custom_pn
  6326 +      = build_function_type (ptr_type_node,
  6327 +  			     CUSTOM_NUM
  6328 +  			     endlink));
  6329 +  custom_pni
  6330 +      = build_function_type (ptr_type_node,
  6331 +  			     CUSTOM_NUM
  6332 +  			     def_param (integer_type_node)
  6333 +  			     endlink)));
  6334 +  custom_pnf
  6335 +      = build_function_type (ptr_type_node,
  6336 +  			     CUSTOM_NUM
  6337 +  			     def_param (float_type_node)
  6338 +  			     endlink)));
  6339 +  custom_pnp
  6340 +      = build_function_type (ptr_type_node,
  6341 +  			     CUSTOM_NUM
  6342 +  			     def_param (ptr_type_node)
  6343 +  			     endlink)));
  6344 +  custom_pnii
  6345 +      = build_function_type (ptr_type_node,
  6346 +  			     CUSTOM_NUM
  6347 +  			     def_param (integer_type_node)
  6348 +  			     def_param (integer_type_node)
  6349 +  			     endlink))));
  6350 +  custom_pnif
  6351 +      = build_function_type (ptr_type_node,
  6352 +  			     CUSTOM_NUM
  6353 +  			     def_param (integer_type_node)
  6354 +  			     def_param (float_type_node)
  6355 +  			     endlink))));
  6356 +  custom_pnip
  6357 +      = build_function_type (ptr_type_node,
  6358 +  			     CUSTOM_NUM
  6359 +  			     def_param (integer_type_node)
  6360 +  			     def_param (ptr_type_node)
  6361 +  			     endlink))));
  6362 +  custom_pnfi
  6363 +      = build_function_type (ptr_type_node,
  6364 +  			     CUSTOM_NUM
  6365 +  			     def_param (float_type_node)
  6366 +  			     def_param (integer_type_node)
  6367 +  			     endlink))));
  6368 +  custom_pnff
  6369 +      = build_function_type (ptr_type_node,
  6370 +  			     CUSTOM_NUM
  6371 +  			     def_param (float_type_node)
  6372 +  			     def_param (float_type_node)
  6373 +  			     endlink))));
  6374 +  custom_pnfp
  6375 +      = build_function_type (ptr_type_node,
  6376 +  			     CUSTOM_NUM
  6377 +  			     def_param (float_type_node)
  6378 +  			     def_param (ptr_type_node)
  6379 +  			     endlink))));
  6380 +  custom_pnpi
  6381 +      = build_function_type (ptr_type_node,
  6382 +  			     CUSTOM_NUM
  6383 +  			     def_param (ptr_type_node)
  6384 +  			     def_param (integer_type_node)
  6385 +  			     endlink))));
  6386 +  custom_pnpf
  6387 +      = build_function_type (ptr_type_node,
  6388 +  			     CUSTOM_NUM
  6389 +  			     def_param (ptr_type_node)
  6390 +  			     def_param (float_type_node)
  6391 +  			     endlink))));
  6392 +  custom_pnpp
  6393 +      = build_function_type (ptr_type_node,
  6394 +  			     CUSTOM_NUM
  6395 +  			     def_param (ptr_type_node)
  6396 +  			     def_param (ptr_type_node)
  6397 +  			     endlink))));
  6398 +
  6399 +
  6400 +
  6401 +  /* *INDENT-ON* */
  6402 +
  6403 +
  6404 +  for (d = bdesc; d->name; d++)
  6405 +    {
  6406 +      builtin_function (d->name, *d->type, d->code,
  6407 +			BUILT_IN_MD, NULL, NULL);
  6408 +    }
  6409 +}
  6410 +
  6411 +/* Expand an expression EXP that calls a built-in function,
  6412 +   with result going to TARGET if that's convenient
  6413 +   (and in mode MODE if that's convenient).
  6414 +   SUBTARGET may be used as the target for computing one of EXP's operands.
  6415 +   IGNORE is nonzero if the value is to be ignored.  */
  6416 +
  6417 +static rtx
  6418 +nios2_expand_builtin (tree exp, rtx target, rtx subtarget, 
  6419 +                      enum machine_mode mode, int ignore)
  6420 +{
  6421 +  const struct builtin_description *d;
  6422 +  tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
  6423 +  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
  6424 +
  6425 +  for (d = bdesc; d->name; d++)
  6426 +    if (d->code == fcode)
  6427 +      return (d->expander) (d, exp, target, subtarget, mode, ignore);
  6428 +
  6429 +  /* we should have seen one of the functins we registered */
  6430 +  abort ();
  6431 +}
  6432 +
  6433 +static rtx nios2_create_target (const struct builtin_description *, rtx);
  6434 +
  6435 +
  6436 +static rtx
  6437 +nios2_create_target (const struct builtin_description *d, rtx target)
  6438 +{
  6439 +  if (!target
  6440 +      || !(*insn_data[d->icode].operand[0].predicate) (target,
  6441 +                                                       insn_data[d->icode].operand[0].mode))
  6442 +    {
  6443 +      target = gen_reg_rtx (insn_data[d->icode].operand[0].mode);
  6444 +    }
  6445 +
  6446 +  return target;
  6447 +}
  6448 +
  6449 +
  6450 +static rtx nios2_extract_opcode (const struct builtin_description *, int, tree);
  6451 +static rtx nios2_extract_operand (const struct builtin_description *, int, int, tree);
  6452 +
  6453 +static rtx
  6454 +nios2_extract_opcode (const struct builtin_description *d, int op, tree arglist)
  6455 +{
  6456 +  enum machine_mode mode = insn_data[d->icode].operand[op].mode;
  6457 +  tree arg = TREE_VALUE (arglist);
  6458 +  rtx opcode = expand_expr (arg, NULL_RTX, mode, 0);
  6459 +  opcode = protect_from_queue (opcode, 0);
  6460 +
  6461 +  if (!(*insn_data[d->icode].operand[op].predicate) (opcode, mode))
  6462 +    error ("Custom instruction opcode must be compile time constant in the range 0-255 for %s", d->name);
  6463 +
  6464 +  return opcode;
  6465 +}
  6466 +
  6467 +static rtx
  6468 +nios2_extract_operand (const struct builtin_description *d, int op, int argnum, tree arglist)
  6469 +{
  6470 +  enum machine_mode mode = insn_data[d->icode].operand[op].mode;
  6471 +  tree arg = TREE_VALUE (arglist);
  6472 +  rtx operand = expand_expr (arg, NULL_RTX, mode, 0);
  6473 +  operand = protect_from_queue (operand, 0);
  6474 +
  6475 +  if (!(*insn_data[d->icode].operand[op].predicate) (operand, mode))
  6476 +    operand = copy_to_mode_reg (mode, operand);
  6477 +
  6478 +  /* ??? Better errors would be nice */
  6479 +  if (!(*insn_data[d->icode].operand[op].predicate) (operand, mode))
  6480 +    error ("Invalid argument %d to %s", argnum, d->name);
  6481 +
  6482 +  return operand;
  6483 +}
  6484 +
  6485 +
  6486 +static rtx
  6487 +nios2_expand_custom_n (const struct builtin_description *d, tree exp, 
  6488 +                       rtx target ATTRIBUTE_UNUSED, rtx subtarget ATTRIBUTE_UNUSED, 
  6489 +                       enum machine_mode mode ATTRIBUTE_UNUSED, int ignore ATTRIBUTE_UNUSED)
  6490 +{
  6491 +  tree arglist = TREE_OPERAND (exp, 1);
  6492 +  rtx pat;
  6493 +  rtx opcode;
  6494 +
  6495 +  /* custom_n should have exactly one operand */
  6496 +  if (insn_data[d->icode].n_operands != 1)
  6497 +    abort ();
  6498 +
  6499 +  opcode = nios2_extract_opcode (d, 0, arglist);
  6500 +
  6501 +  pat = GEN_FCN (d->icode) (opcode);
  6502 +  if (!pat)
  6503 +    return 0;
  6504 +  emit_insn (pat);
  6505 +  return 0;
  6506 +}
  6507 +
  6508 +static rtx
  6509 +nios2_expand_custom_Xn (const struct builtin_description *d, tree exp, 
  6510 +                        rtx target, rtx subtarget ATTRIBUTE_UNUSED, 
  6511 +                        enum machine_mode mode ATTRIBUTE_UNUSED, 
  6512 +                        int ignore ATTRIBUTE_UNUSED)
  6513 +{
  6514 +  tree arglist = TREE_OPERAND (exp, 1);
  6515 +  rtx pat;
  6516 +  rtx opcode;
  6517 +
  6518 +  /* custom_Xn should have exactly two operands */
  6519 +  if (insn_data[d->icode].n_operands != 2)
  6520 +    abort ();
  6521 +
  6522 +  target = nios2_create_target (d, target);
  6523 +  opcode = nios2_extract_opcode (d, 1, arglist);
  6524 +
  6525 +  pat = GEN_FCN (d->icode) (target, opcode);
  6526 +  if (!pat)
  6527 +    return 0;
  6528 +  emit_insn (pat);
  6529 +  return target;
  6530 +}
  6531 +
  6532 +static rtx
  6533 +nios2_expand_custom_nX (const struct builtin_description *d, tree exp, 
  6534 +                        rtx target ATTRIBUTE_UNUSED, rtx subtarget ATTRIBUTE_UNUSED, 
  6535 +                        enum machine_mode mode ATTRIBUTE_UNUSED, int ignore ATTRIBUTE_UNUSED)
  6536 +{
  6537 +  tree arglist = TREE_OPERAND (exp, 1);
  6538 +  rtx pat;
  6539 +  rtx opcode;
  6540 +  rtx operands[1];
  6541 +  int i;
  6542 +
  6543 +
  6544 +  /* custom_nX should have exactly two operands */
  6545 +  if (insn_data[d->icode].n_operands != 2)
  6546 +    abort ();
  6547 +
  6548 +  opcode = nios2_extract_opcode (d, 0, arglist);
  6549 +  for (i = 0; i < 1; i++)
  6550 +    {
  6551 +      arglist = TREE_CHAIN (arglist);
  6552 +      operands[i] = nios2_extract_operand (d, i + 1, i + 1, arglist);
  6553 +    }
  6554 +
  6555 +  pat = GEN_FCN (d->icode) (opcode, operands[0]);
  6556 +  if (!pat)
  6557 +    return 0;
  6558 +  emit_insn (pat);
  6559 +  return 0;
  6560 +}
  6561 +
  6562 +static rtx
  6563 +nios2_expand_custom_XnX (const struct builtin_description *d, tree exp, rtx target, 
  6564 +                         rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, 
  6565 +                         int ignore ATTRIBUTE_UNUSED)
  6566 +{
  6567 +  tree arglist = TREE_OPERAND (exp, 1);
  6568 +  rtx pat;
  6569 +  rtx opcode;
  6570 +  rtx operands[1];
  6571 +  int i;
  6572 +
  6573 +  /* custom_Xn should have exactly three operands */
  6574 +  if (insn_data[d->icode].n_operands != 3)
  6575 +    abort ();
  6576 +
  6577 +  target = nios2_create_target (d, target);
  6578 +  opcode = nios2_extract_opcode (d, 1, arglist);
  6579 +
  6580 +  for (i = 0; i < 1; i++)
  6581 +    {
  6582 +      arglist = TREE_CHAIN (arglist);
  6583 +      operands[i] = nios2_extract_operand (d, i + 2, i + 1, arglist);
  6584 +    }
  6585 +
  6586 +  pat = GEN_FCN (d->icode) (target, opcode, operands[0]);
  6587 +
  6588 +  if (!pat)
  6589 +    return 0;
  6590 +  emit_insn (pat);
  6591 +  return target;
  6592 +}
  6593 +
  6594 +static rtx
  6595 +nios2_expand_custom_nXX (const struct builtin_description *d, tree exp, rtx target ATTRIBUTE_UNUSED, 
  6596 +                         rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, 
  6597 +                         int ignore ATTRIBUTE_UNUSED)
  6598 +{
  6599 +  tree arglist = TREE_OPERAND (exp, 1);
  6600 +  rtx pat;
  6601 +  rtx opcode;
  6602 +  rtx operands[2];
  6603 +  int i;
  6604 +
  6605 +
  6606 +  /* custom_nX should have exactly three operands */
  6607 +  if (insn_data[d->icode].n_operands != 3)
  6608 +    abort ();
  6609 +
  6610 +  opcode = nios2_extract_opcode (d, 0, arglist);
  6611 +  for (i = 0; i < 2; i++)
  6612 +    {
  6613 +      arglist = TREE_CHAIN (arglist);
  6614 +      operands[i] = nios2_extract_operand (d, i + 1, i + 1, arglist);
  6615 +    }
  6616 +
  6617 +  pat = GEN_FCN (d->icode) (opcode, operands[0], operands[1]);
  6618 +  if (!pat)
  6619 +    return 0;
  6620 +  emit_insn (pat);
  6621 +  return 0;
  6622 +}
  6623 +
  6624 +static rtx
  6625 +nios2_expand_custom_XnXX (const struct builtin_description *d, tree exp, rtx target, 
  6626 +                          rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, 
  6627 +                          int ignore ATTRIBUTE_UNUSED)
  6628 +{
  6629 +  tree arglist = TREE_OPERAND (exp, 1);
  6630 +  rtx pat;
  6631 +  rtx opcode;
  6632 +  rtx operands[2];
  6633 +  int i;
  6634 +
  6635 +
  6636 +  /* custom_XnX should have exactly four operands */
  6637 +  if (insn_data[d->icode].n_operands != 4)
  6638 +    abort ();
  6639 +
  6640 +  target = nios2_create_target (d, target);
  6641 +  opcode = nios2_extract_opcode (d, 1, arglist);
  6642 +  for (i = 0; i < 2; i++)
  6643 +    {
  6644 +      arglist = TREE_CHAIN (arglist);
  6645 +      operands[i] = nios2_extract_operand (d, i + 2, i + 1, arglist);
  6646 +    }
  6647 +
  6648 +  pat = GEN_FCN (d->icode) (target, opcode, operands[0], operands[1]);
  6649 +
  6650 +  if (!pat)
  6651 +    return 0;
  6652 +  emit_insn (pat);
  6653 +  return target;
  6654 +}
  6655 +
  6656 +
  6657 +
  6658 +static rtx
  6659 +nios2_expand_STXIO (const struct builtin_description *d, tree exp, rtx target ATTRIBUTE_UNUSED, 
  6660 +                    rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, 
  6661 +                    int ignore ATTRIBUTE_UNUSED)
  6662 +{
  6663 +  tree arglist = TREE_OPERAND (exp, 1);
  6664 +  rtx pat;
  6665 +  rtx store_dest, store_val;
  6666 +  enum insn_code icode = d->icode;
  6667 +
  6668 +  /* stores should have exactly two operands */
  6669 +  if (insn_data[icode].n_operands != 2)
  6670 +    abort ();
  6671 +
  6672 +  /* process the destination of the store */
  6673 +  {
  6674 +    enum machine_mode mode = insn_data[icode].operand[0].mode;
  6675 +    tree arg = TREE_VALUE (arglist);
  6676 +    store_dest = expand_expr (arg, NULL_RTX, VOIDmode, 0);
  6677 +    store_dest = protect_from_queue (store_dest, 0);
  6678 +
  6679 +    store_dest = gen_rtx_MEM (mode, copy_to_mode_reg (Pmode, store_dest));
  6680 +
  6681 +    /* ??? Better errors would be nice */
  6682 +    if (!(*insn_data[icode].operand[0].predicate) (store_dest, mode))
  6683 +      error ("Invalid argument 1 to %s", d->name);
  6684 +  }
  6685 +
  6686 +
  6687 +  /* process the value to store */
  6688 +  {
  6689 +    enum machine_mode mode = insn_data[icode].operand[1].mode;
  6690 +    tree arg = TREE_VALUE (TREE_CHAIN (arglist));
  6691 +    store_val = expand_expr (arg, NULL_RTX, mode, 0);
  6692 +    store_val = protect_from_queue (store_val, 0);
  6693 +
  6694 +    if (!(*insn_data[icode].operand[1].predicate) (store_val, mode))
  6695 +      store_val = copy_to_mode_reg (mode, store_val);
  6696 +
  6697 +    /* ??? Better errors would be nice */
  6698 +    if (!(*insn_data[icode].operand[1].predicate) (store_val, mode))
  6699 +      error ("Invalid argument 2 to %s", d->name);
  6700 +  }
  6701 +
  6702 +  pat = GEN_FCN (d->icode) (store_dest, store_val);
  6703 +  if (!pat)
  6704 +    return 0;
  6705 +  emit_insn (pat);
  6706 +  return 0;
  6707 +}
  6708 +
  6709 +
  6710 +static rtx
  6711 +nios2_expand_LDXIO (const struct builtin_description * d, tree exp, rtx target, 
  6712 +                    rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, 
  6713 +                    int ignore ATTRIBUTE_UNUSED)
  6714 +{
  6715 +  tree arglist = TREE_OPERAND (exp, 1);
  6716 +  rtx pat;
  6717 +  rtx ld_src;
  6718 +  enum insn_code icode = d->icode;
  6719 +
  6720 +  /* loads should have exactly two operands */
  6721 +  if (insn_data[icode].n_operands != 2)
  6722 +    abort ();
  6723 +
  6724 +  target = nios2_create_target (d, target);
  6725 +
  6726 +  {
  6727 +    enum machine_mode mode = insn_data[icode].operand[1].mode;
  6728 +    tree arg = TREE_VALUE (arglist);
  6729 +    ld_src = expand_expr (arg, NULL_RTX, VOIDmode, 0);
  6730 +    ld_src = protect_from_queue (ld_src, 0);
  6731 +
  6732 +    ld_src = gen_rtx_MEM (mode, copy_to_mode_reg (Pmode, ld_src));
  6733 +
  6734 +    /* ??? Better errors would be nice */
  6735 +    if (!(*insn_data[icode].operand[1].predicate) (ld_src, mode))
  6736 +      {
  6737 +        error ("Invalid argument 1 to %s", d->name);
  6738 +      }
  6739 +  }
  6740 +
  6741 +  pat = GEN_FCN (d->icode) (target, ld_src);
  6742 +  if (!pat)
  6743 +    return 0;
  6744 +  emit_insn (pat);
  6745 +  return target;
  6746 +}
  6747 +
  6748 +
  6749 +static rtx
  6750 +nios2_expand_sync (const struct builtin_description * d ATTRIBUTE_UNUSED, 
  6751 +                   tree exp ATTRIBUTE_UNUSED, rtx target ATTRIBUTE_UNUSED, 
  6752 +                   rtx subtarget ATTRIBUTE_UNUSED, 
  6753 +                   enum machine_mode mode ATTRIBUTE_UNUSED, 
  6754 +                   int ignore ATTRIBUTE_UNUSED)
  6755 +{
  6756 +  emit_insn (gen_sync ());
  6757 +  return 0;
  6758 +}
  6759 +
  6760 +static rtx
  6761 +nios2_expand_rdctl (const struct builtin_description * d ATTRIBUTE_UNUSED, 
  6762 +                   tree exp ATTRIBUTE_UNUSED, rtx target ATTRIBUTE_UNUSED, 
  6763 +                   rtx subtarget ATTRIBUTE_UNUSED, 
  6764 +                   enum machine_mode mode ATTRIBUTE_UNUSED, 
  6765 +                   int ignore ATTRIBUTE_UNUSED)
  6766 +{
  6767 +  tree arglist = TREE_OPERAND (exp, 1);
  6768 +  rtx pat;
  6769 +  rtx rdctl_reg;
  6770 +  enum insn_code icode = d->icode;
  6771 +
  6772 +  /* rdctl should have exactly two operands */
  6773 +  if (insn_data[icode].n_operands != 2)
  6774 +    abort ();
  6775 +
  6776 +  target = nios2_create_target (d, target);
  6777 +
  6778 +  {
  6779 +    enum machine_mode mode = insn_data[icode].operand[1].mode;
  6780 +    tree arg = TREE_VALUE (arglist);
  6781 +    rdctl_reg = expand_expr (arg, NULL_RTX, VOIDmode, 0);
  6782 +    rdctl_reg = protect_from_queue (rdctl_reg, 0);
  6783 +
  6784 +    if (!(*insn_data[icode].operand[1].predicate) (rdctl_reg, mode))
  6785 +      {
  6786 +        error ("Control register number must be in range 0-31 for %s", d->name);
  6787 +      }
  6788 +  }
  6789 +
  6790 +  pat = GEN_FCN (d->icode) (target, rdctl_reg);
  6791 +  if (!pat)
  6792 +    return 0;
  6793 +  emit_insn (pat);
  6794 +  return target;
  6795 +}
  6796 +
  6797 +static rtx
  6798 +nios2_expand_wrctl (const struct builtin_description * d ATTRIBUTE_UNUSED, 
  6799 +                   tree exp ATTRIBUTE_UNUSED, rtx target ATTRIBUTE_UNUSED, 
  6800 +                   rtx subtarget ATTRIBUTE_UNUSED, 
  6801 +                   enum machine_mode mode ATTRIBUTE_UNUSED, 
  6802 +                   int ignore ATTRIBUTE_UNUSED)
  6803 +{
  6804 +  tree arglist = TREE_OPERAND (exp, 1);
  6805 +  rtx pat;
  6806 +  rtx wrctl_reg, store_val;
  6807 +  enum insn_code icode = d->icode;
  6808 +
  6809 +  /* stores should have exactly two operands */
  6810 +  if (insn_data[icode].n_operands != 2)
  6811 +    abort ();
  6812 +
  6813 +  /* process the destination of the store */
  6814 +  {
  6815 +    enum machine_mode mode = insn_data[icode].operand[0].mode;
  6816 +    tree arg = TREE_VALUE (arglist);
  6817 +    wrctl_reg = expand_expr (arg, NULL_RTX, VOIDmode, 0);
  6818 +    wrctl_reg = protect_from_queue (wrctl_reg, 0);
  6819 +
  6820 +    if (!(*insn_data[icode].operand[0].predicate) (wrctl_reg, mode))
  6821 +      error ("Control register number must be in range 0-31 for %s", d->name);
  6822 +  }
  6823 +
  6824 +
  6825 +  /* process the value to store */
  6826 +  {
  6827 +    enum machine_mode mode = insn_data[icode].operand[1].mode;
  6828 +    tree arg = TREE_VALUE (TREE_CHAIN (arglist));
  6829 +    store_val = expand_expr (arg, NULL_RTX, mode, 0);
  6830 +    store_val = protect_from_queue (store_val, 0);
  6831 +
  6832 +    if (!(*insn_data[icode].operand[1].predicate) (store_val, mode))
  6833 +      store_val = copy_to_mode_reg (mode, store_val);
  6834 +
  6835 +    /* ??? Better errors would be nice */
  6836 +    if (!(*insn_data[icode].operand[1].predicate) (store_val, mode))
  6837 +      error ("Invalid argument 2 to %s", d->name);
  6838 +  }
  6839 +
  6840 +  pat = GEN_FCN (d->icode) (wrctl_reg, store_val);
  6841 +  if (!pat)
  6842 +    return 0;
  6843 +  emit_insn (pat);
  6844 +  return 0;
  6845 +}
  6846 +
  6847 +
  6848 +#include "gt-nios2.h"
  6849 +
  6850 --- gcc-3.4.3/gcc/config/nios2/nios2.h
  6851 +++ gcc-3.4.3-nios2/gcc/config/nios2/nios2.h
  6852 @@ -0,0 +1,824 @@
  6853 +/* Definitions of target machine for Altera NIOS 2G NIOS2 version.
  6854 +   Copyright (C) 2003 Altera 
  6855 +   Contributed by Jonah Graham (jgraham@altera.com).
  6856 +
  6857 +This file is part of GNU CC.
  6858 +
  6859 +GNU CC is free software; you can redistribute it and/or modify
  6860 +it under the terms of the GNU General Public License as published by
  6861 +the Free Software Foundation; either version 2, or (at your option)
  6862 +any later version.
  6863 +
  6864 +GNU CC is distributed in the hope that it will be useful,
  6865 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  6866 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  6867 +GNU General Public License for more details.
  6868 +
  6869 +You should have received a copy of the GNU General Public License
  6870 +along with GNU CC; see the file COPYING.  If not, write to
  6871 +the Free Software Foundation, 59 Temple Place - Suite 330,
  6872 +Boston, MA 02111-1307, USA.  */
  6873 +
  6874 +
  6875 +
  6876 +#define TARGET_CPU_CPP_BUILTINS()		\
  6877 +  do						\
  6878 +    {						\
  6879 +      builtin_define_std ("NIOS2");		\
  6880 +      builtin_define_std ("nios2");		\
  6881 +      builtin_define ("_GNU_SOURCE");		\
  6882 +    }						\
  6883 +  while (0)
  6884 +#define TARGET_VERSION fprintf (stderr, " (Altera Nios II)")
  6885 +
  6886 +
  6887 +
  6888 +
  6889 +
  6890 +/*********************************
  6891 + * Run-time Target Specification
  6892 + *********************************/
  6893 +
  6894 +#define HAS_DIV_FLAG 0x0001
  6895 +#define HAS_MUL_FLAG 0x0002
  6896 +#define HAS_MULX_FLAG 0x0004
  6897 +#define FAST_SW_DIV_FLAG 0x0008
  6898 +#define INLINE_MEMCPY_FLAG 0x00010
  6899 +#define CACHE_VOLATILE_FLAG 0x0020
  6900 +#define BYPASS_CACHE_FLAG 0x0040
  6901 +
  6902 +extern int target_flags;
  6903 +#define TARGET_HAS_DIV (target_flags & HAS_DIV_FLAG)
  6904 +#define TARGET_HAS_MUL (target_flags & HAS_MUL_FLAG)
  6905 +#define TARGET_HAS_MULX (target_flags & HAS_MULX_FLAG)
  6906 +#define TARGET_FAST_SW_DIV (target_flags & FAST_SW_DIV_FLAG)
  6907 +#define TARGET_INLINE_MEMCPY (target_flags & INLINE_MEMCPY_FLAG)
  6908 +#define TARGET_CACHE_VOLATILE (target_flags & CACHE_VOLATILE_FLAG)
  6909 +#define TARGET_BYPASS_CACHE (target_flags & BYPASS_CACHE_FLAG)
  6910 +
  6911 +#define TARGET_SWITCHES					\
  6912 +{							\
  6913 +    { "hw-div", HAS_DIV_FLAG,				\
  6914 +      N_("Enable DIV, DIVU") },				\
  6915 +    { "no-hw-div", -HAS_DIV_FLAG,			\
  6916 +      N_("Disable DIV, DIVU (default)") },		\
  6917 +    { "hw-mul", HAS_MUL_FLAG,				\
  6918 +      N_("Enable MUL instructions (default)") },				\
  6919 +    { "hw-mulx", HAS_MULX_FLAG,				\
  6920 +      N_("Enable MULX instructions, assume fast shifter") },				\
  6921 +    { "no-hw-mul", -HAS_MUL_FLAG,			\
  6922 +      N_("Disable MUL instructions") },		\
  6923 +    { "no-hw-mulx", -HAS_MULX_FLAG,			\
  6924 +      N_("Disable MULX instructions, assume slow shifter (default and implied by -mno-hw-mul)") },		\
  6925 +    { "fast-sw-div", FAST_SW_DIV_FLAG,				\
  6926 +      N_("Use table based fast divide (default at -O3)") },				\
  6927 +    { "no-fast-sw-div", -FAST_SW_DIV_FLAG,			\
  6928 +      N_("Don't use table based fast divide ever") },		\
  6929 +    { "inline-memcpy", INLINE_MEMCPY_FLAG,				\
  6930 +      N_("Inline small memcpy (default when optimizing)") },				\
  6931 +    { "no-inline-memcpy", -INLINE_MEMCPY_FLAG,			\
  6932 +      N_("Don't Inline small memcpy") },		\
  6933 +    { "cache-volatile", CACHE_VOLATILE_FLAG,				\
  6934 +      N_("Volatile accesses use non-io variants of instructions (default)") },				\
  6935 +    { "no-cache-volatile", -CACHE_VOLATILE_FLAG,			\
  6936 +      N_("Volatile accesses use io variants of instructions") },		\
  6937 +    { "bypass-cache", BYPASS_CACHE_FLAG,				\
  6938 +      N_("All ld/st instructins use io variants") },				\
  6939 +    { "no-bypass-cache", -BYPASS_CACHE_FLAG,			\
  6940 +      N_("All ld/st instructins do not use io variants (default)") },		\
  6941 +    { "smallc", 0,			\
  6942 +      N_("Link with a limited version of the C library") },		\
  6943 +    { "ctors-in-init", 0,			\
  6944 +      "" /* undocumented: N_("Link with static constructors and destructors in init") */ },		\
  6945 +    { "", TARGET_DEFAULT, 0 }				\
  6946 +}
  6947 +
  6948 +
  6949 +extern const char *nios2_sys_nosys_string;    /* for -msys=nosys */
  6950 +extern const char *nios2_sys_lib_string;    /* for -msys-lib= */
  6951 +extern const char *nios2_sys_crt0_string;    /* for -msys-crt0= */
  6952 +
  6953 +#define TARGET_OPTIONS					\
  6954 +{							\
  6955 +  { "sys=nosys",    &nios2_sys_nosys_string,		\
  6956 +      N_("Use stub versions of OS library calls (default)"), 0},	\
  6957 +  { "sys-lib=",    &nios2_sys_lib_string,		\
  6958 +      N_("Name of System Library to link against. (Converted to a -l option)"), 0},	\
  6959 +  { "sys-crt0=",    &nios2_sys_crt0_string,		\
  6960 +      N_("Name of the startfile. (default is a crt0 for the ISS only)"), 0},	\
  6961 +}
  6962 +
  6963 +
  6964 +/* Default target_flags if no switches specified.  */
  6965 +#ifndef TARGET_DEFAULT
  6966 +# define TARGET_DEFAULT (HAS_MUL_FLAG | CACHE_VOLATILE_FLAG)
  6967 +#endif
  6968 +
  6969 +/* Switch  Recognition by gcc.c.  Add -G xx support */
  6970 +#undef  SWITCH_TAKES_ARG
  6971 +#define SWITCH_TAKES_ARG(CHAR)						\
  6972 +  (DEFAULT_SWITCH_TAKES_ARG (CHAR) || (CHAR) == 'G')
  6973 +
  6974 +#define OVERRIDE_OPTIONS override_options ()
  6975 +#define OPTIMIZATION_OPTIONS(LEVEL, SIZE) optimization_options (LEVEL, SIZE)
  6976 +#define CAN_DEBUG_WITHOUT_FP
  6977 + 
  6978 +#define CC1_SPEC "\
  6979 +%{G*}"
  6980 +
  6981 +#undef LIB_SPEC
  6982 +#define LIB_SPEC \
  6983 +"--start-group %{msmallc: -lsmallc} %{!msmallc: -lc} -lgcc \
  6984 + %{msys-lib=*: -l%*} \
  6985 + %{!msys-lib=*: -lc } \
  6986 + --end-group \
  6987 + %{msys-lib=: %eYou need a library name for -msys-lib=} \
  6988 +"
  6989 +
  6990 +
  6991 +#undef STARTFILE_SPEC 
  6992 +#define STARTFILE_SPEC  \
  6993 +"%{msys-crt0=*: %*} %{!msys-crt0=*: crt1%O%s} \
  6994 + %{msys-crt0=: %eYou need a C startup file for -msys-crt0=} \
  6995 + %{mctors-in-init: crti%O%s crtbegin%O%s} \
  6996 +"
  6997 +
  6998 +#undef ENDFILE_SPEC 
  6999 +#define ENDFILE_SPEC \
  7000 + "%{mctors-in-init: crtend%O%s crtn%O%s}"
  7001 +
  7002 +
  7003 +/***********************
  7004 + * Storage Layout
  7005 + ***********************/
  7006 +
  7007 +#define DEFAULT_SIGNED_CHAR 1
  7008 +#define BITS_BIG_ENDIAN 0
  7009 +#define BYTES_BIG_ENDIAN 0
  7010 +#define WORDS_BIG_ENDIAN 0
  7011 +#define BITS_PER_UNIT 8
  7012 +#define BITS_PER_WORD 32
  7013 +#define UNITS_PER_WORD 4
  7014 +#define POINTER_SIZE 32
  7015 +#define BIGGEST_ALIGNMENT 32
  7016 +#define STRICT_ALIGNMENT 1
  7017 +#define FUNCTION_BOUNDARY 32
  7018 +#define PARM_BOUNDARY 32
  7019 +#define STACK_BOUNDARY 32
  7020 +#define PREFERRED_STACK_BOUNDARY 32
  7021 +#define MAX_FIXED_MODE_SIZE 64
  7022 +
  7023 +#define CONSTANT_ALIGNMENT(EXP, ALIGN)				\
  7024 +  ((TREE_CODE (EXP) == STRING_CST) 				\
  7025 +   && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
  7026 +
  7027 +
  7028 +/**********************
  7029 + * Layout of Source Language Data Types
  7030 + **********************/
  7031 +
  7032 +#define INT_TYPE_SIZE 32
  7033 +#define SHORT_TYPE_SIZE 16
  7034 +#define LONG_TYPE_SIZE 32
  7035 +#define LONG_LONG_TYPE_SIZE 64
  7036 +#define FLOAT_TYPE_SIZE 32
  7037 +#define DOUBLE_TYPE_SIZE 64
  7038 +#define LONG_DOUBLE_TYPE_SIZE DOUBLE_TYPE_SIZE
  7039 +
  7040 +
  7041 +/*************************
  7042 + * Condition Code Status
  7043 + ************************/
  7044 +
  7045 +/* comparison type */
  7046 +/* ??? currently only CMP_SI is used */
  7047 +enum cmp_type {
  7048 +  CMP_SI,				/* compare four byte integers */
  7049 +  CMP_DI,				/* compare eight byte integers */
  7050 +  CMP_SF,				/* compare single precision floats */
  7051 +  CMP_DF,				/* compare double precision floats */
  7052 +  CMP_MAX				/* max comparison type */
  7053 +};
  7054 +
  7055 +extern GTY(()) rtx branch_cmp[2];	/* operands for compare */
  7056 +extern enum cmp_type branch_type;	/* what type of branch to use */
  7057 +
  7058 +/**********************
  7059 + * Register Usage
  7060 + **********************/
  7061 +
  7062 +/* ---------------------------------- *
  7063 + * Basic Characteristics of Registers
  7064 + * ---------------------------------- */
  7065 +
  7066 +/*
  7067 +Register Number
  7068 +      Register Name
  7069 +          Alternate Name
  7070 +                Purpose
  7071 +0     r0  zero  always zero
  7072 +1     r1  at    Assembler Temporary
  7073 +2-3   r2-r3     Return Location
  7074 +4-7   r4-r7     Register Arguments
  7075 +8-15  r8-r15    Caller Saved Registers
  7076 +16-22 r16-r22   Callee Saved Registers
  7077 +23    r23 sc    Static Chain (Callee Saved)
  7078 +                ??? Does $sc want to be caller or callee 
  7079 +                saved. If caller, 15, else 23. 
  7080 +24    r24       Exception Temporary
  7081 +25    r25       Breakpoint Temporary
  7082 +26    r26 gp    Global Pointer
  7083 +27    r27 sp    Stack Pointer
  7084 +28    r28 fp    Frame Pointer
  7085 +29    r29 ea    Exception Return Address
  7086 +30    r30 ba    Breakpoint Return Address
  7087 +31    r31 ra    Return Address
  7088 +
  7089 +32    ctl0 status
  7090 +33    ctl1 estatus STATUS saved by exception ? 	
  7091 +34    ctl2 bstatus STATUS saved by break ? 	
  7092 +35    ctl3 ipri    Interrupt Priority Mask ?	
  7093 +36    ctl4 ecause  Exception Cause ? 	
  7094 +
  7095 +37         pc   Not an actual register	
  7096 +
  7097 +38    rap      Return address pointer, this does not
  7098 +                   actually exist and will be eliminated
  7099 +
  7100 +39    fake_fp  Fake Frame Pointer which will always be eliminated.
  7101 +40    fake_ap  Fake Argument Pointer which will always be eliminated.
  7102 +
  7103 +41             First Pseudo Register
  7104 +
  7105 +
  7106 +The definitions for all the hard register numbers
  7107 +are located in nios2.md.
  7108 +*/
  7109 +
  7110 +#define FIRST_PSEUDO_REGISTER 41
  7111 +#define NUM_ARG_REGS (LAST_ARG_REGNO - FIRST_ARG_REGNO + 1)
  7112 +
  7113 +
  7114 +
  7115 +/* also see CONDITIONAL_REGISTER_USAGE */
  7116 +#define FIXED_REGISTERS			     \
  7117 +    {					     \
  7118 +/*        +0  1  2  3  4  5  6  7  8  9 */   \
  7119 +/*   0 */  1, 1, 0, 0, 0, 0, 0, 0, 0, 0,     \
  7120 +/*  10 */  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     \
  7121 +/*  20 */  0, 0, 0, 0, 1, 1, 1, 1, 0, 1,     \
  7122 +/*  30 */  1, 0, 1, 1, 1, 1, 1, 1, 1, 1,     \
  7123 +/*  40 */  1,                                \
  7124 +    }
  7125 +
  7126 +/* call used is the same as caller saved
  7127 +   + fixed regs + args + ret vals */
  7128 +#define CALL_USED_REGISTERS		     \
  7129 +    { 					     \
  7130 +/*        +0  1  2  3  4  5  6  7  8  9 */   \
  7131 +/*   0 */  1, 1, 1, 1, 1, 1, 1, 1, 1, 1,     \
  7132 +/*  10 */  1, 1, 1, 1, 1, 1, 0, 0, 0, 0,     \
  7133 +/*  20 */  0, 0, 0, 0, 1, 1, 1, 1, 0, 1,     \
  7134 +/*  30 */  1, 0, 1, 1, 1, 1, 1, 1, 1, 1,     \
  7135 +/*  40 */  1,                                \
  7136 +    }
  7137 +
  7138 +#define HARD_REGNO_NREGS(REGNO, MODE)            \
  7139 +   ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1)  \
  7140 +    / UNITS_PER_WORD)
  7141 +
  7142 +/* --------------------------- *
  7143 + * How Values Fit in Registers
  7144 + * --------------------------- */
  7145 +
  7146 +#define HARD_REGNO_MODE_OK(REGNO, MODE) 1
  7147 +
  7148 +#define MODES_TIEABLE_P(MODE1, MODE2) 1
  7149 +
  7150 +
  7151 +/*************************
  7152 + * Register Classes
  7153 + *************************/
  7154 +
  7155 +enum reg_class
  7156 +{
  7157 +    NO_REGS,
  7158 +    ALL_REGS,
  7159 +    LIM_REG_CLASSES
  7160 +};
  7161 +
  7162 +#define N_REG_CLASSES (int) LIM_REG_CLASSES
  7163 +
  7164 +#define REG_CLASS_NAMES   \
  7165 +    {"NO_REGS",           \
  7166 +     "ALL_REGS"}
  7167 +
  7168 +#define GENERAL_REGS ALL_REGS
  7169 +
  7170 +#define REG_CLASS_CONTENTS   \
  7171 +/* NO_REGS  */       {{ 0, 0},     \
  7172 +/* ALL_REGS */        {~0,~0}}    \
  7173 +
  7174 +#define REGNO_REG_CLASS(REGNO) ALL_REGS
  7175 +
  7176 +#define BASE_REG_CLASS ALL_REGS
  7177 +#define INDEX_REG_CLASS ALL_REGS
  7178 +
  7179 +/* only one reg class, 'r', is handled automatically */
  7180 +#define REG_CLASS_FROM_LETTER(CHAR) NO_REGS
  7181 +
  7182 +#define REGNO_OK_FOR_BASE_P2(REGNO, STRICT) \
  7183 +    ((STRICT) \
  7184 +     ? (REGNO) < FIRST_PSEUDO_REGISTER \
  7185 +     : (REGNO) < FIRST_PSEUDO_REGISTER || (reg_renumber && reg_renumber[REGNO] < FIRST_PSEUDO_REGISTER))
  7186 +
  7187 +#define REGNO_OK_FOR_INDEX_P2(REGNO, STRICT) \
  7188 +    (REGNO_OK_FOR_BASE_P2 (REGNO, STRICT))
  7189 +
  7190 +#define REGNO_OK_FOR_BASE_P(REGNO) \
  7191 +    (REGNO_OK_FOR_BASE_P2 (REGNO, 1))
  7192 +
  7193 +#define REGNO_OK_FOR_INDEX_P(REGNO) \
  7194 +    (REGNO_OK_FOR_INDEX_P2 (REGNO, 1))
  7195 +
  7196 +#define REG_OK_FOR_BASE_P2(X, STRICT)                                   \
  7197 +    (STRICT                                                             \
  7198 +     ? REGNO_OK_FOR_BASE_P2 (REGNO (X), 1)                              \
  7199 +     : REGNO_OK_FOR_BASE_P2 (REGNO (X), 1) || REGNO(X) >= FIRST_PSEUDO_REGISTER)
  7200 +
  7201 +#define REG_OK_FOR_INDEX_P2(X, STRICT)                                  \
  7202 +    (STRICT                                                             \
  7203 +     ? REGNO_OK_FOR_INDEX_P2 (REGNO (X), 1)                             \
  7204 +     : REGNO_OK_FOR_INDEX_P2 (REGNO (X), 1) || REGNO(X) >= FIRST_PSEUDO_REGISTER)
  7205 +
  7206 +#define CLASS_MAX_NREGS(CLASS, MODE)             \
  7207 +   ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1)  \
  7208 +    / UNITS_PER_WORD)
  7209 +
  7210 +
  7211 +#define SMALL_INT(X) ((unsigned HOST_WIDE_INT) ((X) + 0x8000) < 0x10000)
  7212 +#define SMALL_INT_UNSIGNED(X) ((unsigned HOST_WIDE_INT) (X) < 0x10000)
  7213 +#define UPPER16_INT(X) (((X) & 0xffff) == 0)
  7214 +#define SHIFT_INT(X) ((X) >= 0 && (X) <= 31)
  7215 +#define RDWRCTL_INT(X) ((X) >= 0 && (X) <= 31)
  7216 +#define CUSTOM_INSN_OPCODE(X) ((X) >= 0 && (X) <= 255)
  7217 +
  7218 +#define CONST_OK_FOR_LETTER_P(VALUE, C)			\
  7219 + (							\
  7220 +  (C) == 'I' ? SMALL_INT (VALUE) :			\
  7221 +  (C) == 'J' ? SMALL_INT_UNSIGNED (VALUE) :		\
  7222 +  (C) == 'K' ? UPPER16_INT (VALUE) :         		\
  7223 +  (C) == 'L' ? SHIFT_INT (VALUE) :			\
  7224 +  (C) == 'M' ? (VALUE) == 0 :				\
  7225 +  (C) == 'N' ? CUSTOM_INSN_OPCODE (VALUE) :		\
  7226 +  (C) == 'O' ? RDWRCTL_INT (VALUE) :			\
  7227 +  0)
  7228 +
  7229 +#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) 0
  7230 +
  7231 +#define PREFERRED_RELOAD_CLASS(X, CLASS) \
  7232 +    ((CLASS) == NO_REGS ? GENERAL_REGS : (CLASS))
  7233 +
  7234 +/* 'S' matches immediates which are in small data 
  7235 +   and therefore can be added to gp to create a 
  7236 +   32-bit value. */
  7237 +#define EXTRA_CONSTRAINT(VALUE, C)		\
  7238 +  ((C) == 'S' 					\
  7239 +   && (GET_CODE (VALUE) == SYMBOL_REF)   	\
  7240 +   && SYMBOL_REF_IN_NIOS2_SMALL_DATA_P (VALUE))
  7241 +
  7242 +
  7243 +
  7244 +
  7245 +/* Say that the epilogue uses the return address register.  Note that
  7246 +   in the case of sibcalls, the values "used by the epilogue" are
  7247 +   considered live at the start of the called function.  */
  7248 +#define EPILOGUE_USES(REGNO) ((REGNO) == RA_REGNO)
  7249 +
  7250 +
  7251 +#define DEFAULT_MAIN_RETURN  c_expand_return (integer_zero_node)
  7252 +
  7253 +/**********************************
  7254 + * Trampolines for Nested Functions
  7255 + ***********************************/
  7256 +
  7257 +#define TRAMPOLINE_TEMPLATE(FILE) \
  7258 +    error ("trampolines not yet implemented")
  7259 +#define TRAMPOLINE_SIZE 20
  7260 +#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
  7261 +    error ("trampolines not yet implemented")
  7262 +
  7263 +/***************************
  7264 + * Stack Layout and Calling Conventions
  7265 + ***************************/
  7266 +
  7267 +/* ------------------ *
  7268 + * Basic Stack Layout
  7269 + * ------------------ */
  7270 +
  7271 +/* The downward variants are used by the compiler,
  7272 +   the upward ones serve as documentation */
  7273 +#define STACK_GROWS_DOWNWARD
  7274 +#define FRAME_GROWS_UPWARD
  7275 +#define ARGS_GROW_UPWARD
  7276 +
  7277 +#define STARTING_FRAME_OFFSET current_function_outgoing_args_size
  7278 +#define FIRST_PARM_OFFSET(FUNDECL) 0
  7279 +
  7280 +/* Before the prologue, RA lives in r31.  */
  7281 +#define INCOMING_RETURN_ADDR_RTX  gen_rtx_REG (VOIDmode, RA_REGNO)
  7282 +
  7283 +/* -------------------------------------- *
  7284 + * Registers That Address the Stack Frame
  7285 + * -------------------------------------- */
  7286 +
  7287 +#define STACK_POINTER_REGNUM SP_REGNO
  7288 +#define STATIC_CHAIN_REGNUM SC_REGNO
  7289 +#define PC_REGNUM PC_REGNO
  7290 +#define DWARF_FRAME_RETURN_COLUMN RA_REGNO
  7291 +
  7292 +/* Base register for access to local variables of the function.  We
  7293 +   pretend that the frame pointer is a non-existent hard register, and 
  7294 +   then eliminate it to HARD_FRAME_POINTER_REGNUM. */
  7295 +#define FRAME_POINTER_REGNUM FAKE_FP_REGNO
  7296 +
  7297 +#define HARD_FRAME_POINTER_REGNUM FP_REGNO
  7298 +#define RETURN_ADDRESS_POINTER_REGNUM RAP_REGNO
  7299 +/* the argumnet pointer needs to always be eliminated
  7300 +   so it is set to a fake hard register. */
  7301 +#define ARG_POINTER_REGNUM FAKE_AP_REGNO
  7302 +
  7303 +/* ----------------------------------------- *
  7304 + * Eliminating Frame Pointer and Arg Pointer
  7305 + * ----------------------------------------- */
  7306 +
  7307 +#define FRAME_POINTER_REQUIRED 0
  7308 +
  7309 +#define ELIMINABLE_REGS							\
  7310 +{{ ARG_POINTER_REGNUM,   STACK_POINTER_REGNUM},				\
  7311 + { ARG_POINTER_REGNUM,   HARD_FRAME_POINTER_REGNUM},			\
  7312 + { RETURN_ADDRESS_POINTER_REGNUM, STACK_POINTER_REGNUM},		\
  7313 + { RETURN_ADDRESS_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM},		\
  7314 + { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},				\
  7315 + { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
  7316 +
  7317 +#define CAN_ELIMINATE(FROM, TO)	1
  7318 +
  7319 +#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
  7320 +	(OFFSET) = nios2_initial_elimination_offset ((FROM), (TO))
  7321 +
  7322 +#define MUST_SAVE_REGISTER(regno) \
  7323 + ((regs_ever_live[regno] && !call_used_regs[regno])			\
  7324 +  || (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)	\
  7325 +  || (regno == RA_REGNO && regs_ever_live[RA_REGNO]))
  7326 +
  7327 +/* Treat LOC as a byte offset from the stack pointer and round it up
  7328 +   to the next fully-aligned offset.  */
  7329 +#define STACK_ALIGN(LOC)						\
  7330 +  (((LOC) + ((PREFERRED_STACK_BOUNDARY / 8) - 1)) & ~((PREFERRED_STACK_BOUNDARY / 8) - 1))
  7331 +
  7332 +
  7333 +/* ------------------------------ *
  7334 + * Passing Arguments in Registers
  7335 + * ------------------------------ */
  7336 +
  7337 +/* see nios2.c */
  7338 +#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
  7339 +  (function_arg (&CUM, MODE, TYPE, NAMED))
  7340 +
  7341 +#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
  7342 +  (function_arg_partial_nregs (&CUM, MODE, TYPE, NAMED))
  7343 +
  7344 +#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) 0
  7345 +
  7346 +#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) 0
  7347 +
  7348 +typedef struct nios2_args
  7349 +{
  7350 +    int regs_used;
  7351 +} CUMULATIVE_ARGS;
  7352 +
  7353 +/* This is to initialize the above unused CUM data type */
  7354 +#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \
  7355 +    (init_cumulative_args (&CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS))
  7356 +
  7357 +#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
  7358 +    (function_arg_advance (&CUM, MODE, TYPE, NAMED))
  7359 +
  7360 +#define FUNCTION_ARG_REGNO_P(REGNO) \
  7361 +    ((REGNO) >= FIRST_ARG_REGNO && (REGNO) <= LAST_ARG_REGNO)
  7362 +
  7363 +#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL)   \
  7364 +  {								    \
  7365 +    int pret_size = nios2_setup_incoming_varargs (&(CUM), (MODE),	    \
  7366 +						(TYPE), (NO_RTL));  \
  7367 +    if (pret_size)						    \
  7368 +      (PRETEND_SIZE) = pret_size;				    \
  7369 +  }
  7370 +
  7371 +/* ----------------------------- *
  7372 + * Generating Code for Profiling
  7373 + * ----------------------------- */
  7374 +
  7375 +#define PROFILE_BEFORE_PROLOGUE
  7376 +
  7377 +#define FUNCTION_PROFILER(FILE, LABELNO) \
  7378 +  function_profiler ((FILE), (LABELNO))
  7379 +
  7380 +/* --------------------------------------- *
  7381 + * Passing Function Arguments on the Stack
  7382 + * --------------------------------------- */
  7383 +
  7384 +#define PROMOTE_PROTOTYPES 1
  7385 +
  7386 +#define PUSH_ARGS 0
  7387 +#define ACCUMULATE_OUTGOING_ARGS 1
  7388 +
  7389 +#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACKSIZE) 0
  7390 +
  7391 +/* --------------------------------------- *
  7392 + * How Scalar Function Values Are Returned
  7393 + * --------------------------------------- */
  7394 +
  7395 +#define FUNCTION_VALUE(VALTYPE, FUNC) \
  7396 +    gen_rtx(REG, TYPE_MODE(VALTYPE), FIRST_RETVAL_REGNO)
  7397 +
  7398 +#define LIBCALL_VALUE(MODE) \
  7399 +    gen_rtx(REG, MODE, FIRST_RETVAL_REGNO)
  7400 +
  7401 +#define FUNCTION_VALUE_REGNO_P(REGNO) ((REGNO) == FIRST_RETVAL_REGNO)
  7402 +
  7403 +/* ----------------------------- *
  7404 + * How Large Values Are Returned
  7405 + * ----------------------------- */
  7406 +
  7407 +
  7408 +#define RETURN_IN_MEMORY(TYPE)	\
  7409 +  nios2_return_in_memory (TYPE)
  7410 +
  7411 +
  7412 +#define STRUCT_VALUE 0
  7413 +
  7414 +#define DEFAULT_PCC_STRUCT_RETURN 0
  7415 +
  7416 +/*******************
  7417 + * Addressing Modes
  7418 + *******************/
  7419 +
  7420 +
  7421 +#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)
  7422 +
  7423 +#define CONSTANT_ADDRESS_P(X) (CONSTANT_P (X))
  7424 +
  7425 +#define MAX_REGS_PER_ADDRESS 1
  7426 +
  7427 +/* Go to ADDR if X is a valid address.  */
  7428 +#ifndef REG_OK_STRICT
  7429 +#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)        \
  7430 +    {                                                  \
  7431 +        if (nios2_legitimate_address ((X), (MODE), 0))  \
  7432 +            goto ADDR;                                 \
  7433 +    }
  7434 +#else
  7435 +#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)        \
  7436 +    {                                                  \
  7437 +        if (nios2_legitimate_address ((X), (MODE), 1))  \
  7438 +            goto ADDR;                                 \
  7439 +    }
  7440 +#endif
  7441 +
  7442 +#ifndef REG_OK_STRICT
  7443 +#define REG_OK_FOR_BASE_P(X)   REGNO_OK_FOR_BASE_P2 (REGNO (X), 0)
  7444 +#define REG_OK_FOR_INDEX_P(X)  REGNO_OK_FOR_INDEX_P2 (REGNO (X), 0)
  7445 +#else
  7446 +#define REG_OK_FOR_BASE_P(X)   REGNO_OK_FOR_BASE_P2 (REGNO (X), 1)
  7447 +#define REG_OK_FOR_INDEX_P(X)  REGNO_OK_FOR_INDEX_P2 (REGNO (X), 1)
  7448 +#endif
  7449 +
  7450 +#define LEGITIMATE_CONSTANT_P(X) 1
  7451 +
  7452 +/* Nios II has no mode dependent addresses.  */
  7453 +#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)
  7454 +
  7455 +/* Set if this has a weak declaration  */
  7456 +#define SYMBOL_FLAG_WEAK_DECL	(1 << SYMBOL_FLAG_MACH_DEP_SHIFT)
  7457 +#define SYMBOL_REF_WEAK_DECL_P(RTX) \
  7458 +  ((SYMBOL_REF_FLAGS (RTX) & SYMBOL_FLAG_WEAK_DECL) != 0)
  7459 +
  7460 +
  7461 +/* true if a symbol is both small and not weak. In this case, gp
  7462 +   relative access can be used */
  7463 +#define SYMBOL_REF_IN_NIOS2_SMALL_DATA_P(RTX) \
  7464 +   (SYMBOL_REF_SMALL_P(RTX) && !SYMBOL_REF_WEAK_DECL_P(RTX))
  7465 +
  7466 +/*****************
  7467 + * Describing Relative Costs of Operations
  7468 + *****************/
  7469 +
  7470 +#define SLOW_BYTE_ACCESS 1
  7471 +
  7472 +/* It is as good to call a constant function address as to call an address
  7473 +   kept in a register.
  7474 +   ??? Not true anymore really. Now that call cannot address full range
  7475 +   of memory callr may need to be used */
  7476 +
  7477 +#define NO_FUNCTION_CSE
  7478 +#define NO_RECURSIVE_FUNCTION_CSE
  7479 +
  7480 +
  7481 +
  7482 +/*****************************************
  7483 + * Defining the Output Assembler Language
  7484 + *****************************************/
  7485 +
  7486 +/* ------------------------------------------ *
  7487 + * The Overall Framework of an Assembler File
  7488 + * ------------------------------------------ */
  7489 +
  7490 +#define ASM_APP_ON "#APP\n"
  7491 +#define ASM_APP_OFF "#NO_APP\n"
  7492 +
  7493 +#define ASM_COMMENT_START "# "
  7494 +
  7495 +/* ------------------------------- *
  7496 + * Output and Generation of Labels
  7497 + * ------------------------------- */
  7498 +
  7499 +#define GLOBAL_ASM_OP "\t.global\t"
  7500 +
  7501 +
  7502 +/* -------------- *
  7503 + * Output of Data
  7504 + * -------------- */
  7505 +
  7506 +#define DWARF2_UNWIND_INFO 0
  7507 +
  7508 +
  7509 +/* -------------------------------- *
  7510 + * Assembler Commands for Alignment
  7511 + * -------------------------------- */
  7512 +
  7513 +#define ASM_OUTPUT_ALIGN(FILE, LOG) \
  7514 +  do { \
  7515 +    fprintf ((FILE), "%s%d\n", ALIGN_ASM_OP, (LOG)); \
  7516 +  } while (0)
  7517 +
  7518 +
  7519 +/* -------------------------------- *
  7520 + * Output of Assembler Instructions
  7521 + * -------------------------------- */
  7522 +
  7523 +#define REGISTER_NAMES \
  7524 +{ \
  7525 +    "zero", \
  7526 +    "at", \
  7527 +    "r2", \
  7528 +    "r3", \
  7529 +    "r4", \
  7530 +    "r5", \
  7531 +    "r6", \
  7532 +    "r7", \
  7533 +    "r8", \
  7534 +    "r9", \
  7535 +    "r10", \
  7536 +    "r11", \
  7537 +    "r12", \
  7538 +    "r13", \
  7539 +    "r14", \
  7540 +    "r15", \
  7541 +    "r16", \
  7542 +    "r17", \
  7543 +    "r18", \
  7544 +    "r19", \
  7545 +    "r20", \
  7546 +    "r21", \
  7547 +    "r22", \
  7548 +    "r23", \
  7549 +    "r24", \
  7550 +    "r25", \
  7551 +    "gp", \
  7552 +    "sp", \
  7553 +    "fp", \
  7554 +    "ta", \
  7555 +    "ba", \
  7556 +    "ra", \
  7557 +    "status", \
  7558 +    "estatus", \
  7559 +    "bstatus", \
  7560 +    "ipri", \
  7561 +    "ecause", \
  7562 +    "pc", \
  7563 +    "rap", \
  7564 +    "fake_fp", \
  7565 +    "fake_ap", \
  7566 +}
  7567 +
  7568 +#define ASM_OUTPUT_OPCODE(STREAM, PTR)\
  7569 +   (PTR) = asm_output_opcode (STREAM, PTR)
  7570 +
  7571 +#define PRINT_OPERAND(STREAM, X, CODE) \
  7572 +    nios2_print_operand (STREAM, X, CODE)
  7573 +
  7574 +#define PRINT_OPERAND_ADDRESS(STREAM, X) \
  7575 +    nios2_print_operand_address (STREAM, X)
  7576 +
  7577 +#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)  \
  7578 +do { fputs (integer_asm_op (POINTER_SIZE / BITS_PER_UNIT, TRUE), FILE); \
  7579 +     fprintf (FILE, ".L%u\n", (unsigned) (VALUE));               \
  7580 +   } while (0)
  7581 +
  7582 +
  7583 +/* ------------ *
  7584 + * Label Output
  7585 + * ------------ */
  7586 +
  7587 +
  7588 +/* ---------------------------------------------------- *
  7589 + * Dividing the Output into Sections (Texts, Data, ...)
  7590 + * ---------------------------------------------------- */
  7591 +
  7592 +/* Output before read-only data.  */
  7593 +#define TEXT_SECTION_ASM_OP ("\t.section\t.text")
  7594 +
  7595 +/* Output before writable data.  */
  7596 +#define DATA_SECTION_ASM_OP ("\t.section\t.data")
  7597 +
  7598 +
  7599 +/* Default the definition of "small data" to 8 bytes. */
  7600 +/* ??? How come I can't use HOST_WIDE_INT here? */
  7601 +extern unsigned long nios2_section_threshold;
  7602 +#define NIOS2_DEFAULT_GVALUE 8
  7603 +
  7604 +
  7605 +
  7606 +/* This says how to output assembler code to declare an
  7607 +   uninitialized external linkage data object.  Under SVR4,
  7608 +   the linker seems to want the alignment of data objects
  7609 +   to depend on their types.  We do exactly that here.  */
  7610 +
  7611 +#undef COMMON_ASM_OP
  7612 +#define COMMON_ASM_OP	"\t.comm\t"
  7613 +
  7614 +#undef  ASM_OUTPUT_ALIGNED_COMMON
  7615 +#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN)		\
  7616 +do 									\
  7617 +{									\
  7618 +  if ((SIZE) <= nios2_section_threshold)				\
  7619 +    {									\
  7620 +      named_section (0, ".sbss", 0);					\
  7621 +      (*targetm.asm_out.globalize_label) (FILE, NAME);			\
  7622 +      ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");			\
  7623 +      if (!flag_inhibit_size_directive)					\
  7624 +	ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE);			\
  7625 +      ASM_OUTPUT_ALIGN ((FILE), exact_log2((ALIGN) / BITS_PER_UNIT));	\
  7626 +      ASM_OUTPUT_LABEL(FILE, NAME);					\
  7627 +      ASM_OUTPUT_SKIP((FILE), (SIZE) ? (SIZE) : 1);			\
  7628 +    }									\
  7629 +  else									\
  7630 +    {									\
  7631 +      fprintf ((FILE), "%s", COMMON_ASM_OP);				\
  7632 +      assemble_name ((FILE), (NAME));					\
  7633 +      fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT);	\
  7634 +    }									\
  7635 +}									\
  7636 +while (0)
  7637 +
  7638 +
  7639 +/* This says how to output assembler code to declare an
  7640 +   uninitialized internal linkage data object.  Under SVR4,
  7641 +   the linker seems to want the alignment of data objects
  7642 +   to depend on their types.  We do exactly that here.  */
  7643 +
  7644 +#undef  ASM_OUTPUT_ALIGNED_LOCAL
  7645 +#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN)		\
  7646 +do {									\
  7647 +  if ((SIZE) <= nios2_section_threshold)				\
  7648 +    named_section (0, ".sbss", 0);					\
  7649 +  else									\
  7650 +    named_section (0, ".bss", 0);					\
  7651 +  ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");			\
  7652 +  if (!flag_inhibit_size_directive)					\
  7653 +    ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE);			\
  7654 +  ASM_OUTPUT_ALIGN ((FILE), exact_log2((ALIGN) / BITS_PER_UNIT));	\
  7655 +  ASM_OUTPUT_LABEL(FILE, NAME);						\
  7656 +  ASM_OUTPUT_SKIP((FILE), (SIZE) ? (SIZE) : 1);				\
  7657 +} while (0)
  7658 +
  7659 +
  7660 +
  7661 +/***************************
  7662 + * Miscellaneous Parameters
  7663 + ***************************/
  7664 +
  7665 +#define MOVE_MAX 4
  7666 +
  7667 +#define Pmode SImode
  7668 +#define FUNCTION_MODE QImode
  7669 +
  7670 +#define CASE_VECTOR_MODE Pmode
  7671 +
  7672 +#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
  7673 +
  7674 +#define LOAD_EXTEND_OP(MODE) (ZERO_EXTEND)
  7675 +
  7676 +#define WORD_REGISTER_OPERATIONS
  7677 --- gcc-3.4.3/gcc/config/nios2/nios2.md
  7678 +++ gcc-3.4.3-nios2/gcc/config/nios2/nios2.md
  7679 @@ -0,0 +1,2078 @@
  7680 +;; Machine Description for Altera NIOS 2G NIOS2 version.
  7681 +;;    Copyright (C) 2003 Altera 
  7682 +;;    Contributed by Jonah Graham (jgraham@altera.com).
  7683 +;; 
  7684 +;; This file is part of GNU CC.
  7685 +;; 
  7686 +;; GNU CC is free software; you can redistribute it and/or modify
  7687 +;; it under the terms of the GNU General Public License as published by
  7688 +;; the Free Software Foundation; either version 2, or (at your option)
  7689 +;; any later version.
  7690 +;; 
  7691 +;; GNU CC is distributed in the hope that it will be useful,
  7692 +;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  7693 +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  7694 +;; GNU General Public License for more details.
  7695 +;; 
  7696 +;; You should have received a copy of the GNU General Public License
  7697 +;; along with GNU CC; see the file COPYING.  If not, write to
  7698 +;; the Free Software Foundation, 59 Temple Place - Suite 330,
  7699 +;; Boston, MA 02111-1307, USA.  */
  7700 +
  7701 +
  7702 +
  7703 +;*****************************************************************************
  7704 +;*
  7705 +;* constants
  7706 +;*
  7707 +;*****************************************************************************
  7708 +(define_constants [
  7709 +  (GP_REGNO 26)
  7710 +  (SP_REGNO 27)
  7711 +  (FP_REGNO 28)
  7712 +  (RA_REGNO 31)
  7713 +  (RAP_REGNO 38)
  7714 +  (FIRST_RETVAL_REGNO 2)
  7715 +  (LAST_RETVAL_REGNO 3)
  7716 +  (FIRST_ARG_REGNO 4)
  7717 +  (LAST_ARG_REGNO 7)
  7718 +  (SC_REGNO 23)
  7719 +  (PC_REGNO 37)
  7720 +  (FAKE_FP_REGNO 39)
  7721 +  (FAKE_AP_REGNO 40)
  7722 +
  7723 +
  7724 +  (UNSPEC_BLOCKAGE 0)
  7725 +  (UNSPEC_LDBIO 1)
  7726 +  (UNSPEC_LDBUIO 2)
  7727 +  (UNSPEC_LDHIO 3)
  7728 +  (UNSPEC_LDHUIO 4)
  7729 +  (UNSPEC_LDWIO 5)
  7730 +  (UNSPEC_STBIO 6)
  7731 +  (UNSPEC_STHIO 7)
  7732 +  (UNSPEC_STWIO 8)
  7733 +  (UNSPEC_SYNC 9)
  7734 +  (UNSPEC_WRCTL 10)
  7735 +  (UNSPEC_RDCTL 11)
  7736 +  
  7737 +])
  7738 +
  7739 +
  7740 +
  7741 +;*****************************************************************************
  7742 +;*
  7743 +;* instruction scheduler
  7744 +;*
  7745 +;*****************************************************************************
  7746 +
  7747 +; No schedule info is currently available, using an assumption that no
  7748 +; instruction can use the results of the previous instruction without
  7749 +; incuring a stall.
  7750 +
  7751 +; length of an instruction (in bytes)
  7752 +(define_attr "length" "" (const_int 4))
  7753 +(define_attr "type" "unknown,complex,control,alu,cond_alu,st,ld,shift,mul,div,custom" (const_string "complex"))
  7754 +
  7755 +(define_asm_attributes
  7756 + [(set_attr "length" "4")
  7757 +  (set_attr "type" "complex")])
  7758 +
  7759 +(define_automaton "nios2")
  7760 +(automata_option "v")
  7761 +;(automata_option "no-minimization")
  7762 +(automata_option "ndfa")
  7763 +
  7764 +; The nios2 pipeline is fairly straightforward for the fast model.
  7765 +; Every alu operation is pipelined so that an instruction can
  7766 +; be issued every cycle. However, there are still potential
  7767 +; stalls which this description tries to deal with.
  7768 +
  7769 +(define_cpu_unit "cpu" "nios2")
  7770 +
  7771 +(define_insn_reservation "complex" 1
  7772 +  (eq_attr "type" "complex")
  7773 +  "cpu")
  7774 +
  7775 +(define_insn_reservation "control" 1
  7776 +  (eq_attr "type" "control")
  7777 +  "cpu")
  7778 +
  7779 +(define_insn_reservation "alu" 1
  7780 +  (eq_attr "type" "alu")
  7781 +  "cpu")
  7782 +
  7783 +(define_insn_reservation "cond_alu" 1
  7784 +  (eq_attr "type" "cond_alu")
  7785 +  "cpu")
  7786 +
  7787 +(define_insn_reservation "st" 1
  7788 +  (eq_attr "type" "st")
  7789 +  "cpu")
  7790 +  
  7791 +(define_insn_reservation "custom" 1
  7792 +  (eq_attr "type" "custom")
  7793 +  "cpu")
  7794 +
  7795 +; shifts, muls and lds have three cycle latency
  7796 +(define_insn_reservation "ld" 3
  7797 +  (eq_attr "type" "ld")
  7798 +  "cpu")
  7799 +
  7800 +(define_insn_reservation "shift" 3
  7801 +  (eq_attr "type" "shift")
  7802 +  "cpu")
  7803 +
  7804 +(define_insn_reservation "mul" 3
  7805 +  (eq_attr "type" "mul")
  7806 +  "cpu")
  7807 +
  7808 +(define_insn_reservation "div" 1
  7809 +  (eq_attr "type" "div")
  7810 +  "cpu")
  7811 +
  7812 +
  7813 +;*****************************************************************************
  7814 +;*
  7815 +;* MOV Instructions
  7816 +;*
  7817 +;*****************************************************************************
  7818 +
  7819 +(define_expand "movqi"
  7820 +  [(set (match_operand:QI 0 "nonimmediate_operand" "")
  7821 +        (match_operand:QI 1 "general_operand" ""))]
  7822 +  ""
  7823 +{
  7824 +  if (nios2_emit_move_sequence (operands, QImode))
  7825 +    DONE;
  7826 +})
  7827 +
  7828 +(define_insn "movqi_internal"
  7829 +  [(set (match_operand:QI 0 "nonimmediate_operand" "=m, r,r, r")
  7830 +        (match_operand:QI 1 "general_operand"       "rM,m,rM,I"))]
  7831 +  "(register_operand (operands[0], QImode)
  7832 +    || register_operand (operands[1], QImode)
  7833 +    || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
  7834 +  "@
  7835 +    stb%o0\\t%z1, %0
  7836 +    ldbu%o1\\t%0, %1
  7837 +    mov\\t%0, %z1
  7838 +    movi\\t%0, %1"
  7839 +  [(set_attr "type" "st,ld,alu,alu")])
  7840 +
  7841 +(define_insn "ldbio"
  7842 +  [(set (match_operand:SI 0 "register_operand" "=r")
  7843 +	(unspec_volatile:SI [(const_int 0)] UNSPEC_LDBIO))
  7844 +   (use (match_operand:SI 1 "memory_operand" "m"))]
  7845 +  ""
  7846 +  "ldbio\\t%0, %1"
  7847 +  [(set_attr "type" "ld")])
  7848 +
  7849 +(define_insn "ldbuio"
  7850 +  [(set (match_operand:SI 0 "register_operand" "=r")
  7851 +	(unspec_volatile:SI [(const_int 0)] UNSPEC_LDBUIO))
  7852 +   (use (match_operand:SI 1 "memory_operand" "m"))]
  7853 +  ""
  7854 +  "ldbuio\\t%0, %1"
  7855 +  [(set_attr "type" "ld")])
  7856 +
  7857 +(define_insn "stbio"
  7858 +  [(set (match_operand:SI 0 "memory_operand" "=m")
  7859 +	(match_operand:SI 1 "register_operand"   "r"))
  7860 +   (unspec_volatile:SI [(const_int 0)] UNSPEC_STBIO)]
  7861 +  ""
  7862 +  "stbio\\t%z1, %0"
  7863 +  [(set_attr "type" "st")])
  7864 +
  7865 +
  7866 +(define_expand "movhi"
  7867 +  [(set (match_operand:HI 0 "nonimmediate_operand" "")
  7868 +        (match_operand:HI 1 "general_operand" ""))]
  7869 +  ""
  7870 +{
  7871 +  if (nios2_emit_move_sequence (operands, HImode))
  7872 +    DONE;
  7873 +})
  7874 +
  7875 +(define_insn "movhi_internal"
  7876 +  [(set (match_operand:HI 0 "nonimmediate_operand" "=m, r,r, r,r")
  7877 +        (match_operand:HI 1 "general_operand"       "rM,m,rM,I,J"))]
  7878 +  "(register_operand (operands[0], HImode)
  7879 +    || register_operand (operands[1], HImode)
  7880 +    || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
  7881 +  "@
  7882 +    sth%o0\\t%z1, %0
  7883 +    ldhu%o1\\t%0, %1
  7884 +    mov\\t%0, %z1
  7885 +    movi\\t%0, %1
  7886 +    movui\\t%0, %1"
  7887 +  [(set_attr "type" "st,ld,alu,alu,alu")])
  7888 +
  7889 +(define_insn "ldhio"
  7890 +  [(set (match_operand:SI 0 "register_operand" "=r")
  7891 +	(unspec_volatile:SI [(const_int 0)] UNSPEC_LDHIO))
  7892 +   (use (match_operand:SI 1 "memory_operand" "m"))]
  7893 +  ""
  7894 +  "ldhio\\t%0, %1"
  7895 +  [(set_attr "type" "ld")])
  7896 +
  7897 +(define_insn "ldhuio"
  7898 +  [(set (match_operand:SI 0 "register_operand" "=r")
  7899 +	(unspec_volatile:SI [(const_int 0)] UNSPEC_LDHUIO))
  7900 +   (use (match_operand:SI 1 "memory_operand" "m"))]
  7901 +  ""
  7902 +  "ldhuio\\t%0, %1"
  7903 +  [(set_attr "type" "ld")])
  7904 +
  7905 +(define_insn "sthio"
  7906 +  [(set (match_operand:SI 0 "memory_operand" "=m")
  7907 +	(match_operand:SI 1 "register_operand"   "r"))
  7908 +   (unspec_volatile:SI [(const_int 0)] UNSPEC_STHIO)]
  7909 +  ""
  7910 +  "sthio\\t%z1, %0"
  7911 +  [(set_attr "type" "st")])
  7912 +
  7913 +(define_expand "movsi"
  7914 +  [(set (match_operand:SI 0 "nonimmediate_operand" "")
  7915 +        (match_operand:SI 1 "general_operand" ""))]
  7916 +  ""
  7917 +{
  7918 +  if (nios2_emit_move_sequence (operands, SImode))
  7919 +    DONE;
  7920 +})
  7921 +
  7922 +(define_insn "movsi_internal"
  7923 +  [(set (match_operand:SI 0 "nonimmediate_operand" "=m, r,r, r,r,r,r")
  7924 +        (match_operand:SI 1 "general_operand"       "rM,m,rM,I,J,S,i"))]
  7925 +  "(register_operand (operands[0], SImode)
  7926 +    || register_operand (operands[1], SImode)
  7927 +    || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
  7928 +  "@
  7929 +    stw%o0\\t%z1, %0
  7930 +    ldw%o1\\t%0, %1
  7931 +    mov\\t%0, %z1
  7932 +    movi\\t%0, %1
  7933 +    movui\\t%0, %1
  7934 +    addi\\t%0, gp, %%gprel(%1)
  7935 +    movhi\\t%0, %H1\;addi\\t%0, %0, %L1"
  7936 +  [(set_attr "type" "st,ld,alu,alu,alu,alu,alu")])
  7937 +
  7938 +(define_insn "ldwio"
  7939 +  [(set (match_operand:SI 0 "register_operand" "=r")
  7940 +	(unspec_volatile:SI [(const_int 0)] UNSPEC_LDWIO))
  7941 +   (use (match_operand:SI 1 "memory_operand" "m"))]
  7942 +  ""
  7943 +  "ldwio\\t%0, %1"
  7944 +  [(set_attr "type" "ld")])
  7945 +
  7946 +(define_insn "stwio"
  7947 +  [(set (match_operand:SI 0 "memory_operand" "=m")
  7948 +	(match_operand:SI 1 "register_operand"   "r"))
  7949 +   (unspec_volatile:SI [(const_int 0)] UNSPEC_STWIO)]
  7950 +  ""
  7951 +  "stwio\\t%z1, %0"
  7952 +  [(set_attr "type" "st")])
  7953 +
  7954 +
  7955 +
  7956 +;*****************************************************************************
  7957 +;*
  7958 +;* zero extension
  7959 +;*
  7960 +;*****************************************************************************
  7961 +
  7962 +
  7963 +(define_insn "zero_extendhisi2"
  7964 +  [(set (match_operand:SI 0 "register_operand" "=r,r")
  7965 +	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
  7966 +  ""
  7967 +  "@
  7968 +    andi\\t%0, %1, 0xffff
  7969 +    ldhu%o1\\t%0, %1"
  7970 +  [(set_attr "type"	"alu,ld")])
  7971 +
  7972 +(define_insn "zero_extendqihi2"
  7973 +  [(set (match_operand:HI 0 "register_operand" "=r,r")
  7974 +	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
  7975 +  ""
  7976 +  "@
  7977 +    andi\\t%0, %1, 0xff
  7978 +    ldbu%o1\\t%0, %1"
  7979 +  [(set_attr "type"	"alu,ld")])
  7980 +
  7981 +(define_insn "zero_extendqisi2"
  7982 +  [(set (match_operand:SI 0 "register_operand" "=r,r")
  7983 +	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
  7984 +  ""
  7985 +  "@
  7986 +    andi\\t%0, %1, 0xff
  7987 +    ldbu%o1\\t%0, %1"
  7988 +  [(set_attr "type"	"alu,ld")])
  7989 +
  7990 +
  7991 +
  7992 +;*****************************************************************************
  7993 +;*
  7994 +;* sign extension
  7995 +;*
  7996 +;*****************************************************************************
  7997 +
  7998 +(define_expand "extendhisi2"
  7999 +  [(set (match_operand:SI 0 "register_operand" "")
  8000 +	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
  8001 +  ""
  8002 +{
  8003 +  if (optimize && GET_CODE (operands[1]) == MEM)
  8004 +    operands[1] = force_not_mem (operands[1]);
  8005 +
  8006 +  if (GET_CODE (operands[1]) != MEM)
  8007 +    {
  8008 +      rtx op1   = gen_lowpart (SImode, operands[1]);
  8009 +      rtx temp  = gen_reg_rtx (SImode);
  8010 +      rtx shift = GEN_INT (16);
  8011 +
  8012 +      emit_insn (gen_ashlsi3 (temp, op1, shift));
  8013 +      emit_insn (gen_ashrsi3 (operands[0], temp, shift));
  8014 +      DONE;
  8015 +    }
  8016 +})
  8017 +
  8018 +(define_insn "extendhisi2_internal"
  8019 +  [(set (match_operand:SI 0 "register_operand" "=r")
  8020 +	(sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
  8021 +  ""
  8022 +  "ldh%o1\\t%0, %1"
  8023 +  [(set_attr "type"	"ld")])
  8024 +
  8025 +(define_expand "extendqihi2"
  8026 +  [(set (match_operand:HI 0 "register_operand" "")
  8027 +	(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
  8028 +  ""
  8029 +{
  8030 +  if (optimize && GET_CODE (operands[1]) == MEM)
  8031 +    operands[1] = force_not_mem (operands[1]);
  8032 +
  8033 +  if (GET_CODE (operands[1]) != MEM)
  8034 +    {
  8035 +      rtx op0   = gen_lowpart (SImode, operands[0]);
  8036 +      rtx op1   = gen_lowpart (SImode, operands[1]);
  8037 +      rtx temp  = gen_reg_rtx (SImode);
  8038 +      rtx shift = GEN_INT (24);
  8039 +
  8040 +      emit_insn (gen_ashlsi3 (temp, op1, shift));
  8041 +      emit_insn (gen_ashrsi3 (op0, temp, shift));
  8042 +      DONE;
  8043 +    }
  8044 +})
  8045 +
  8046 +(define_insn "extendqihi2_internal"
  8047 +  [(set (match_operand:HI 0 "register_operand" "=r")
  8048 +	(sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
  8049 +  ""
  8050 +  "ldb%o1\\t%0, %1"
  8051 +  [(set_attr "type"	"ld")])
  8052 +
  8053 +
  8054 +(define_expand "extendqisi2"
  8055 +  [(set (match_operand:SI 0 "register_operand" "")
  8056 +	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
  8057 +  ""
  8058 +{
  8059 +  if (optimize && GET_CODE (operands[1]) == MEM)
  8060 +    operands[1] = force_not_mem (operands[1]);
  8061 +
  8062 +  if (GET_CODE (operands[1]) != MEM)
  8063 +    {
  8064 +      rtx op1   = gen_lowpart (SImode, operands[1]);
  8065 +      rtx temp  = gen_reg_rtx (SImode);
  8066 +      rtx shift = GEN_INT (24);
  8067 +
  8068 +      emit_insn (gen_ashlsi3 (temp, op1, shift));
  8069 +      emit_insn (gen_ashrsi3 (operands[0], temp, shift));
  8070 +      DONE;
  8071 +    }
  8072 +})
  8073 +
  8074 +(define_insn "extendqisi2_insn"
  8075 +  [(set (match_operand:SI 0 "register_operand" "=r")
  8076 +	(sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
  8077 +  ""
  8078 +  "ldb%o1\\t%0, %1"
  8079 +  [(set_attr "type"	"ld")])
  8080 +
  8081 +
  8082 +
  8083 +;*****************************************************************************
  8084 +;*
  8085 +;* Arithmetic Operations
  8086 +;*
  8087 +;*****************************************************************************
  8088 +
  8089 +(define_insn "addsi3"
  8090 +  [(set (match_operand:SI 0 "register_operand"          "=r,r")
  8091 +        (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
  8092 +                 (match_operand:SI 2 "arith_operand"     "r,I")))]
  8093 +  ""
  8094 +  "add%i2\\t%0, %1, %z2"
  8095 +  [(set_attr "type" "alu")])
  8096 +
  8097 +(define_insn "subsi3"
  8098 +  [(set (match_operand:SI 0 "register_operand"           "=r")
  8099 +        (minus:SI (match_operand:SI 1 "reg_or_0_operand"  "rM")
  8100 +                  (match_operand:SI 2 "register_operand"  "r")))]
  8101 +  ""
  8102 +  "sub\\t%0, %z1, %2"
  8103 +  [(set_attr "type" "alu")])
  8104 +
  8105 +(define_insn "mulsi3"
  8106 +  [(set (match_operand:SI 0 "register_operand"            "=r,r")
  8107 +        (mult:SI (match_operand:SI 1 "register_operand"    "r,r")
  8108 +                 (match_operand:SI 2 "arith_operand"       "r,I")))]
  8109 +  "TARGET_HAS_MUL"
  8110 +  "mul%i2\\t%0, %1, %z2"
  8111 +  [(set_attr "type" "mul")])
  8112 +
  8113 +(define_expand "divsi3"
  8114 +  [(set (match_operand:SI 0 "register_operand"            "=r")
  8115 +        (div:SI (match_operand:SI 1 "register_operand"     "r")
  8116 +                (match_operand:SI 2 "register_operand"     "r")))]
  8117 +  ""
  8118 +{
  8119 +  if (!TARGET_HAS_DIV)
  8120 +    {
  8121 +      if (!TARGET_FAST_SW_DIV)
  8122 +	FAIL;
  8123 +      else
  8124 +        {
  8125 +	  if (nios2_emit_expensive_div (operands, SImode))
  8126 +	    DONE;
  8127 +	}
  8128 +    }
  8129 +})
  8130 +
  8131 +(define_insn "divsi3_insn"
  8132 +  [(set (match_operand:SI 0 "register_operand"            "=r")
  8133 +        (div:SI (match_operand:SI 1 "register_operand"     "r")
  8134 +                (match_operand:SI 2 "register_operand"     "r")))]
  8135 +  "TARGET_HAS_DIV"
  8136 +  "div\\t%0, %1, %2"
  8137 +  [(set_attr "type" "div")])
  8138 +
  8139 +(define_insn "udivsi3"
  8140 +  [(set (match_operand:SI 0 "register_operand"            "=r")
  8141 +        (udiv:SI (match_operand:SI 1 "register_operand"     "r")
  8142 +                (match_operand:SI 2 "register_operand"     "r")))]
  8143 +  "TARGET_HAS_DIV"
  8144 +  "divu\\t%0, %1, %2"
  8145 +  [(set_attr "type" "div")])
  8146 +
  8147 +(define_insn "smulsi3_highpart"
  8148 +  [(set (match_operand:SI 0 "register_operand"                            "=r")
  8149 +	(truncate:SI
  8150 +	 (lshiftrt:DI
  8151 +	  (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand"  "r"))
  8152 +		   (sign_extend:DI (match_operand:SI 2 "register_operand"  "r")))
  8153 +	  (const_int 32))))]
  8154 +  "TARGET_HAS_MULX"
  8155 +  "mulxss\\t%0, %1, %2"
  8156 +  [(set_attr "type" "mul")])
  8157 +
  8158 +(define_insn "umulsi3_highpart"
  8159 +  [(set (match_operand:SI 0 "register_operand"                            "=r")
  8160 +	(truncate:SI
  8161 +	 (lshiftrt:DI
  8162 +	  (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand"  "r"))
  8163 +		   (zero_extend:DI (match_operand:SI 2 "register_operand"  "r")))
  8164 +	  (const_int 32))))]
  8165 +  "TARGET_HAS_MULX"
  8166 +  "mulxuu\\t%0, %1, %2"
  8167 +  [(set_attr "type" "mul")])
  8168 +
  8169 +
  8170 +(define_expand "mulsidi3"
  8171 +    [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 0)
  8172 +	  (mult:SI (match_operand:SI 1 "register_operand" "")
  8173 +		   (match_operand:SI 2 "register_operand" "")))
  8174 +     (set (subreg:SI (match_dup 0) 4)
  8175 +	  (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
  8176 +					     (sign_extend:DI (match_dup 2)))
  8177 +				    (const_int 32))))]
  8178 +  "TARGET_HAS_MULX"
  8179 +  "")
  8180 +
  8181 +(define_expand "umulsidi3"
  8182 +    [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 0)
  8183 +	  (mult:SI (match_operand:SI 1 "register_operand" "")
  8184 +		   (match_operand:SI 2 "register_operand" "")))
  8185 +     (set (subreg:SI (match_dup 0) 4)
  8186 +	  (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
  8187 +					     (zero_extend:DI (match_dup 2)))
  8188 +				    (const_int 32))))]
  8189 +  "TARGET_HAS_MULX"
  8190 +  "")
  8191 +
  8192 +
  8193 +
  8194 +;*****************************************************************************
  8195 +;*
  8196 +;* Negate and ones complement
  8197 +;*
  8198 +;*****************************************************************************
  8199 +
  8200 +(define_insn "negsi2"
  8201 +  [(set (match_operand:SI 0 "register_operand"        "=r")
  8202 +	(neg:SI (match_operand:SI 1 "register_operand" "r")))]
  8203 +  ""
  8204 +{
  8205 +  operands[2] = const0_rtx;
  8206 +  return "sub\\t%0, %z2, %1";
  8207 +}
  8208 +  [(set_attr "type" "alu")])
  8209 +
  8210 +(define_insn "one_cmplsi2"
  8211 +  [(set (match_operand:SI 0 "register_operand"        "=r")
  8212 +	(not:SI (match_operand:SI 1 "register_operand" "r")))]
  8213 +  ""
  8214 +{
  8215 +  operands[2] = const0_rtx;
  8216 +  return "nor\\t%0, %z2, %1";
  8217 +}
  8218 +  [(set_attr "type" "alu")])
  8219 +
  8220 +
  8221 +
  8222 +; Logical Operantions
  8223 +
  8224 +(define_insn "andsi3"
  8225 +  [(set (match_operand:SI 0 "register_operand"         "=r, r,r")
  8226 +        (and:SI (match_operand:SI 1 "register_operand" "%r, r,r")
  8227 +                (match_operand:SI 2 "logical_operand"   "rM,J,K")))]
  8228 +  ""
  8229 +  "@
  8230 +    and\\t%0, %1, %z2
  8231 +    and%i2\\t%0, %1, %2
  8232 +    andh%i2\\t%0, %1, %U2"
  8233 +  [(set_attr "type" "alu")])
  8234 +
  8235 +(define_insn "iorsi3"
  8236 +  [(set (match_operand:SI 0 "register_operand"          "=r, r,r")
  8237 +        (ior:SI (match_operand:SI 1 "register_operand"  "%r, r,r")
  8238 +                (match_operand:SI 2 "logical_operand"    "rM,J,K")))]
  8239 +  ""
  8240 +  "@
  8241 +    or\\t%0, %1, %z2
  8242 +    or%i2\\t%0, %1, %2
  8243 +    orh%i2\\t%0, %1, %U2"
  8244 +  [(set_attr "type" "alu")])
  8245 +
  8246 +(define_insn "*norsi3"
  8247 +  [(set (match_operand:SI 0 "register_operand"                  "=r")
  8248 +        (and:SI (not:SI (match_operand:SI 1 "register_operand"  "%r"))
  8249 +                (not:SI (match_operand:SI 2 "reg_or_0_operand"   "rM"))))]
  8250 +  ""
  8251 +  "nor\\t%0, %1, %z2"
  8252 +  [(set_attr "type" "alu")])
  8253 +
  8254 +(define_insn "xorsi3"
  8255 +  [(set (match_operand:SI 0 "register_operand"          "=r, r,r")
  8256 +        (xor:SI (match_operand:SI 1 "register_operand"  "%r, r,r")
  8257 +                (match_operand:SI 2 "logical_operand"    "rM,J,K")))]
  8258 +  ""
  8259 +  "@
  8260 +    xor\\t%0, %1, %z2
  8261 +    xor%i2\\t%0, %1, %2
  8262 +    xorh%i2\\t%0, %1, %U2"
  8263 +  [(set_attr "type" "alu")])
  8264 +
  8265 +
  8266 +
  8267 +;*****************************************************************************
  8268 +;*
  8269 +;* Shifts
  8270 +;*
  8271 +;*****************************************************************************
  8272 +
  8273 +(define_insn "ashlsi3"
  8274 +  [(set (match_operand:SI 0 "register_operand"           "=r,r")
  8275 +	(ashift:SI (match_operand:SI 1 "register_operand" "r,r")
  8276 +		   (match_operand:SI 2 "shift_operand"    "r,L")))]
  8277 +  ""
  8278 +  "sll%i2\\t%0, %1, %z2"
  8279 +  [(set_attr "type" "shift")])
  8280 +
  8281 +(define_insn "ashrsi3"
  8282 +  [(set (match_operand:SI 0 "register_operand"             "=r,r")
  8283 +	(ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
  8284 +		     (match_operand:SI 2 "shift_operand"    "r,L")))]
  8285 +  ""
  8286 +  "sra%i2\\t%0, %1, %z2"
  8287 +  [(set_attr "type" "shift")])
  8288 +
  8289 +(define_insn "lshrsi3"
  8290 +  [(set (match_operand:SI 0 "register_operand"             "=r,r")
  8291 +	(lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
  8292 +		     (match_operand:SI 2 "shift_operand"    "r,L")))]
  8293 +  ""
  8294 +  "srl%i2\\t%0, %1, %z2"
  8295 +  [(set_attr "type" "shift")])
  8296 +
  8297 +(define_insn "rotlsi3"
  8298 +  [(set (match_operand:SI 0 "register_operand"           "=r,r")
  8299 +	(rotate:SI (match_operand:SI 1 "register_operand" "r,r")
  8300 +		   (match_operand:SI 2 "shift_operand"    "r,L")))]
  8301 +  ""
  8302 +  "rol%i2\\t%0, %1, %z2"
  8303 +  [(set_attr "type" "shift")])
  8304 +
  8305 +(define_insn "rotrsi3"
  8306 +  [(set (match_operand:SI 0 "register_operand"             "=r,r")
  8307 +	(rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
  8308 +		     (match_operand:SI 2 "register_operand" "r,r")))]
  8309 +  ""
  8310 +  "ror\\t%0, %1, %2"
  8311 +  [(set_attr "type" "shift")])
  8312 +
  8313 +(define_insn "*shift_mul_constants"
  8314 +  [(set (match_operand:SI 0 "register_operand"                     "=r")
  8315 +	(ashift:SI (mult:SI (match_operand:SI 1 "register_operand"  "r")
  8316 +		            (match_operand:SI 2 "const_int_operand" "I"))
  8317 +		   (match_operand:SI 3          "const_int_operand" "I")))]
  8318 +  "TARGET_HAS_MUL && SMALL_INT (INTVAL (operands[2]) << INTVAL (operands[3]))"
  8319 +{
  8320 +  HOST_WIDE_INT mul = INTVAL (operands[2]) << INTVAL (operands[3]);
  8321 +  rtx ops[3];
  8322 +  
  8323 +  ops[0] = operands[0];
  8324 +  ops[1] = operands[1];
  8325 +  ops[2] = GEN_INT (mul);
  8326 +  
  8327 +  output_asm_insn ("muli\t%0, %1, %2", ops);
  8328 +  return "";
  8329 +}
  8330 +  [(set_attr "type" "mul")])
  8331 +
  8332 +
  8333 +
  8334 +
  8335 +;*****************************************************************************
  8336 +;*
  8337 +;* Prologue, Epilogue and Return
  8338 +;*
  8339 +;*****************************************************************************
  8340 +
  8341 +(define_expand "prologue"
  8342 +  [(const_int 1)]
  8343 +  ""
  8344 +{
  8345 +  expand_prologue ();
  8346 +  DONE;
  8347 +})
  8348 +
  8349 +(define_expand "epilogue"
  8350 +  [(return)]
  8351 +  ""
  8352 +{
  8353 +  expand_epilogue (false);
  8354 +  DONE;
  8355 +})
  8356 +
  8357 +(define_expand "sibcall_epilogue"
  8358 +  [(return)]
  8359 +  ""
  8360 +{
  8361 +  expand_epilogue (true);
  8362 +  DONE;
  8363 +})
  8364 +
  8365 +(define_insn "return"
  8366 +  [(return)]
  8367 +  "reload_completed && nios2_can_use_return_insn ()"
  8368 +  "ret\\t"
  8369 +)
  8370 +
  8371 +(define_insn "return_from_epilogue"
  8372 +  [(use (match_operand 0 "pmode_register_operand" ""))
  8373 +   (return)]
  8374 +  "reload_completed"
  8375 +  "ret\\t"
  8376 +)
  8377 +
  8378 +;; Block any insns from being moved before this point, since the
  8379 +;; profiling call to mcount can use various registers that aren't
  8380 +;; saved or used to pass arguments.
  8381 +
  8382 +(define_insn "blockage"
  8383 +  [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
  8384 +  ""
  8385 +  ""
  8386 +  [(set_attr "type" "unknown")
  8387 +   (set_attr "length" "0")])
  8388 +
  8389 +
  8390 +
  8391 +;*****************************************************************************
  8392 +;*
  8393 +;* Jumps and Calls
  8394 +;*
  8395 +;*****************************************************************************
  8396 +
  8397 +(define_insn "indirect_jump"
  8398 +  [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
  8399 +  ""
  8400 +  "jmp\\t%0"
  8401 +  [(set_attr "type" "control")])
  8402 +
  8403 +(define_insn "jump"
  8404 +  [(set (pc)
  8405 +        (label_ref (match_operand 0 "" "")))]
  8406 +  ""
  8407 +  "br\\t%0"
  8408 +  [(set_attr "type" "control")])
  8409 +
  8410 +
  8411 +(define_insn "indirect_call"
  8412 +  [(call (mem:QI (match_operand:SI 0 "register_operand" "r"))
  8413 +         (match_operand 1 "" ""))
  8414 +   (clobber (reg:SI RA_REGNO))]
  8415 +  ""
  8416 +  "callr\\t%0"
  8417 +  [(set_attr "type" "control")])
  8418 +
  8419 +(define_insn "indirect_call_value"
  8420 +  [(set (match_operand 0 "" "")
  8421 +        (call (mem:QI (match_operand:SI 1 "register_operand" "r"))
  8422 +              (match_operand 2 "" "")))
  8423 +   (clobber (reg:SI RA_REGNO))]
  8424 +  ""
  8425 +  "callr\\t%1"
  8426 +)
  8427 +
  8428 +(define_expand "call"
  8429 +  [(parallel [(call (match_operand 0 "" "")
  8430 +                    (match_operand 1 "" ""))
  8431 +              (clobber (reg:SI RA_REGNO))])]
  8432 +  ""
  8433 +  "")
  8434 +
  8435 +(define_expand "call_value"
  8436 +  [(parallel [(set (match_operand 0 "" "")
  8437 +                   (call (match_operand 1 "" "")
  8438 +                         (match_operand 2 "" "")))
  8439 +              (clobber (reg:SI RA_REGNO))])]
  8440 +  ""
  8441 +  "")
  8442 +
  8443 +(define_insn "*call"
  8444 +  [(call (mem:QI (match_operand:SI 0 "immediate_operand" "i"))
  8445 +         (match_operand 1 "" ""))
  8446 +   (clobber (match_operand:SI 2 "register_operand" "=r"))]
  8447 +  ""
  8448 +  "call\\t%0"
  8449 +  [(set_attr "type" "control")])
  8450 +
  8451 +(define_insn "*call_value"
  8452 +  [(set (match_operand 0 "" "")
  8453 +        (call (mem:QI (match_operand:SI 1 "immediate_operand" "i"))
  8454 +              (match_operand 2 "" "")))
  8455 +   (clobber (match_operand:SI 3 "register_operand" "=r"))]
  8456 +  ""
  8457 +  "call\\t%1"
  8458 +  [(set_attr "type" "control")])
  8459 +
  8460 +(define_expand "sibcall"
  8461 +  [(parallel [(call (match_operand 0 "" "")
  8462 +		    (match_operand 1 "" ""))
  8463 +	      (return)
  8464 +	      (use (match_operand 2 "" ""))])]
  8465 +  ""
  8466 +  {
  8467 +    XEXP (operands[0], 0) = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
  8468 +
  8469 +    if (operands[2] == NULL_RTX)
  8470 +      operands[2] = const0_rtx;
  8471 +  }
  8472 +)
  8473 +
  8474 +(define_expand "sibcall_value"
  8475 +  [(parallel [(set (match_operand 0 "" "")
  8476 +		   (call (match_operand 1 "" "")
  8477 +			 (match_operand 2 "" "")))
  8478 +	      (return)
  8479 +	      (use (match_operand 3 "" ""))])]
  8480 +  ""
  8481 +  {
  8482 +    XEXP (operands[1], 0) = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
  8483 +
  8484 +    if (operands[3] == NULL_RTX)
  8485 +      operands[3] = const0_rtx;
  8486 +  }
  8487 +)
  8488 +
  8489 +(define_insn "sibcall_insn"
  8490 + [(call (mem:QI (match_operand:SI 0 "register_operand" "r"))
  8491 +	(match_operand 1 "" ""))
  8492 +  (return)
  8493 +  (use (match_operand 2 "" ""))]
  8494 +  ""
  8495 +  "jmp\\t%0"
  8496 +)
  8497 +
  8498 +(define_insn "sibcall_value_insn"
  8499 + [(set (match_operand 0 "register_operand" "")
  8500 +       (call (mem:QI (match_operand:SI 1 "register_operand" "r"))
  8501 +	     (match_operand 2 "" "")))
  8502 +  (return)
  8503 +  (use (match_operand 3 "" ""))]
  8504 +  ""
  8505 +  "jmp\\t%1"
  8506 +)
  8507 +
  8508 +
  8509 +
  8510 +
  8511 +(define_expand "tablejump"
  8512 +  [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
  8513 +              (use (label_ref (match_operand 1 "" "")))])]
  8514 +  ""
  8515 +  ""
  8516 +)
  8517 +
  8518 +(define_insn "*tablejump"
  8519 +  [(set (pc)
  8520 +	(match_operand:SI 0 "register_operand" "r"))
  8521 +   (use (label_ref (match_operand 1 "" "")))]
  8522 +  ""
  8523 +  "jmp\\t%0"
  8524 +  [(set_attr "type" "control")])
  8525 +
  8526 +
  8527 +
  8528 +;*****************************************************************************
  8529 +;*
  8530 +;* Comparisons
  8531 +;*
  8532 +;*****************************************************************************
  8533 +;; Flow here is rather complex (based on MIPS):
  8534 +;;
  8535 +;;  1)	The cmp{si,di,sf,df} routine is called.  It deposits the
  8536 +;;	arguments into the branch_cmp array, and the type into
  8537 +;;	branch_type.  No RTL is generated.
  8538 +;;
  8539 +;;  2)	The appropriate branch define_expand is called, which then
  8540 +;;	creates the appropriate RTL for the comparison and branch.
  8541 +;;	Different CC modes are used, based on what type of branch is
  8542 +;;	done, so that we can constrain things appropriately.  There
  8543 +;;	are assumptions in the rest of GCC that break if we fold the
  8544 +;;	operands into the branchs for integer operations, and use cc0
  8545 +;;	for floating point, so we use the fp status register instead.
  8546 +;;	If needed, an appropriate temporary is created to hold the
  8547 +;;	of the integer compare.
  8548 +
  8549 +(define_expand "cmpsi"
  8550 +  [(set (cc0)
  8551 +	(compare:CC (match_operand:SI 0 "register_operand" "")
  8552 +		    (match_operand:SI 1 "arith_operand" "")))]
  8553 +  ""
  8554 +{
  8555 +  branch_cmp[0] = operands[0];
  8556 +  branch_cmp[1] = operands[1];
  8557 +  branch_type = CMP_SI;
  8558 +  DONE;
  8559 +})
  8560 +
  8561 +(define_expand "tstsi"
  8562 +  [(set (cc0)
  8563 +	(match_operand:SI 0 "register_operand" ""))]
  8564 +  ""
  8565 +{
  8566 +  branch_cmp[0] = operands[0];
  8567 +  branch_cmp[1] = const0_rtx;
  8568 +  branch_type = CMP_SI;
  8569 +  DONE;
  8570 +})
  8571 +
  8572 +
  8573 +;*****************************************************************************
  8574 +;*
  8575 +;* setting a register from a comparison
  8576 +;*
  8577 +;*****************************************************************************
  8578 +
  8579 +(define_expand "seq"
  8580 +  [(set (match_operand:SI 0 "register_operand" "=r")
  8581 +	(eq:SI (match_dup 1)
  8582 +	       (match_dup 2)))]
  8583 +  ""
  8584 +{
  8585 +  if (branch_type != CMP_SI)
  8586 +    FAIL;
  8587 +
  8588 +  /* set up operands from compare.  */
  8589 +  operands[1] = branch_cmp[0];
  8590 +  operands[2] = branch_cmp[1];
  8591 +
  8592 +  gen_int_relational (EQ, operands[0], operands[1], operands[2], NULL_RTX);
  8593 +  DONE;
  8594 +})
  8595 +
  8596 +
  8597 +(define_insn "*seq"
  8598 +  [(set (match_operand:SI 0 "register_operand"        "=r")
  8599 +	(eq:SI (match_operand:SI 1 "reg_or_0_operand" "%rM")
  8600 +	       (match_operand:SI 2 "arith_operand"     "rI")))]
  8601 +  ""
  8602 +  "cmpeq%i2\\t%0, %z1, %z2"
  8603 +  [(set_attr "type" "alu")])
  8604 +
  8605 +
  8606 +(define_expand "sne"
  8607 +  [(set (match_operand:SI 0 "register_operand" "=r")
  8608 +	(ne:SI (match_dup 1)
  8609 +	       (match_dup 2)))]
  8610 +  ""
  8611 +{
  8612 +  if (branch_type != CMP_SI)
  8613 +    FAIL;
  8614 +
  8615 +  /* set up operands from compare.  */
  8616 +  operands[1] = branch_cmp[0];
  8617 +  operands[2] = branch_cmp[1];
  8618 +
  8619 +  gen_int_relational (NE, operands[0], operands[1], operands[2], NULL_RTX);
  8620 +  DONE;
  8621 +})
  8622 +
  8623 +
  8624 +(define_insn "*sne"
  8625 +  [(set (match_operand:SI 0 "register_operand"        "=r")
  8626 +	(ne:SI (match_operand:SI 1 "reg_or_0_operand" "%rM")
  8627 +	       (match_operand:SI 2 "arith_operand"     "rI")))]
  8628 +  ""
  8629 +  "cmpne%i2\\t%0, %z1, %z2"
  8630 +  [(set_attr "type" "alu")])
  8631 +
  8632 +
  8633 +(define_expand "sgt"
  8634 +  [(set (match_operand:SI 0 "register_operand" "=r")
  8635 +	(gt:SI (match_dup 1)
  8636 +	       (match_dup 2)))]
  8637 +  ""
  8638 +{
  8639 +  if (branch_type != CMP_SI)
  8640 +    FAIL;
  8641 +
  8642 +  /* set up operands from compare.  */
  8643 +  operands[1] = branch_cmp[0];
  8644 +  operands[2] = branch_cmp[1];
  8645 +
  8646 +  gen_int_relational (GT, operands[0], operands[1], operands[2], NULL_RTX);
  8647 +  DONE;
  8648 +})
  8649 +
  8650 +
  8651 +(define_insn "*sgt"
  8652 +  [(set (match_operand:SI 0 "register_operand"        "=r")
  8653 +	(gt:SI (match_operand:SI 1 "reg_or_0_operand"  "rM")
  8654 +	       (match_operand:SI 2 "reg_or_0_operand"  "rM")))]
  8655 +  ""
  8656 +  "cmplt\\t%0, %z2, %z1"
  8657 +  [(set_attr "type" "alu")])
  8658 +
  8659 +
  8660 +(define_expand "sge"
  8661 +  [(set (match_operand:SI 0 "register_operand" "=r")
  8662 +	(ge:SI (match_dup 1)
  8663 +	       (match_dup 2)))]
  8664 +  ""
  8665 +{
  8666 +  if (branch_type != CMP_SI)
  8667 +    FAIL;
  8668 +
  8669 +  /* set up operands from compare.  */
  8670 +  operands[1] = branch_cmp[0];
  8671 +  operands[2] = branch_cmp[1];
  8672 +
  8673 +  gen_int_relational (GE, operands[0], operands[1], operands[2], NULL_RTX);
  8674 +  DONE;
  8675 +})
  8676 +
  8677 +
  8678 +(define_insn "*sge"
  8679 +  [(set (match_operand:SI 0 "register_operand"        "=r")
  8680 +	(ge:SI (match_operand:SI 1 "reg_or_0_operand"  "rM")
  8681 +	       (match_operand:SI 2 "arith_operand"     "rI")))]
  8682 +  ""
  8683 +  "cmpge%i2\\t%0, %z1, %z2"
  8684 +  [(set_attr "type" "alu")])
  8685 +
  8686 +(define_expand "sle"
  8687 +  [(set (match_operand:SI 0 "register_operand" "=r")
  8688 +	(le:SI (match_dup 1)
  8689 +	       (match_dup 2)))]
  8690 +  ""
  8691 +{
  8692 +  if (branch_type != CMP_SI)
  8693 +    FAIL;
  8694 +
  8695 +  /* set up operands from compare.  */
  8696 +  operands[1] = branch_cmp[0];
  8697 +  operands[2] = branch_cmp[1];
  8698 +
  8699 +  gen_int_relational (LE, operands[0], operands[1], operands[2], NULL_RTX);
  8700 +  DONE;
  8701 +})
  8702 +
  8703 +
  8704 +(define_insn "*sle"
  8705 +  [(set (match_operand:SI 0 "register_operand"        "=r")
  8706 +	(le:SI (match_operand:SI 1 "reg_or_0_operand"  "rM")
  8707 +	       (match_operand:SI 2 "reg_or_0_operand"  "rM")))]
  8708 +  ""
  8709 +  "cmpge\\t%0, %z2, %z1"
  8710 +  [(set_attr "type" "alu")])
  8711 +
  8712 +
  8713 +(define_expand "slt"
  8714 +  [(set (match_operand:SI 0 "register_operand" "=r")
  8715 +	(lt:SI (match_dup 1)
  8716 +	       (match_dup 2)))]
  8717 +  ""
  8718 +{
  8719 +  if (branch_type != CMP_SI)
  8720 +    FAIL;
  8721 +
  8722 +  /* set up operands from compare.  */
  8723 +  operands[1] = branch_cmp[0];
  8724 +  operands[2] = branch_cmp[1];
  8725 +
  8726 +  gen_int_relational (LT, operands[0], operands[1], operands[2], NULL_RTX);
  8727 +  DONE;
  8728 +})
  8729 +
  8730 +
  8731 +(define_insn "*slt"
  8732 +  [(set (match_operand:SI 0 "register_operand"        "=r")
  8733 +	(lt:SI (match_operand:SI 1 "reg_or_0_operand"  "rM")
  8734 +	       (match_operand:SI 2 "arith_operand"     "rI")))]
  8735 +  ""
  8736 +  "cmplt%i2\\t%0, %z1, %z2"
  8737 +  [(set_attr "type" "alu")])
  8738 +
  8739 +
  8740 +(define_expand "sgtu"
  8741 +  [(set (match_operand:SI 0 "register_operand" "=r")
  8742 +	(gtu:SI (match_dup 1)
  8743 +	        (match_dup 2)))]
  8744 +  ""
  8745 +{
  8746 +  if (branch_type != CMP_SI)
  8747 +    FAIL;
  8748 +
  8749 +  /* set up operands from compare.  */
  8750 +  operands[1] = branch_cmp[0];
  8751 +  operands[2] = branch_cmp[1];
  8752 +
  8753 +  gen_int_relational (GTU, operands[0], operands[1], operands[2], NULL_RTX);
  8754 +  DONE;
  8755 +})
  8756 +
  8757 +
  8758 +(define_insn "*sgtu"
  8759 +  [(set (match_operand:SI 0 "register_operand"        "=r")
  8760 +	(gtu:SI (match_operand:SI 1 "reg_or_0_operand"  "rM")
  8761 +	        (match_operand:SI 2 "reg_or_0_operand"  "rM")))]
  8762 +  ""
  8763 +  "cmpltu\\t%0, %z2, %z1"
  8764 +  [(set_attr "type" "alu")])
  8765 +
  8766 +
  8767 +(define_expand "sgeu"
  8768 +  [(set (match_operand:SI 0 "register_operand" "=r")
  8769 +	(geu:SI (match_dup 1)
  8770 +	        (match_dup 2)))]
  8771 +  ""
  8772 +{
  8773 +  if (branch_type != CMP_SI)
  8774 +    FAIL;
  8775 +
  8776 +  /* set up operands from compare.  */
  8777 +  operands[1] = branch_cmp[0];
  8778 +  operands[2] = branch_cmp[1];
  8779 +
  8780 +  gen_int_relational (GEU, operands[0], operands[1], operands[2], NULL_RTX);
  8781 +  DONE;
  8782 +})
  8783 +
  8784 +
  8785 +(define_insn "*sgeu"
  8786 +  [(set (match_operand:SI 0 "register_operand"        "=r")
  8787 +	(geu:SI (match_operand:SI 1 "reg_or_0_operand"  "rM")
  8788 +	        (match_operand:SI 2 "uns_arith_operand"     "rJ")))]
  8789 +  ""
  8790 +  "cmpgeu%i2\\t%0, %z1, %z2"
  8791 +  [(set_attr "type" "alu")])
  8792 +
  8793 +(define_expand "sleu"
  8794 +  [(set (match_operand:SI 0 "register_operand" "=r")
  8795 +	(leu:SI (match_dup 1)
  8796 +	        (match_dup 2)))]
  8797 +  ""
  8798 +{
  8799 +  if (branch_type != CMP_SI)
  8800 +    FAIL;
  8801 +
  8802 +  /* set up operands from compare.  */
  8803 +  operands[1] = branch_cmp[0];
  8804 +  operands[2] = branch_cmp[1];
  8805 +
  8806 +  gen_int_relational (LEU, operands[0], operands[1], operands[2], NULL_RTX);
  8807 +  DONE;
  8808 +})
  8809 +
  8810 +
  8811 +(define_insn "*sleu"
  8812 +  [(set (match_operand:SI 0 "register_operand"        "=r")
  8813 +	(leu:SI (match_operand:SI 1 "reg_or_0_operand"  "rM")
  8814 +	        (match_operand:SI 2 "reg_or_0_operand"  "rM")))]
  8815 +  ""
  8816 +  "cmpgeu\\t%0, %z2, %z1"
  8817 +  [(set_attr "type" "alu")])
  8818 +
  8819 +
  8820 +(define_expand "sltu"
  8821 +  [(set (match_operand:SI 0 "register_operand" "=r")
  8822 +	(ltu:SI (match_dup 1)
  8823 +	        (match_dup 2)))]
  8824 +  ""
  8825 +{
  8826 +  if (branch_type != CMP_SI)
  8827 +    FAIL;
  8828 +
  8829 +  /* set up operands from compare.  */
  8830 +  operands[1] = branch_cmp[0];
  8831 +  operands[2] = branch_cmp[1];
  8832 +
  8833 +  gen_int_relational (LTU, operands[0], operands[1], operands[2], NULL_RTX);
  8834 +  DONE;
  8835 +})
  8836 +
  8837 +
  8838 +(define_insn "*sltu"
  8839 +  [(set (match_operand:SI 0 "register_operand"        "=r")
  8840 +	(ltu:SI (match_operand:SI 1 "reg_or_0_operand"  "rM")
  8841 +	        (match_operand:SI 2 "uns_arith_operand"     "rJ")))]
  8842 +  ""
  8843 +  "cmpltu%i2\\t%0, %z1, %z2"
  8844 +  [(set_attr "type" "alu")])
  8845 +
  8846 +
  8847 +
  8848 +
  8849 +;*****************************************************************************
  8850 +;*
  8851 +;* branches
  8852 +;*
  8853 +;*****************************************************************************
  8854 +
  8855 +(define_insn "*cbranch"
  8856 +  [(set (pc)
  8857 +	(if_then_else
  8858 +         (match_operator:SI 0 "comparison_operator"
  8859 +			    [(match_operand:SI 2 "reg_or_0_operand" "rM")
  8860 +			     (match_operand:SI 3 "reg_or_0_operand" "rM")])
  8861 +        (label_ref (match_operand 1 "" ""))
  8862 +        (pc)))]
  8863 +  ""
  8864 +  "b%0\\t%z2, %z3, %l1"
  8865 +  [(set_attr "type" "control")])
  8866 +
  8867 +
  8868 +(define_expand "beq"
  8869 +  [(set (pc)
  8870 +	(if_then_else (eq:CC (cc0)
  8871 +			     (const_int 0))
  8872 +		      (label_ref (match_operand 0 "" ""))
  8873 +		      (pc)))]
  8874 +  ""
  8875 +{
  8876 +  gen_int_relational (EQ, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
  8877 +  DONE;
  8878 +})
  8879 +
  8880 +
  8881 +(define_expand "bne"
  8882 +  [(set (pc)
  8883 +	(if_then_else (ne:CC (cc0)
  8884 +			     (const_int 0))
  8885 +		      (label_ref (match_operand 0 "" ""))
  8886 +		      (pc)))]
  8887 +  ""
  8888 +{
  8889 +  gen_int_relational (NE, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
  8890 +  DONE;
  8891 +})
  8892 +
  8893 +
  8894 +(define_expand "bgt"
  8895 +  [(set (pc)
  8896 +	(if_then_else (gt:CC (cc0)
  8897 +			     (const_int 0))
  8898 +		      (label_ref (match_operand 0 "" ""))
  8899 +		      (pc)))]
  8900 +  ""
  8901 +{
  8902 +  gen_int_relational (GT, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
  8903 +  DONE;
  8904 +})
  8905 +
  8906 +(define_expand "bge"
  8907 +  [(set (pc)
  8908 +	(if_then_else (ge:CC (cc0)
  8909 +			     (const_int 0))
  8910 +		      (label_ref (match_operand 0 "" ""))
  8911 +		      (pc)))]
  8912 +  ""
  8913 +{
  8914 +  gen_int_relational (GE, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
  8915 +  DONE;
  8916 +})
  8917 +
  8918 +(define_expand "ble"
  8919 +  [(set (pc)
  8920 +	(if_then_else (le:CC (cc0)
  8921 +			     (const_int 0))
  8922 +		      (label_ref (match_operand 0 "" ""))
  8923 +		      (pc)))]
  8924 +  ""
  8925 +{
  8926 +  gen_int_relational (LE, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
  8927 +  DONE;
  8928 +})
  8929 +
  8930 +(define_expand "blt"
  8931 +  [(set (pc)
  8932 +	(if_then_else (lt:CC (cc0)
  8933 +			     (const_int 0))
  8934 +		      (label_ref (match_operand 0 "" ""))
  8935 +		      (pc)))]
  8936 +  ""
  8937 +{
  8938 +  gen_int_relational (LT, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
  8939 +  DONE;
  8940 +})
  8941 +
  8942 +
  8943 +(define_expand "bgtu"
  8944 +  [(set (pc)
  8945 +	(if_then_else (gtu:CC (cc0)
  8946 +		 	      (const_int 0))
  8947 +		      (label_ref (match_operand 0 "" ""))
  8948 +		      (pc)))]
  8949 +  ""
  8950 +{
  8951 +  gen_int_relational (GTU, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
  8952 +  DONE;
  8953 +})
  8954 +
  8955 +(define_expand "bgeu"
  8956 +  [(set (pc)
  8957 +	(if_then_else (geu:CC (cc0)
  8958 +			      (const_int 0))
  8959 +		      (label_ref (match_operand 0 "" ""))
  8960 +		      (pc)))]
  8961 +  ""
  8962 +{
  8963 +  gen_int_relational (GEU, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
  8964 +  DONE;
  8965 +})
  8966 +
  8967 +(define_expand "bleu"
  8968 +  [(set (pc)
  8969 +	(if_then_else (leu:CC (cc0)
  8970 +			      (const_int 0))
  8971 +		      (label_ref (match_operand 0 "" ""))
  8972 +		      (pc)))]
  8973 +  ""
  8974 +{
  8975 +  gen_int_relational (LEU, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
  8976 +  DONE;
  8977 +})
  8978 +
  8979 +(define_expand "bltu"
  8980 +  [(set (pc)
  8981 +	(if_then_else (ltu:CC (cc0)
  8982 +			      (const_int 0))
  8983 +		      (label_ref (match_operand 0 "" ""))
  8984 +		      (pc)))]
  8985 +  ""
  8986 +{
  8987 +  gen_int_relational (LTU, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
  8988 +  DONE;
  8989 +})
  8990 +
  8991 +
  8992 +;*****************************************************************************
  8993 +;*
  8994 +;* String and Block Operations
  8995 +;*
  8996 +;*****************************************************************************
  8997 +
  8998 +; ??? This is all really a hack to get Dhrystone to work as fast as possible
  8999 +;     things to be fixed:
  9000 +;        * let the compiler core handle all of this, for that to work the extra
  9001 +;          aliasing needs to be addressed.
  9002 +;        * we use three temporary registers for loading and storing to ensure no
  9003 +;          ld use stalls, this is excessive, because after the first ld/st only
  9004 +;          two are needed. Only two would be needed all the way through if 
  9005 +;          we could schedule with other code. Consider:
  9006 +;           1  ld $1, 0($src)
  9007 +;           2  ld $2, 4($src)
  9008 +;           3  ld $3, 8($src)
  9009 +;           4  st $1, 0($dest)
  9010 +;           5  ld $1, 12($src)
  9011 +;           6  st $2, 4($src)
  9012 +;           7  etc.
  9013 +;          The first store has to wait until 4. If it does not there will be one
  9014 +;          cycle of stalling. However, if any other instruction could be placed
  9015 +;          between 1 and 4, $3 would not be needed.
  9016 +;        * In small we probably don't want to ever do this ourself because there
  9017 +;          is no ld use stall.
  9018 +
  9019 +(define_expand "movstrsi"
  9020 +  [(parallel [(set (match_operand:BLK 0 "general_operand"  "")
  9021 +		   (match_operand:BLK 1 "general_operand"  ""))
  9022 +	      (use (match_operand:SI 2 "const_int_operand" ""))
  9023 +	      (use (match_operand:SI 3 "const_int_operand" ""))
  9024 +	      (clobber (match_scratch:SI 4                "=&r"))
  9025 +	      (clobber (match_scratch:SI 5                "=&r"))
  9026 +	      (clobber (match_scratch:SI 6                "=&r"))])]
  9027 +  "TARGET_INLINE_MEMCPY"
  9028 +{
  9029 +  rtx ld_addr_reg, st_addr_reg;
  9030 +
  9031 +  /* If the predicate for op2 fails in expr.c:emit_block_move_via_movstr 
  9032 +     it trys to copy to a register, but does not re-try the predicate.
  9033 +     ??? Intead of fixing expr.c, I fix it here. */
  9034 +  if (!const_int_operand (operands[2], SImode))
  9035 +    FAIL;
  9036 +
  9037 +  /* ??? there are some magic numbers which need to be sorted out here.
  9038 +         the basis for them is not increasing code size hugely or going
  9039 +         out of range of offset addressing */
  9040 +  if (INTVAL (operands[3]) < 4)
  9041 +    FAIL;
  9042 +  if (!optimize
  9043 +      || (optimize_size && INTVAL (operands[2]) > 12)
  9044 +      || (optimize < 3 && INTVAL (operands[2]) > 100)
  9045 +      || INTVAL (operands[2]) > 200)
  9046 +    FAIL;
  9047 +
  9048 +  st_addr_reg
  9049 +    = replace_equiv_address (operands[0],
  9050 +			     copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
  9051 +  ld_addr_reg
  9052 +    = replace_equiv_address (operands[1],
  9053 +			     copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
  9054 +  emit_insn (gen_movstrsi_internal (st_addr_reg, ld_addr_reg,
  9055 +				    operands[2], operands[3]));
  9056 +
  9057 +  DONE;
  9058 +})
  9059 +
  9060 +
  9061 +(define_insn "movstrsi_internal"
  9062 +  [(set (match_operand:BLK 0 "memory_operand"   "=o")
  9063 +	(match_operand:BLK 1 "memory_operand"    "o"))
  9064 +   (use (match_operand:SI 2 "const_int_operand"  "i"))
  9065 +   (use (match_operand:SI 3 "const_int_operand"  "i"))
  9066 +   (clobber (match_scratch:SI 4                "=&r"))
  9067 +   (clobber (match_scratch:SI 5                "=&r"))
  9068 +   (clobber (match_scratch:SI 6                "=&r"))]
  9069 +  "TARGET_INLINE_MEMCPY"
  9070 +{
  9071 +  int ld_offset = INTVAL (operands[2]);
  9072 +  int ld_len = INTVAL (operands[2]);
  9073 +  int ld_reg = 0;
  9074 +  rtx ld_addr_reg = XEXP (operands[1], 0);
  9075 +  int st_offset = INTVAL (operands[2]);
  9076 +  int st_len = INTVAL (operands[2]);
  9077 +  int st_reg = 0;
  9078 +  rtx st_addr_reg = XEXP (operands[0], 0);
  9079 +  int delay_count = 0;
  9080 +  
  9081 +  /* ops[0] is the address used by the insn
  9082 +     ops[1] is the register being loaded or stored */
  9083 +  rtx ops[2];
  9084 +  
  9085 +  if (INTVAL (operands[3]) < 4)
  9086 +    abort ();
  9087 +  
  9088 +  while (ld_offset >= 4)
  9089 +    {
  9090 +      /* if the load use delay has been met, I can start
  9091 +         storing */
  9092 +      if (delay_count >= 3)
  9093 +        {
  9094 +	  ops[0] = gen_rtx (MEM, SImode, 
  9095 +			    plus_constant (st_addr_reg, st_len - st_offset));
  9096 +	  ops[1] = operands[st_reg + 4];			 
  9097 +	  output_asm_insn ("stw\t%1, %0", ops);
  9098 +	  
  9099 +	  st_reg = (st_reg + 1) % 3;
  9100 +	  st_offset -= 4;
  9101 +        }
  9102 +    
  9103 +      ops[0] = gen_rtx (MEM, SImode, 
  9104 +			plus_constant (ld_addr_reg, ld_len - ld_offset));
  9105 +      ops[1] = operands[ld_reg + 4];			 
  9106 +      output_asm_insn ("ldw\t%1, %0", ops);
  9107 +      
  9108 +      ld_reg = (ld_reg + 1) % 3;
  9109 +      ld_offset -= 4;
  9110 +      delay_count++;
  9111 +    }
  9112 +  
  9113 +  if (ld_offset >= 2)
  9114 +    {
  9115 +      /* if the load use delay has been met, I can start
  9116 +         storing */
  9117 +      if (delay_count >= 3)
  9118 +        {
  9119 +	  ops[0] = gen_rtx (MEM, SImode, 
  9120 +			    plus_constant (st_addr_reg, st_len - st_offset));
  9121 +	  ops[1] = operands[st_reg + 4];			 
  9122 +	  output_asm_insn ("stw\t%1, %0", ops);
  9123 +	  
  9124 +	  st_reg = (st_reg + 1) % 3;
  9125 +	  st_offset -= 4;
  9126 +        }
  9127 +    
  9128 +      ops[0] = gen_rtx (MEM, HImode, 
  9129 +			plus_constant (ld_addr_reg, ld_len - ld_offset));
  9130 +      ops[1] = operands[ld_reg + 4];			 
  9131 +      output_asm_insn ("ldh\t%1, %0", ops);
  9132 +      
  9133 +      ld_reg = (ld_reg + 1) % 3;
  9134 +      ld_offset -= 2;
  9135 +      delay_count++;
  9136 +    }
  9137 +  
  9138 +  if (ld_offset >= 1)
  9139 +    {
  9140 +      /* if the load use delay has been met, I can start
  9141 +         storing */
  9142 +      if (delay_count >= 3)
  9143 +        {
  9144 +	  ops[0] = gen_rtx (MEM, SImode, 
  9145 +			    plus_constant (st_addr_reg, st_len - st_offset));
  9146 +	  ops[1] = operands[st_reg + 4];			 
  9147 +	  output_asm_insn ("stw\t%1, %0", ops);
  9148 +	  
  9149 +	  st_reg = (st_reg + 1) % 3;
  9150 +	  st_offset -= 4;
  9151 +        }
  9152 +    
  9153 +      ops[0] = gen_rtx (MEM, QImode, 
  9154 +			plus_constant (ld_addr_reg, ld_len - ld_offset));
  9155 +      ops[1] = operands[ld_reg + 4];			 
  9156 +      output_asm_insn ("ldb\t%1, %0", ops);
  9157 +      
  9158 +      ld_reg = (ld_reg + 1) % 3;
  9159 +      ld_offset -= 1;
  9160 +      delay_count++;
  9161 +    }
  9162 +
  9163 +    while (st_offset >= 4)
  9164 +      {
  9165 +	ops[0] = gen_rtx (MEM, SImode, 
  9166 +			  plus_constant (st_addr_reg, st_len - st_offset));
  9167 +	ops[1] = operands[st_reg + 4];			 
  9168 +	output_asm_insn ("stw\t%1, %0", ops);
  9169 +
  9170 +	st_reg = (st_reg + 1) % 3;
  9171 +	st_offset -= 4;
  9172 +      }
  9173 +  
  9174 +    while (st_offset >= 2)
  9175 +      {
  9176 +	ops[0] = gen_rtx (MEM, HImode, 
  9177 +			  plus_constant (st_addr_reg, st_len - st_offset));
  9178 +	ops[1] = operands[st_reg + 4];			 
  9179 +	output_asm_insn ("sth\t%1, %0", ops);
  9180 +
  9181 +	st_reg = (st_reg + 1) % 3;
  9182 +	st_offset -= 2;
  9183 +      }
  9184 +  
  9185 +    while (st_offset >= 1)
  9186 +      {
  9187 +	ops[0] = gen_rtx (MEM, QImode, 
  9188 +			  plus_constant (st_addr_reg, st_len - st_offset));
  9189 +	ops[1] = operands[st_reg + 4];			 
  9190 +	output_asm_insn ("stb\t%1, %0", ops);
  9191 +
  9192 +	st_reg = (st_reg + 1) % 3;
  9193 +	st_offset -= 1;
  9194 +      }
  9195 +  
  9196 +  return "";
  9197 +}
  9198 +; ??? lengths are not being used yet, but I will probably forget
  9199 +; to update this once I am using lengths, so set it to something
  9200 +; definetely big enough to cover it. 400 allows for 200 bytes
  9201 +; of motion.
  9202 +  [(set_attr "length" "400")])
  9203 +
  9204 +
  9205 +
  9206 +;*****************************************************************************
  9207 +;*
  9208 +;* Custom instructions
  9209 +;*
  9210 +;*****************************************************************************
  9211 +
  9212 +(define_constants [
  9213 +  (CUSTOM_N 100)
  9214 +  (CUSTOM_NI 101)
  9215 +  (CUSTOM_NF 102)
  9216 +  (CUSTOM_NP 103)
  9217 +  (CUSTOM_NII 104)
  9218 +  (CUSTOM_NIF 105)
  9219 +  (CUSTOM_NIP 106)
  9220 +  (CUSTOM_NFI 107)
  9221 +  (CUSTOM_NFF 108)
  9222 +  (CUSTOM_NFP 109)
  9223 +  (CUSTOM_NPI 110)
  9224 +  (CUSTOM_NPF 111)
  9225 +  (CUSTOM_NPP 112)
  9226 +  (CUSTOM_IN 113)
  9227 +  (CUSTOM_INI 114)
  9228 +  (CUSTOM_INF 115)
  9229 +  (CUSTOM_INP 116)
  9230 +  (CUSTOM_INII 117)
  9231 +  (CUSTOM_INIF 118)
  9232 +  (CUSTOM_INIP 119)
  9233 +  (CUSTOM_INFI 120)
  9234 +  (CUSTOM_INFF 121)
  9235 +  (CUSTOM_INFP 122)
  9236 +  (CUSTOM_INPI 123)
  9237 +  (CUSTOM_INPF 124)
  9238 +  (CUSTOM_INPP 125)
  9239 +  (CUSTOM_FN 126)
  9240 +  (CUSTOM_FNI 127)
  9241 +  (CUSTOM_FNF 128)
  9242 +  (CUSTOM_FNP 129)
  9243 +  (CUSTOM_FNII 130)
  9244 +  (CUSTOM_FNIF 131)
  9245 +  (CUSTOM_FNIP 132)
  9246 +  (CUSTOM_FNFI 133)
  9247 +  (CUSTOM_FNFF 134)
  9248 +  (CUSTOM_FNFP 135)
  9249 +  (CUSTOM_FNPI 136)
  9250 +  (CUSTOM_FNPF 137)
  9251 +  (CUSTOM_FNPP 138)
  9252 +  (CUSTOM_PN 139)
  9253 +  (CUSTOM_PNI 140)
  9254 +  (CUSTOM_PNF 141)
  9255 +  (CUSTOM_PNP 142)
  9256 +  (CUSTOM_PNII 143)
  9257 +  (CUSTOM_PNIF 144)
  9258 +  (CUSTOM_PNIP 145)
  9259 +  (CUSTOM_PNFI 146)
  9260 +  (CUSTOM_PNFF 147)
  9261 +  (CUSTOM_PNFP 148)
  9262 +  (CUSTOM_PNPI 149)
  9263 +  (CUSTOM_PNPF 150)
  9264 +  (CUSTOM_PNPP 151)
  9265 +])
  9266 +
  9267 +
  9268 +(define_insn "custom_n"
  9269 +  [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")] CUSTOM_N)]
  9270 +  ""
  9271 +  "custom\\t%0, zero, zero, zero"
  9272 +  [(set_attr "type" "custom")])
  9273 +
  9274 +(define_insn "custom_ni"
  9275 +  [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
  9276 +                     (match_operand:SI 1 "register_operand"   "r")] CUSTOM_NI)]
  9277 +  ""
  9278 +  "custom\\t%0, zero, %1, zero"
  9279 +  [(set_attr "type" "custom")])
  9280 +
  9281 +(define_insn "custom_nf"
  9282 +  [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
  9283 +                     (match_operand:SF 1 "register_operand"   "r")] CUSTOM_NF)]
  9284 +  ""
  9285 +  "custom\\t%0, zero, %1, zero"
  9286 +  [(set_attr "type" "custom")])
  9287 +
  9288 +(define_insn "custom_np"
  9289 +  [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
  9290 +                     (match_operand:SI 1 "register_operand"   "r")] CUSTOM_NP)]
  9291 +  ""
  9292 +  "custom\\t%0, zero, %1, zero"
  9293 +  [(set_attr "type" "custom")])
  9294 +
  9295 +(define_insn "custom_nii"
  9296 +  [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
  9297 +                     (match_operand:SI 1 "register_operand"   "r")
  9298 +                     (match_operand:SI 2 "register_operand"   "r")] CUSTOM_NII)]
  9299 +  ""
  9300 +  "custom\\t%0, zero, %1, %2"
  9301 +  [(set_attr "type" "custom")])
  9302 +
  9303 +(define_insn "custom_nif"
  9304 +  [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
  9305 +                     (match_operand:SI 1 "register_operand"   "r")
  9306 +                     (match_operand:SF 2 "register_operand"   "r")] CUSTOM_NIF)]
  9307 +  ""
  9308 +  "custom\\t%0, zero, %1, %2"
  9309 +  [(set_attr "type" "custom")])
  9310 +
  9311 +(define_insn "custom_nip"
  9312 +  [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
  9313 +                     (match_operand:SI 1 "register_operand"   "r")
  9314 +                     (match_operand:SI 2 "register_operand"   "r")] CUSTOM_NIP)]
  9315 +  ""
  9316 +  "custom\\t%0, zero, %1, %2"
  9317 +  [(set_attr "type" "custom")])
  9318 +
  9319 +(define_insn "custom_nfi"
  9320 +  [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
  9321 +                     (match_operand:SF 1 "register_operand"   "r")
  9322 +                     (match_operand:SI 2 "register_operand"   "r")] CUSTOM_NFI)]
  9323 +  ""
  9324 +  "custom\\t%0, zero, %1, %2"
  9325 +  [(set_attr "type" "custom")])
  9326 +
  9327 +(define_insn "custom_nff"
  9328 +  [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
  9329 +                     (match_operand:SF 1 "register_operand"   "r")
  9330 +                     (match_operand:SF 2 "register_operand"   "r")] CUSTOM_NFF)]
  9331 +  ""
  9332 +  "custom\\t%0, zero, %1, %2"
  9333 +  [(set_attr "type" "custom")])
  9334 +
  9335 +(define_insn "custom_nfp"
  9336 +  [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
  9337 +                     (match_operand:SF 1 "register_operand"   "r")
  9338 +                     (match_operand:SI 2 "register_operand"   "r")] CUSTOM_NFP)]
  9339 +  ""
  9340 +  "custom\\t%0, zero, %1, %2"
  9341 +  [(set_attr "type" "custom")])
  9342 +
  9343 +(define_insn "custom_npi"
  9344 +  [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
  9345 +                     (match_operand:SI 1 "register_operand"   "r")
  9346 +                     (match_operand:SI 2 "register_operand"   "r")] CUSTOM_NPI)]
  9347 +  ""
  9348 +  "custom\\t%0, zero, %1, %2"
  9349 +  [(set_attr "type" "custom")])
  9350 +
  9351 +(define_insn "custom_npf"
  9352 +  [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
  9353 +                     (match_operand:SI 1 "register_operand"   "r")
  9354 +                     (match_operand:SF 2 "register_operand"   "r")] CUSTOM_NPF)]
  9355 +  ""
  9356 +  "custom\\t%0, zero, %1, %2"
  9357 +  [(set_attr "type" "custom")])
  9358 +
  9359 +(define_insn "custom_npp"
  9360 +  [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
  9361 +                     (match_operand:SI 1 "register_operand"   "r")
  9362 +                     (match_operand:SI 2 "register_operand"   "r")] CUSTOM_NPP)]
  9363 +  ""
  9364 +  "custom\\t%0, zero, %1, %2"
  9365 +  [(set_attr "type" "custom")])
  9366 +
  9367 +
  9368 +
  9369 +(define_insn "custom_in"
  9370 +  [(set (match_operand:SI 0 "register_operand"   "=r")
  9371 +        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")] CUSTOM_IN))]
  9372 +  ""
  9373 +  "custom\\t%1, %0, zero, zero"
  9374 +  [(set_attr "type" "custom")])
  9375 +
  9376 +(define_insn "custom_ini"
  9377 +  [(set (match_operand:SI 0 "register_operand"   "=r")
  9378 +        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  9379 +                          (match_operand:SI 2 "register_operand"   "r")] CUSTOM_INI))]
  9380 +  ""
  9381 +  "custom\\t%1, %0, %2, zero"
  9382 +  [(set_attr "type" "custom")])
  9383 +
  9384 +(define_insn "custom_inf"
  9385 +  [(set (match_operand:SI 0 "register_operand"   "=r")
  9386 +        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  9387 +                          (match_operand:SF 2 "register_operand"   "r")] CUSTOM_INF))]
  9388 +  ""
  9389 +  "custom\\t%1, %0, %2, zero"
  9390 +  [(set_attr "type" "custom")])
  9391 +
  9392 +(define_insn "custom_inp"
  9393 +  [(set (match_operand:SI 0 "register_operand"   "=r")
  9394 +        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  9395 +                          (match_operand:SI 2 "register_operand"   "r")] CUSTOM_INP))]
  9396 +  ""
  9397 +  "custom\\t%1, %0, %2, zero"
  9398 +  [(set_attr "type" "custom")])
  9399 +
  9400 +(define_insn "custom_inii"
  9401 +  [(set (match_operand:SI 0 "register_operand"   "=r")
  9402 +        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  9403 +                          (match_operand:SI 2 "register_operand"   "r")
  9404 +                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_INII))]
  9405 +  ""
  9406 +  "custom\\t%1, %0, %2, %3"
  9407 +  [(set_attr "type" "custom")])
  9408 +
  9409 +(define_insn "custom_inif"
  9410 +  [(set (match_operand:SI 0 "register_operand"   "=r")
  9411 +        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  9412 +                          (match_operand:SI 2 "register_operand"   "r")
  9413 +                          (match_operand:SF 3 "register_operand"   "r")] CUSTOM_INIF))]
  9414 +  ""
  9415 +  "custom\\t%1, %0, %2, %3"
  9416 +  [(set_attr "type" "custom")])
  9417 +
  9418 +(define_insn "custom_inip"
  9419 +  [(set (match_operand:SI 0 "register_operand"   "=r")
  9420 +        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  9421 +                          (match_operand:SI 2 "register_operand"   "r")
  9422 +                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_INIP))]
  9423 +  ""
  9424 +  "custom\\t%1, %0, %2, %3"
  9425 +  [(set_attr "type" "custom")])
  9426 +
  9427 +(define_insn "custom_infi"
  9428 +  [(set (match_operand:SI 0 "register_operand"   "=r")
  9429 +        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  9430 +                          (match_operand:SF 2 "register_operand"   "r")
  9431 +                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_INFI))]
  9432 +  ""
  9433 +  "custom\\t%1, %0, %2, %3"
  9434 +  [(set_attr "type" "custom")])
  9435 +
  9436 +(define_insn "custom_inff"
  9437 +  [(set (match_operand:SI 0 "register_operand"   "=r")
  9438 +        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  9439 +                          (match_operand:SF 2 "register_operand"   "r")
  9440 +                          (match_operand:SF 3 "register_operand"   "r")] CUSTOM_INFF))]
  9441 +  ""
  9442 +  "custom\\t%1, %0, %2, %3"
  9443 +  [(set_attr "type" "custom")])
  9444 +
  9445 +(define_insn "custom_infp"
  9446 +  [(set (match_operand:SI 0 "register_operand"   "=r")
  9447 +        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  9448 +                          (match_operand:SF 2 "register_operand"   "r")
  9449 +                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_INFP))]
  9450 +  ""
  9451 +  "custom\\t%1, %0, %2, %3"
  9452 +  [(set_attr "type" "custom")])
  9453 +
  9454 +(define_insn "custom_inpi"
  9455 +  [(set (match_operand:SI 0 "register_operand"   "=r")
  9456 +        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  9457 +                          (match_operand:SI 2 "register_operand"   "r")
  9458 +                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_INPI))]
  9459 +  ""
  9460 +  "custom\\t%1, %0, %2, %3"
  9461 +  [(set_attr "type" "custom")])
  9462 +
  9463 +(define_insn "custom_inpf"
  9464 +  [(set (match_operand:SI 0 "register_operand"   "=r")
  9465 +        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  9466 +                          (match_operand:SI 2 "register_operand"   "r")
  9467 +                          (match_operand:SF 3 "register_operand"   "r")] CUSTOM_INPF))]
  9468 +  ""
  9469 +  "custom\\t%1, %0, %2, %3"
  9470 +  [(set_attr "type" "custom")])
  9471 +
  9472 +(define_insn "custom_inpp"
  9473 +  [(set (match_operand:SI 0 "register_operand"   "=r")
  9474 +        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  9475 +                          (match_operand:SI 2 "register_operand"   "r")
  9476 +                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_INPP))]
  9477 +  ""
  9478 +  "custom\\t%1, %0, %2, %3"
  9479 +  [(set_attr "type" "custom")])
  9480 +
  9481 +
  9482 +
  9483 +
  9484 +
  9485 +(define_insn "custom_fn"
  9486 +  [(set (match_operand:SF 0 "register_operand"   "=r")
  9487 +        (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")] CUSTOM_FN))]
  9488 +  ""
  9489 +  "custom\\t%1, %0, zero, zero"
  9490 +  [(set_attr "type" "custom")])
  9491 +
  9492 +(define_insn "custom_fni"
  9493 +  [(set (match_operand:SF 0 "register_operand"   "=r")
  9494 +        (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
  9495 +                          (match_operand:SI 2 "register_operand"   "r")] CUSTOM_FNI))]
  9496 +  ""
  9497 +  "custom\\t%1, %0, %2, zero"
  9498 +  [(set_attr "type" "custom")])
  9499 +
  9500 +(define_insn "custom_fnf"
  9501 +  [(set (match_operand:SF 0 "register_operand"   "=r")
  9502 +        (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
  9503 +                          (match_operand:SF 2 "register_operand"   "r")] CUSTOM_FNF))]
  9504 +  ""
  9505 +  "custom\\t%1, %0, %2, zero"
  9506 +  [(set_attr "type" "custom")])
  9507 +
  9508 +(define_insn "custom_fnp"
  9509 +  [(set (match_operand:SF 0 "register_operand"   "=r")
  9510 +        (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
  9511 +                          (match_operand:SI 2 "register_operand"   "r")] CUSTOM_FNP))]
  9512 +  ""
  9513 +  "custom\\t%1, %0, %2, zero"
  9514 +  [(set_attr "type" "custom")])
  9515 +
  9516 +(define_insn "custom_fnii"
  9517 +  [(set (match_operand:SF 0 "register_operand"   "=r")
  9518 +        (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
  9519 +                          (match_operand:SI 2 "register_operand"   "r")
  9520 +                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_FNII))]
  9521 +  ""
  9522 +  "custom\\t%1, %0, %2, %3"
  9523 +  [(set_attr "type" "custom")])
  9524 +
  9525 +(define_insn "custom_fnif"
  9526 +  [(set (match_operand:SF 0 "register_operand"   "=r")
  9527 +        (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
  9528 +                          (match_operand:SI 2 "register_operand"   "r")
  9529 +                          (match_operand:SF 3 "register_operand"   "r")] CUSTOM_FNIF))]
  9530 +  ""
  9531 +  "custom\\t%1, %0, %2, %3"
  9532 +  [(set_attr "type" "custom")])
  9533 +
  9534 +(define_insn "custom_fnip"
  9535 +  [(set (match_operand:SF 0 "register_operand"   "=r")
  9536 +        (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
  9537 +                          (match_operand:SI 2 "register_operand"   "r")
  9538 +                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_FNIP))]
  9539 +  ""
  9540 +  "custom\\t%1, %0, %2, %3"
  9541 +  [(set_attr "type" "custom")])
  9542 +
  9543 +(define_insn "custom_fnfi"
  9544 +  [(set (match_operand:SF 0 "register_operand"   "=r")
  9545 +        (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
  9546 +                          (match_operand:SF 2 "register_operand"   "r")
  9547 +                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_FNFI))]
  9548 +  ""
  9549 +  "custom\\t%1, %0, %2, %3"
  9550 +  [(set_attr "type" "custom")])
  9551 +
  9552 +(define_insn "custom_fnff"
  9553 +  [(set (match_operand:SF 0 "register_operand"   "=r")
  9554 +        (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
  9555 +                          (match_operand:SF 2 "register_operand"   "r")
  9556 +                          (match_operand:SF 3 "register_operand"   "r")] CUSTOM_FNFF))]
  9557 +  ""
  9558 +  "custom\\t%1, %0, %2, %3"
  9559 +  [(set_attr "type" "custom")])
  9560 +
  9561 +(define_insn "custom_fnfp"
  9562 +  [(set (match_operand:SF 0 "register_operand"   "=r")
  9563 +        (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
  9564 +                          (match_operand:SF 2 "register_operand"   "r")
  9565 +                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_FNFP))]
  9566 +  ""
  9567 +  "custom\\t%1, %0, %2, %3"
  9568 +  [(set_attr "type" "custom")])
  9569 +
  9570 +(define_insn "custom_fnpi"
  9571 +  [(set (match_operand:SF 0 "register_operand"   "=r")
  9572 +        (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
  9573 +                          (match_operand:SI 2 "register_operand"   "r")
  9574 +                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_FNPI))]
  9575 +  ""
  9576 +  "custom\\t%1, %0, %2, %3"
  9577 +  [(set_attr "type" "custom")])
  9578 +
  9579 +(define_insn "custom_fnpf"
  9580 +  [(set (match_operand:SF 0 "register_operand"   "=r")
  9581 +        (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
  9582 +                          (match_operand:SI 2 "register_operand"   "r")
  9583 +                          (match_operand:SF 3 "register_operand"   "r")] CUSTOM_FNPF))]
  9584 +  ""
  9585 +  "custom\\t%1, %0, %2, %3"
  9586 +  [(set_attr "type" "custom")])
  9587 +
  9588 +(define_insn "custom_fnpp"
  9589 +  [(set (match_operand:SF 0 "register_operand"   "=r")
  9590 +        (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
  9591 +                          (match_operand:SI 2 "register_operand"   "r")
  9592 +                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_FNPP))]
  9593 +  ""
  9594 +  "custom\\t%1, %0, %2, %3"
  9595 +  [(set_attr "type" "custom")])
  9596 +
  9597 +
  9598 +
  9599 +(define_insn "custom_pn"
  9600 +  [(set (match_operand:SI 0 "register_operand"   "=r")
  9601 +        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")] CUSTOM_PN))]
  9602 +  ""
  9603 +  "custom\\t%1, %0, zero, zero"
  9604 +  [(set_attr "type" "custom")])
  9605 +
  9606 +(define_insn "custom_pni"
  9607 +  [(set (match_operand:SI 0 "register_operand"   "=r")
  9608 +        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  9609 +                          (match_operand:SI 2 "register_operand"   "r")] CUSTOM_PNI))]
  9610 +  ""
  9611 +  "custom\\t%1, %0, %2, zero"
  9612 +  [(set_attr "type" "custom")])
  9613 +
  9614 +(define_insn "custom_pnf"
  9615 +  [(set (match_operand:SI 0 "register_operand"   "=r")
  9616 +        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  9617 +                          (match_operand:SF 2 "register_operand"   "r")] CUSTOM_PNF))]
  9618 +  ""
  9619 +  "custom\\t%1, %0, %2, zero"
  9620 +  [(set_attr "type" "custom")])
  9621 +
  9622 +(define_insn "custom_pnp"
  9623 +  [(set (match_operand:SI 0 "register_operand"   "=r")
  9624 +        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  9625 +                          (match_operand:SI 2 "register_operand"   "r")] CUSTOM_PNP))]
  9626 +  ""
  9627 +  "custom\\t%1, %0, %2, zero"
  9628 +  [(set_attr "type" "custom")])
  9629 +
  9630 +(define_insn "custom_pnii"
  9631 +  [(set (match_operand:SI 0 "register_operand"   "=r")
  9632 +        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  9633 +                          (match_operand:SI 2 "register_operand"   "r")
  9634 +                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_PNII))]
  9635 +  ""
  9636 +  "custom\\t%1, %0, %2, %3"
  9637 +  [(set_attr "type" "custom")])
  9638 +
  9639 +(define_insn "custom_pnif"
  9640 +  [(set (match_operand:SI 0 "register_operand"   "=r")
  9641 +        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  9642 +                          (match_operand:SI 2 "register_operand"   "r")
  9643 +                          (match_operand:SF 3 "register_operand"   "r")] CUSTOM_PNIF))]
  9644 +  ""
  9645 +  "custom\\t%1, %0, %2, %3"
  9646 +  [(set_attr "type" "custom")])
  9647 +
  9648 +(define_insn "custom_pnip"
  9649 +  [(set (match_operand:SI 0 "register_operand"   "=r")
  9650 +        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  9651 +                          (match_operand:SI 2 "register_operand"   "r")
  9652 +                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_PNIP))]
  9653 +  ""
  9654 +  "custom\\t%1, %0, %2, %3"
  9655 +  [(set_attr "type" "custom")])
  9656 +
  9657 +(define_insn "custom_pnfi"
  9658 +  [(set (match_operand:SI 0 "register_operand"   "=r")
  9659 +        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  9660 +                          (match_operand:SF 2 "register_operand"   "r")
  9661 +                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_PNFI))]
  9662 +  ""
  9663 +  "custom\\t%1, %0, %2, %3"
  9664 +  [(set_attr "type" "custom")])
  9665 +
  9666 +(define_insn "custom_pnff"
  9667 +  [(set (match_operand:SI 0 "register_operand"   "=r")
  9668 +        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  9669 +                          (match_operand:SF 2 "register_operand"   "r")
  9670 +                          (match_operand:SF 3 "register_operand"   "r")] CUSTOM_PNFF))]
  9671 +  ""
  9672 +  "custom\\t%1, %0, %2, %3"
  9673 +  [(set_attr "type" "custom")])
  9674 +
  9675 +(define_insn "custom_pnfp"
  9676 +  [(set (match_operand:SI 0 "register_operand"   "=r")
  9677 +        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  9678 +                          (match_operand:SF 2 "register_operand"   "r")
  9679 +                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_PNFP))]
  9680 +  ""
  9681 +  "custom\\t%1, %0, %2, %3"
  9682 +  [(set_attr "type" "custom")])
  9683 +
  9684 +(define_insn "custom_pnpi"
  9685 +  [(set (match_operand:SI 0 "register_operand"   "=r")
  9686 +        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  9687 +                          (match_operand:SI 2 "register_operand"   "r")
  9688 +                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_PNPI))]
  9689 +  ""
  9690 +  "custom\\t%1, %0, %2, %3"
  9691 +  [(set_attr "type" "custom")])
  9692 +
  9693 +(define_insn "custom_pnpf"
  9694 +  [(set (match_operand:SI 0 "register_operand"   "=r")
  9695 +        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  9696 +                          (match_operand:SI 2 "register_operand"   "r")
  9697 +                          (match_operand:SF 3 "register_operand"   "r")] CUSTOM_PNPF))]
  9698 +  ""
  9699 +  "custom\\t%1, %0, %2, %3"
  9700 +  [(set_attr "type" "custom")])
  9701 +
  9702 +(define_insn "custom_pnpp"
  9703 +  [(set (match_operand:SI 0 "register_operand"   "=r")
  9704 +        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
  9705 +                          (match_operand:SI 2 "register_operand"   "r")
  9706 +                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_PNPP))]
  9707 +  ""
  9708 +  "custom\\t%1, %0, %2, %3"
  9709 +  [(set_attr "type" "custom")])
  9710 +
  9711 +
  9712 +
  9713 +
  9714 +
  9715 +
  9716 +;*****************************************************************************
  9717 +;*
  9718 +;* Misc
  9719 +;*
  9720 +;*****************************************************************************
  9721 +
  9722 +(define_insn "nop"
  9723 +  [(const_int 0)]
  9724 +  ""
  9725 +  "nop\\t"
  9726 +  [(set_attr "type" "alu")])
  9727 +
  9728 +(define_insn "sync"
  9729 +  [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)]
  9730 +  ""
  9731 +  "sync\\t"
  9732 +  [(set_attr "type" "control")])
  9733 +
  9734 +
  9735 +(define_insn "rdctl"
  9736 +  [(set (match_operand:SI 0 "register_operand" "=r")
  9737 +	(unspec_volatile:SI [(match_operand:SI 1 "rdwrctl_operand" "O")] UNSPEC_RDCTL))]
  9738 +  ""
  9739 +  "rdctl\\t%0, ctl%1"
  9740 +  [(set_attr "type" "control")])
  9741 +
  9742 +(define_insn "wrctl"
  9743 +  [(unspec_volatile:SI [(match_operand:SI 0 "rdwrctl_operand"  "O")
  9744 +                        (match_operand:SI 1 "register_operand" "r")] UNSPEC_WRCTL)]
  9745 +  ""
  9746 +  "wrctl\\tctl%0, %1"
  9747 +  [(set_attr "type" "control")])
  9748 +
  9749 +
  9750 +
  9751 +;*****************************************************************************
  9752 +;*
  9753 +;* Peepholes
  9754 +;*
  9755 +;*****************************************************************************
  9756 +
  9757 +
  9758 --- gcc-3.4.3/gcc/config/nios2/t-nios2
  9759 +++ gcc-3.4.3-nios2/gcc/config/nios2/t-nios2
  9760 @@ -0,0 +1,123 @@
  9761 +##
  9762 +## Compiler flags to use when compiling libgcc2.c.
  9763 +##
  9764 +## LIB2FUNCS_EXTRA
  9765 +## A list of source file names to be compiled or assembled and inserted into libgcc.a.
  9766 +
  9767 +LIB2FUNCS_EXTRA=$(srcdir)/config/nios2/lib2-divmod.c \
  9768 +  $(srcdir)/config/nios2/lib2-divmod-hi.c \
  9769 +  $(srcdir)/config/nios2/lib2-divtable.c \
  9770 +  $(srcdir)/config/nios2/lib2-mul.c
  9771 +
  9772 +##
  9773 +## Floating Point Emulation
  9774 +## To have GCC include software floating point libraries in libgcc.a define FPBIT
  9775 +## and DPBIT along with a few rules as follows:
  9776 +##
  9777 +## # We want fine grained libraries, so use the new code
  9778 +## # to build the floating point emulation libraries.
  9779 +FPBIT=$(srcdir)/config/nios2/nios2-fp-bit.c
  9780 +DPBIT=$(srcdir)/config/nios2/nios2-dp-bit.c
  9781 +
  9782 +TARGET_LIBGCC2_CFLAGS = -O2
  9783 +
  9784 +# FLOAT_ONLY - no doubles
  9785 +# SMALL_MACHINE - QI/HI is faster than SI
  9786 +#     Actually SMALL_MACHINE uses chars and shorts instead of ints
  9787 +#     since ints (16-bit ones as they are today) are at least as fast
  9788 +#     as chars and shorts, don't define SMALL_MACHINE
  9789 +# CMPtype - type returned by FP compare, i.e. INT (hard coded in fp-bit - see code )
  9790 +
  9791 +$(FPBIT): $(srcdir)/config/fp-bit.c Makefile
  9792 +	echo '#define FLOAT'          >  ${FPBIT}
  9793 +	cat $(srcdir)/config/fp-bit.c >> ${FPBIT}
  9794 +
  9795 +$(DPBIT): $(srcdir)/config/fp-bit.c Makefile
  9796 +	echo ''          >  ${DPBIT}
  9797 +	cat $(srcdir)/config/fp-bit.c >> ${DPBIT}
  9798 +
  9799 +EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crti.o crtn.o 
  9800 +
  9801 +# Assemble startup files. 
  9802 +$(T)crti.o: $(srcdir)/config/nios2/crti.asm $(GCC_PASSES) 
  9803 +	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
  9804 +	-c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/nios2/crti.asm 
  9805 +
  9806 +$(T)crtn.o: $(srcdir)/config/nios2/crtn.asm $(GCC_PASSES) 
  9807 +	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
  9808 +	-c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/nios2/crtn.asm 
  9809 +
  9810 +
  9811 +## You may need to provide additional #defines at the beginning of
  9812 +## fp-bit.c and dp-bit.c to control target endianness and other options
  9813 +##
  9814 +## CRTSTUFF_T_CFLAGS
  9815 +## Special flags used when compiling crtstuff.c.  See Initialization.
  9816 +##
  9817 +## CRTSTUFF_T_CFLAGS_S
  9818 +## Special flags used when compiling crtstuff.c for shared linking.  Used
  9819 +## if you use crtbeginS.o and crtendS.o in EXTRA-PARTS. See Initialization.
  9820 +##
  9821 +## MULTILIB_OPTIONS
  9822 +## For some targets, invoking GCC in different ways produces objects that
  9823 +## can not be linked together.  For example, for some targets GCC produces
  9824 +## both big and little endian code.  For these targets, you must arrange
  9825 +## for multiple versions of libgcc.a to be compiled, one for each set of
  9826 +## incompatible options.  When GCC invokes the linker, it arranges to link
  9827 +## in the right version of libgcc.a, based on the command line options
  9828 +## used.
  9829 +## The MULTILIB_OPTIONS macro lists the set of options for which special
  9830 +## versions of libgcc.a must be built.  Write options that are mutually
  9831 +## incompatible side by side, separated by a slash.  Write options that may
  9832 +## be used together separated by a space.  The build procedure will build
  9833 +## all combinations of compatible options.
  9834 +##
  9835 +## For example, if you set MULTILIB_OPTIONS to m68000/m68020 msoft-float,
  9836 +## Makefile will build special versions of libgcc.a using the following
  9837 +## sets of options: -m68000, -m68020, -msoft-float, -m68000 -msoft-float,
  9838 +## and -m68020 -msoft-float.
  9839 +
  9840 +MULTILIB_OPTIONS = mno-hw-mul mhw-mulx
  9841 +
  9842 +## MULTILIB_DIRNAMES
  9843 +## If MULTILIB_OPTIONS is used, this variable specifies the directory names
  9844 +## that should be used to hold the various libraries.  Write one element in
  9845 +## MULTILIB_DIRNAMES for each element in MULTILIB_OPTIONS. If
  9846 +## MULTILIB_DIRNAMES is not used, the default value will be
  9847 +## MULTILIB_OPTIONS, with all slashes treated as spaces.
  9848 +## For example, if MULTILIB_OPTIONS is set to m68000/m68020 msoft-float,
  9849 +## then the default value of MULTILIB_DIRNAMES is m68000 m68020
  9850 +## msoft-float.  You may specify a different value if you desire a
  9851 +## different set of directory names.
  9852 +
  9853 +# MULTILIB_DIRNAMES =
  9854 +
  9855 +## MULTILIB_MATCHES
  9856 +## Sometimes the same option may be written in two different ways.  If an
  9857 +## option is listed in MULTILIB_OPTIONS, GCC needs to know about any
  9858 +## synonyms.  In that case, set MULTILIB_MATCHES to a list of items of the
  9859 +## form option=option to describe all relevant synonyms.  For example,
  9860 +## m68000=mc68000 m68020=mc68020.
  9861 +##
  9862 +## MULTILIB_EXCEPTIONS
  9863 +## Sometimes when there are multiple sets of MULTILIB_OPTIONS being
  9864 +## specified, there are combinations that should not be built.  In that
  9865 +## case, set MULTILIB_EXCEPTIONS to be all of the switch exceptions in
  9866 +## shell case syntax that should not be built.
  9867 +## For example, in the PowerPC embedded ABI support, it is not desirable to
  9868 +## build libraries compiled with the -mcall-aix option and either of the
  9869 +## -fleading-underscore or -mlittle options at the same time.  Therefore
  9870 +## MULTILIB_EXCEPTIONS is set to
  9871 +##
  9872 +## *mcall-aix/*fleading-underscore* *mlittle/*mcall-aix*
  9873 +##
  9874 +
  9875 +MULTILIB_EXCEPTIONS = *mno-hw-mul/*mhw-mulx*
  9876 +
  9877 +##
  9878 +## MULTILIB_EXTRA_OPTS Sometimes it is desirable that when building
  9879 +## multiple versions of libgcc.a certain options should always be passed on
  9880 +## to the compiler.  In that case, set MULTILIB_EXTRA_OPTS to be the list
  9881 +## of options to be used for all builds.
  9882 +##
  9883 +
  9884 --- gcc-3.4.3/gcc/config.gcc
  9885 +++ gcc-3.4.3-nios2/gcc/config.gcc
  9886 @@ -1321,6 +1321,10 @@ m32rle-*-linux*)
  9887  		thread_file='posix'
  9888  	fi
  9889  	;;
  9890 +# JBG
  9891 +nios2-*-* | nios2-*-*)
  9892 +	tm_file="elfos.h ${tm_file}"
  9893 +	;;
  9894  # m68hc11 and m68hc12 share the same machine description.
  9895  m68hc11-*-*|m6811-*-*)
  9896  	tm_file="dbxelf.h elfos.h m68hc11/m68hc11.h"
  9897 --- gcc-3.4.3/gcc/cse.c
  9898 +++ gcc-3.4.3-nios2/gcc/cse.c
  9899 @@ -3134,6 +3134,10 @@ find_comparison_args (enum rtx_code code
  9900  #ifdef FLOAT_STORE_FLAG_VALUE
  9901  	  REAL_VALUE_TYPE fsfv;
  9902  #endif
  9903 +#ifdef __nios2__
  9904 +	  if (p->is_const)
  9905 +	    break;
  9906 +#endif
  9907  
  9908  	  /* If the entry isn't valid, skip it.  */
  9909  	  if (! exp_equiv_p (p->exp, p->exp, 1, 0))
  9910 --- gcc-3.4.3/gcc/doc/extend.texi
  9911 +++ gcc-3.4.3-nios2/gcc/doc/extend.texi
  9912 @@ -5636,12 +5636,118 @@ to those machines.  Generally these gene
  9913  instructions, but allow the compiler to schedule those calls.
  9914  
  9915  @menu
  9916 +* Altera Nios II Built-in Functions::
  9917  * Alpha Built-in Functions::
  9918  * ARM Built-in Functions::
  9919  * X86 Built-in Functions::
  9920  * PowerPC AltiVec Built-in Functions::
  9921  @end menu
  9922  
  9923 +@node Altera Nios II Built-in Functions
  9924 +@subsection Altera Nios II Built-in Functions
  9925 +
  9926 +These built-in functions are available for the Altera Nios II
  9927 +family of processors.
  9928 +
  9929 +The following built-in functions are always available.  They
  9930 +all generate the machine instruction that is part of the name.
  9931 +
  9932 +@example
  9933 +int __builtin_ldbio (volatile const void *)
  9934 +int __builtin_ldbuio (volatile const void *)
  9935 +int __builtin_ldhio (volatile const void *)
  9936 +int __builtin_ldhuio (volatile const void *)
  9937 +int __builtin_ldwio (volatile const void *)
  9938 +void __builtin_stbio (volatile void *, int)
  9939 +void __builtin_sthio (volatile void *, int)
  9940 +void __builtin_stwio (volatile void *, int)
  9941 +void __builtin_sync (void)
  9942 +int __builtin_rdctl (int) 
  9943 +void __builtin_wrctl (int, int)
  9944 +@end example
  9945 +
  9946 +The following built-in functions are always available.  They
  9947 +all generate a Nios II Custom Instruction. The name of the 
  9948 +function represents the types that the function takes and 
  9949 +returns. The letter before the @code{n} is the return type
  9950 +or void if absent. The @code{n} represnts the first parameter
  9951 +to all the custom instructions, the custom instruction number.
  9952 +The two letters after the @code{n} represent the up to two 
  9953 +parameters to the function.
  9954 +
  9955 +The letters reprsent the following data types:
  9956 +@table @code
  9957 +@item <no letter>
  9958 +@code{void} for return type and no parameter for parameter types.
  9959 +
  9960 +@item i
  9961 +@code{int} for return type and parameter type
  9962 +
  9963 +@item f
  9964 +@code{float} for return type and parameter type
  9965 +
  9966 +@item p
  9967 +@code{void *} for return type and parameter type
  9968 +
  9969 +@end table
  9970 +
  9971 +And the function names are:
  9972 +@example
  9973 +void __builtin_custom_n (void)
  9974 +void __builtin_custom_ni (int)
  9975 +void __builtin_custom_nf (float)
  9976 +void __builtin_custom_np (void *)
  9977 +void __builtin_custom_nii (int, int)
  9978 +void __builtin_custom_nif (int, float)
  9979 +void __builtin_custom_nip (int, void *)
  9980 +void __builtin_custom_nfi (float, int)
  9981 +void __builtin_custom_nff (float, float)
  9982 +void __builtin_custom_nfp (float, void *)
  9983 +void __builtin_custom_npi (void *, int)
  9984 +void __builtin_custom_npf (void *, float)
  9985 +void __builtin_custom_npp (void *, void *)
  9986 +int __builtin_custom_in (void)
  9987 +int __builtin_custom_ini (int)
  9988 +int __builtin_custom_inf (float)
  9989 +int __builtin_custom_inp (void *)
  9990 +int __builtin_custom_inii (int, int)
  9991 +int __builtin_custom_inif (int, float)
  9992 +int __builtin_custom_inip (int, void *)
  9993 +int __builtin_custom_infi (float, int)
  9994 +int __builtin_custom_inff (float, float)
  9995 +int __builtin_custom_infp (float, void *)
  9996 +int __builtin_custom_inpi (void *, int)
  9997 +int __builtin_custom_inpf (void *, float)
  9998 +int __builtin_custom_inpp (void *, void *)
  9999 +float __builtin_custom_fn (void)
 10000 +float __builtin_custom_fni (int)
 10001 +float __builtin_custom_fnf (float)
 10002 +float __builtin_custom_fnp (void *)
 10003 +float __builtin_custom_fnii (int, int)
 10004 +float __builtin_custom_fnif (int, float)
 10005 +float __builtin_custom_fnip (int, void *)
 10006 +float __builtin_custom_fnfi (float, int)
 10007 +float __builtin_custom_fnff (float, float)
 10008 +float __builtin_custom_fnfp (float, void *)
 10009 +float __builtin_custom_fnpi (void *, int)
 10010 +float __builtin_custom_fnpf (void *, float)
 10011 +float __builtin_custom_fnpp (void *, void *)
 10012 +void * __builtin_custom_pn (void)
 10013 +void * __builtin_custom_pni (int)
 10014 +void * __builtin_custom_pnf (float)
 10015 +void * __builtin_custom_pnp (void *)
 10016 +void * __builtin_custom_pnii (int, int)
 10017 +void * __builtin_custom_pnif (int, float)
 10018 +void * __builtin_custom_pnip (int, void *)
 10019 +void * __builtin_custom_pnfi (float, int)
 10020 +void * __builtin_custom_pnff (float, float)
 10021 +void * __builtin_custom_pnfp (float, void *)
 10022 +void * __builtin_custom_pnpi (void *, int)
 10023 +void * __builtin_custom_pnpf (void *, float)
 10024 +void * __builtin_custom_pnpp (void *, void *)
 10025 +@end example
 10026 +
 10027 +
 10028  @node Alpha Built-in Functions
 10029  @subsection Alpha Built-in Functions
 10030  
 10031 --- gcc-3.4.3/gcc/doc/invoke.texi
 10032 +++ gcc-3.4.3-nios2/gcc/doc/invoke.texi
 10033 @@ -337,6 +337,14 @@ in the following sections.
 10034  @item Machine Dependent Options
 10035  @xref{Submodel Options,,Hardware Models and Configurations}.
 10036  
 10037 +@emph{Altera Nios II Options}
 10038 +@gccoptlist{-msmallc -mno-bypass-cache -mbypass-cache @gol
 10039 +-mno-cache-volatile -mcache-volatile -mno-inline-memcpy @gol 
 10040 +-minline-memcpy -mno-fast-sw-div -mfast-sw-div @gol
 10041 +-mhw-mul -mno-hw-mul -mhw-mulx -mno-hw-mulx @gol
 10042 +-mno-hw-div -mhw-div @gol
 10043 +-msys-crt0= -msys-lib= -msys=nosys }
 10044 +
 10045  @emph{M680x0 Options}
 10046  @gccoptlist{-m68000  -m68020  -m68020-40  -m68020-60  -m68030  -m68040 @gol
 10047  -m68060  -mcpu32  -m5200  -m68881  -mbitfield  -mc68000  -mc68020   @gol
 10048 @@ -5836,6 +5844,7 @@ machine description.  The default for th
 10049  that macro, which enables you to change the defaults.
 10050  
 10051  @menu
 10052 +* Altera Nios II Options::
 10053  * M680x0 Options::
 10054  * M68hc1x Options::
 10055  * VAX Options::
 10056 @@ -5871,6 +5880,103 @@ that macro, which enables you to change 
 10057  * FRV Options::
 10058  @end menu
 10059  
 10060 +
 10061 +@node Altera Nios II Options
 10062 +@subsection Altera Nios II Options
 10063 +@cindex Altera Nios II options
 10064 +
 10065 +These are the @samp{-m} options defined for the Altera Nios II 
 10066 +processor.
 10067 +
 10068 +@table @gcctabopt
 10069 +
 10070 +@item -msmallc
 10071 +@opindex msmallc
 10072 +
 10073 +Link with a limited version of the C library, -lsmallc. For more 
 10074 +information see the C Library Documentation.
 10075 +
 10076 +
 10077 +@item -mbypass-cache
 10078 +@itemx -mno-bypass-cache
 10079 +@opindex mno-bypass-cache
 10080 +@opindex mbypass-cache
 10081 +
 10082 +Force all load and store instructions to always bypass cache by 
 10083 +using io variants of the instructions. The default is to not
 10084 +bypass the cache.
 10085 +
 10086 +@item -mno-cache-volatile 
 10087 +@itemx -mcache-volatile       
 10088 +@opindex mcache-volatile 
 10089 +@opindex mno-cache-volatile
 10090 +
 10091 +Volatile memory access bypass the cache using the io variants of 
 10092 +the ld and st instructions. The default is to cache volatile 
 10093 +accesses. 
 10094 +
 10095 +-mno-cache-volatile is deprecated and will be deleted in a 
 10096 +future GCC release.
 10097 +
 10098 +
 10099 +@item -mno-inline-memcpy
 10100 +@itemx -minline-memcpy
 10101 +@opindex mno-inline-memcpy 
 10102 +@opindex minline-memcpy
 10103 +
 10104 +Do not inline memcpy. The default is to inline when -O is on.
 10105 +
 10106 +
 10107 +@item -mno-fast-sw-div
 10108 +@itemx -mfast-sw-div
 10109 +@opindex mno-fast-sw-div
 10110 +@opindex mfast-sw-div
 10111 +
 10112 +Do no use table based fast divide for small numbers. The default 
 10113 +is to use the fast divide at -O3 and above.
 10114 +
 10115 +
 10116 +@item -mno-hw-mul
 10117 +@itemx -mhw-mul
 10118 +@itemx -mno-hw-mulx
 10119 +@itemx -mhw-mulx
 10120 +@itemx -mno-hw-div
 10121 +@itemx -mhw-div
 10122 +@opindex mno-hw-mul
 10123 +@opindex mhw-mul
 10124 +@opindex mno-hw-mulx
 10125 +@opindex mhw-mulx
 10126 +@opindex mno-hw-div
 10127 +@opindex mhw-div
 10128 +
 10129 +Enable or disable emitting @code{mul}, @code{mulx} and @code{div} family of 
 10130 +instructions by the compiler. The default is to emit @code{mul}
 10131 +and not emit @code{div} and @code{mulx}.
 10132 +
 10133 +The different combinations of @code{mul} and @code{mulx} instructions 
 10134 +generate a different multilib options. 
 10135 +
 10136 +
 10137 +@item -msys-crt0=@var{startfile}
 10138 +@opindex msys-crt0
 10139 +
 10140 +@var{startfile} is the file name  of the startfile (crt0) to use 
 10141 +when linking. The default is crt0.o that comes with libgloss
 10142 +and is only suitable for use with the instruction set
 10143 +simulator.
 10144 +
 10145 +@item -msys-lib=@var{systemlib}
 10146 +@itemx -msys-lib=nosys
 10147 +@opindex msys-lib
 10148 +
 10149 +@var{systemlib} is the library name of the library which provides
 10150 +the system calls required by the C library, e.g. @code{read}, @code{write}
 10151 +etc. The default is to use nosys, this library provides
 10152 +stub implementations of the calls and is part of libgloss.
 10153 +
 10154 +@end table
 10155 +
 10156 +
 10157  @node M680x0 Options
 10158  @subsection M680x0 Options
 10159  @cindex M680x0 options
 10160 --- gcc-3.4.3/gcc/doc/md.texi
 10161 +++ gcc-3.4.3-nios2/gcc/doc/md.texi
 10162 @@ -1335,6 +1335,49 @@ However, here is a summary of the machin
 10163  available on some particular machines.
 10164  
 10165  @table @emph
 10166 +
 10167 +@item Altera Nios II family---@file{nios2.h}
 10168 +@table @code
 10169 +
 10170 +@item I
 10171 +Integer that is valid as an immediate operand in an
 10172 +instruction taking a signed 16-bit number. Range
 10173 +@minus{}32768 to 32767.
 10174 +
 10175 +@item J
 10176 +Integer that is valid as an immediate operand in an
 10177 +instruction taking an unsigned 16-bit number. Range
 10178 +0 to 65535.
 10179 +
 10180 +@item K
 10181 +Integer that is valid as an immediate operand in an
 10182 +instruction taking only the upper 16-bits of a
 10183 +32-bit number. Range 32-bit numbers with the lower
 10184 +16-bits being 0.
 10185 +
 10186 +@item L
 10187 +Integer that is valid as an immediate operand for a 
 10188 +shift instruction. Range 0 to 31.
 10189 +
 10190 +
 10191 +@item M
 10192 +Integer that is valid as an immediate operand for
 10193 +only the value 0. Can be used in conjunction with
 10194 +the format modifier @code{z} to use @code{r0}
 10195 +instead of @code{0} in the assembly output.
 10196 +
 10197 +@item N
 10198 +Integer that is valid as an immediate operand for
 10199 +a custom instruction opcode. Range 0 to 255.
 10200 +
 10201 +@item S
 10202 +Matches immediates which are addresses in the small
 10203 +data section and therefore can be added to @code{gp}
 10204 +as a 16-bit immediate to re-create their 32-bit value.
 10205 +
 10206 +@end table
 10207 +
 10208 +
 10209  @item ARM family---@file{arm.h}
 10210  @table @code
 10211  @item f