patches/gcc/3.4.6/250-nios2.patch
author Remy Bohmer <linux@bohmer.net>
Sun Jul 11 22:23:34 2010 +0200 (2010-07-11)
changeset 2021 3e52a1510f87
parent 339 bd5e0a849352
permissions -rw-r--r--
debug/gdb: Fix compilation for Mingw hosts

GDB requires PDcurses instead of ncurses while running on Windows.
So, do not always compile ncurses in case GDB needs to build.

PDcurses is provided by an earlier build step and is not described in
this file.

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