patches/gcc/3.4.6/250-nios2.patch
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Mon Jul 28 21:32:33 2008 +0000 (2008-07-28)
changeset 747 d3e603e7c17c
parent 339 patches/gcc/3.4.6/900-nios2.patch@bd5e0a849352
permissions -rw-r--r--
Fourth step at renaming patches: renumber all patches with a 10-step.
     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