patches/gcc/3.4.6/250-nios2.patch
author "Benoît Thébaudeau" <benoit.thebaudeau@advansee.com>
Mon Apr 16 15:25:36 2012 +0200 (2012-04-16)
changeset 2941 13e40098fffc
parent 339 bd5e0a849352
permissions -rw-r--r--
cc/gcc: update Linaro GCC revisions to 2012.04

Update Linaro GCC with the latest available revisions.

The 4.7 revision is also released, but the infrastructure is not yet ready for
it in CT-NG.

Signed-off-by: "Benoît Thébaudeau" <benoit.thebaudeau@advansee.com>
yann@339
     1
diff -durN gcc-3.4.6.orig/gcc/combine.c gcc-3.4.6/gcc/combine.c
yann@339
     2
--- gcc-3.4.6.orig/gcc/combine.c	2005-08-08 20:41:04.000000000 +0200
yann@339
     3
+++ gcc-3.4.6/gcc/combine.c	2007-08-15 23:09:36.000000000 +0200
yann@339
     4
@@ -4381,6 +4381,14 @@
yann@339
     5
 					 mode);
yann@339
     6
 	    }
yann@339
     7
 
yann@339
     8
+#ifndef __nios2__
yann@339
     9
+/* This screws up Nios II in this test case:
yann@339
    10
+
yann@339
    11
+if (x & 1)
yann@339
    12
+  return 2;
yann@339
    13
+else
yann@339
    14
+  return 3;
yann@339
    15
+*/
yann@339
    16
 	  else if (STORE_FLAG_VALUE == 1
yann@339
    17
 		   && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT
yann@339
    18
 		   && op1 == const0_rtx
yann@339
    19
@@ -4392,6 +4400,7 @@
yann@339
    20
 				 gen_lowpart_for_combine (mode, op0),
yann@339
    21
 				 const1_rtx);
yann@339
    22
 	    }
yann@339
    23
+#endif
yann@339
    24
 
yann@339
    25
 	  else if (STORE_FLAG_VALUE == 1
yann@339
    26
 		   && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT
yann@339
    27
diff -durN gcc-3.4.6.orig/gcc/config/nios2/crti.asm gcc-3.4.6/gcc/config/nios2/crti.asm
yann@339
    28
--- gcc-3.4.6.orig/gcc/config/nios2/crti.asm	1970-01-01 01:00:00.000000000 +0100
yann@339
    29
+++ gcc-3.4.6/gcc/config/nios2/crti.asm	2007-08-15 23:09:36.000000000 +0200
yann@339
    30
@@ -0,0 +1,88 @@
yann@339
    31
+/*
yann@339
    32
+  Copyright (C) 2003 
yann@339
    33
+ by Jonah Graham (jgraham@altera.com)
yann@339
    34
+
yann@339
    35
+This file is free software; you can redistribute it and/or modify it
yann@339
    36
+under the terms of the GNU General Public License as published by the
yann@339
    37
+Free Software Foundation; either version 2, or (at your option) any
yann@339
    38
+later version.
yann@339
    39
+
yann@339
    40
+In addition to the permissions in the GNU General Public License, the
yann@339
    41
+Free Software Foundation gives you unlimited permission to link the
yann@339
    42
+compiled version of this file with other programs, and to distribute
yann@339
    43
+those programs without any restriction coming from the use of this
yann@339
    44
+file.  (The General Public License restrictions do apply in other
yann@339
    45
+respects; for example, they cover modification of the file, and
yann@339
    46
+distribution when not linked into another program.)
yann@339
    47
+
yann@339
    48
+This file is distributed in the hope that it will be useful, but
yann@339
    49
+WITHOUT ANY WARRANTY; without even the implied warranty of
yann@339
    50
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
yann@339
    51
+General Public License for more details.
yann@339
    52
+
yann@339
    53
+You should have received a copy of the GNU General Public License
yann@339
    54
+along with this program; see the file COPYING.  If not, write to
yann@339
    55
+the Free Software Foundation, 59 Temple Place - Suite 330,
yann@339
    56
+Boston, MA 02111-1307, USA.
yann@339
    57
+
yann@339
    58
+   As a special exception, if you link this library with files
yann@339
    59
+   compiled with GCC to produce an executable, this does not cause
yann@339
    60
+   the resulting executable to be covered by the GNU General Public License.
yann@339
    61
+   This exception does not however invalidate any other reasons why
yann@339
    62
+   the executable file might be covered by the GNU General Public License.
yann@339
    63
+
yann@339
    64
+
yann@339
    65
+This file just make a stack frame for the contents of the .fini and
yann@339
    66
+.init sections.  Users may put any desired instructions in those
yann@339
    67
+sections.
yann@339
    68
+
yann@339
    69
+
yann@339
    70
+While technically any code can be put in the init and fini sections
yann@339
    71
+most stuff will not work other than stuff which obeys the call frame
yann@339
    72
+and ABI. All the call-preserved registers are saved, the call clobbered
yann@339
    73
+registers should have been saved by the code calling init and fini.
yann@339
    74
+
yann@339
    75
+See crtstuff.c for an example of code that inserts itself in the 
yann@339
    76
+init and fini sections. 
yann@339
    77
+
yann@339
    78
+See crt0.s for the code that calls init and fini.
yann@339
    79
+*/
yann@339
    80
+
yann@339
    81
+	.file	"crti.asm"
yann@339
    82
+
yann@339
    83
+	.section	".init"
yann@339
    84
+	.align 2
yann@339
    85
+	.global	_init
yann@339
    86
+_init:
yann@339
    87
+	addi	sp, sp, -48
yann@339
    88
+	stw	ra, 44(sp)
yann@339
    89
+	stw	r23, 40(sp)
yann@339
    90
+	stw	r22, 36(sp)
yann@339
    91
+	stw	r21, 32(sp)
yann@339
    92
+	stw	r20, 28(sp)
yann@339
    93
+	stw	r19, 24(sp)
yann@339
    94
+	stw	r18, 20(sp)
yann@339
    95
+	stw	r17, 16(sp)
yann@339
    96
+	stw	r16, 12(sp)
yann@339
    97
+	stw	fp, 8(sp)
yann@339
    98
+	mov	fp, sp
yann@339
    99
+	
yann@339
   100
+	
yann@339
   101
+	.section	".fini"
yann@339
   102
+	.align	2
yann@339
   103
+	.global	_fini
yann@339
   104
+_fini:
yann@339
   105
+	addi	sp, sp, -48
yann@339
   106
+	stw	ra, 44(sp)
yann@339
   107
+	stw	r23, 40(sp)
yann@339
   108
+	stw	r22, 36(sp)
yann@339
   109
+	stw	r21, 32(sp)
yann@339
   110
+	stw	r20, 28(sp)
yann@339
   111
+	stw	r19, 24(sp)
yann@339
   112
+	stw	r18, 20(sp)
yann@339
   113
+	stw	r17, 16(sp)
yann@339
   114
+	stw	r16, 12(sp)
yann@339
   115
+	stw	fp, 8(sp)
yann@339
   116
+	mov	fp, sp
yann@339
   117
+	
yann@339
   118
+
yann@339
   119
diff -durN gcc-3.4.6.orig/gcc/config/nios2/crtn.asm gcc-3.4.6/gcc/config/nios2/crtn.asm
yann@339
   120
--- gcc-3.4.6.orig/gcc/config/nios2/crtn.asm	1970-01-01 01:00:00.000000000 +0100
yann@339
   121
+++ gcc-3.4.6/gcc/config/nios2/crtn.asm	2007-08-15 23:09:36.000000000 +0200
yann@339
   122
@@ -0,0 +1,70 @@
yann@339
   123
+/*
yann@339
   124
+  Copyright (C) 2003 
yann@339
   125
+ by Jonah Graham (jgraham@altera.com)
yann@339
   126
+
yann@339
   127
+This file is free software; you can redistribute it and/or modify it
yann@339
   128
+under the terms of the GNU General Public License as published by the
yann@339
   129
+Free Software Foundation; either version 2, or (at your option) any
yann@339
   130
+later version.
yann@339
   131
+
yann@339
   132
+In addition to the permissions in the GNU General Public License, the
yann@339
   133
+Free Software Foundation gives you unlimited permission to link the
yann@339
   134
+compiled version of this file with other programs, and to distribute
yann@339
   135
+those programs without any restriction coming from the use of this
yann@339
   136
+file.  (The General Public License restrictions do apply in other
yann@339
   137
+respects; for example, they cover modification of the file, and
yann@339
   138
+distribution when not linked into another program.)
yann@339
   139
+
yann@339
   140
+This file is distributed in the hope that it will be useful, but
yann@339
   141
+WITHOUT ANY WARRANTY; without even the implied warranty of
yann@339
   142
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
yann@339
   143
+General Public License for more details.
yann@339
   144
+
yann@339
   145
+You should have received a copy of the GNU General Public License
yann@339
   146
+along with this program; see the file COPYING.  If not, write to
yann@339
   147
+the Free Software Foundation, 59 Temple Place - Suite 330,
yann@339
   148
+Boston, MA 02111-1307, USA.
yann@339
   149
+
yann@339
   150
+   As a special exception, if you link this library with files
yann@339
   151
+   compiled with GCC to produce an executable, this does not cause
yann@339
   152
+   the resulting executable to be covered by the GNU General Public License.
yann@339
   153
+   This exception does not however invalidate any other reasons why
yann@339
   154
+   the executable file might be covered by the GNU General Public License.
yann@339
   155
+
yann@339
   156
+
yann@339
   157
+This file just makes sure that the .fini and .init sections do in
yann@339
   158
+fact return.  Users may put any desired instructions in those sections.
yann@339
   159
+This file is the last thing linked into any executable.
yann@339
   160
+*/	
yann@339
   161
+	.file	"crtn.asm"
yann@339
   162
+
yann@339
   163
+
yann@339
   164
+
yann@339
   165
+	.section	".init"
yann@339
   166
+	ldw	ra, 44(sp)
yann@339
   167
+	ldw	r23, 40(sp)
yann@339
   168
+	ldw	r22, 36(sp)
yann@339
   169
+	ldw	r21, 32(sp)
yann@339
   170
+	ldw	r20, 28(sp)
yann@339
   171
+	ldw	r19, 24(sp)
yann@339
   172
+	ldw	r18, 20(sp)
yann@339
   173
+	ldw	r17, 16(sp)
yann@339
   174
+	ldw	r16, 12(sp)
yann@339
   175
+	ldw	fp, 8(sp)
yann@339
   176
+	addi	sp, sp, -48
yann@339
   177
+	ret
yann@339
   178
+	
yann@339
   179
+	.section	".fini"
yann@339
   180
+	ldw	ra, 44(sp)
yann@339
   181
+	ldw	r23, 40(sp)
yann@339
   182
+	ldw	r22, 36(sp)
yann@339
   183
+	ldw	r21, 32(sp)
yann@339
   184
+	ldw	r20, 28(sp)
yann@339
   185
+	ldw	r19, 24(sp)
yann@339
   186
+	ldw	r18, 20(sp)
yann@339
   187
+	ldw	r17, 16(sp)
yann@339
   188
+	ldw	r16, 12(sp)
yann@339
   189
+	ldw	fp, 8(sp)
yann@339
   190
+	addi	sp, sp, -48
yann@339
   191
+	ret
yann@339
   192
+	
yann@339
   193
diff -durN gcc-3.4.6.orig/gcc/config/nios2/lib2-divmod.c gcc-3.4.6/gcc/config/nios2/lib2-divmod.c
yann@339
   194
--- gcc-3.4.6.orig/gcc/config/nios2/lib2-divmod.c	1970-01-01 01:00:00.000000000 +0100
yann@339
   195
+++ gcc-3.4.6/gcc/config/nios2/lib2-divmod.c	2007-08-15 23:09:36.000000000 +0200
yann@339
   196
@@ -0,0 +1,126 @@
yann@339
   197
+
yann@339
   198
+/* We include auto-host.h here to get HAVE_GAS_HIDDEN.  This is
yann@339
   199
+   supposedly valid even though this is a "target" file.  */
yann@339
   200
+#include "auto-host.h"
yann@339
   201
+
yann@339
   202
+
yann@339
   203
+#include "tconfig.h"
yann@339
   204
+#include "tsystem.h"
yann@339
   205
+#include "coretypes.h"
yann@339
   206
+#include "tm.h"
yann@339
   207
+
yann@339
   208
+
yann@339
   209
+/* Don't use `fancy_abort' here even if config.h says to use it.  */
yann@339
   210
+#ifdef abort
yann@339
   211
+#undef abort
yann@339
   212
+#endif
yann@339
   213
+
yann@339
   214
+
yann@339
   215
+#ifdef HAVE_GAS_HIDDEN
yann@339
   216
+#define ATTRIBUTE_HIDDEN  __attribute__ ((__visibility__ ("hidden")))
yann@339
   217
+#else
yann@339
   218
+#define ATTRIBUTE_HIDDEN
yann@339
   219
+#endif
yann@339
   220
+
yann@339
   221
+#include "libgcc2.h"
yann@339
   222
+
yann@339
   223
+extern SItype __modsi3 (SItype, SItype);
yann@339
   224
+extern SItype __divsi3 (SItype, SItype);
yann@339
   225
+extern SItype __umodsi3 (SItype, SItype);
yann@339
   226
+extern SItype __udivsi3 (SItype, SItype);
yann@339
   227
+
yann@339
   228
+static USItype udivmodsi4(USItype, USItype, word_type);
yann@339
   229
+
yann@339
   230
+/* 16-bit SI divide and modulo as used in NIOS */
yann@339
   231
+
yann@339
   232
+
yann@339
   233
+static USItype
yann@339
   234
+udivmodsi4(USItype num, USItype den, word_type modwanted)
yann@339
   235
+{
yann@339
   236
+  USItype bit = 1;
yann@339
   237
+  USItype res = 0;
yann@339
   238
+
yann@339
   239
+  while (den < num && bit && !(den & (1L<<31)))
yann@339
   240
+    {
yann@339
   241
+      den <<=1;
yann@339
   242
+      bit <<=1;
yann@339
   243
+    }
yann@339
   244
+  while (bit)
yann@339
   245
+    {
yann@339
   246
+      if (num >= den)
yann@339
   247
+	{
yann@339
   248
+	  num -= den;
yann@339
   249
+	  res |= bit;
yann@339
   250
+	}
yann@339
   251
+      bit >>=1;
yann@339
   252
+      den >>=1;
yann@339
   253
+    }
yann@339
   254
+  if (modwanted) return num;
yann@339
   255
+  return res;
yann@339
   256
+}
yann@339
   257
+
yann@339
   258
+
yann@339
   259
+SItype
yann@339
   260
+__divsi3 (SItype a, SItype b)
yann@339
   261
+{
yann@339
   262
+  word_type neg = 0;
yann@339
   263
+  SItype res;
yann@339
   264
+
yann@339
   265
+  if (a < 0)
yann@339
   266
+    {
yann@339
   267
+      a = -a;
yann@339
   268
+      neg = !neg;
yann@339
   269
+    }
yann@339
   270
+
yann@339
   271
+  if (b < 0)
yann@339
   272
+    {
yann@339
   273
+      b = -b;
yann@339
   274
+      neg = !neg;
yann@339
   275
+    }
yann@339
   276
+
yann@339
   277
+  res = udivmodsi4 (a, b, 0);
yann@339
   278
+
yann@339
   279
+  if (neg)
yann@339
   280
+    res = -res;
yann@339
   281
+
yann@339
   282
+  return res;
yann@339
   283
+}
yann@339
   284
+
yann@339
   285
+
yann@339
   286
+SItype
yann@339
   287
+__modsi3 (SItype a, SItype b)
yann@339
   288
+{
yann@339
   289
+  word_type neg = 0;
yann@339
   290
+  SItype res;
yann@339
   291
+
yann@339
   292
+  if (a < 0)
yann@339
   293
+    {
yann@339
   294
+      a = -a;
yann@339
   295
+      neg = 1;
yann@339
   296
+    }
yann@339
   297
+
yann@339
   298
+  if (b < 0)
yann@339
   299
+    b = -b;
yann@339
   300
+
yann@339
   301
+  res = udivmodsi4 (a, b, 1);
yann@339
   302
+
yann@339
   303
+  if (neg)
yann@339
   304
+    res = -res;
yann@339
   305
+
yann@339
   306
+  return res;
yann@339
   307
+}
yann@339
   308
+
yann@339
   309
+
yann@339
   310
+SItype
yann@339
   311
+__udivsi3 (SItype a, SItype b)
yann@339
   312
+{
yann@339
   313
+  return udivmodsi4 (a, b, 0);
yann@339
   314
+}
yann@339
   315
+
yann@339
   316
+
yann@339
   317
+SItype
yann@339
   318
+__umodsi3 (SItype a, SItype b)
yann@339
   319
+{
yann@339
   320
+  return udivmodsi4 (a, b, 1);
yann@339
   321
+}
yann@339
   322
+
yann@339
   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
yann@339
   324
--- gcc-3.4.6.orig/gcc/config/nios2/lib2-divmod-hi.c	1970-01-01 01:00:00.000000000 +0100
yann@339
   325
+++ gcc-3.4.6/gcc/config/nios2/lib2-divmod-hi.c	2007-08-15 23:09:36.000000000 +0200
yann@339
   326
@@ -0,0 +1,123 @@
yann@339
   327
+
yann@339
   328
+/* We include auto-host.h here to get HAVE_GAS_HIDDEN.  This is
yann@339
   329
+   supposedly valid even though this is a "target" file.  */
yann@339
   330
+#include "auto-host.h"
yann@339
   331
+
yann@339
   332
+
yann@339
   333
+#include "tconfig.h"
yann@339
   334
+#include "tsystem.h"
yann@339
   335
+#include "coretypes.h"
yann@339
   336
+#include "tm.h"
yann@339
   337
+
yann@339
   338
+
yann@339
   339
+/* Don't use `fancy_abort' here even if config.h says to use it.  */
yann@339
   340
+#ifdef abort
yann@339
   341
+#undef abort
yann@339
   342
+#endif
yann@339
   343
+
yann@339
   344
+
yann@339
   345
+#ifdef HAVE_GAS_HIDDEN
yann@339
   346
+#define ATTRIBUTE_HIDDEN  __attribute__ ((__visibility__ ("hidden")))
yann@339
   347
+#else
yann@339
   348
+#define ATTRIBUTE_HIDDEN
yann@339
   349
+#endif
yann@339
   350
+
yann@339
   351
+#include "libgcc2.h"
yann@339
   352
+
yann@339
   353
+extern HItype __modhi3 (HItype, HItype);
yann@339
   354
+extern HItype __divhi3 (HItype, HItype);
yann@339
   355
+extern HItype __umodhi3 (HItype, HItype);
yann@339
   356
+extern HItype __udivhi3 (HItype, HItype);
yann@339
   357
+
yann@339
   358
+static UHItype udivmodhi4(UHItype, UHItype, word_type);
yann@339
   359
+
yann@339
   360
+static UHItype
yann@339
   361
+udivmodhi4(UHItype num, UHItype den, word_type modwanted)
yann@339
   362
+{
yann@339
   363
+  UHItype bit = 1;
yann@339
   364
+  UHItype res = 0;
yann@339
   365
+
yann@339
   366
+  while (den < num && bit && !(den & (1L<<15)))
yann@339
   367
+    {
yann@339
   368
+      den <<=1;
yann@339
   369
+      bit <<=1;
yann@339
   370
+    }
yann@339
   371
+  while (bit)
yann@339
   372
+    {
yann@339
   373
+      if (num >= den)
yann@339
   374
+	{
yann@339
   375
+	  num -= den;
yann@339
   376
+	  res |= bit;
yann@339
   377
+	}
yann@339
   378
+      bit >>=1;
yann@339
   379
+      den >>=1;
yann@339
   380
+    }
yann@339
   381
+  if (modwanted) return num;
yann@339
   382
+  return res;
yann@339
   383
+}
yann@339
   384
+
yann@339
   385
+
yann@339
   386
+HItype
yann@339
   387
+__divhi3 (HItype a, HItype b)
yann@339
   388
+{
yann@339
   389
+  word_type neg = 0;
yann@339
   390
+  HItype res;
yann@339
   391
+
yann@339
   392
+  if (a < 0)
yann@339
   393
+    {
yann@339
   394
+      a = -a;
yann@339
   395
+      neg = !neg;
yann@339
   396
+    }
yann@339
   397
+
yann@339
   398
+  if (b < 0)
yann@339
   399
+    {
yann@339
   400
+      b = -b;
yann@339
   401
+      neg = !neg;
yann@339
   402
+    }
yann@339
   403
+
yann@339
   404
+  res = udivmodhi4 (a, b, 0);
yann@339
   405
+
yann@339
   406
+  if (neg)
yann@339
   407
+    res = -res;
yann@339
   408
+
yann@339
   409
+  return res;
yann@339
   410
+}
yann@339
   411
+
yann@339
   412
+
yann@339
   413
+HItype
yann@339
   414
+__modhi3 (HItype a, HItype b)
yann@339
   415
+{
yann@339
   416
+  word_type neg = 0;
yann@339
   417
+  HItype res;
yann@339
   418
+
yann@339
   419
+  if (a < 0)
yann@339
   420
+    {
yann@339
   421
+      a = -a;
yann@339
   422
+      neg = 1;
yann@339
   423
+    }
yann@339
   424
+
yann@339
   425
+  if (b < 0)
yann@339
   426
+    b = -b;
yann@339
   427
+
yann@339
   428
+  res = udivmodhi4 (a, b, 1);
yann@339
   429
+
yann@339
   430
+  if (neg)
yann@339
   431
+    res = -res;
yann@339
   432
+
yann@339
   433
+  return res;
yann@339
   434
+}
yann@339
   435
+
yann@339
   436
+
yann@339
   437
+HItype
yann@339
   438
+__udivhi3 (HItype a, HItype b)
yann@339
   439
+{
yann@339
   440
+  return udivmodhi4 (a, b, 0);
yann@339
   441
+}
yann@339
   442
+
yann@339
   443
+
yann@339
   444
+HItype
yann@339
   445
+__umodhi3 (HItype a, HItype b)
yann@339
   446
+{
yann@339
   447
+  return udivmodhi4 (a, b, 1);
yann@339
   448
+}
yann@339
   449
+
yann@339
   450
diff -durN gcc-3.4.6.orig/gcc/config/nios2/lib2-divtable.c gcc-3.4.6/gcc/config/nios2/lib2-divtable.c
yann@339
   451
--- gcc-3.4.6.orig/gcc/config/nios2/lib2-divtable.c	1970-01-01 01:00:00.000000000 +0100
yann@339
   452
+++ gcc-3.4.6/gcc/config/nios2/lib2-divtable.c	2007-08-15 23:09:36.000000000 +0200
yann@339
   453
@@ -0,0 +1,46 @@
yann@339
   454
+
yann@339
   455
+/* We include auto-host.h here to get HAVE_GAS_HIDDEN.  This is
yann@339
   456
+   supposedly valid even though this is a "target" file.  */
yann@339
   457
+#include "auto-host.h"
yann@339
   458
+
yann@339
   459
+
yann@339
   460
+#include "tconfig.h"
yann@339
   461
+#include "tsystem.h"
yann@339
   462
+#include "coretypes.h"
yann@339
   463
+#include "tm.h"
yann@339
   464
+
yann@339
   465
+
yann@339
   466
+/* Don't use `fancy_abort' here even if config.h says to use it.  */
yann@339
   467
+#ifdef abort
yann@339
   468
+#undef abort
yann@339
   469
+#endif
yann@339
   470
+
yann@339
   471
+
yann@339
   472
+#ifdef HAVE_GAS_HIDDEN
yann@339
   473
+#define ATTRIBUTE_HIDDEN  __attribute__ ((__visibility__ ("hidden")))
yann@339
   474
+#else
yann@339
   475
+#define ATTRIBUTE_HIDDEN
yann@339
   476
+#endif
yann@339
   477
+
yann@339
   478
+#include "libgcc2.h"
yann@339
   479
+
yann@339
   480
+UQItype __divsi3_table[] =
yann@339
   481
+{
yann@339
   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,
yann@339
   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,
yann@339
   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,
yann@339
   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,
yann@339
   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,
yann@339
   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,
yann@339
   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,
yann@339
   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,
yann@339
   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,
yann@339
   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,
yann@339
   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,
yann@339
   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,
yann@339
   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,
yann@339
   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,
yann@339
   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,
yann@339
   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,
yann@339
   498
+};
yann@339
   499
+
yann@339
   500
diff -durN gcc-3.4.6.orig/gcc/config/nios2/lib2-mul.c gcc-3.4.6/gcc/config/nios2/lib2-mul.c
yann@339
   501
--- gcc-3.4.6.orig/gcc/config/nios2/lib2-mul.c	1970-01-01 01:00:00.000000000 +0100
yann@339
   502
+++ gcc-3.4.6/gcc/config/nios2/lib2-mul.c	2007-08-15 23:09:36.000000000 +0200
yann@339
   503
@@ -0,0 +1,103 @@
yann@339
   504
+/* while we are debugging (ie compile outside of gcc build) 
yann@339
   505
+   disable gcc specific headers */
yann@339
   506
+#ifndef DEBUG_MULSI3
yann@339
   507
+
yann@339
   508
+
yann@339
   509
+/* We include auto-host.h here to get HAVE_GAS_HIDDEN.  This is
yann@339
   510
+   supposedly valid even though this is a "target" file.  */
yann@339
   511
+#include "auto-host.h"
yann@339
   512
+
yann@339
   513
+
yann@339
   514
+#include "tconfig.h"
yann@339
   515
+#include "tsystem.h"
yann@339
   516
+#include "coretypes.h"
yann@339
   517
+#include "tm.h"
yann@339
   518
+
yann@339
   519
+
yann@339
   520
+/* Don't use `fancy_abort' here even if config.h says to use it.  */
yann@339
   521
+#ifdef abort
yann@339
   522
+#undef abort
yann@339
   523
+#endif
yann@339
   524
+
yann@339
   525
+
yann@339
   526
+#ifdef HAVE_GAS_HIDDEN
yann@339
   527
+#define ATTRIBUTE_HIDDEN  __attribute__ ((__visibility__ ("hidden")))
yann@339
   528
+#else
yann@339
   529
+#define ATTRIBUTE_HIDDEN
yann@339
   530
+#endif
yann@339
   531
+
yann@339
   532
+#include "libgcc2.h"
yann@339
   533
+
yann@339
   534
+#else
yann@339
   535
+#define SItype int
yann@339
   536
+#define USItype unsigned int
yann@339
   537
+#endif
yann@339
   538
+
yann@339
   539
+
yann@339
   540
+extern SItype __mulsi3 (SItype, SItype);
yann@339
   541
+
yann@339
   542
+SItype
yann@339
   543
+__mulsi3 (SItype a, SItype b)
yann@339
   544
+{
yann@339
   545
+  SItype res = 0;
yann@339
   546
+  USItype cnt = a;
yann@339
   547
+  
yann@339
   548
+  while (cnt)
yann@339
   549
+    {
yann@339
   550
+      if (cnt & 1)
yann@339
   551
+        {
yann@339
   552
+	  res += b;	  
yann@339
   553
+	}
yann@339
   554
+      b <<= 1;
yann@339
   555
+      cnt >>= 1;
yann@339
   556
+    }
yann@339
   557
+    
yann@339
   558
+  return res;
yann@339
   559
+}
yann@339
   560
+/*
yann@339
   561
+TODO: Choose best alternative implementation.
yann@339
   562
+
yann@339
   563
+SItype
yann@339
   564
+__divsi3 (SItype a, SItype b)
yann@339
   565
+{
yann@339
   566
+  SItype res = 0;
yann@339
   567
+  USItype cnt = 0;
yann@339
   568
+  
yann@339
   569
+  while (cnt < 32)
yann@339
   570
+    {
yann@339
   571
+      if (a & (1L << cnt))
yann@339
   572
+        {
yann@339
   573
+	  res += b;	  
yann@339
   574
+	}
yann@339
   575
+      b <<= 1;
yann@339
   576
+      cnt++;
yann@339
   577
+    }
yann@339
   578
+    
yann@339
   579
+  return res;
yann@339
   580
+}
yann@339
   581
+*/
yann@339
   582
+
yann@339
   583
+
yann@339
   584
+#ifdef DEBUG_MULSI3
yann@339
   585
+
yann@339
   586
+int
yann@339
   587
+main ()
yann@339
   588
+{
yann@339
   589
+  int i, j;
yann@339
   590
+  int error = 0;
yann@339
   591
+  
yann@339
   592
+  for (i = -1000; i < 1000; i++)
yann@339
   593
+    for (j = -1000; j < 1000; j++)
yann@339
   594
+      {
yann@339
   595
+	int expect = i * j;
yann@339
   596
+	int actual = A__divsi3 (i, j);
yann@339
   597
+	if (expect != actual)
yann@339
   598
+	  {
yann@339
   599
+	    printf ("error: %d * %d = %d not %d\n", i, j, expect, actual);
yann@339
   600
+	    error = 1;
yann@339
   601
+	  }
yann@339
   602
+      }
yann@339
   603
+
yann@339
   604
+  return error;
yann@339
   605
+}
yann@339
   606
+#endif
yann@339
   607
diff -durN gcc-3.4.6.orig/gcc/config/nios2/nios2.c gcc-3.4.6/gcc/config/nios2/nios2.c
yann@339
   608
--- gcc-3.4.6.orig/gcc/config/nios2/nios2.c	1970-01-01 01:00:00.000000000 +0100
yann@339
   609
+++ gcc-3.4.6/gcc/config/nios2/nios2.c	2007-08-15 23:09:36.000000000 +0200
yann@339
   610
@@ -0,0 +1,2853 @@
yann@339
   611
+/* Subroutines for assembler code output for Altera NIOS 2G NIOS2 version.
yann@339
   612
+   Copyright (C) 2003 Altera
yann@339
   613
+   Contributed by Jonah Graham (jgraham@altera.com).
yann@339
   614
+
yann@339
   615
+This file is part of GNU CC.
yann@339
   616
+
yann@339
   617
+GNU CC is free software; you can redistribute it and/or modify
yann@339
   618
+it under the terms of the GNU General Public License as published by
yann@339
   619
+the Free Software Foundation; either version 2, or (at your option)
yann@339
   620
+any later version.
yann@339
   621
+
yann@339
   622
+GNU CC is distributed in the hope that it will be useful,
yann@339
   623
+but WITHOUT ANY WARRANTY; without even the implied warranty of
yann@339
   624
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
yann@339
   625
+GNU General Public License for more details.
yann@339
   626
+
yann@339
   627
+You should have received a copy of the GNU General Public License
yann@339
   628
+along with GNU CC; see the file COPYING.  If not, write to
yann@339
   629
+the Free Software Foundation, 59 Temple Place - Suite 330,
yann@339
   630
+Boston, MA 02111-1307, USA.  */
yann@339
   631
+
yann@339
   632
+
yann@339
   633
+#include <stdio.h>
yann@339
   634
+#include "config.h"
yann@339
   635
+#include "system.h"
yann@339
   636
+#include "coretypes.h"
yann@339
   637
+#include "tm.h"
yann@339
   638
+#include "rtl.h"
yann@339
   639
+#include "tree.h"
yann@339
   640
+#include "tm_p.h"
yann@339
   641
+#include "regs.h"
yann@339
   642
+#include "hard-reg-set.h"
yann@339
   643
+#include "real.h"
yann@339
   644
+#include "insn-config.h"
yann@339
   645
+#include "conditions.h"
yann@339
   646
+#include "output.h"
yann@339
   647
+#include "insn-attr.h"
yann@339
   648
+#include "flags.h"
yann@339
   649
+#include "recog.h"
yann@339
   650
+#include "expr.h"
yann@339
   651
+#include "toplev.h"
yann@339
   652
+#include "basic-block.h"
yann@339
   653
+#include "function.h"
yann@339
   654
+#include "ggc.h"
yann@339
   655
+#include "reload.h"
yann@339
   656
+#include "debug.h"
yann@339
   657
+#include "optabs.h"
yann@339
   658
+#include "target.h"
yann@339
   659
+#include "target-def.h"
yann@339
   660
+
yann@339
   661
+/* local prototypes */
yann@339
   662
+static bool nios2_rtx_costs (rtx, int, int, int *);
yann@339
   663
+
yann@339
   664
+static void nios2_asm_function_prologue (FILE *, HOST_WIDE_INT);
yann@339
   665
+static int nios2_use_dfa_pipeline_interface (void);
yann@339
   666
+static int nios2_issue_rate (void);
yann@339
   667
+static struct machine_function *nios2_init_machine_status (void);
yann@339
   668
+static bool nios2_in_small_data_p (tree);
yann@339
   669
+static rtx save_reg (int, HOST_WIDE_INT, rtx);
yann@339
   670
+static rtx restore_reg (int, HOST_WIDE_INT);
yann@339
   671
+static unsigned int nios2_section_type_flags (tree, const char *, int);
yann@339
   672
+static void nios2_init_builtins (void);
yann@339
   673
+static rtx nios2_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
yann@339
   674
+static bool nios2_function_ok_for_sibcall (tree, tree);
yann@339
   675
+static void nios2_encode_section_info (tree, rtx, int);
yann@339
   676
+
yann@339
   677
+/* Initialize the GCC target structure.  */
yann@339
   678
+#undef TARGET_ASM_FUNCTION_PROLOGUE
yann@339
   679
+#define TARGET_ASM_FUNCTION_PROLOGUE nios2_asm_function_prologue
yann@339
   680
+
yann@339
   681
+#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
yann@339
   682
+#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE \
yann@339
   683
+ nios2_use_dfa_pipeline_interface
yann@339
   684
+#undef TARGET_SCHED_ISSUE_RATE
yann@339
   685
+#define TARGET_SCHED_ISSUE_RATE nios2_issue_rate
yann@339
   686
+#undef TARGET_IN_SMALL_DATA_P
yann@339
   687
+#define TARGET_IN_SMALL_DATA_P nios2_in_small_data_p
yann@339
   688
+#undef  TARGET_ENCODE_SECTION_INFO
yann@339
   689
+#define TARGET_ENCODE_SECTION_INFO nios2_encode_section_info
yann@339
   690
+#undef  TARGET_SECTION_TYPE_FLAGS
yann@339
   691
+#define TARGET_SECTION_TYPE_FLAGS  nios2_section_type_flags
yann@339
   692
+
yann@339
   693
+#undef TARGET_INIT_BUILTINS
yann@339
   694
+#define TARGET_INIT_BUILTINS nios2_init_builtins
yann@339
   695
+#undef TARGET_EXPAND_BUILTIN
yann@339
   696
+#define TARGET_EXPAND_BUILTIN nios2_expand_builtin
yann@339
   697
+
yann@339
   698
+#undef TARGET_FUNCTION_OK_FOR_SIBCALL
yann@339
   699
+#define TARGET_FUNCTION_OK_FOR_SIBCALL nios2_function_ok_for_sibcall
yann@339
   700
+
yann@339
   701
+#undef TARGET_RTX_COSTS
yann@339
   702
+#define TARGET_RTX_COSTS nios2_rtx_costs
yann@339
   703
+
yann@339
   704
+
yann@339
   705
+struct gcc_target targetm = TARGET_INITIALIZER;
yann@339
   706
+
yann@339
   707
+
yann@339
   708
+
yann@339
   709
+/* Threshold for data being put into the small data/bss area, instead
yann@339
   710
+   of the normal data area (references to the small data/bss area take
yann@339
   711
+   1 instruction, and use the global pointer, references to the normal
yann@339
   712
+   data area takes 2 instructions).  */
yann@339
   713
+unsigned HOST_WIDE_INT nios2_section_threshold = NIOS2_DEFAULT_GVALUE;
yann@339
   714
+
yann@339
   715
+
yann@339
   716
+/* Structure to be filled in by compute_frame_size with register
yann@339
   717
+   save masks, and offsets for the current function.  */
yann@339
   718
+
yann@339
   719
+struct nios2_frame_info
yann@339
   720
+GTY (())
yann@339
   721
+{
yann@339
   722
+  long total_size;		/* # bytes that the entire frame takes up */
yann@339
   723
+  long var_size;		/* # bytes that variables take up */
yann@339
   724
+  long args_size;		/* # bytes that outgoing arguments take up */
yann@339
   725
+  int save_reg_size;		/* # bytes needed to store gp regs */
yann@339
   726
+  int save_reg_rounded;		/* # bytes needed to store gp regs */
yann@339
   727
+  long save_regs_offset;	/* offset from new sp to store gp registers */
yann@339
   728
+  int initialized;		/* != 0 if frame size already calculated */
yann@339
   729
+  int num_regs;			/* number of gp registers saved */
yann@339
   730
+};
yann@339
   731
+
yann@339
   732
+struct machine_function
yann@339
   733
+GTY (())
yann@339
   734
+{
yann@339
   735
+
yann@339
   736
+  /* Current frame information, calculated by compute_frame_size.  */
yann@339
   737
+  struct nios2_frame_info frame;
yann@339
   738
+};
yann@339
   739
+
yann@339
   740
+
yann@339
   741
+/***************************************
yann@339
   742
+ * Section encodings
yann@339
   743
+ ***************************************/
yann@339
   744
+
yann@339
   745
+
yann@339
   746
+
yann@339
   747
+
yann@339
   748
+
yann@339
   749
+/***************************************
yann@339
   750
+ * Stack Layout and Calling Conventions
yann@339
   751
+ ***************************************/
yann@339
   752
+
yann@339
   753
+
yann@339
   754
+#define TOO_BIG_OFFSET(X) ((X) > ((1 << 15) - 1))
yann@339
   755
+#define TEMP_REG_NUM 8
yann@339
   756
+
yann@339
   757
+static void
yann@339
   758
+nios2_asm_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
yann@339
   759
+{
yann@339
   760
+  if (flag_verbose_asm || flag_debug_asm)
yann@339
   761
+    {
yann@339
   762
+      compute_frame_size ();
yann@339
   763
+      dump_frame_size (file);
yann@339
   764
+    }
yann@339
   765
+}
yann@339
   766
+
yann@339
   767
+static rtx
yann@339
   768
+save_reg (int regno, HOST_WIDE_INT offset, rtx cfa_store_reg)
yann@339
   769
+{
yann@339
   770
+  rtx insn, stack_slot;
yann@339
   771
+
yann@339
   772
+  stack_slot = gen_rtx_PLUS (SImode,
yann@339
   773
+			     cfa_store_reg,
yann@339
   774
+			     GEN_INT (offset));
yann@339
   775
+
yann@339
   776
+  insn = emit_insn (gen_rtx_SET (SImode,
yann@339
   777
+				 gen_rtx_MEM (SImode, stack_slot),
yann@339
   778
+				 gen_rtx_REG (SImode, regno)));
yann@339
   779
+
yann@339
   780
+  RTX_FRAME_RELATED_P (insn) = 1;
yann@339
   781
+
yann@339
   782
+  return insn;
yann@339
   783
+}
yann@339
   784
+
yann@339
   785
+static rtx
yann@339
   786
+restore_reg (int regno, HOST_WIDE_INT offset)
yann@339
   787
+{
yann@339
   788
+  rtx insn, stack_slot;
yann@339
   789
+
yann@339
   790
+  if (TOO_BIG_OFFSET (offset))
yann@339
   791
+    {
yann@339
   792
+      stack_slot = gen_rtx_REG (SImode, TEMP_REG_NUM);
yann@339
   793
+      insn = emit_insn (gen_rtx_SET (SImode,
yann@339
   794
+				     stack_slot,
yann@339
   795
+				     GEN_INT (offset)));
yann@339
   796
+
yann@339
   797
+      insn = emit_insn (gen_rtx_SET (SImode,
yann@339
   798
+				     stack_slot,
yann@339
   799
+                                     gen_rtx_PLUS (SImode,
yann@339
   800
+				                   stack_slot,
yann@339
   801
+				                   stack_pointer_rtx)));
yann@339
   802
+    }
yann@339
   803
+  else
yann@339
   804
+    {
yann@339
   805
+      stack_slot = gen_rtx_PLUS (SImode,
yann@339
   806
+			         stack_pointer_rtx,
yann@339
   807
+				 GEN_INT (offset));
yann@339
   808
+    }
yann@339
   809
+
yann@339
   810
+  stack_slot = gen_rtx_MEM (SImode, stack_slot);
yann@339
   811
+
yann@339
   812
+  insn = emit_move_insn (gen_rtx_REG (SImode, regno), stack_slot);
yann@339
   813
+
yann@339
   814
+  return insn;
yann@339
   815
+}
yann@339
   816
+
yann@339
   817
+
yann@339
   818
+/* There are two possible paths for prologue expansion,
yann@339
   819
+- the first is if the total frame size is < 2^15-1. In that
yann@339
   820
+case all the immediates will fit into the 16-bit immediate
yann@339
   821
+fields.
yann@339
   822
+- the second is when the frame size is too big, in that
yann@339
   823
+case an additional temporary register is used, first 
yann@339
   824
+as a cfa_temp to offset the sp, second as the cfa_store
yann@339
   825
+register.
yann@339
   826
+
yann@339
   827
+See the comment above dwarf2out_frame_debug_expr in 
yann@339
   828
+dwarf2out.c for more explanation of the "rules."
yann@339
   829
+
yann@339
   830
+
yann@339
   831
+Case 1:
yann@339
   832
+Rule #  Example Insn                       Effect
yann@339
   833
+2  	addi	sp, sp, -total_frame_size  cfa.reg=sp, cfa.offset=total_frame_size
yann@339
   834
+                                           cfa_store.reg=sp, cfa_store.offset=total_frame_size
yann@339
   835
+12  	stw	ra, offset(sp)		   
yann@339
   836
+12  	stw	r16, offset(sp)
yann@339
   837
+1  	mov	fp, sp
yann@339
   838
+  
yann@339
   839
+Case 2: 
yann@339
   840
+Rule #  Example Insn                       Effect
yann@339
   841
+6 	movi	r8, total_frame_size       cfa_temp.reg=r8, cfa_temp.offset=total_frame_size
yann@339
   842
+2  	sub	sp, sp, r8                 cfa.reg=sp, cfa.offset=total_frame_size
yann@339
   843
+                                           cfa_store.reg=sp, cfa_store.offset=total_frame_size
yann@339
   844
+5   	add	r8, r8, sp                 cfa_store.reg=r8, cfa_store.offset=0
yann@339
   845
+12  	stw	ra, offset(r8)
yann@339
   846
+12  	stw	r16, offset(r8)
yann@339
   847
+1  	mov	fp, sp
yann@339
   848
+
yann@339
   849
+*/
yann@339
   850
+
yann@339
   851
+void
yann@339
   852
+expand_prologue ()
yann@339
   853
+{
yann@339
   854
+  int i;
yann@339
   855
+  HOST_WIDE_INT total_frame_size;
yann@339
   856
+  int cfa_store_offset;
yann@339
   857
+  rtx insn;
yann@339
   858
+  rtx cfa_store_reg = 0;
yann@339
   859
+
yann@339
   860
+  total_frame_size = compute_frame_size ();
yann@339
   861
+
yann@339
   862
+  if (total_frame_size)
yann@339
   863
+    {
yann@339
   864
+
yann@339
   865
+      if (TOO_BIG_OFFSET (total_frame_size)) 
yann@339
   866
+	{
yann@339
   867
+	    /* cfa_temp and cfa_store_reg are the same register,
yann@339
   868
+	       cfa_store_reg overwrites cfa_temp */
yann@339
   869
+	    cfa_store_reg = gen_rtx_REG (SImode, TEMP_REG_NUM);
yann@339
   870
+	    insn = emit_insn (gen_rtx_SET (SImode,
yann@339
   871
+					   cfa_store_reg,
yann@339
   872
+					   GEN_INT (total_frame_size)));
yann@339
   873
+
yann@339
   874
+	    RTX_FRAME_RELATED_P (insn) = 1;
yann@339
   875
+
yann@339
   876
+
yann@339
   877
+	    insn = gen_rtx_SET (SImode,
yann@339
   878
+				stack_pointer_rtx,
yann@339
   879
+				gen_rtx_MINUS (SImode,
yann@339
   880
+					       stack_pointer_rtx,
yann@339
   881
+					       cfa_store_reg));
yann@339
   882
+
yann@339
   883
+	    insn = emit_insn (insn);
yann@339
   884
+	    RTX_FRAME_RELATED_P (insn) = 1;
yann@339
   885
+
yann@339
   886
+
yann@339
   887
+	    /* if there are no registers to save, I don't need to
yann@339
   888
+	       create a cfa_store */
yann@339
   889
+	    if (cfun->machine->frame.save_reg_size) 
yann@339
   890
+	      {
yann@339
   891
+		insn = gen_rtx_SET (SImode,
yann@339
   892
+				    cfa_store_reg,
yann@339
   893
+				    gen_rtx_PLUS (SImode,
yann@339
   894
+						  cfa_store_reg,
yann@339
   895
+						  stack_pointer_rtx));
yann@339
   896
+
yann@339
   897
+		insn = emit_insn (insn);
yann@339
   898
+		RTX_FRAME_RELATED_P (insn) = 1;
yann@339
   899
+	      }
yann@339
   900
+
yann@339
   901
+	    cfa_store_offset 
yann@339
   902
+	      = total_frame_size 
yann@339
   903
+		- (cfun->machine->frame.save_regs_offset
yann@339
   904
+		   + cfun->machine->frame.save_reg_rounded);
yann@339
   905
+	}
yann@339
   906
+      else
yann@339
   907
+	{
yann@339
   908
+	    insn = gen_rtx_SET (SImode,
yann@339
   909
+				stack_pointer_rtx,
yann@339
   910
+				gen_rtx_PLUS (SImode,
yann@339
   911
+					      stack_pointer_rtx,
yann@339
   912
+					      GEN_INT (-total_frame_size)));
yann@339
   913
+	    insn = emit_insn (insn);
yann@339
   914
+	    RTX_FRAME_RELATED_P (insn) = 1;
yann@339
   915
+
yann@339
   916
+	    cfa_store_reg = stack_pointer_rtx;
yann@339
   917
+	    cfa_store_offset 
yann@339
   918
+	      = cfun->machine->frame.save_regs_offset
yann@339
   919
+		+ cfun->machine->frame.save_reg_rounded;
yann@339
   920
+	}
yann@339
   921
+    }
yann@339
   922
+
yann@339
   923
+  if (MUST_SAVE_REGISTER (RA_REGNO))
yann@339
   924
+    {
yann@339
   925
+      cfa_store_offset -= 4;
yann@339
   926
+      save_reg (RA_REGNO, cfa_store_offset, cfa_store_reg);
yann@339
   927
+    }
yann@339
   928
+  if (MUST_SAVE_REGISTER (FP_REGNO))
yann@339
   929
+    {
yann@339
   930
+      cfa_store_offset -= 4;
yann@339
   931
+      save_reg (FP_REGNO, cfa_store_offset, cfa_store_reg);
yann@339
   932
+    }
yann@339
   933
+
yann@339
   934
+  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
yann@339
   935
+    {
yann@339
   936
+      if (MUST_SAVE_REGISTER (i) && i != FP_REGNO && i != RA_REGNO)
yann@339
   937
+	{
yann@339
   938
+	  cfa_store_offset -= 4;
yann@339
   939
+	  save_reg (i, cfa_store_offset, cfa_store_reg);
yann@339
   940
+	}
yann@339
   941
+    }
yann@339
   942
+
yann@339
   943
+  if (frame_pointer_needed)
yann@339
   944
+    {
yann@339
   945
+      insn = emit_insn (gen_rtx_SET (SImode,
yann@339
   946
+				     gen_rtx_REG (SImode, FP_REGNO),
yann@339
   947
+				     gen_rtx_REG (SImode, SP_REGNO)));
yann@339
   948
+
yann@339
   949
+      RTX_FRAME_RELATED_P (insn) = 1;
yann@339
   950
+    }
yann@339
   951
+
yann@339
   952
+  /* If we are profiling, make sure no instructions are scheduled before
yann@339
   953
+     the call to mcount.  */
yann@339
   954
+  if (current_function_profile)
yann@339
   955
+    emit_insn (gen_blockage ());
yann@339
   956
+}
yann@339
   957
+
yann@339
   958
+void
yann@339
   959
+expand_epilogue (bool sibcall_p)
yann@339
   960
+{
yann@339
   961
+  rtx insn;
yann@339
   962
+  int i;
yann@339
   963
+  HOST_WIDE_INT total_frame_size;
yann@339
   964
+  int register_store_offset;
yann@339
   965
+
yann@339
   966
+  total_frame_size = compute_frame_size ();
yann@339
   967
+
yann@339
   968
+  if (!sibcall_p && nios2_can_use_return_insn ())
yann@339
   969
+    {
yann@339
   970
+      insn = emit_jump_insn (gen_return ());
yann@339
   971
+      return;
yann@339
   972
+    }
yann@339
   973
+
yann@339
   974
+  emit_insn (gen_blockage ());
yann@339
   975
+
yann@339
   976
+  register_store_offset =
yann@339
   977
+    cfun->machine->frame.save_regs_offset +
yann@339
   978
+    cfun->machine->frame.save_reg_rounded;
yann@339
   979
+
yann@339
   980
+  if (MUST_SAVE_REGISTER (RA_REGNO))
yann@339
   981
+    {
yann@339
   982
+      register_store_offset -= 4;
yann@339
   983
+      restore_reg (RA_REGNO, register_store_offset);
yann@339
   984
+    }
yann@339
   985
+
yann@339
   986
+  if (MUST_SAVE_REGISTER (FP_REGNO))
yann@339
   987
+    {
yann@339
   988
+      register_store_offset -= 4;
yann@339
   989
+      restore_reg (FP_REGNO, register_store_offset);
yann@339
   990
+    }
yann@339
   991
+
yann@339
   992
+  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
yann@339
   993
+    {
yann@339
   994
+      if (MUST_SAVE_REGISTER (i) && i != FP_REGNO && i != RA_REGNO)
yann@339
   995
+	{
yann@339
   996
+	  register_store_offset -= 4;
yann@339
   997
+	  restore_reg (i, register_store_offset);
yann@339
   998
+	}
yann@339
   999
+    }
yann@339
  1000
+
yann@339
  1001
+  if (total_frame_size)
yann@339
  1002
+    {
yann@339
  1003
+      rtx sp_adjust;
yann@339
  1004
+
yann@339
  1005
+      if (TOO_BIG_OFFSET (total_frame_size))
yann@339
  1006
+        {
yann@339
  1007
+	  sp_adjust = gen_rtx_REG (SImode, TEMP_REG_NUM);
yann@339
  1008
+	  insn = emit_insn (gen_rtx_SET (SImode,
yann@339
  1009
+					 sp_adjust,
yann@339
  1010
+					 GEN_INT (total_frame_size)));
yann@339
  1011
+
yann@339
  1012
+      	}
yann@339
  1013
+      else
yann@339
  1014
+        {
yann@339
  1015
+	  sp_adjust = GEN_INT (total_frame_size);
yann@339
  1016
+	}
yann@339
  1017
+
yann@339
  1018
+      insn = gen_rtx_SET (SImode,
yann@339
  1019
+			  stack_pointer_rtx,
yann@339
  1020
+			  gen_rtx_PLUS (SImode,
yann@339
  1021
+					stack_pointer_rtx,
yann@339
  1022
+					sp_adjust));
yann@339
  1023
+      insn = emit_insn (insn);
yann@339
  1024
+    }
yann@339
  1025
+
yann@339
  1026
+
yann@339
  1027
+  if (!sibcall_p)
yann@339
  1028
+    {
yann@339
  1029
+      insn = emit_jump_insn (gen_return_from_epilogue (gen_rtx (REG, Pmode,
yann@339
  1030
+								RA_REGNO)));
yann@339
  1031
+    }
yann@339
  1032
+}
yann@339
  1033
+
yann@339
  1034
+
yann@339
  1035
+bool
yann@339
  1036
+nios2_function_ok_for_sibcall (tree a ATTRIBUTE_UNUSED, tree b ATTRIBUTE_UNUSED)
yann@339
  1037
+{
yann@339
  1038
+  return true;
yann@339
  1039
+}
yann@339
  1040
+
yann@339
  1041
+
yann@339
  1042
+
yann@339
  1043
+
yann@339
  1044
+
yann@339
  1045
+/* ----------------------- *
yann@339
  1046
+ * Profiling
yann@339
  1047
+ * ----------------------- */
yann@339
  1048
+
yann@339
  1049
+void
yann@339
  1050
+function_profiler (FILE *file, int labelno)
yann@339
  1051
+{
yann@339
  1052
+  fprintf (file, "\t%s mcount begin, label: .LP%d\n", 
yann@339
  1053
+           ASM_COMMENT_START, labelno);
yann@339
  1054
+  fprintf (file, "\tnextpc\tr8\n");
yann@339
  1055
+  fprintf (file, "\tmov\tr9, ra\n");
yann@339
  1056
+  fprintf (file, "\tmovhi\tr10, %%hiadj(.LP%d)\n", labelno);
yann@339
  1057
+  fprintf (file, "\taddi\tr10, r10, %%lo(.LP%d)\n", labelno);
yann@339
  1058
+  fprintf (file, "\tcall\tmcount\n");
yann@339
  1059
+  fprintf (file, "\tmov\tra, r9\n");
yann@339
  1060
+  fprintf (file, "\t%s mcount end\n", ASM_COMMENT_START);
yann@339
  1061
+}
yann@339
  1062
+
yann@339
  1063
+
yann@339
  1064
+/***************************************
yann@339
  1065
+ * Stack Layout
yann@339
  1066
+ ***************************************/
yann@339
  1067
+
yann@339
  1068
+
yann@339
  1069
+void
yann@339
  1070
+dump_frame_size (FILE *file)
yann@339
  1071
+{
yann@339
  1072
+  fprintf (file, "\t%s Current Frame Info\n", ASM_COMMENT_START);
yann@339
  1073
+
yann@339
  1074
+  fprintf (file, "\t%s total_size = %ld\n", ASM_COMMENT_START,
yann@339
  1075
+	   cfun->machine->frame.total_size);
yann@339
  1076
+  fprintf (file, "\t%s var_size = %ld\n", ASM_COMMENT_START,
yann@339
  1077
+	   cfun->machine->frame.var_size);
yann@339
  1078
+  fprintf (file, "\t%s args_size = %ld\n", ASM_COMMENT_START,
yann@339
  1079
+	   cfun->machine->frame.args_size);
yann@339
  1080
+  fprintf (file, "\t%s save_reg_size = %d\n", ASM_COMMENT_START,
yann@339
  1081
+	   cfun->machine->frame.save_reg_size);
yann@339
  1082
+  fprintf (file, "\t%s save_reg_rounded = %d\n", ASM_COMMENT_START,
yann@339
  1083
+	   cfun->machine->frame.save_reg_rounded);
yann@339
  1084
+  fprintf (file, "\t%s initialized = %d\n", ASM_COMMENT_START,
yann@339
  1085
+	   cfun->machine->frame.initialized);
yann@339
  1086
+  fprintf (file, "\t%s num_regs = %d\n", ASM_COMMENT_START,
yann@339
  1087
+	   cfun->machine->frame.num_regs);
yann@339
  1088
+  fprintf (file, "\t%s save_regs_offset = %ld\n", ASM_COMMENT_START,
yann@339
  1089
+	   cfun->machine->frame.save_regs_offset);
yann@339
  1090
+  fprintf (file, "\t%s current_function_is_leaf = %d\n", ASM_COMMENT_START,
yann@339
  1091
+	   current_function_is_leaf);
yann@339
  1092
+  fprintf (file, "\t%s frame_pointer_needed = %d\n", ASM_COMMENT_START,
yann@339
  1093
+	   frame_pointer_needed);
yann@339
  1094
+  fprintf (file, "\t%s pretend_args_size = %d\n", ASM_COMMENT_START,
yann@339
  1095
+	   current_function_pretend_args_size);
yann@339
  1096
+
yann@339
  1097
+}
yann@339
  1098
+
yann@339
  1099
+
yann@339
  1100
+/* Return the bytes needed to compute the frame pointer from the current
yann@339
  1101
+   stack pointer.
yann@339
  1102
+*/
yann@339
  1103
+
yann@339
  1104
+HOST_WIDE_INT
yann@339
  1105
+compute_frame_size ()
yann@339
  1106
+{
yann@339
  1107
+  unsigned int regno;
yann@339
  1108
+  HOST_WIDE_INT var_size;	/* # of var. bytes allocated */
yann@339
  1109
+  HOST_WIDE_INT total_size;	/* # bytes that the entire frame takes up */
yann@339
  1110
+  HOST_WIDE_INT save_reg_size;	/* # bytes needed to store callee save regs */
yann@339
  1111
+  HOST_WIDE_INT save_reg_rounded;	
yann@339
  1112
+    /* # bytes needed to store callee save regs (rounded) */
yann@339
  1113
+  HOST_WIDE_INT out_args_size;	/* # bytes needed for outgoing args */
yann@339
  1114
+
yann@339
  1115
+  save_reg_size = 0;
yann@339
  1116
+  var_size = STACK_ALIGN (get_frame_size ());
yann@339
  1117
+  out_args_size = STACK_ALIGN (current_function_outgoing_args_size);
yann@339
  1118
+
yann@339
  1119
+  total_size = var_size + out_args_size;
yann@339
  1120
+
yann@339
  1121
+  /* Calculate space needed for gp registers.  */
yann@339
  1122
+  for (regno = 0; regno <= FIRST_PSEUDO_REGISTER; regno++)
yann@339
  1123
+    {
yann@339
  1124
+      if (MUST_SAVE_REGISTER (regno))
yann@339
  1125
+	{
yann@339
  1126
+	  save_reg_size += 4;
yann@339
  1127
+	}
yann@339
  1128
+    }
yann@339
  1129
+
yann@339
  1130
+  save_reg_rounded = STACK_ALIGN (save_reg_size);
yann@339
  1131
+  total_size += save_reg_rounded;
yann@339
  1132
+
yann@339
  1133
+  total_size += STACK_ALIGN (current_function_pretend_args_size);
yann@339
  1134
+
yann@339
  1135
+  /* Save other computed information.  */
yann@339
  1136
+  cfun->machine->frame.total_size = total_size;
yann@339
  1137
+  cfun->machine->frame.var_size = var_size;
yann@339
  1138
+  cfun->machine->frame.args_size = current_function_outgoing_args_size;
yann@339
  1139
+  cfun->machine->frame.save_reg_size = save_reg_size;
yann@339
  1140
+  cfun->machine->frame.save_reg_rounded = save_reg_rounded;
yann@339
  1141
+  cfun->machine->frame.initialized = reload_completed;
yann@339
  1142
+  cfun->machine->frame.num_regs = save_reg_size / UNITS_PER_WORD;
yann@339
  1143
+
yann@339
  1144
+  cfun->machine->frame.save_regs_offset
yann@339
  1145
+    = save_reg_rounded ? current_function_outgoing_args_size + var_size : 0;
yann@339
  1146
+
yann@339
  1147
+  return total_size;
yann@339
  1148
+}
yann@339
  1149
+
yann@339
  1150
+
yann@339
  1151
+int
yann@339
  1152
+nios2_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED)
yann@339
  1153
+{
yann@339
  1154
+  int offset;
yann@339
  1155
+
yann@339
  1156
+  /* Set OFFSET to the offset from the stack pointer.  */
yann@339
  1157
+  switch (from)
yann@339
  1158
+    {
yann@339
  1159
+    case FRAME_POINTER_REGNUM:
yann@339
  1160
+      offset = 0;
yann@339
  1161
+      break;
yann@339
  1162
+
yann@339
  1163
+    case ARG_POINTER_REGNUM:
yann@339
  1164
+      compute_frame_size ();
yann@339
  1165
+      offset = cfun->machine->frame.total_size;
yann@339
  1166
+      offset -= current_function_pretend_args_size;
yann@339
  1167
+      break;
yann@339
  1168
+
yann@339
  1169
+    case RETURN_ADDRESS_POINTER_REGNUM:
yann@339
  1170
+      compute_frame_size ();
yann@339
  1171
+      /* since the return address is always the first of the
yann@339
  1172
+         saved registers, return the offset to the beginning
yann@339
  1173
+         of the saved registers block */
yann@339
  1174
+      offset = cfun->machine->frame.save_regs_offset;
yann@339
  1175
+      break;
yann@339
  1176
+
yann@339
  1177
+    default:
yann@339
  1178
+      abort ();
yann@339
  1179
+    }
yann@339
  1180
+
yann@339
  1181
+  return offset;
yann@339
  1182
+}
yann@339
  1183
+
yann@339
  1184
+/* Return nonzero if this function is known to have a null epilogue.
yann@339
  1185
+   This allows the optimizer to omit jumps to jumps if no stack
yann@339
  1186
+   was created.  */
yann@339
  1187
+int
yann@339
  1188
+nios2_can_use_return_insn ()
yann@339
  1189
+{
yann@339
  1190
+  if (!reload_completed)
yann@339
  1191
+    return 0;
yann@339
  1192
+
yann@339
  1193
+  if (regs_ever_live[RA_REGNO] || current_function_profile)
yann@339
  1194
+    return 0;
yann@339
  1195
+
yann@339
  1196
+  if (cfun->machine->frame.initialized)
yann@339
  1197
+    return cfun->machine->frame.total_size == 0;
yann@339
  1198
+
yann@339
  1199
+  return compute_frame_size () == 0;
yann@339
  1200
+}
yann@339
  1201
+
yann@339
  1202
+
yann@339
  1203
+
yann@339
  1204
+
yann@339
  1205
+
yann@339
  1206
+/***************************************
yann@339
  1207
+ *
yann@339
  1208
+ ***************************************/
yann@339
  1209
+
yann@339
  1210
+const char *nios2_sys_nosys_string;    /* for -msys=nosys */
yann@339
  1211
+const char *nios2_sys_lib_string;    /* for -msys-lib= */
yann@339
  1212
+const char *nios2_sys_crt0_string;    /* for -msys-crt0= */
yann@339
  1213
+
yann@339
  1214
+void
yann@339
  1215
+override_options ()
yann@339
  1216
+{
yann@339
  1217
+  /* Function to allocate machine-dependent function status.  */
yann@339
  1218
+  init_machine_status = &nios2_init_machine_status;
yann@339
  1219
+
yann@339
  1220
+  nios2_section_threshold 
yann@339
  1221
+    = g_switch_set ? g_switch_value : NIOS2_DEFAULT_GVALUE;
yann@339
  1222
+
yann@339
  1223
+  if (nios2_sys_nosys_string && *nios2_sys_nosys_string)
yann@339
  1224
+    {
yann@339
  1225
+      error ("invalid option '-msys=nosys%s'", nios2_sys_nosys_string);
yann@339
  1226
+    }
yann@339
  1227
+
yann@339
  1228
+  /* If we don't have mul, we don't have mulx either! */
yann@339
  1229
+  if (!TARGET_HAS_MUL && TARGET_HAS_MULX) 
yann@339
  1230
+    {
yann@339
  1231
+      target_flags &= ~HAS_MULX_FLAG;
yann@339
  1232
+    }
yann@339
  1233
+
yann@339
  1234
+}
yann@339
  1235
+
yann@339
  1236
+void
yann@339
  1237
+optimization_options (int level, int size)
yann@339
  1238
+{
yann@339
  1239
+  if (level || size)
yann@339
  1240
+    {
yann@339
  1241
+      target_flags |= INLINE_MEMCPY_FLAG;
yann@339
  1242
+    }
yann@339
  1243
+
yann@339
  1244
+  if (level >= 3 && !size)
yann@339
  1245
+    {
yann@339
  1246
+      target_flags |= FAST_SW_DIV_FLAG;
yann@339
  1247
+    }
yann@339
  1248
+}
yann@339
  1249
+
yann@339
  1250
+/* Allocate a chunk of memory for per-function machine-dependent data.  */
yann@339
  1251
+static struct machine_function *
yann@339
  1252
+nios2_init_machine_status ()
yann@339
  1253
+{
yann@339
  1254
+  return ((struct machine_function *)
yann@339
  1255
+	  ggc_alloc_cleared (sizeof (struct machine_function)));
yann@339
  1256
+}
yann@339
  1257
+
yann@339
  1258
+
yann@339
  1259
+
yann@339
  1260
+/*****************
yann@339
  1261
+ * Describing Relative Costs of Operations
yann@339
  1262
+ *****************/
yann@339
  1263
+
yann@339
  1264
+/* Compute a (partial) cost for rtx X.  Return true if the complete
yann@339
  1265
+   cost has been computed, and false if subexpressions should be
yann@339
  1266
+   scanned.  In either case, *TOTAL contains the cost result.  */
yann@339
  1267
+
yann@339
  1268
+
yann@339
  1269
+
yann@339
  1270
+static bool
yann@339
  1271
+nios2_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total)
yann@339
  1272
+{
yann@339
  1273
+  switch (code)
yann@339
  1274
+    {
yann@339
  1275
+      case CONST_INT:
yann@339
  1276
+	if (INTVAL (x) == 0)
yann@339
  1277
+	  {
yann@339
  1278
+	    *total = COSTS_N_INSNS (0);
yann@339
  1279
+	    return true;
yann@339
  1280
+	  }
yann@339
  1281
+	else if (SMALL_INT (INTVAL (x))
yann@339
  1282
+		|| SMALL_INT_UNSIGNED (INTVAL (x))
yann@339
  1283
+		|| UPPER16_INT (INTVAL (x)))
yann@339
  1284
+	  {
yann@339
  1285
+	    *total = COSTS_N_INSNS (2);
yann@339
  1286
+	    return true;
yann@339
  1287
+	  }
yann@339
  1288
+	else
yann@339
  1289
+	  {
yann@339
  1290
+	    *total = COSTS_N_INSNS (4);
yann@339
  1291
+	    return true;
yann@339
  1292
+	  }
yann@339
  1293
+
yann@339
  1294
+      case LABEL_REF:
yann@339
  1295
+      case SYMBOL_REF:
yann@339
  1296
+	/* ??? gp relative stuff will fit in here */
yann@339
  1297
+	/* fall through */
yann@339
  1298
+      case CONST:
yann@339
  1299
+      case CONST_DOUBLE:
yann@339
  1300
+	{
yann@339
  1301
+	  *total = COSTS_N_INSNS (4);
yann@339
  1302
+	  return true;
yann@339
  1303
+	}
yann@339
  1304
+
yann@339
  1305
+      case MULT:
yann@339
  1306
+	{
yann@339
  1307
+	  *total = COSTS_N_INSNS (1);
yann@339
  1308
+	  return false;
yann@339
  1309
+	}
yann@339
  1310
+      case SIGN_EXTEND:
yann@339
  1311
+	{
yann@339
  1312
+	  *total = COSTS_N_INSNS (3);
yann@339
  1313
+	  return false;
yann@339
  1314
+	}
yann@339
  1315
+      case ZERO_EXTEND:
yann@339
  1316
+	{
yann@339
  1317
+	  *total = COSTS_N_INSNS (1);
yann@339
  1318
+	  return false;
yann@339
  1319
+	}
yann@339
  1320
+
yann@339
  1321
+    default:
yann@339
  1322
+      return false;
yann@339
  1323
+    }
yann@339
  1324
+}
yann@339
  1325
+
yann@339
  1326
+
yann@339
  1327
+/***************************************
yann@339
  1328
+ * INSTRUCTION SUPPORT
yann@339
  1329
+ *
yann@339
  1330
+ * These functions are used within the Machine Description to
yann@339
  1331
+ * handle common or complicated output and expansions from
yann@339
  1332
+ * instructions.
yann@339
  1333
+ ***************************************/
yann@339
  1334
+
yann@339
  1335
+int
yann@339
  1336
+nios2_emit_move_sequence (rtx *operands, enum machine_mode mode)
yann@339
  1337
+{
yann@339
  1338
+  rtx to = operands[0];
yann@339
  1339
+  rtx from = operands[1];
yann@339
  1340
+
yann@339
  1341
+  if (!register_operand (to, mode) && !reg_or_0_operand (from, mode))
yann@339
  1342
+    {
yann@339
  1343
+      if (no_new_pseudos)
yann@339
  1344
+	internal_error ("Trying to force_reg no_new_pseudos == 1");
yann@339
  1345
+      from = copy_to_mode_reg (mode, from);
yann@339
  1346
+    }
yann@339
  1347
+
yann@339
  1348
+  operands[0] = to;
yann@339
  1349
+  operands[1] = from;
yann@339
  1350
+  return 0;
yann@339
  1351
+}
yann@339
  1352
+
yann@339
  1353
+/* Divide Support */
yann@339
  1354
+
yann@339
  1355
+/*
yann@339
  1356
+  If -O3 is used, we want to output a table lookup for
yann@339
  1357
+  divides between small numbers (both num and den >= 0
yann@339
  1358
+  and < 0x10). The overhead of this method in the worse
yann@339
  1359
+  case is 40 bytes in the text section (10 insns) and
yann@339
  1360
+  256 bytes in the data section. Additional divides do
yann@339
  1361
+  not incur additional penalties in the data section.
yann@339
  1362
+
yann@339
  1363
+  Code speed is improved for small divides by about 5x
yann@339
  1364
+  when using this method in the worse case (~9 cycles
yann@339
  1365
+  vs ~45). And in the worse case divides not within the
yann@339
  1366
+  table are penalized by about 10% (~5 cycles vs ~45).
yann@339
  1367
+  However in the typical case the penalty is not as bad
yann@339
  1368
+  because doing the long divide in only 45 cycles is
yann@339
  1369
+  quite optimistic.
yann@339
  1370
+
yann@339
  1371
+  ??? It would be nice to have some benchmarks other
yann@339
  1372
+  than Dhrystone to back this up.
yann@339
  1373
+
yann@339
  1374
+  This bit of expansion is to create this instruction
yann@339
  1375
+  sequence as rtl.
yann@339
  1376
+	or	$8, $4, $5
yann@339
  1377
+	slli	$9, $4, 4
yann@339
  1378
+	cmpgeui	$3, $8, 16
yann@339
  1379
+	beq	$3, $0, .L3
yann@339
  1380
+	or	$10, $9, $5
yann@339
  1381
+	add	$12, $11, divide_table
yann@339
  1382
+	ldbu	$2, 0($12)
yann@339
  1383
+	br	.L1
yann@339
  1384
+.L3:
yann@339
  1385
+	call	slow_div
yann@339
  1386
+.L1:
yann@339
  1387
+#	continue here with result in $2
yann@339
  1388
+
yann@339
  1389
+  ??? Ideally I would like the emit libcall block to contain
yann@339
  1390
+  all of this code, but I don't know how to do that. What it
yann@339
  1391
+  means is that if the divide can be eliminated, it may not
yann@339
  1392
+  completely disappear.
yann@339
  1393
+
yann@339
  1394
+  ??? The __divsi3_table label should ideally be moved out
yann@339
  1395
+  of this block and into a global. If it is placed into the
yann@339
  1396
+  sdata section we can save even more cycles by doing things
yann@339
  1397
+  gp relative.
yann@339
  1398
+*/
yann@339
  1399
+int
yann@339
  1400
+nios2_emit_expensive_div (rtx *operands, enum machine_mode mode)
yann@339
  1401
+{
yann@339
  1402
+  rtx or_result, shift_left_result;
yann@339
  1403
+  rtx lookup_value;
yann@339
  1404
+  rtx lab1, lab3;
yann@339
  1405
+  rtx insns;
yann@339
  1406
+  rtx libfunc;
yann@339
  1407
+  rtx final_result;
yann@339
  1408
+  rtx tmp;
yann@339
  1409
+
yann@339
  1410
+  /* it may look a little generic, but only SImode
yann@339
  1411
+     is supported for now */
yann@339
  1412
+  if (mode != SImode)
yann@339
  1413
+    abort ();
yann@339
  1414
+
yann@339
  1415
+  libfunc = sdiv_optab->handlers[(int) SImode].libfunc;
yann@339
  1416
+
yann@339
  1417
+
yann@339
  1418
+
yann@339
  1419
+  lab1 = gen_label_rtx ();
yann@339
  1420
+  lab3 = gen_label_rtx ();
yann@339
  1421
+
yann@339
  1422
+  or_result = expand_simple_binop (SImode, IOR,
yann@339
  1423
+				   operands[1], operands[2],
yann@339
  1424
+				   0, 0, OPTAB_LIB_WIDEN);
yann@339
  1425
+
yann@339
  1426
+  emit_cmp_and_jump_insns (or_result, GEN_INT (15), GTU, 0,
yann@339
  1427
+			   GET_MODE (or_result), 0, lab3);
yann@339
  1428
+  JUMP_LABEL (get_last_insn ()) = lab3;
yann@339
  1429
+
yann@339
  1430
+  shift_left_result = expand_simple_binop (SImode, ASHIFT,
yann@339
  1431
+					   operands[1], GEN_INT (4),
yann@339
  1432
+					   0, 0, OPTAB_LIB_WIDEN);
yann@339
  1433
+
yann@339
  1434
+  lookup_value = expand_simple_binop (SImode, IOR,
yann@339
  1435
+				      shift_left_result, operands[2],
yann@339
  1436
+				      0, 0, OPTAB_LIB_WIDEN);
yann@339
  1437
+
yann@339
  1438
+  convert_move (operands[0],
yann@339
  1439
+		gen_rtx (MEM, QImode,
yann@339
  1440
+			 gen_rtx (PLUS, SImode,
yann@339
  1441
+				  lookup_value,
yann@339
  1442
+				  gen_rtx_SYMBOL_REF (SImode, "__divsi3_table"))),
yann@339
  1443
+		1);
yann@339
  1444
+
yann@339
  1445
+
yann@339
  1446
+  tmp = emit_jump_insn (gen_jump (lab1));
yann@339
  1447
+  JUMP_LABEL (tmp) = lab1;
yann@339
  1448
+  emit_barrier ();
yann@339
  1449
+
yann@339
  1450
+  emit_label (lab3);
yann@339
  1451
+  LABEL_NUSES (lab3) = 1;
yann@339
  1452
+
yann@339
  1453
+  start_sequence ();
yann@339
  1454
+  final_result = emit_library_call_value (libfunc, NULL_RTX,
yann@339
  1455
+					  LCT_CONST, SImode, 2,
yann@339
  1456
+					  operands[1], SImode,
yann@339
  1457
+					  operands[2], SImode);
yann@339
  1458
+
yann@339
  1459
+
yann@339
  1460
+  insns = get_insns ();
yann@339
  1461
+  end_sequence ();
yann@339
  1462
+  emit_libcall_block (insns, operands[0], final_result,
yann@339
  1463
+		      gen_rtx (DIV, SImode, operands[1], operands[2]));
yann@339
  1464
+
yann@339
  1465
+  emit_label (lab1);
yann@339
  1466
+  LABEL_NUSES (lab1) = 1;
yann@339
  1467
+  return 1;
yann@339
  1468
+}
yann@339
  1469
+
yann@339
  1470
+/* Branches/Compares */
yann@339
  1471
+
yann@339
  1472
+/* the way of handling branches/compares
yann@339
  1473
+   in gcc is heavily borrowed from MIPS */
yann@339
  1474
+
yann@339
  1475
+enum internal_test
yann@339
  1476
+{
yann@339
  1477
+  ITEST_EQ,
yann@339
  1478
+  ITEST_NE,
yann@339
  1479
+  ITEST_GT,
yann@339
  1480
+  ITEST_GE,
yann@339
  1481
+  ITEST_LT,
yann@339
  1482
+  ITEST_LE,
yann@339
  1483
+  ITEST_GTU,
yann@339
  1484
+  ITEST_GEU,
yann@339
  1485
+  ITEST_LTU,
yann@339
  1486
+  ITEST_LEU,
yann@339
  1487
+  ITEST_MAX
yann@339
  1488
+};
yann@339
  1489
+
yann@339
  1490
+static enum internal_test map_test_to_internal_test (enum rtx_code);
yann@339
  1491
+
yann@339
  1492
+/* Cached operands, and operator to compare for use in set/branch/trap
yann@339
  1493
+   on condition codes.  */
yann@339
  1494
+rtx branch_cmp[2];
yann@339
  1495
+enum cmp_type branch_type;
yann@339
  1496
+
yann@339
  1497
+/* Make normal rtx_code into something we can index from an array */
yann@339
  1498
+
yann@339
  1499
+static enum internal_test
yann@339
  1500
+map_test_to_internal_test (enum rtx_code test_code)
yann@339
  1501
+{
yann@339
  1502
+  enum internal_test test = ITEST_MAX;
yann@339
  1503
+
yann@339
  1504
+  switch (test_code)
yann@339
  1505
+    {
yann@339
  1506
+    case EQ:
yann@339
  1507
+      test = ITEST_EQ;
yann@339
  1508
+      break;
yann@339
  1509
+    case NE:
yann@339
  1510
+      test = ITEST_NE;
yann@339
  1511
+      break;
yann@339
  1512
+    case GT:
yann@339
  1513
+      test = ITEST_GT;
yann@339
  1514
+      break;
yann@339
  1515
+    case GE:
yann@339
  1516
+      test = ITEST_GE;
yann@339
  1517
+      break;
yann@339
  1518
+    case LT:
yann@339
  1519
+      test = ITEST_LT;
yann@339
  1520
+      break;
yann@339
  1521
+    case LE:
yann@339
  1522
+      test = ITEST_LE;
yann@339
  1523
+      break;
yann@339
  1524
+    case GTU:
yann@339
  1525
+      test = ITEST_GTU;
yann@339
  1526
+      break;
yann@339
  1527
+    case GEU:
yann@339
  1528
+      test = ITEST_GEU;
yann@339
  1529
+      break;
yann@339
  1530
+    case LTU:
yann@339
  1531
+      test = ITEST_LTU;
yann@339
  1532
+      break;
yann@339
  1533
+    case LEU:
yann@339
  1534
+      test = ITEST_LEU;
yann@339
  1535
+      break;
yann@339
  1536
+    default:
yann@339
  1537
+      break;
yann@339
  1538
+    }
yann@339
  1539
+
yann@339
  1540
+  return test;
yann@339
  1541
+}
yann@339
  1542
+
yann@339
  1543
+/* Generate the code to compare (and possibly branch) two integer values
yann@339
  1544
+   TEST_CODE is the comparison code we are trying to emulate 
yann@339
  1545
+     (or implement directly)
yann@339
  1546
+   RESULT is where to store the result of the comparison, 
yann@339
  1547
+     or null to emit a branch
yann@339
  1548
+   CMP0 CMP1 are the two comparison operands
yann@339
  1549
+   DESTINATION is the destination of the branch, or null to only compare
yann@339
  1550
+   */
yann@339
  1551
+
yann@339
  1552
+void
yann@339
  1553
+gen_int_relational (enum rtx_code test_code, /* relational test (EQ, etc) */
yann@339
  1554
+		    rtx result,		/* result to store comp. or 0 if branch */
yann@339
  1555
+		    rtx cmp0,		/* first operand to compare */
yann@339
  1556
+		    rtx cmp1,		/* second operand to compare */
yann@339
  1557
+		    rtx destination)	/* destination of the branch, or 0 if compare */
yann@339
  1558
+{
yann@339
  1559
+  struct cmp_info
yann@339
  1560
+  {
yann@339
  1561
+    /* for register (or 0) compares */
yann@339
  1562
+    enum rtx_code test_code_reg;	/* code to use in instruction (LT vs. LTU) */
yann@339
  1563
+    int reverse_regs;		/* reverse registers in test */
yann@339
  1564
+
yann@339
  1565
+    /* for immediate compares */
yann@339
  1566
+    enum rtx_code test_code_const;	
yann@339
  1567
+         /* code to use in instruction (LT vs. LTU) */
yann@339
  1568
+    int const_low;		/* low bound of constant we can accept */
yann@339
  1569
+    int const_high;		/* high bound of constant we can accept */
yann@339
  1570
+    int const_add;		/* constant to add */
yann@339
  1571
+
yann@339
  1572
+    /* generic info */
yann@339
  1573
+    int unsignedp;		/* != 0 for unsigned comparisons.  */
yann@339
  1574
+  };
yann@339
  1575
+
yann@339
  1576
+  static const struct cmp_info info[(int) ITEST_MAX] = {
yann@339
  1577
+
yann@339
  1578
+    {EQ, 0, EQ, -32768, 32767, 0, 0}, /* EQ  */
yann@339
  1579
+    {NE, 0, NE, -32768, 32767, 0, 0}, /* NE  */
yann@339
  1580
+
yann@339
  1581
+    {LT, 1, GE, -32769, 32766, 1, 0}, /* GT  */
yann@339
  1582
+    {GE, 0, GE, -32768, 32767, 0, 0}, /* GE  */
yann@339
  1583
+    {LT, 0, LT, -32768, 32767, 0, 0}, /* LT  */
yann@339
  1584
+    {GE, 1, LT, -32769, 32766, 1, 0}, /* LE  */
yann@339
  1585
+
yann@339
  1586
+    {LTU, 1, GEU, 0, 65534, 1, 0}, /* GTU */
yann@339
  1587
+    {GEU, 0, GEU, 0, 65535, 0, 0}, /* GEU */
yann@339
  1588
+    {LTU, 0, LTU, 0, 65535, 0, 0}, /* LTU */
yann@339
  1589
+    {GEU, 1, LTU, 0, 65534, 1, 0}, /* LEU */
yann@339
  1590
+  };
yann@339
  1591
+
yann@339
  1592
+  enum internal_test test;
yann@339
  1593
+  enum machine_mode mode;
yann@339
  1594
+  const struct cmp_info *p_info;
yann@339
  1595
+  int branch_p;
yann@339
  1596
+
yann@339
  1597
+
yann@339
  1598
+
yann@339
  1599
+
yann@339
  1600
+  test = map_test_to_internal_test (test_code);
yann@339
  1601
+  if (test == ITEST_MAX)
yann@339
  1602
+    abort ();
yann@339
  1603
+
yann@339
  1604
+  p_info = &info[(int) test];
yann@339
  1605
+
yann@339
  1606
+  mode = GET_MODE (cmp0);
yann@339
  1607
+  if (mode == VOIDmode)
yann@339
  1608
+    mode = GET_MODE (cmp1);
yann@339
  1609
+
yann@339
  1610
+  branch_p = (destination != 0);
yann@339
  1611
+
yann@339
  1612
+  /* We can't, under any circumstances, have const_ints in cmp0
yann@339
  1613
+     ??? Actually we could have const0 */
yann@339
  1614
+  if (GET_CODE (cmp0) == CONST_INT)
yann@339
  1615
+    cmp0 = force_reg (mode, cmp0);
yann@339
  1616
+
yann@339
  1617
+  /* if the comparison is against an int not in legal range
yann@339
  1618
+     move it into a register */
yann@339
  1619
+  if (GET_CODE (cmp1) == CONST_INT)
yann@339
  1620
+    {
yann@339
  1621
+      HOST_WIDE_INT value = INTVAL (cmp1);
yann@339
  1622
+
yann@339
  1623
+      if (value < p_info->const_low || value > p_info->const_high)
yann@339
  1624
+	cmp1 = force_reg (mode, cmp1);
yann@339
  1625
+    }
yann@339
  1626
+
yann@339
  1627
+  /* Comparison to constants, may involve adding 1 to change a GT into GE.
yann@339
  1628
+     Comparison between two registers, may involve switching operands.  */
yann@339
  1629
+  if (GET_CODE (cmp1) == CONST_INT)
yann@339
  1630
+    {
yann@339
  1631
+      if (p_info->const_add != 0)
yann@339
  1632
+	{
yann@339
  1633
+	  HOST_WIDE_INT new = INTVAL (cmp1) + p_info->const_add;
yann@339
  1634
+
yann@339
  1635
+	  /* If modification of cmp1 caused overflow,
yann@339
  1636
+	     we would get the wrong answer if we follow the usual path;
yann@339
  1637
+	     thus, x > 0xffffffffU would turn into x > 0U.  */
yann@339
  1638
+	  if ((p_info->unsignedp
yann@339
  1639
+	       ? (unsigned HOST_WIDE_INT) new >
yann@339
  1640
+	       (unsigned HOST_WIDE_INT) INTVAL (cmp1)
yann@339
  1641
+	       : new > INTVAL (cmp1)) != (p_info->const_add > 0))
yann@339
  1642
+	    {
yann@339
  1643
+	      /* ??? This case can never happen with the current numbers,
yann@339
  1644
+	         but I am paranoid and would rather an abort than
yann@339
  1645
+	         a bug I will never find */
yann@339
  1646
+	      abort ();
yann@339
  1647
+	    }
yann@339
  1648
+	  else
yann@339
  1649
+	    cmp1 = GEN_INT (new);
yann@339
  1650
+	}
yann@339
  1651
+    }
yann@339
  1652
+
yann@339
  1653
+  else if (p_info->reverse_regs)
yann@339
  1654
+    {
yann@339
  1655
+      rtx temp = cmp0;
yann@339
  1656
+      cmp0 = cmp1;
yann@339
  1657
+      cmp1 = temp;
yann@339
  1658
+    }
yann@339
  1659
+
yann@339
  1660
+
yann@339
  1661
+
yann@339
  1662
+  if (branch_p)
yann@339
  1663
+    {
yann@339
  1664
+      if (register_operand (cmp0, mode) && register_operand (cmp1, mode))
yann@339
  1665
+	{
yann@339
  1666
+	  rtx insn;
yann@339
  1667
+	  rtx cond = gen_rtx (p_info->test_code_reg, mode, cmp0, cmp1);
yann@339
  1668
+	  rtx label = gen_rtx_LABEL_REF (VOIDmode, destination);
yann@339
  1669
+
yann@339
  1670
+	  insn = gen_rtx_SET (VOIDmode, pc_rtx,
yann@339
  1671
+			      gen_rtx_IF_THEN_ELSE (VOIDmode,
yann@339
  1672
+						    cond, label, pc_rtx));
yann@339
  1673
+	  emit_jump_insn (insn);
yann@339
  1674
+	}
yann@339
  1675
+      else
yann@339
  1676
+	{
yann@339
  1677
+	  rtx cond, label;
yann@339
  1678
+
yann@339
  1679
+	  result = gen_reg_rtx (mode);
yann@339
  1680
+
yann@339
  1681
+	  emit_move_insn (result,
yann@339
  1682
+			  gen_rtx (p_info->test_code_const, mode, cmp0,
yann@339
  1683
+				   cmp1));
yann@339
  1684
+
yann@339
  1685
+	  cond = gen_rtx (NE, mode, result, const0_rtx);
yann@339
  1686
+	  label = gen_rtx_LABEL_REF (VOIDmode, destination);
yann@339
  1687
+
yann@339
  1688
+	  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
yann@339
  1689
+				       gen_rtx_IF_THEN_ELSE (VOIDmode,
yann@339
  1690
+							     cond,
yann@339
  1691
+							     label, pc_rtx)));
yann@339
  1692
+	}
yann@339
  1693
+    }
yann@339
  1694
+  else
yann@339
  1695
+    {
yann@339
  1696
+      if (register_operand (cmp0, mode) && register_operand (cmp1, mode))
yann@339
  1697
+	{
yann@339
  1698
+	  emit_move_insn (result,
yann@339
  1699
+			  gen_rtx (p_info->test_code_reg, mode, cmp0, cmp1));
yann@339
  1700
+	}
yann@339
  1701
+      else
yann@339
  1702
+	{
yann@339
  1703
+	  emit_move_insn (result,
yann@339
  1704
+			  gen_rtx (p_info->test_code_const, mode, cmp0,
yann@339
  1705
+				   cmp1));
yann@339
  1706
+	}
yann@339
  1707
+    }
yann@339
  1708
+
yann@339
  1709
+}
yann@339
  1710
+
yann@339
  1711
+
yann@339
  1712
+/* ??? For now conditional moves are only supported
yann@339
  1713
+   when the mode of the operands being compared are
yann@339
  1714
+   the same as the ones being moved */
yann@339
  1715
+
yann@339
  1716
+void
yann@339
  1717
+gen_conditional_move (rtx *operands, enum machine_mode mode)
yann@339
  1718
+{
yann@339
  1719
+  rtx insn, cond;
yann@339
  1720
+  rtx cmp_reg = gen_reg_rtx (mode);
yann@339
  1721
+  enum rtx_code cmp_code = GET_CODE (operands[1]);
yann@339
  1722
+  enum rtx_code move_code = EQ;
yann@339
  1723
+
yann@339
  1724
+  /* emit a comparison if it is not "simple".
yann@339
  1725
+     Simple comparisons are X eq 0 and X ne 0 */
yann@339
  1726
+  if ((cmp_code == EQ || cmp_code == NE) && branch_cmp[1] == const0_rtx)
yann@339
  1727
+    {
yann@339
  1728
+      cmp_reg = branch_cmp[0];
yann@339
  1729
+      move_code = cmp_code;
yann@339
  1730
+    }
yann@339
  1731
+  else if ((cmp_code == EQ || cmp_code == NE) && branch_cmp[0] == const0_rtx)
yann@339
  1732
+    {
yann@339
  1733
+      cmp_reg = branch_cmp[1];
yann@339
  1734
+      move_code = cmp_code == EQ ? NE : EQ;
yann@339
  1735
+    }
yann@339
  1736
+  else
yann@339
  1737
+    gen_int_relational (cmp_code, cmp_reg, branch_cmp[0], branch_cmp[1],
yann@339
  1738
+			NULL_RTX);
yann@339
  1739
+
yann@339
  1740
+  cond = gen_rtx (move_code, VOIDmode, cmp_reg, CONST0_RTX (mode));
yann@339
  1741
+  insn = gen_rtx_SET (mode, operands[0],
yann@339
  1742
+		      gen_rtx_IF_THEN_ELSE (mode,
yann@339
  1743
+					    cond, operands[2], operands[3]));
yann@339
  1744
+  emit_insn (insn);
yann@339
  1745
+}
yann@339
  1746
+
yann@339
  1747
+/*******************
yann@339
  1748
+ * Addressing Modes
yann@339
  1749
+ *******************/
yann@339
  1750
+
yann@339
  1751
+int
yann@339
  1752
+nios2_legitimate_address (rtx operand, enum machine_mode mode ATTRIBUTE_UNUSED, 
yann@339
  1753
+                          int strict)
yann@339
  1754
+{
yann@339
  1755
+  int ret_val = 0;
yann@339
  1756
+
yann@339
  1757
+  switch (GET_CODE (operand))
yann@339
  1758
+    {
yann@339
  1759
+      /* direct.  */
yann@339
  1760
+    case SYMBOL_REF:
yann@339
  1761
+      if (SYMBOL_REF_IN_NIOS2_SMALL_DATA_P (operand))
yann@339
  1762
+        {
yann@339
  1763
+          ret_val = 1;
yann@339
  1764
+          break;
yann@339
  1765
+	}
yann@339
  1766
+      /* else, fall through */
yann@339
  1767
+    case LABEL_REF:
yann@339
  1768
+    case CONST_INT:
yann@339
  1769
+    case CONST:
yann@339
  1770
+    case CONST_DOUBLE:
yann@339
  1771
+      /* ??? In here I need to add gp addressing */
yann@339
  1772
+      ret_val = 0;
yann@339
  1773
+
yann@339
  1774
+      break;
yann@339
  1775
+
yann@339
  1776
+      /* Register indirect.  */
yann@339
  1777
+    case REG:
yann@339
  1778
+      ret_val = REG_OK_FOR_BASE_P2 (operand, strict);
yann@339
  1779
+      break;
yann@339
  1780
+
yann@339
  1781
+      /* Register indirect with displacement */
yann@339
  1782
+    case PLUS:
yann@339
  1783
+      {
yann@339
  1784
+	rtx op0 = XEXP (operand, 0);
yann@339
  1785
+	rtx op1 = XEXP (operand, 1);
yann@339
  1786
+
yann@339
  1787
+	if (REG_P (op0) && REG_P (op1))
yann@339
  1788
+	  ret_val = 0;
yann@339
  1789
+	else if (REG_P (op0) && CONSTANT_P (op1))
yann@339
  1790
+	  ret_val = REG_OK_FOR_BASE_P2 (op0, strict)
yann@339
  1791
+	    && SMALL_INT (INTVAL (op1));
yann@339
  1792
+	else if (REG_P (op1) && CONSTANT_P (op0))
yann@339
  1793
+	  ret_val = REG_OK_FOR_BASE_P2 (op1, strict)
yann@339
  1794
+	    && SMALL_INT (INTVAL (op0));
yann@339
  1795
+	else
yann@339
  1796
+	  ret_val = 0;
yann@339
  1797
+      }
yann@339
  1798
+      break;
yann@339
  1799
+
yann@339
  1800
+    default:
yann@339
  1801
+      ret_val = 0;
yann@339
  1802
+      break;
yann@339
  1803
+    }
yann@339
  1804
+
yann@339
  1805
+  return ret_val;
yann@339
  1806
+}
yann@339
  1807
+
yann@339
  1808
+/* Return true if EXP should be placed in the small data section.  */
yann@339
  1809
+
yann@339
  1810
+static bool
yann@339
  1811
+nios2_in_small_data_p (tree exp)
yann@339
  1812
+{
yann@339
  1813
+  /* We want to merge strings, so we never consider them small data.  */
yann@339
  1814
+  if (TREE_CODE (exp) == STRING_CST)
yann@339
  1815
+    return false;
yann@339
  1816
+
yann@339
  1817
+  if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
yann@339
  1818
+    {
yann@339
  1819
+      const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
yann@339
  1820
+      /* ??? these string names need moving into 
yann@339
  1821
+         an array in some header file */
yann@339
  1822
+      if (nios2_section_threshold > 0
yann@339
  1823
+          && (strcmp (section, ".sbss") == 0
yann@339
  1824
+	      || strncmp (section, ".sbss.", 6) == 0
yann@339
  1825
+	      || strcmp (section, ".sdata") == 0
yann@339
  1826
+	      || strncmp (section, ".sdata.", 7) == 0))
yann@339
  1827
+	return true;
yann@339
  1828
+    }
yann@339
  1829
+  else if (TREE_CODE (exp) == VAR_DECL)
yann@339
  1830
+    {
yann@339
  1831
+      HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
yann@339
  1832
+
yann@339
  1833
+      /* If this is an incomplete type with size 0, then we can't put it
yann@339
  1834
+         in sdata because it might be too big when completed.  */
yann@339
  1835
+      if (size > 0 && size <= nios2_section_threshold)
yann@339
  1836
+	return true;
yann@339
  1837
+    }
yann@339
  1838
+
yann@339
  1839
+  return false;
yann@339
  1840
+}
yann@339
  1841
+
yann@339
  1842
+static void
yann@339
  1843
+nios2_encode_section_info (tree decl, rtx rtl, int first)
yann@339
  1844
+{
yann@339
  1845
+
yann@339
  1846
+  rtx symbol;
yann@339
  1847
+  int flags;
yann@339
  1848
+
yann@339
  1849
+  default_encode_section_info (decl, rtl, first);
yann@339
  1850
+  
yann@339
  1851
+  /* Careful not to prod global register variables.  */
yann@339
  1852
+  if (GET_CODE (rtl) != MEM)
yann@339
  1853
+    return;
yann@339
  1854
+  symbol = XEXP (rtl, 0);
yann@339
  1855
+  if (GET_CODE (symbol) != SYMBOL_REF)
yann@339
  1856
+    return;
yann@339
  1857
+
yann@339
  1858
+  flags = SYMBOL_REF_FLAGS (symbol);
yann@339
  1859
+    
yann@339
  1860
+  /* We don't want weak variables to be addressed with gp in case they end up with
yann@339
  1861
+     value 0 which is not within 2^15 of $gp */
yann@339
  1862
+  if (DECL_P (decl) && DECL_WEAK (decl))
yann@339
  1863
+    flags |= SYMBOL_FLAG_WEAK_DECL;
yann@339
  1864
+
yann@339
  1865
+  SYMBOL_REF_FLAGS (symbol) = flags;
yann@339
  1866
+}
yann@339
  1867
+
yann@339
  1868
+
yann@339
  1869
+static unsigned int
yann@339
  1870
+nios2_section_type_flags (tree decl, const char *name, int reloc)
yann@339
  1871
+{
yann@339
  1872
+  unsigned int flags;
yann@339
  1873
+
yann@339
  1874
+  flags = default_section_type_flags (decl, name, reloc);
yann@339
  1875
+
yann@339
  1876
+  /* ??? these string names need moving into an array in some header file */
yann@339
  1877
+  if (strcmp (name, ".sbss") == 0
yann@339
  1878
+      || strncmp (name, ".sbss.", 6) == 0
yann@339
  1879
+      || strcmp (name, ".sdata") == 0
yann@339
  1880
+      || strncmp (name, ".sdata.", 7) == 0)
yann@339
  1881
+    flags |= SECTION_SMALL;
yann@339
  1882
+
yann@339
  1883
+  return flags;
yann@339
  1884
+}
yann@339
  1885
+
yann@339
  1886
+
yann@339
  1887
+
yann@339
  1888
+
yann@339
  1889
+/*****************************************
yann@339
  1890
+ * Defining the Output Assembler Language
yann@339
  1891
+ *****************************************/
yann@339
  1892
+
yann@339
  1893
+/* -------------- *
yann@339
  1894
+ * Output of Data
yann@339
  1895
+ * -------------- */
yann@339
  1896
+
yann@339
  1897
+
yann@339
  1898
+/* -------------------------------- *
yann@339
  1899
+ * Output of Assembler Instructions
yann@339
  1900
+ * -------------------------------- */
yann@339
  1901
+
yann@339
  1902
+
yann@339
  1903
+/* print the operand OP to file stream
yann@339
  1904
+   FILE modified by LETTER. LETTER
yann@339
  1905
+   can be one of:
yann@339
  1906
+     i: print "i" if OP is an immediate, except 0
yann@339
  1907
+     o: print "io" if OP is volatile
yann@339
  1908
+
yann@339
  1909
+     z: for const0_rtx print $0 instead of 0
yann@339
  1910
+     H: for %hiadj
yann@339
  1911
+     L: for %lo
yann@339
  1912
+     U: for upper half of 32 bit value
yann@339
  1913
+ */
yann@339
  1914
+
yann@339
  1915
+void
yann@339
  1916
+nios2_print_operand (FILE *file, rtx op, int letter)
yann@339
  1917
+{
yann@339
  1918
+
yann@339
  1919
+  switch (letter)
yann@339
  1920
+    {
yann@339
  1921
+    case 'i':
yann@339
  1922
+      if (CONSTANT_P (op) && (op != const0_rtx))
yann@339
  1923
+	fprintf (file, "i");
yann@339
  1924
+      return;
yann@339
  1925
+
yann@339
  1926
+    case 'o':
yann@339
  1927
+      if (GET_CODE (op) == MEM
yann@339
  1928
+          && ((MEM_VOLATILE_P (op) && !TARGET_CACHE_VOLATILE)
yann@339
  1929
+              || TARGET_BYPASS_CACHE))
yann@339
  1930
+	fprintf (file, "io");
yann@339
  1931
+      return;
yann@339
  1932
+
yann@339
  1933
+    default:
yann@339
  1934
+      break;
yann@339
  1935
+    }
yann@339
  1936
+
yann@339
  1937
+  if (comparison_operator (op, VOIDmode))
yann@339
  1938
+    {
yann@339
  1939
+      if (letter == 0)
yann@339
  1940
+	{
yann@339
  1941
+	  fprintf (file, "%s", GET_RTX_NAME (GET_CODE (op)));
yann@339
  1942
+	  return;
yann@339
  1943
+	}
yann@339
  1944
+    }
yann@339
  1945
+
yann@339
  1946
+
yann@339
  1947
+  switch (GET_CODE (op))
yann@339
  1948
+    {
yann@339
  1949
+    case REG:
yann@339
  1950
+      if (letter == 0 || letter == 'z')
yann@339
  1951
+	{
yann@339
  1952
+	  fprintf (file, "%s", reg_names[REGNO (op)]);
yann@339
  1953
+	  return;
yann@339
  1954
+	}
yann@339
  1955
+
yann@339
  1956
+    case CONST_INT:
yann@339
  1957
+      if (INTVAL (op) == 0 && letter == 'z')
yann@339
  1958
+	{
yann@339
  1959
+	  fprintf (file, "zero");
yann@339
  1960
+	  return;
yann@339
  1961
+	}
yann@339
  1962
+      else if (letter == 'U')
yann@339
  1963
+	{
yann@339
  1964
+	  HOST_WIDE_INT val = INTVAL (op);
yann@339
  1965
+	  rtx new_op;
yann@339
  1966
+	  val = (val / 65536) & 0xFFFF;
yann@339
  1967
+	  new_op = GEN_INT (val);
yann@339
  1968
+	  output_addr_const (file, new_op);
yann@339
  1969
+	  return;
yann@339
  1970
+	}
yann@339
  1971
+
yann@339
  1972
+      /* else, fall through */
yann@339
  1973
+    case CONST:
yann@339
  1974
+    case LABEL_REF:
yann@339
  1975
+    case SYMBOL_REF:
yann@339
  1976
+    case CONST_DOUBLE:
yann@339
  1977
+      if (letter == 0 || letter == 'z')
yann@339
  1978
+	{
yann@339
  1979
+	  output_addr_const (file, op);
yann@339
  1980
+	  return;
yann@339
  1981
+	}
yann@339
  1982
+      else if (letter == 'H')
yann@339
  1983
+	{
yann@339
  1984
+	  fprintf (file, "%%hiadj(");
yann@339
  1985
+	  output_addr_const (file, op);
yann@339
  1986
+	  fprintf (file, ")");
yann@339
  1987
+	  return;
yann@339
  1988
+	}
yann@339
  1989
+      else if (letter == 'L')
yann@339
  1990
+	{
yann@339
  1991
+	  fprintf (file, "%%lo(");
yann@339
  1992
+	  output_addr_const (file, op);
yann@339
  1993
+	  fprintf (file, ")");
yann@339
  1994
+	  return;
yann@339
  1995
+	}
yann@339
  1996
+
yann@339
  1997
+
yann@339
  1998
+    case SUBREG:
yann@339
  1999
+    case MEM:
yann@339
  2000
+      if (letter == 0)
yann@339
  2001
+	{
yann@339
  2002
+	  output_address (op);
yann@339
  2003
+	  return;
yann@339
  2004
+	}
yann@339
  2005
+
yann@339
  2006
+    case CODE_LABEL:
yann@339
  2007
+      if (letter == 0)
yann@339
  2008
+	{
yann@339
  2009
+	  output_addr_const (file, op);
yann@339
  2010
+	  return;
yann@339
  2011
+	}
yann@339
  2012
+
yann@339
  2013
+    default:
yann@339
  2014
+      break;
yann@339
  2015
+    }
yann@339
  2016
+
yann@339
  2017
+  fprintf (stderr, "Missing way to print (%c) ", letter);
yann@339
  2018
+  debug_rtx (op);
yann@339
  2019
+  abort ();
yann@339
  2020
+}
yann@339
  2021
+
yann@339
  2022
+static int gprel_constant (rtx);
yann@339
  2023
+
yann@339
  2024
+static int
yann@339
  2025
+gprel_constant (rtx op)
yann@339
  2026
+{
yann@339
  2027
+  if (GET_CODE (op) == SYMBOL_REF
yann@339
  2028
+      && SYMBOL_REF_IN_NIOS2_SMALL_DATA_P (op))
yann@339
  2029
+    {
yann@339
  2030
+      return 1;
yann@339
  2031
+    }
yann@339
  2032
+  else if (GET_CODE (op) == CONST
yann@339
  2033
+           && GET_CODE (XEXP (op, 0)) == PLUS)
yann@339
  2034
+    {
yann@339
  2035
+      return gprel_constant (XEXP (XEXP (op, 0), 0));
yann@339
  2036
+    }
yann@339
  2037
+  else
yann@339
  2038
+    {
yann@339
  2039
+      return 0;
yann@339
  2040
+    }
yann@339
  2041
+}
yann@339
  2042
+
yann@339
  2043
+void
yann@339
  2044
+nios2_print_operand_address (FILE *file, rtx op)
yann@339
  2045
+{
yann@339
  2046
+  switch (GET_CODE (op))
yann@339
  2047
+    {
yann@339
  2048
+    case CONST:
yann@339
  2049
+    case CONST_INT:
yann@339
  2050
+    case LABEL_REF:
yann@339
  2051
+    case CONST_DOUBLE:
yann@339
  2052
+    case SYMBOL_REF:
yann@339
  2053
+      if (gprel_constant (op))
yann@339
  2054
+        {
yann@339
  2055
+          fprintf (file, "%%gprel(");
yann@339
  2056
+          output_addr_const (file, op);
yann@339
  2057
+          fprintf (file, ")(%s)", reg_names[GP_REGNO]);
yann@339
  2058
+          return;
yann@339
  2059
+        }
yann@339
  2060
+
yann@339
  2061
+      break;
yann@339
  2062
+
yann@339
  2063
+    case PLUS:
yann@339
  2064
+      {
yann@339
  2065
+	rtx op0 = XEXP (op, 0);
yann@339
  2066
+	rtx op1 = XEXP (op, 1);
yann@339
  2067
+
yann@339
  2068
+	if (REG_P (op0) && CONSTANT_P (op1))
yann@339
  2069
+	  {
yann@339
  2070
+	    output_addr_const (file, op1);
yann@339
  2071
+	    fprintf (file, "(%s)", reg_names[REGNO (op0)]);
yann@339
  2072
+	    return;
yann@339
  2073
+	  }
yann@339
  2074
+	else if (REG_P (op1) && CONSTANT_P (op0))
yann@339
  2075
+	  {
yann@339
  2076
+	    output_addr_const (file, op0);
yann@339
  2077
+	    fprintf (file, "(%s)", reg_names[REGNO (op1)]);
yann@339
  2078
+	    return;
yann@339
  2079
+	  }
yann@339
  2080
+      }
yann@339
  2081
+      break;
yann@339
  2082
+
yann@339
  2083
+    case REG:
yann@339
  2084
+      fprintf (file, "0(%s)", reg_names[REGNO (op)]);
yann@339
  2085
+      return;
yann@339
  2086
+
yann@339
  2087
+    case MEM:
yann@339
  2088
+      {
yann@339
  2089
+	rtx base = XEXP (op, 0);
yann@339
  2090
+	PRINT_OPERAND_ADDRESS (file, base);
yann@339
  2091
+	return;
yann@339
  2092
+      }
yann@339
  2093
+    default:
yann@339
  2094
+      break;
yann@339
  2095
+    }
yann@339
  2096
+
yann@339
  2097
+  fprintf (stderr, "Missing way to print address\n");
yann@339
  2098
+  debug_rtx (op);
yann@339
  2099
+  abort ();
yann@339
  2100
+}
yann@339
  2101
+
yann@339
  2102
+
yann@339
  2103
+
yann@339
  2104
+
yann@339
  2105
+
yann@339
  2106
+/****************************
yann@339
  2107
+ * Predicates
yann@339
  2108
+ ****************************/
yann@339
  2109
+
yann@339
  2110
+int
yann@339
  2111
+arith_operand (rtx op, enum machine_mode mode)
yann@339
  2112
+{
yann@339
  2113
+  if (GET_CODE (op) == CONST_INT && SMALL_INT (INTVAL (op)))
yann@339
  2114
+    return 1;
yann@339
  2115
+
yann@339
  2116
+  return register_operand (op, mode);
yann@339
  2117
+}
yann@339
  2118
+
yann@339
  2119
+int
yann@339
  2120
+uns_arith_operand (rtx op, enum machine_mode mode)
yann@339
  2121
+{
yann@339
  2122
+  if (GET_CODE (op) == CONST_INT && SMALL_INT_UNSIGNED (INTVAL (op)))
yann@339
  2123
+    return 1;
yann@339
  2124
+
yann@339
  2125
+  return register_operand (op, mode);
yann@339
  2126
+}
yann@339
  2127
+
yann@339
  2128
+int
yann@339
  2129
+logical_operand (rtx op, enum machine_mode mode)
yann@339
  2130
+{
yann@339
  2131
+  if (GET_CODE (op) == CONST_INT
yann@339
  2132
+      && (SMALL_INT_UNSIGNED (INTVAL (op)) || UPPER16_INT (INTVAL (op))))
yann@339
  2133
+    return 1;
yann@339
  2134
+
yann@339
  2135
+  return register_operand (op, mode);
yann@339
  2136
+}
yann@339
  2137
+
yann@339
  2138
+int
yann@339
  2139
+shift_operand (rtx op, enum machine_mode mode)
yann@339
  2140
+{
yann@339
  2141
+  if (GET_CODE (op) == CONST_INT && SHIFT_INT (INTVAL (op)))
yann@339
  2142
+    return 1;
yann@339
  2143
+
yann@339
  2144
+  return register_operand (op, mode);
yann@339
  2145
+}
yann@339
  2146
+
yann@339
  2147
+int
yann@339
  2148
+rdwrctl_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
yann@339
  2149
+{
yann@339
  2150
+  return GET_CODE (op) == CONST_INT && RDWRCTL_INT (INTVAL (op));
yann@339
  2151
+}
yann@339
  2152
+
yann@339
  2153
+/* Return truth value of whether OP is a register or the constant 0. */
yann@339
  2154
+
yann@339
  2155
+int
yann@339
  2156
+reg_or_0_operand (rtx op, enum machine_mode mode)
yann@339
  2157
+{
yann@339
  2158
+  switch (GET_CODE (op))
yann@339
  2159
+    {
yann@339
  2160
+    case CONST_INT:
yann@339
  2161
+      return INTVAL (op) == 0;
yann@339
  2162
+
yann@339
  2163
+    case CONST_DOUBLE:
yann@339
  2164
+      return op == CONST0_RTX (mode);
yann@339
  2165
+
yann@339
  2166
+    default:
yann@339
  2167
+      break;
yann@339
  2168
+    }
yann@339
  2169
+
yann@339
  2170
+  return register_operand (op, mode);
yann@339
  2171
+}
yann@339
  2172
+
yann@339
  2173
+
yann@339
  2174
+int
yann@339
  2175
+equality_op (rtx op, enum machine_mode mode)
yann@339
  2176
+{
yann@339
  2177
+  if (mode != GET_MODE (op))
yann@339
  2178
+    return 0;
yann@339
  2179
+
yann@339
  2180
+  return GET_CODE (op) == EQ || GET_CODE (op) == NE;
yann@339
  2181
+}
yann@339
  2182
+
yann@339
  2183
+int
yann@339
  2184
+custom_insn_opcode (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
yann@339
  2185
+{
yann@339
  2186
+  return GET_CODE (op) == CONST_INT && CUSTOM_INSN_OPCODE (INTVAL (op));
yann@339
  2187
+}
yann@339
  2188
+
yann@339
  2189
+
yann@339
  2190
+
yann@339
  2191
+
yann@339
  2192
+
yann@339
  2193
+
yann@339
  2194
+
yann@339
  2195
+/*****************************************************************************
yann@339
  2196
+**
yann@339
  2197
+** instruction scheduler
yann@339
  2198
+**
yann@339
  2199
+*****************************************************************************/
yann@339
  2200
+static int
yann@339
  2201
+nios2_use_dfa_pipeline_interface ()
yann@339
  2202
+{
yann@339
  2203
+  return 1;
yann@339
  2204
+}
yann@339
  2205
+
yann@339
  2206
+
yann@339
  2207
+static int
yann@339
  2208
+nios2_issue_rate ()
yann@339
  2209
+{
yann@339
  2210
+#ifdef MAX_DFA_ISSUE_RATE
yann@339
  2211
+  return MAX_DFA_ISSUE_RATE;
yann@339
  2212
+#else
yann@339
  2213
+  return 1;
yann@339
  2214
+#endif
yann@339
  2215
+}
yann@339
  2216
+
yann@339
  2217
+
yann@339
  2218
+const char *
yann@339
  2219
+asm_output_opcode (FILE *file ATTRIBUTE_UNUSED, 
yann@339
  2220
+                   const char *ptr ATTRIBUTE_UNUSED)
yann@339
  2221
+{
yann@339
  2222
+  const char *p;
yann@339
  2223
+
yann@339
  2224
+  p = ptr;
yann@339
  2225
+  return ptr;
yann@339
  2226
+}
yann@339
  2227
+
yann@339
  2228
+
yann@339
  2229
+
yann@339
  2230
+/*****************************************************************************
yann@339
  2231
+**
yann@339
  2232
+** function arguments
yann@339
  2233
+**
yann@339
  2234
+*****************************************************************************/
yann@339
  2235
+
yann@339
  2236
+void
yann@339
  2237
+init_cumulative_args (CUMULATIVE_ARGS *cum, 
yann@339
  2238
+                      tree fntype ATTRIBUTE_UNUSED, 
yann@339
  2239
+                      rtx libname ATTRIBUTE_UNUSED, 
yann@339
  2240
+                      tree fndecl ATTRIBUTE_UNUSED, 
yann@339
  2241
+                      int n_named_args ATTRIBUTE_UNUSED)
yann@339
  2242
+{
yann@339
  2243
+  cum->regs_used = 0;
yann@339
  2244
+}
yann@339
  2245
+
yann@339
  2246
+
yann@339
  2247
+/* Update the data in CUM to advance over an argument
yann@339
  2248
+   of mode MODE and data type TYPE.
yann@339
  2249
+   (TYPE is null for libcalls where that information may not be available.)  */
yann@339
  2250
+
yann@339
  2251
+void
yann@339
  2252
+function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, 
yann@339
  2253
+                      tree type ATTRIBUTE_UNUSED, int named ATTRIBUTE_UNUSED)
yann@339
  2254
+{
yann@339
  2255
+  HOST_WIDE_INT param_size;
yann@339
  2256
+
yann@339
  2257
+  if (mode == BLKmode)
yann@339
  2258
+    {
yann@339
  2259
+      param_size = int_size_in_bytes (type);
yann@339
  2260
+      if (param_size < 0)
yann@339
  2261
+	internal_error
yann@339
  2262
+	  ("Do not know how to handle large structs or variable length types");
yann@339
  2263
+    }
yann@339
  2264
+  else
yann@339
  2265
+    {
yann@339
  2266
+      param_size = GET_MODE_SIZE (mode);
yann@339
  2267
+    }
yann@339
  2268
+
yann@339
  2269
+  /* convert to words (round up) */
yann@339
  2270
+  param_size = (3 + param_size) / 4;
yann@339
  2271
+
yann@339
  2272
+  if (cum->regs_used + param_size > NUM_ARG_REGS)
yann@339
  2273
+    {
yann@339
  2274
+      cum->regs_used = NUM_ARG_REGS;
yann@339
  2275
+    }
yann@339
  2276
+  else
yann@339
  2277
+    {
yann@339
  2278
+      cum->regs_used += param_size;
yann@339
  2279
+    }
yann@339
  2280
+
yann@339
  2281
+  return;
yann@339
  2282
+}
yann@339
  2283
+
yann@339
  2284
+/* Define where to put the arguments to a function.  Value is zero to
yann@339
  2285
+   push the argument on the stack, or a hard register in which to
yann@339
  2286
+   store the argument.
yann@339
  2287
+
yann@339
  2288
+   MODE is the argument's machine mode.
yann@339
  2289
+   TYPE is the data type of the argument (as a tree).
yann@339
  2290
+   This is null for libcalls where that information may
yann@339
  2291
+   not be available.
yann@339
  2292
+   CUM is a variable of type CUMULATIVE_ARGS which gives info about
yann@339
  2293
+   the preceding args and about the function being called.
yann@339
  2294
+   NAMED is nonzero if this argument is a named parameter
yann@339
  2295
+   (otherwise it is an extra parameter matching an ellipsis).  */
yann@339
  2296
+rtx
yann@339
  2297
+function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode, 
yann@339
  2298
+              tree type ATTRIBUTE_UNUSED, int named ATTRIBUTE_UNUSED)
yann@339
  2299
+{
yann@339
  2300
+  rtx return_rtx = NULL_RTX;
yann@339
  2301
+
yann@339
  2302
+  if (cum->regs_used < NUM_ARG_REGS)
yann@339
  2303
+    {
yann@339
  2304
+      return_rtx = gen_rtx_REG (mode, FIRST_ARG_REGNO + cum->regs_used);
yann@339
  2305
+    }
yann@339
  2306
+
yann@339
  2307
+  return return_rtx;
yann@339
  2308
+}
yann@339
  2309
+
yann@339
  2310
+int
yann@339
  2311
+function_arg_partial_nregs (const CUMULATIVE_ARGS *cum,
yann@339
  2312
+                            enum machine_mode mode, tree type, 
yann@339
  2313
+                            int named ATTRIBUTE_UNUSED)
yann@339
  2314
+{
yann@339
  2315
+  HOST_WIDE_INT param_size;
yann@339
  2316
+
yann@339
  2317
+  if (mode == BLKmode)
yann@339
  2318
+    {
yann@339
  2319
+      param_size = int_size_in_bytes (type);
yann@339
  2320
+      if (param_size < 0)
yann@339
  2321
+	internal_error
yann@339
  2322
+	  ("Do not know how to handle large structs or variable length types");
yann@339
  2323
+    }
yann@339
  2324
+  else
yann@339
  2325
+    {
yann@339
  2326
+      param_size = GET_MODE_SIZE (mode);
yann@339
  2327
+    }
yann@339
  2328
+
yann@339
  2329
+  /* convert to words (round up) */
yann@339
  2330
+  param_size = (3 + param_size) / 4;
yann@339
  2331
+
yann@339
  2332
+  if (cum->regs_used < NUM_ARG_REGS
yann@339
  2333
+      && cum->regs_used + param_size > NUM_ARG_REGS)
yann@339
  2334
+    {
yann@339
  2335
+      return NUM_ARG_REGS - cum->regs_used;
yann@339
  2336
+    }
yann@339
  2337
+  else
yann@339
  2338
+    {
yann@339
  2339
+      return 0;
yann@339
  2340
+    }
yann@339
  2341
+}
yann@339
  2342
+
yann@339
  2343
+
yann@339
  2344
+int
yann@339
  2345
+nios2_return_in_memory (tree type)
yann@339
  2346
+{
yann@339
  2347
+  int res = ((int_size_in_bytes (type) > (2 * UNITS_PER_WORD))
yann@339
  2348
+  	     || (int_size_in_bytes (type) == -1));
yann@339
  2349
+
yann@339
  2350
+  return res;
yann@339
  2351
+}
yann@339
  2352
+
yann@339
  2353
+/* ??? It may be possible to eliminate the copyback and implement
yann@339
  2354
+       my own va_arg type, but that is more work for now. */
yann@339
  2355
+int
yann@339
  2356
+nios2_setup_incoming_varargs (const CUMULATIVE_ARGS *cum, 
yann@339
  2357
+                              enum machine_mode mode, tree type, 
yann@339
  2358
+                              int no_rtl)
yann@339
  2359
+{
yann@339
  2360
+  CUMULATIVE_ARGS local_cum;
yann@339
  2361
+  int regs_to_push;
yann@339
  2362
+
yann@339
  2363
+  local_cum = *cum;
yann@339
  2364
+  FUNCTION_ARG_ADVANCE (local_cum, mode, type, 1);
yann@339
  2365
+
yann@339
  2366
+  regs_to_push = NUM_ARG_REGS - local_cum.regs_used;
yann@339
  2367
+
yann@339
  2368
+  if (!no_rtl)
yann@339
  2369
+    {
yann@339
  2370
+      if (regs_to_push > 0)
yann@339
  2371
+	{
yann@339
  2372
+	  rtx ptr, mem;
yann@339
  2373
+
yann@339
  2374
+	  ptr = virtual_incoming_args_rtx;
yann@339
  2375
+	  mem = gen_rtx_MEM (BLKmode, ptr);
yann@339
  2376
+
yann@339
  2377
+	  /* va_arg is an array access in this case, which causes
yann@339
  2378
+	     it to get MEM_IN_STRUCT_P set.  We must set it here
yann@339
  2379
+	     so that the insn scheduler won't assume that these
yann@339
  2380
+	     stores can't possibly overlap with the va_arg loads.  */
yann@339
  2381
+	  MEM_SET_IN_STRUCT_P (mem, 1);
yann@339
  2382
+
yann@339
  2383
+	  emit_insn (gen_blockage ());
yann@339
  2384
+	  move_block_from_reg (local_cum.regs_used + FIRST_ARG_REGNO, mem,
yann@339
  2385
+			       regs_to_push);
yann@339
  2386
+	  emit_insn (gen_blockage ());
yann@339
  2387
+	}
yann@339
  2388
+    }
yann@339
  2389
+
yann@339
  2390
+  return regs_to_push * UNITS_PER_WORD;
yann@339
  2391
+
yann@339
  2392
+}
yann@339
  2393
+
yann@339
  2394
+
yann@339
  2395
+
yann@339
  2396
+/*****************************************************************************
yann@339
  2397
+**
yann@339
  2398
+** builtins
yann@339
  2399
+**
yann@339
  2400
+** This method for handling builtins is from CSP where _many_ more types of
yann@339
  2401
+** expanders have already been written. Check there first before writing
yann@339
  2402
+** new ones.
yann@339
  2403
+**
yann@339
  2404
+*****************************************************************************/
yann@339
  2405
+
yann@339
  2406
+enum nios2_builtins
yann@339
  2407
+{
yann@339
  2408
+  NIOS2_BUILTIN_LDBIO,
yann@339
  2409
+  NIOS2_BUILTIN_LDBUIO,
yann@339
  2410
+  NIOS2_BUILTIN_LDHIO,
yann@339
  2411
+  NIOS2_BUILTIN_LDHUIO,
yann@339
  2412
+  NIOS2_BUILTIN_LDWIO,
yann@339
  2413
+  NIOS2_BUILTIN_STBIO,
yann@339
  2414
+  NIOS2_BUILTIN_STHIO,
yann@339
  2415
+  NIOS2_BUILTIN_STWIO,
yann@339
  2416
+  NIOS2_BUILTIN_SYNC,
yann@339
  2417
+  NIOS2_BUILTIN_RDCTL,
yann@339
  2418
+  NIOS2_BUILTIN_WRCTL,
yann@339
  2419
+
yann@339
  2420
+  NIOS2_BUILTIN_CUSTOM_N,
yann@339
  2421
+  NIOS2_BUILTIN_CUSTOM_NI,
yann@339
  2422
+  NIOS2_BUILTIN_CUSTOM_NF,
yann@339
  2423
+  NIOS2_BUILTIN_CUSTOM_NP,
yann@339
  2424
+  NIOS2_BUILTIN_CUSTOM_NII,
yann@339
  2425
+  NIOS2_BUILTIN_CUSTOM_NIF,
yann@339
  2426
+  NIOS2_BUILTIN_CUSTOM_NIP,
yann@339
  2427
+  NIOS2_BUILTIN_CUSTOM_NFI,
yann@339
  2428
+  NIOS2_BUILTIN_CUSTOM_NFF,
yann@339
  2429
+  NIOS2_BUILTIN_CUSTOM_NFP,
yann@339
  2430
+  NIOS2_BUILTIN_CUSTOM_NPI,
yann@339
  2431
+  NIOS2_BUILTIN_CUSTOM_NPF,
yann@339
  2432
+  NIOS2_BUILTIN_CUSTOM_NPP,
yann@339
  2433
+  NIOS2_BUILTIN_CUSTOM_IN,
yann@339
  2434
+  NIOS2_BUILTIN_CUSTOM_INI,
yann@339
  2435
+  NIOS2_BUILTIN_CUSTOM_INF,
yann@339
  2436
+  NIOS2_BUILTIN_CUSTOM_INP,
yann@339
  2437
+  NIOS2_BUILTIN_CUSTOM_INII,
yann@339
  2438
+  NIOS2_BUILTIN_CUSTOM_INIF,
yann@339
  2439
+  NIOS2_BUILTIN_CUSTOM_INIP,
yann@339
  2440
+  NIOS2_BUILTIN_CUSTOM_INFI,
yann@339
  2441
+  NIOS2_BUILTIN_CUSTOM_INFF,
yann@339
  2442
+  NIOS2_BUILTIN_CUSTOM_INFP,
yann@339
  2443
+  NIOS2_BUILTIN_CUSTOM_INPI,
yann@339
  2444
+  NIOS2_BUILTIN_CUSTOM_INPF,
yann@339
  2445
+  NIOS2_BUILTIN_CUSTOM_INPP,
yann@339
  2446
+  NIOS2_BUILTIN_CUSTOM_FN,
yann@339
  2447
+  NIOS2_BUILTIN_CUSTOM_FNI,
yann@339
  2448
+  NIOS2_BUILTIN_CUSTOM_FNF,
yann@339
  2449
+  NIOS2_BUILTIN_CUSTOM_FNP,
yann@339
  2450
+  NIOS2_BUILTIN_CUSTOM_FNII,
yann@339
  2451
+  NIOS2_BUILTIN_CUSTOM_FNIF,
yann@339
  2452
+  NIOS2_BUILTIN_CUSTOM_FNIP,
yann@339
  2453
+  NIOS2_BUILTIN_CUSTOM_FNFI,
yann@339
  2454
+  NIOS2_BUILTIN_CUSTOM_FNFF,
yann@339
  2455
+  NIOS2_BUILTIN_CUSTOM_FNFP,
yann@339
  2456
+  NIOS2_BUILTIN_CUSTOM_FNPI,
yann@339
  2457
+  NIOS2_BUILTIN_CUSTOM_FNPF,
yann@339
  2458
+  NIOS2_BUILTIN_CUSTOM_FNPP,
yann@339
  2459
+  NIOS2_BUILTIN_CUSTOM_PN,
yann@339
  2460
+  NIOS2_BUILTIN_CUSTOM_PNI,
yann@339
  2461
+  NIOS2_BUILTIN_CUSTOM_PNF,
yann@339
  2462
+  NIOS2_BUILTIN_CUSTOM_PNP,
yann@339
  2463
+  NIOS2_BUILTIN_CUSTOM_PNII,
yann@339
  2464
+  NIOS2_BUILTIN_CUSTOM_PNIF,
yann@339
  2465
+  NIOS2_BUILTIN_CUSTOM_PNIP,
yann@339
  2466
+  NIOS2_BUILTIN_CUSTOM_PNFI,
yann@339
  2467
+  NIOS2_BUILTIN_CUSTOM_PNFF,
yann@339
  2468
+  NIOS2_BUILTIN_CUSTOM_PNFP,
yann@339
  2469
+  NIOS2_BUILTIN_CUSTOM_PNPI,
yann@339
  2470
+  NIOS2_BUILTIN_CUSTOM_PNPF,
yann@339
  2471
+  NIOS2_BUILTIN_CUSTOM_PNPP,
yann@339
  2472
+
yann@339
  2473
+
yann@339
  2474
+  LIM_NIOS2_BUILTINS
yann@339
  2475
+};
yann@339
  2476
+
yann@339
  2477
+struct builtin_description
yann@339
  2478
+{
yann@339
  2479
+    const enum insn_code icode;
yann@339
  2480
+    const char *const name;
yann@339
  2481
+    const enum nios2_builtins code;
yann@339
  2482
+    const tree *type;
yann@339
  2483
+    rtx (* expander) PARAMS ((const struct builtin_description *,
yann@339
  2484
+                              tree, rtx, rtx, enum machine_mode, int));
yann@339
  2485
+};
yann@339
  2486
+
yann@339
  2487
+static rtx nios2_expand_STXIO (const struct builtin_description *, 
yann@339
  2488
+                               tree, rtx, rtx, enum machine_mode, int);
yann@339
  2489
+static rtx nios2_expand_LDXIO (const struct builtin_description *, 
yann@339
  2490
+                               tree, rtx, rtx, enum machine_mode, int);
yann@339
  2491
+static rtx nios2_expand_sync (const struct builtin_description *, 
yann@339
  2492
+                              tree, rtx, rtx, enum machine_mode, int);
yann@339
  2493
+static rtx nios2_expand_rdctl (const struct builtin_description *, 
yann@339
  2494
+                               tree, rtx, rtx, enum machine_mode, int);
yann@339
  2495
+static rtx nios2_expand_wrctl (const struct builtin_description *, 
yann@339
  2496
+                               tree, rtx, rtx, enum machine_mode, int);
yann@339
  2497
+
yann@339
  2498
+static rtx nios2_expand_custom_n (const struct builtin_description *, 
yann@339
  2499
+                                  tree, rtx, rtx, enum machine_mode, int);
yann@339
  2500
+static rtx nios2_expand_custom_Xn (const struct builtin_description *, 
yann@339
  2501
+                                   tree, rtx, rtx, enum machine_mode, int);
yann@339
  2502
+static rtx nios2_expand_custom_nX (const struct builtin_description *, 
yann@339
  2503
+                                   tree, rtx, rtx, enum machine_mode, int);
yann@339
  2504
+static rtx nios2_expand_custom_XnX (const struct builtin_description *, 
yann@339
  2505
+                                    tree, rtx, rtx, enum machine_mode, int);
yann@339
  2506
+static rtx nios2_expand_custom_nXX (const struct builtin_description *, 
yann@339
  2507
+                                    tree, rtx, rtx, enum machine_mode, int);
yann@339
  2508
+static rtx nios2_expand_custom_XnXX (const struct builtin_description *, 
yann@339
  2509
+                                     tree, rtx, rtx, enum machine_mode, int);
yann@339
  2510
+
yann@339
  2511
+static tree endlink;
yann@339
  2512
+
yann@339
  2513
+/* int fn (volatile const void *)
yann@339
  2514
+ */
yann@339
  2515
+static tree int_ftype_volatile_const_void_p;
yann@339
  2516
+
yann@339
  2517
+/* int fn (int)
yann@339
  2518
+ */
yann@339
  2519
+static tree int_ftype_int;
yann@339
  2520
+
yann@339
  2521
+/* void fn (int, int)
yann@339
  2522
+ */
yann@339
  2523
+static tree void_ftype_int_int;
yann@339
  2524
+
yann@339
  2525
+/* void fn (volatile void *, int)
yann@339
  2526
+ */
yann@339
  2527
+static tree void_ftype_volatile_void_p_int;
yann@339
  2528
+
yann@339
  2529
+/* void fn (void)
yann@339
  2530
+ */
yann@339
  2531
+static tree void_ftype_void;
yann@339
  2532
+
yann@339
  2533
+static tree custom_n;
yann@339
  2534
+static tree custom_ni;
yann@339
  2535
+static tree custom_nf;
yann@339
  2536
+static tree custom_np;
yann@339
  2537
+static tree custom_nii;
yann@339
  2538
+static tree custom_nif;
yann@339
  2539
+static tree custom_nip;
yann@339
  2540
+static tree custom_nfi;
yann@339
  2541
+static tree custom_nff;
yann@339
  2542
+static tree custom_nfp;
yann@339
  2543
+static tree custom_npi;
yann@339
  2544
+static tree custom_npf;
yann@339
  2545
+static tree custom_npp;
yann@339
  2546
+static tree custom_in;
yann@339
  2547
+static tree custom_ini;
yann@339
  2548
+static tree custom_inf;
yann@339
  2549
+static tree custom_inp;
yann@339
  2550
+static tree custom_inii;
yann@339
  2551
+static tree custom_inif;
yann@339
  2552
+static tree custom_inip;
yann@339
  2553
+static tree custom_infi;
yann@339
  2554
+static tree custom_inff;
yann@339
  2555
+static tree custom_infp;
yann@339
  2556
+static tree custom_inpi;
yann@339
  2557
+static tree custom_inpf;
yann@339
  2558
+static tree custom_inpp;
yann@339
  2559
+static tree custom_fn;
yann@339
  2560
+static tree custom_fni;
yann@339
  2561
+static tree custom_fnf;
yann@339
  2562
+static tree custom_fnp;
yann@339
  2563
+static tree custom_fnii;
yann@339
  2564
+static tree custom_fnif;
yann@339
  2565
+static tree custom_fnip;
yann@339
  2566
+static tree custom_fnfi;
yann@339
  2567
+static tree custom_fnff;
yann@339
  2568
+static tree custom_fnfp;
yann@339
  2569
+static tree custom_fnpi;
yann@339
  2570
+static tree custom_fnpf;
yann@339
  2571
+static tree custom_fnpp;
yann@339
  2572
+static tree custom_pn;
yann@339
  2573
+static tree custom_pni;
yann@339
  2574
+static tree custom_pnf;
yann@339
  2575
+static tree custom_pnp;
yann@339
  2576
+static tree custom_pnii;
yann@339
  2577
+static tree custom_pnif;
yann@339
  2578
+static tree custom_pnip;
yann@339
  2579
+static tree custom_pnfi;
yann@339
  2580
+static tree custom_pnff;
yann@339
  2581
+static tree custom_pnfp;
yann@339
  2582
+static tree custom_pnpi;
yann@339
  2583
+static tree custom_pnpf;
yann@339
  2584
+static tree custom_pnpp;
yann@339
  2585
+
yann@339
  2586
+
yann@339
  2587
+static const struct builtin_description bdesc[] = {
yann@339
  2588
+    {CODE_FOR_ldbio, "__builtin_ldbio", NIOS2_BUILTIN_LDBIO, &int_ftype_volatile_const_void_p, nios2_expand_LDXIO},
yann@339
  2589
+    {CODE_FOR_ldbuio, "__builtin_ldbuio", NIOS2_BUILTIN_LDBUIO, &int_ftype_volatile_const_void_p, nios2_expand_LDXIO},
yann@339
  2590
+    {CODE_FOR_ldhio, "__builtin_ldhio", NIOS2_BUILTIN_LDHIO, &int_ftype_volatile_const_void_p, nios2_expand_LDXIO},
yann@339
  2591
+    {CODE_FOR_ldhuio, "__builtin_ldhuio", NIOS2_BUILTIN_LDHUIO, &int_ftype_volatile_const_void_p, nios2_expand_LDXIO},
yann@339
  2592
+    {CODE_FOR_ldwio, "__builtin_ldwio", NIOS2_BUILTIN_LDWIO, &int_ftype_volatile_const_void_p, nios2_expand_LDXIO},
yann@339
  2593
+
yann@339
  2594
+    {CODE_FOR_stbio, "__builtin_stbio", NIOS2_BUILTIN_STBIO, &void_ftype_volatile_void_p_int, nios2_expand_STXIO},
yann@339
  2595
+    {CODE_FOR_sthio, "__builtin_sthio", NIOS2_BUILTIN_STHIO, &void_ftype_volatile_void_p_int, nios2_expand_STXIO},
yann@339
  2596
+    {CODE_FOR_stwio, "__builtin_stwio", NIOS2_BUILTIN_STWIO, &void_ftype_volatile_void_p_int, nios2_expand_STXIO},
yann@339
  2597
+
yann@339
  2598
+    {CODE_FOR_sync, "__builtin_sync", NIOS2_BUILTIN_SYNC, &void_ftype_void, nios2_expand_sync},
yann@339
  2599
+    {CODE_FOR_rdctl, "__builtin_rdctl", NIOS2_BUILTIN_RDCTL, &int_ftype_int, nios2_expand_rdctl},
yann@339
  2600
+    {CODE_FOR_wrctl, "__builtin_wrctl", NIOS2_BUILTIN_WRCTL, &void_ftype_int_int, nios2_expand_wrctl},
yann@339
  2601
+
yann@339
  2602
+    {CODE_FOR_custom_n, "__builtin_custom_n", NIOS2_BUILTIN_CUSTOM_N, &custom_n, nios2_expand_custom_n},
yann@339
  2603
+    {CODE_FOR_custom_ni, "__builtin_custom_ni", NIOS2_BUILTIN_CUSTOM_NI, &custom_ni, nios2_expand_custom_nX},
yann@339
  2604
+    {CODE_FOR_custom_nf, "__builtin_custom_nf", NIOS2_BUILTIN_CUSTOM_NF, &custom_nf, nios2_expand_custom_nX},
yann@339
  2605
+    {CODE_FOR_custom_np, "__builtin_custom_np", NIOS2_BUILTIN_CUSTOM_NP, &custom_np, nios2_expand_custom_nX},
yann@339
  2606
+    {CODE_FOR_custom_nii, "__builtin_custom_nii", NIOS2_BUILTIN_CUSTOM_NII, &custom_nii, nios2_expand_custom_nXX},
yann@339
  2607
+    {CODE_FOR_custom_nif, "__builtin_custom_nif", NIOS2_BUILTIN_CUSTOM_NIF, &custom_nif, nios2_expand_custom_nXX},
yann@339
  2608
+    {CODE_FOR_custom_nip, "__builtin_custom_nip", NIOS2_BUILTIN_CUSTOM_NIP, &custom_nip, nios2_expand_custom_nXX},
yann@339
  2609
+    {CODE_FOR_custom_nfi, "__builtin_custom_nfi", NIOS2_BUILTIN_CUSTOM_NFI, &custom_nfi, nios2_expand_custom_nXX},
yann@339
  2610
+    {CODE_FOR_custom_nff, "__builtin_custom_nff", NIOS2_BUILTIN_CUSTOM_NFF, &custom_nff, nios2_expand_custom_nXX},
yann@339
  2611
+    {CODE_FOR_custom_nfp, "__builtin_custom_nfp", NIOS2_BUILTIN_CUSTOM_NFP, &custom_nfp, nios2_expand_custom_nXX},
yann@339
  2612
+    {CODE_FOR_custom_npi, "__builtin_custom_npi", NIOS2_BUILTIN_CUSTOM_NPI, &custom_npi, nios2_expand_custom_nXX},
yann@339
  2613
+    {CODE_FOR_custom_npf, "__builtin_custom_npf", NIOS2_BUILTIN_CUSTOM_NPF, &custom_npf, nios2_expand_custom_nXX},
yann@339
  2614
+    {CODE_FOR_custom_npp, "__builtin_custom_npp", NIOS2_BUILTIN_CUSTOM_NPP, &custom_npp, nios2_expand_custom_nXX},
yann@339
  2615
+    {CODE_FOR_custom_in, "__builtin_custom_in", NIOS2_BUILTIN_CUSTOM_IN, &custom_in, nios2_expand_custom_Xn},
yann@339
  2616
+    {CODE_FOR_custom_ini, "__builtin_custom_ini", NIOS2_BUILTIN_CUSTOM_INI, &custom_ini, nios2_expand_custom_XnX},
yann@339
  2617
+    {CODE_FOR_custom_inf, "__builtin_custom_inf", NIOS2_BUILTIN_CUSTOM_INF, &custom_inf, nios2_expand_custom_XnX},
yann@339
  2618
+    {CODE_FOR_custom_inp, "__builtin_custom_inp", NIOS2_BUILTIN_CUSTOM_INP, &custom_inp, nios2_expand_custom_XnX},
yann@339
  2619
+    {CODE_FOR_custom_inii, "__builtin_custom_inii", NIOS2_BUILTIN_CUSTOM_INII, &custom_inii, nios2_expand_custom_XnXX},
yann@339
  2620
+    {CODE_FOR_custom_inif, "__builtin_custom_inif", NIOS2_BUILTIN_CUSTOM_INIF, &custom_inif, nios2_expand_custom_XnXX},
yann@339
  2621
+    {CODE_FOR_custom_inip, "__builtin_custom_inip", NIOS2_BUILTIN_CUSTOM_INIP, &custom_inip, nios2_expand_custom_XnXX},
yann@339
  2622
+    {CODE_FOR_custom_infi, "__builtin_custom_infi", NIOS2_BUILTIN_CUSTOM_INFI, &custom_infi, nios2_expand_custom_XnXX},
yann@339
  2623
+    {CODE_FOR_custom_inff, "__builtin_custom_inff", NIOS2_BUILTIN_CUSTOM_INFF, &custom_inff, nios2_expand_custom_XnXX},
yann@339
  2624
+    {CODE_FOR_custom_infp, "__builtin_custom_infp", NIOS2_BUILTIN_CUSTOM_INFP, &custom_infp, nios2_expand_custom_XnXX},
yann@339
  2625
+    {CODE_FOR_custom_inpi, "__builtin_custom_inpi", NIOS2_BUILTIN_CUSTOM_INPI, &custom_inpi, nios2_expand_custom_XnXX},
yann@339
  2626
+    {CODE_FOR_custom_inpf, "__builtin_custom_inpf", NIOS2_BUILTIN_CUSTOM_INPF, &custom_inpf, nios2_expand_custom_XnXX},
yann@339
  2627
+    {CODE_FOR_custom_inpp, "__builtin_custom_inpp", NIOS2_BUILTIN_CUSTOM_INPP, &custom_inpp, nios2_expand_custom_XnXX},
yann@339
  2628
+    {CODE_FOR_custom_fn, "__builtin_custom_fn", NIOS2_BUILTIN_CUSTOM_FN, &custom_fn, nios2_expand_custom_Xn},
yann@339
  2629
+    {CODE_FOR_custom_fni, "__builtin_custom_fni", NIOS2_BUILTIN_CUSTOM_FNI, &custom_fni, nios2_expand_custom_XnX},
yann@339
  2630
+    {CODE_FOR_custom_fnf, "__builtin_custom_fnf", NIOS2_BUILTIN_CUSTOM_FNF, &custom_fnf, nios2_expand_custom_XnX},
yann@339
  2631
+    {CODE_FOR_custom_fnp, "__builtin_custom_fnp", NIOS2_BUILTIN_CUSTOM_FNP, &custom_fnp, nios2_expand_custom_XnX},
yann@339
  2632
+    {CODE_FOR_custom_fnii, "__builtin_custom_fnii", NIOS2_BUILTIN_CUSTOM_FNII, &custom_fnii, nios2_expand_custom_XnXX},
yann@339
  2633
+    {CODE_FOR_custom_fnif, "__builtin_custom_fnif", NIOS2_BUILTIN_CUSTOM_FNIF, &custom_fnif, nios2_expand_custom_XnXX},
yann@339
  2634
+    {CODE_FOR_custom_fnip, "__builtin_custom_fnip", NIOS2_BUILTIN_CUSTOM_FNIP, &custom_fnip, nios2_expand_custom_XnXX},
yann@339
  2635
+    {CODE_FOR_custom_fnfi, "__builtin_custom_fnfi", NIOS2_BUILTIN_CUSTOM_FNFI, &custom_fnfi, nios2_expand_custom_XnXX},
yann@339
  2636
+    {CODE_FOR_custom_fnff, "__builtin_custom_fnff", NIOS2_BUILTIN_CUSTOM_FNFF, &custom_fnff, nios2_expand_custom_XnXX},
yann@339
  2637
+    {CODE_FOR_custom_fnfp, "__builtin_custom_fnfp", NIOS2_BUILTIN_CUSTOM_FNFP, &custom_fnfp, nios2_expand_custom_XnXX},
yann@339
  2638
+    {CODE_FOR_custom_fnpi, "__builtin_custom_fnpi", NIOS2_BUILTIN_CUSTOM_FNPI, &custom_fnpi, nios2_expand_custom_XnXX},
yann@339
  2639
+    {CODE_FOR_custom_fnpf, "__builtin_custom_fnpf", NIOS2_BUILTIN_CUSTOM_FNPF, &custom_fnpf, nios2_expand_custom_XnXX},
yann@339
  2640
+    {CODE_FOR_custom_fnpp, "__builtin_custom_fnpp", NIOS2_BUILTIN_CUSTOM_FNPP, &custom_fnpp, nios2_expand_custom_XnXX},
yann@339
  2641
+    {CODE_FOR_custom_pn, "__builtin_custom_pn", NIOS2_BUILTIN_CUSTOM_PN, &custom_pn, nios2_expand_custom_Xn},
yann@339
  2642
+    {CODE_FOR_custom_pni, "__builtin_custom_pni", NIOS2_BUILTIN_CUSTOM_PNI, &custom_pni, nios2_expand_custom_XnX},
yann@339
  2643
+    {CODE_FOR_custom_pnf, "__builtin_custom_pnf", NIOS2_BUILTIN_CUSTOM_PNF, &custom_pnf, nios2_expand_custom_XnX},
yann@339
  2644
+    {CODE_FOR_custom_pnp, "__builtin_custom_pnp", NIOS2_BUILTIN_CUSTOM_PNP, &custom_pnp, nios2_expand_custom_XnX},
yann@339
  2645
+    {CODE_FOR_custom_pnii, "__builtin_custom_pnii", NIOS2_BUILTIN_CUSTOM_PNII, &custom_pnii, nios2_expand_custom_XnXX},
yann@339
  2646
+    {CODE_FOR_custom_pnif, "__builtin_custom_pnif", NIOS2_BUILTIN_CUSTOM_PNIF, &custom_pnif, nios2_expand_custom_XnXX},
yann@339
  2647
+    {CODE_FOR_custom_pnip, "__builtin_custom_pnip", NIOS2_BUILTIN_CUSTOM_PNIP, &custom_pnip, nios2_expand_custom_XnXX},
yann@339
  2648
+    {CODE_FOR_custom_pnfi, "__builtin_custom_pnfi", NIOS2_BUILTIN_CUSTOM_PNFI, &custom_pnfi, nios2_expand_custom_XnXX},
yann@339
  2649
+    {CODE_FOR_custom_pnff, "__builtin_custom_pnff", NIOS2_BUILTIN_CUSTOM_PNFF, &custom_pnff, nios2_expand_custom_XnXX},
yann@339
  2650
+    {CODE_FOR_custom_pnfp, "__builtin_custom_pnfp", NIOS2_BUILTIN_CUSTOM_PNFP, &custom_pnfp, nios2_expand_custom_XnXX},
yann@339
  2651
+    {CODE_FOR_custom_pnpi, "__builtin_custom_pnpi", NIOS2_BUILTIN_CUSTOM_PNPI, &custom_pnpi, nios2_expand_custom_XnXX},
yann@339
  2652
+    {CODE_FOR_custom_pnpf, "__builtin_custom_pnpf", NIOS2_BUILTIN_CUSTOM_PNPF, &custom_pnpf, nios2_expand_custom_XnXX},
yann@339
  2653
+    {CODE_FOR_custom_pnpp, "__builtin_custom_pnpp", NIOS2_BUILTIN_CUSTOM_PNPP, &custom_pnpp, nios2_expand_custom_XnXX},
yann@339
  2654
+
yann@339
  2655
+
yann@339
  2656
+    {0, 0, 0, 0, 0},
yann@339
  2657
+};
yann@339
  2658
+
yann@339
  2659
+/* This does not have a closing bracket on purpose (see use) */
yann@339
  2660
+#define def_param(TYPE) \
yann@339
  2661
+  tree_cons (NULL_TREE, TYPE,
yann@339
  2662
+
yann@339
  2663
+static void
yann@339
  2664
+nios2_init_builtins ()
yann@339
  2665
+{
yann@339
  2666
+  const struct builtin_description *d;
yann@339
  2667
+
yann@339
  2668
+
yann@339
  2669
+  endlink = void_list_node;
yann@339
  2670
+
yann@339
  2671
+  /* Special indenting here because one of the brackets is in def_param */
yann@339
  2672
+  /* *INDENT-OFF* */
yann@339
  2673
+
yann@339
  2674
+  /* int fn (volatile const void *)
yann@339
  2675
+   */
yann@339
  2676
+  int_ftype_volatile_const_void_p
yann@339
  2677
+    = build_function_type (integer_type_node,
yann@339
  2678
+			   def_param (build_qualified_type (ptr_type_node,
yann@339
  2679
+			                                    TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE))
yann@339
  2680
+			   endlink));
yann@339
  2681
+
yann@339
  2682
+
yann@339
  2683
+  /* void fn (volatile void *, int)
yann@339
  2684
+   */
yann@339
  2685
+  void_ftype_volatile_void_p_int
yann@339
  2686
+    = build_function_type (void_type_node,
yann@339
  2687
+			   def_param (build_qualified_type (ptr_type_node,
yann@339
  2688
+			                                    TYPE_QUAL_VOLATILE))
yann@339
  2689
+			   def_param (integer_type_node)
yann@339
  2690
+			   endlink)));
yann@339
  2691
+
yann@339
  2692
+  /* void fn (void)
yann@339
  2693
+   */
yann@339
  2694
+  void_ftype_void
yann@339
  2695
+      = build_function_type (void_type_node,
yann@339
  2696
+                             endlink);
yann@339
  2697
+
yann@339
  2698
+  /* int fn (int)
yann@339
  2699
+   */
yann@339
  2700
+  int_ftype_int
yann@339
  2701
+      = build_function_type (integer_type_node,
yann@339
  2702
+                             def_param (integer_type_node)
yann@339
  2703
+                             endlink));
yann@339
  2704
+
yann@339
  2705
+  /* void fn (int, int)
yann@339
  2706
+   */
yann@339
  2707
+  void_ftype_int_int
yann@339
  2708
+      = build_function_type (void_type_node,
yann@339
  2709
+                             def_param (integer_type_node)
yann@339
  2710
+                             def_param (integer_type_node)
yann@339
  2711
+                             endlink)));
yann@339
  2712
+
yann@339
  2713
+
yann@339
  2714
+#define CUSTOM_NUM def_param (integer_type_node)
yann@339
  2715
+
yann@339
  2716
+  custom_n
yann@339
  2717
+      = build_function_type (void_type_node,
yann@339
  2718
+  			     CUSTOM_NUM
yann@339
  2719
+  			     endlink));
yann@339
  2720
+  custom_ni
yann@339
  2721
+      = build_function_type (void_type_node,
yann@339
  2722
+  			     CUSTOM_NUM
yann@339
  2723
+  			     def_param (integer_type_node)
yann@339
  2724
+  			     endlink)));
yann@339
  2725
+  custom_nf
yann@339
  2726
+      = build_function_type (void_type_node,
yann@339
  2727
+  			     CUSTOM_NUM
yann@339
  2728
+  			     def_param (float_type_node)
yann@339
  2729
+  			     endlink)));
yann@339
  2730
+  custom_np
yann@339
  2731
+      = build_function_type (void_type_node,
yann@339
  2732
+  			     CUSTOM_NUM
yann@339
  2733
+  			     def_param (ptr_type_node)
yann@339
  2734
+  			     endlink)));
yann@339
  2735
+  custom_nii
yann@339
  2736
+      = build_function_type (void_type_node,
yann@339
  2737
+  			     CUSTOM_NUM
yann@339
  2738
+  			     def_param (integer_type_node)
yann@339
  2739
+  			     def_param (integer_type_node)
yann@339
  2740
+  			     endlink))));
yann@339
  2741
+  custom_nif
yann@339
  2742
+      = build_function_type (void_type_node,
yann@339
  2743
+  			     CUSTOM_NUM
yann@339
  2744
+  			     def_param (integer_type_node)
yann@339
  2745
+  			     def_param (float_type_node)
yann@339
  2746
+  			     endlink))));
yann@339
  2747
+  custom_nip
yann@339
  2748
+      = build_function_type (void_type_node,
yann@339
  2749
+  			     CUSTOM_NUM
yann@339
  2750
+  			     def_param (integer_type_node)
yann@339
  2751
+  			     def_param (ptr_type_node)
yann@339
  2752
+  			     endlink))));
yann@339
  2753
+  custom_nfi
yann@339
  2754
+      = build_function_type (void_type_node,
yann@339
  2755
+  			     CUSTOM_NUM
yann@339
  2756
+  			     def_param (float_type_node)
yann@339
  2757
+  			     def_param (integer_type_node)
yann@339
  2758
+  			     endlink))));
yann@339
  2759
+  custom_nff
yann@339
  2760
+      = build_function_type (void_type_node,
yann@339
  2761
+  			     CUSTOM_NUM
yann@339
  2762
+  			     def_param (float_type_node)
yann@339
  2763
+  			     def_param (float_type_node)
yann@339
  2764
+  			     endlink))));
yann@339
  2765
+  custom_nfp
yann@339
  2766
+      = build_function_type (void_type_node,
yann@339
  2767
+  			     CUSTOM_NUM
yann@339
  2768
+  			     def_param (float_type_node)
yann@339
  2769
+  			     def_param (ptr_type_node)
yann@339
  2770
+  			     endlink))));
yann@339
  2771
+  custom_npi
yann@339
  2772
+      = build_function_type (void_type_node,
yann@339
  2773
+  			     CUSTOM_NUM
yann@339
  2774
+  			     def_param (ptr_type_node)
yann@339
  2775
+  			     def_param (integer_type_node)
yann@339
  2776
+  			     endlink))));
yann@339
  2777
+  custom_npf
yann@339
  2778
+      = build_function_type (void_type_node,
yann@339
  2779
+  			     CUSTOM_NUM
yann@339
  2780
+  			     def_param (ptr_type_node)
yann@339
  2781
+  			     def_param (float_type_node)
yann@339
  2782
+  			     endlink))));
yann@339
  2783
+  custom_npp
yann@339
  2784
+      = build_function_type (void_type_node,
yann@339
  2785
+  			     CUSTOM_NUM
yann@339
  2786
+  			     def_param (ptr_type_node)
yann@339
  2787
+  			     def_param (ptr_type_node)
yann@339
  2788
+  			     endlink))));
yann@339
  2789
+
yann@339
  2790
+  custom_in
yann@339
  2791
+      = build_function_type (integer_type_node,
yann@339
  2792
+  			     CUSTOM_NUM
yann@339
  2793
+  			     endlink));
yann@339
  2794
+  custom_ini
yann@339
  2795
+      = build_function_type (integer_type_node,
yann@339
  2796
+  			     CUSTOM_NUM
yann@339
  2797
+  			     def_param (integer_type_node)
yann@339
  2798
+  			     endlink)));
yann@339
  2799
+  custom_inf
yann@339
  2800
+      = build_function_type (integer_type_node,
yann@339
  2801
+  			     CUSTOM_NUM
yann@339
  2802
+  			     def_param (float_type_node)
yann@339
  2803
+  			     endlink)));
yann@339
  2804
+  custom_inp
yann@339
  2805
+      = build_function_type (integer_type_node,
yann@339
  2806
+  			     CUSTOM_NUM
yann@339
  2807
+  			     def_param (ptr_type_node)
yann@339
  2808
+  			     endlink)));
yann@339
  2809
+  custom_inii
yann@339
  2810
+      = build_function_type (integer_type_node,
yann@339
  2811
+  			     CUSTOM_NUM
yann@339
  2812
+  			     def_param (integer_type_node)
yann@339
  2813
+  			     def_param (integer_type_node)
yann@339
  2814
+  			     endlink))));
yann@339
  2815
+  custom_inif
yann@339
  2816
+      = build_function_type (integer_type_node,
yann@339
  2817
+  			     CUSTOM_NUM
yann@339
  2818
+  			     def_param (integer_type_node)
yann@339
  2819
+  			     def_param (float_type_node)
yann@339
  2820
+  			     endlink))));
yann@339
  2821
+  custom_inip
yann@339
  2822
+      = build_function_type (integer_type_node,
yann@339
  2823
+  			     CUSTOM_NUM
yann@339
  2824
+  			     def_param (integer_type_node)
yann@339
  2825
+  			     def_param (ptr_type_node)
yann@339
  2826
+  			     endlink))));
yann@339
  2827
+  custom_infi
yann@339
  2828
+      = build_function_type (integer_type_node,
yann@339
  2829
+  			     CUSTOM_NUM
yann@339
  2830
+  			     def_param (float_type_node)
yann@339
  2831
+  			     def_param (integer_type_node)
yann@339
  2832
+  			     endlink))));
yann@339
  2833
+  custom_inff
yann@339
  2834
+      = build_function_type (integer_type_node,
yann@339
  2835
+  			     CUSTOM_NUM
yann@339
  2836
+  			     def_param (float_type_node)
yann@339
  2837
+  			     def_param (float_type_node)
yann@339
  2838
+  			     endlink))));
yann@339
  2839
+  custom_infp
yann@339
  2840
+      = build_function_type (integer_type_node,
yann@339
  2841
+  			     CUSTOM_NUM
yann@339
  2842
+  			     def_param (float_type_node)
yann@339
  2843
+  			     def_param (ptr_type_node)
yann@339
  2844
+  			     endlink))));
yann@339
  2845
+  custom_inpi
yann@339
  2846
+      = build_function_type (integer_type_node,
yann@339
  2847
+  			     CUSTOM_NUM
yann@339
  2848
+  			     def_param (ptr_type_node)
yann@339
  2849
+  			     def_param (integer_type_node)
yann@339
  2850
+  			     endlink))));
yann@339
  2851
+  custom_inpf
yann@339
  2852
+      = build_function_type (integer_type_node,
yann@339
  2853
+  			     CUSTOM_NUM
yann@339
  2854
+  			     def_param (ptr_type_node)
yann@339
  2855
+  			     def_param (float_type_node)
yann@339
  2856
+  			     endlink))));
yann@339
  2857
+  custom_inpp
yann@339
  2858
+      = build_function_type (integer_type_node,
yann@339
  2859
+  			     CUSTOM_NUM
yann@339
  2860
+  			     def_param (ptr_type_node)
yann@339
  2861
+  			     def_param (ptr_type_node)
yann@339
  2862
+  			     endlink))));
yann@339
  2863
+
yann@339
  2864
+  custom_fn
yann@339
  2865
+      = build_function_type (float_type_node,
yann@339
  2866
+  			     CUSTOM_NUM
yann@339
  2867
+  			     endlink));
yann@339
  2868
+  custom_fni
yann@339
  2869
+      = build_function_type (float_type_node,
yann@339
  2870
+  			     CUSTOM_NUM
yann@339
  2871
+  			     def_param (integer_type_node)
yann@339
  2872
+  			     endlink)));
yann@339
  2873
+  custom_fnf
yann@339
  2874
+      = build_function_type (float_type_node,
yann@339
  2875
+  			     CUSTOM_NUM
yann@339
  2876
+  			     def_param (float_type_node)
yann@339
  2877
+  			     endlink)));
yann@339
  2878
+  custom_fnp
yann@339
  2879
+      = build_function_type (float_type_node,
yann@339
  2880
+  			     CUSTOM_NUM
yann@339
  2881
+  			     def_param (ptr_type_node)
yann@339
  2882
+  			     endlink)));
yann@339
  2883
+  custom_fnii
yann@339
  2884
+      = build_function_type (float_type_node,
yann@339
  2885
+  			     CUSTOM_NUM
yann@339
  2886
+  			     def_param (integer_type_node)
yann@339
  2887
+  			     def_param (integer_type_node)
yann@339
  2888
+  			     endlink))));
yann@339
  2889
+  custom_fnif
yann@339
  2890
+      = build_function_type (float_type_node,
yann@339
  2891
+  			     CUSTOM_NUM
yann@339
  2892
+  			     def_param (integer_type_node)
yann@339
  2893
+  			     def_param (float_type_node)
yann@339
  2894
+  			     endlink))));
yann@339
  2895
+  custom_fnip
yann@339
  2896
+      = build_function_type (float_type_node,
yann@339
  2897
+  			     CUSTOM_NUM
yann@339
  2898
+  			     def_param (integer_type_node)
yann@339
  2899
+  			     def_param (ptr_type_node)
yann@339
  2900
+  			     endlink))));
yann@339
  2901
+  custom_fnfi
yann@339
  2902
+      = build_function_type (float_type_node,
yann@339
  2903
+  			     CUSTOM_NUM
yann@339
  2904
+  			     def_param (float_type_node)
yann@339
  2905
+  			     def_param (integer_type_node)
yann@339
  2906
+  			     endlink))));
yann@339
  2907
+  custom_fnff
yann@339
  2908
+      = build_function_type (float_type_node,
yann@339
  2909
+  			     CUSTOM_NUM
yann@339
  2910
+  			     def_param (float_type_node)
yann@339
  2911
+  			     def_param (float_type_node)
yann@339
  2912
+  			     endlink))));
yann@339
  2913
+  custom_fnfp
yann@339
  2914
+      = build_function_type (float_type_node,
yann@339
  2915
+  			     CUSTOM_NUM
yann@339
  2916
+  			     def_param (float_type_node)
yann@339
  2917
+  			     def_param (ptr_type_node)
yann@339
  2918
+  			     endlink))));
yann@339
  2919
+  custom_fnpi
yann@339
  2920
+      = build_function_type (float_type_node,
yann@339
  2921
+  			     CUSTOM_NUM
yann@339
  2922
+  			     def_param (ptr_type_node)
yann@339
  2923
+  			     def_param (integer_type_node)
yann@339
  2924
+  			     endlink))));
yann@339
  2925
+  custom_fnpf
yann@339
  2926
+      = build_function_type (float_type_node,
yann@339
  2927
+  			     CUSTOM_NUM
yann@339
  2928
+  			     def_param (ptr_type_node)
yann@339
  2929
+  			     def_param (float_type_node)
yann@339
  2930
+  			     endlink))));
yann@339
  2931
+  custom_fnpp
yann@339
  2932
+      = build_function_type (float_type_node,
yann@339
  2933
+  			     CUSTOM_NUM
yann@339
  2934
+  			     def_param (ptr_type_node)
yann@339
  2935
+  			     def_param (ptr_type_node)
yann@339
  2936
+  			     endlink))));
yann@339
  2937
+
yann@339
  2938
+
yann@339
  2939
+  custom_pn
yann@339
  2940
+      = build_function_type (ptr_type_node,
yann@339
  2941
+  			     CUSTOM_NUM
yann@339
  2942
+  			     endlink));
yann@339
  2943
+  custom_pni
yann@339
  2944
+      = build_function_type (ptr_type_node,
yann@339
  2945
+  			     CUSTOM_NUM
yann@339
  2946
+  			     def_param (integer_type_node)
yann@339
  2947
+  			     endlink)));
yann@339
  2948
+  custom_pnf
yann@339
  2949
+      = build_function_type (ptr_type_node,
yann@339
  2950
+  			     CUSTOM_NUM
yann@339
  2951
+  			     def_param (float_type_node)
yann@339
  2952
+  			     endlink)));
yann@339
  2953
+  custom_pnp
yann@339
  2954
+      = build_function_type (ptr_type_node,
yann@339
  2955
+  			     CUSTOM_NUM
yann@339
  2956
+  			     def_param (ptr_type_node)
yann@339
  2957
+  			     endlink)));
yann@339
  2958
+  custom_pnii
yann@339
  2959
+      = build_function_type (ptr_type_node,
yann@339
  2960
+  			     CUSTOM_NUM
yann@339
  2961
+  			     def_param (integer_type_node)
yann@339
  2962
+  			     def_param (integer_type_node)
yann@339
  2963
+  			     endlink))));
yann@339
  2964
+  custom_pnif
yann@339
  2965
+      = build_function_type (ptr_type_node,
yann@339
  2966
+  			     CUSTOM_NUM
yann@339
  2967
+  			     def_param (integer_type_node)
yann@339
  2968
+  			     def_param (float_type_node)
yann@339
  2969
+  			     endlink))));
yann@339
  2970
+  custom_pnip
yann@339
  2971
+      = build_function_type (ptr_type_node,
yann@339
  2972
+  			     CUSTOM_NUM
yann@339
  2973
+  			     def_param (integer_type_node)
yann@339
  2974
+  			     def_param (ptr_type_node)
yann@339
  2975
+  			     endlink))));
yann@339
  2976
+  custom_pnfi
yann@339
  2977
+      = build_function_type (ptr_type_node,
yann@339
  2978
+  			     CUSTOM_NUM
yann@339
  2979
+  			     def_param (float_type_node)
yann@339
  2980
+  			     def_param (integer_type_node)
yann@339
  2981
+  			     endlink))));
yann@339
  2982
+  custom_pnff
yann@339
  2983
+      = build_function_type (ptr_type_node,
yann@339
  2984
+  			     CUSTOM_NUM
yann@339
  2985
+  			     def_param (float_type_node)
yann@339
  2986
+  			     def_param (float_type_node)
yann@339
  2987
+  			     endlink))));
yann@339
  2988
+  custom_pnfp
yann@339
  2989
+      = build_function_type (ptr_type_node,
yann@339
  2990
+  			     CUSTOM_NUM
yann@339
  2991
+  			     def_param (float_type_node)
yann@339
  2992
+  			     def_param (ptr_type_node)
yann@339
  2993
+  			     endlink))));
yann@339
  2994
+  custom_pnpi
yann@339
  2995
+      = build_function_type (ptr_type_node,
yann@339
  2996
+  			     CUSTOM_NUM
yann@339
  2997
+  			     def_param (ptr_type_node)
yann@339
  2998
+  			     def_param (integer_type_node)
yann@339
  2999
+  			     endlink))));
yann@339
  3000
+  custom_pnpf
yann@339
  3001
+      = build_function_type (ptr_type_node,
yann@339
  3002
+  			     CUSTOM_NUM
yann@339
  3003
+  			     def_param (ptr_type_node)
yann@339
  3004
+  			     def_param (float_type_node)
yann@339
  3005
+  			     endlink))));
yann@339
  3006
+  custom_pnpp
yann@339
  3007
+      = build_function_type (ptr_type_node,
yann@339
  3008
+  			     CUSTOM_NUM
yann@339
  3009
+  			     def_param (ptr_type_node)
yann@339
  3010
+  			     def_param (ptr_type_node)
yann@339
  3011
+  			     endlink))));
yann@339
  3012
+
yann@339
  3013
+
yann@339
  3014
+
yann@339
  3015
+  /* *INDENT-ON* */
yann@339
  3016
+
yann@339
  3017
+
yann@339
  3018
+  for (d = bdesc; d->name; d++)
yann@339
  3019
+    {
yann@339
  3020
+      builtin_function (d->name, *d->type, d->code,
yann@339
  3021
+			BUILT_IN_MD, NULL, NULL);
yann@339
  3022
+    }
yann@339
  3023
+}
yann@339
  3024
+
yann@339
  3025
+/* Expand an expression EXP that calls a built-in function,
yann@339
  3026
+   with result going to TARGET if that's convenient
yann@339
  3027
+   (and in mode MODE if that's convenient).
yann@339
  3028
+   SUBTARGET may be used as the target for computing one of EXP's operands.
yann@339
  3029
+   IGNORE is nonzero if the value is to be ignored.  */
yann@339
  3030
+
yann@339
  3031
+static rtx
yann@339
  3032
+nios2_expand_builtin (tree exp, rtx target, rtx subtarget, 
yann@339
  3033
+                      enum machine_mode mode, int ignore)
yann@339
  3034
+{
yann@339
  3035
+  const struct builtin_description *d;
yann@339
  3036
+  tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
yann@339
  3037
+  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
yann@339
  3038
+
yann@339
  3039
+  for (d = bdesc; d->name; d++)
yann@339
  3040
+    if (d->code == fcode)
yann@339
  3041
+      return (d->expander) (d, exp, target, subtarget, mode, ignore);
yann@339
  3042
+
yann@339
  3043
+  /* we should have seen one of the functins we registered */
yann@339
  3044
+  abort ();
yann@339
  3045
+}
yann@339
  3046
+
yann@339
  3047
+static rtx nios2_create_target (const struct builtin_description *, rtx);
yann@339
  3048
+
yann@339
  3049
+
yann@339
  3050
+static rtx
yann@339
  3051
+nios2_create_target (const struct builtin_description *d, rtx target)
yann@339
  3052
+{
yann@339
  3053
+  if (!target
yann@339
  3054
+      || !(*insn_data[d->icode].operand[0].predicate) (target,
yann@339
  3055
+                                                       insn_data[d->icode].operand[0].mode))
yann@339
  3056
+    {
yann@339
  3057
+      target = gen_reg_rtx (insn_data[d->icode].operand[0].mode);
yann@339
  3058
+    }
yann@339
  3059
+
yann@339
  3060
+  return target;
yann@339
  3061
+}
yann@339
  3062
+
yann@339
  3063
+
yann@339
  3064
+static rtx nios2_extract_opcode (const struct builtin_description *, int, tree);
yann@339
  3065
+static rtx nios2_extract_operand (const struct builtin_description *, int, int, tree);
yann@339
  3066
+
yann@339
  3067
+static rtx
yann@339
  3068
+nios2_extract_opcode (const struct builtin_description *d, int op, tree arglist)
yann@339
  3069
+{
yann@339
  3070
+  enum machine_mode mode = insn_data[d->icode].operand[op].mode;
yann@339
  3071
+  tree arg = TREE_VALUE (arglist);
yann@339
  3072
+  rtx opcode = expand_expr (arg, NULL_RTX, mode, 0);
yann@339
  3073
+  opcode = protect_from_queue (opcode, 0);
yann@339
  3074
+
yann@339
  3075
+  if (!(*insn_data[d->icode].operand[op].predicate) (opcode, mode))
yann@339
  3076
+    error ("Custom instruction opcode must be compile time constant in the range 0-255 for %s", d->name);
yann@339
  3077
+
yann@339
  3078
+  return opcode;
yann@339
  3079
+}
yann@339
  3080
+
yann@339
  3081
+static rtx
yann@339
  3082
+nios2_extract_operand (const struct builtin_description *d, int op, int argnum, tree arglist)
yann@339
  3083
+{
yann@339
  3084
+  enum machine_mode mode = insn_data[d->icode].operand[op].mode;
yann@339
  3085
+  tree arg = TREE_VALUE (arglist);
yann@339
  3086
+  rtx operand = expand_expr (arg, NULL_RTX, mode, 0);
yann@339
  3087
+  operand = protect_from_queue (operand, 0);
yann@339
  3088
+
yann@339
  3089
+  if (!(*insn_data[d->icode].operand[op].predicate) (operand, mode))
yann@339
  3090
+    operand = copy_to_mode_reg (mode, operand);
yann@339
  3091
+
yann@339
  3092
+  /* ??? Better errors would be nice */
yann@339
  3093
+  if (!(*insn_data[d->icode].operand[op].predicate) (operand, mode))
yann@339
  3094
+    error ("Invalid argument %d to %s", argnum, d->name);
yann@339
  3095
+
yann@339
  3096
+  return operand;
yann@339
  3097
+}
yann@339
  3098
+
yann@339
  3099
+
yann@339
  3100
+static rtx
yann@339
  3101
+nios2_expand_custom_n (const struct builtin_description *d, tree exp, 
yann@339
  3102
+                       rtx target ATTRIBUTE_UNUSED, rtx subtarget ATTRIBUTE_UNUSED, 
yann@339
  3103
+                       enum machine_mode mode ATTRIBUTE_UNUSED, int ignore ATTRIBUTE_UNUSED)
yann@339
  3104
+{
yann@339
  3105
+  tree arglist = TREE_OPERAND (exp, 1);
yann@339
  3106
+  rtx pat;
yann@339
  3107
+  rtx opcode;
yann@339
  3108
+
yann@339
  3109
+  /* custom_n should have exactly one operand */
yann@339
  3110
+  if (insn_data[d->icode].n_operands != 1)
yann@339
  3111
+    abort ();
yann@339
  3112
+
yann@339
  3113
+  opcode = nios2_extract_opcode (d, 0, arglist);
yann@339
  3114
+
yann@339
  3115
+  pat = GEN_FCN (d->icode) (opcode);
yann@339
  3116
+  if (!pat)
yann@339
  3117
+    return 0;
yann@339
  3118
+  emit_insn (pat);
yann@339
  3119
+  return 0;
yann@339
  3120
+}
yann@339
  3121
+
yann@339
  3122
+static rtx
yann@339
  3123
+nios2_expand_custom_Xn (const struct builtin_description *d, tree exp, 
yann@339
  3124
+                        rtx target, rtx subtarget ATTRIBUTE_UNUSED, 
yann@339
  3125
+                        enum machine_mode mode ATTRIBUTE_UNUSED, 
yann@339
  3126
+                        int ignore ATTRIBUTE_UNUSED)
yann@339
  3127
+{
yann@339
  3128
+  tree arglist = TREE_OPERAND (exp, 1);
yann@339
  3129
+  rtx pat;
yann@339
  3130
+  rtx opcode;
yann@339
  3131
+
yann@339
  3132
+  /* custom_Xn should have exactly two operands */
yann@339
  3133
+  if (insn_data[d->icode].n_operands != 2)
yann@339
  3134
+    abort ();
yann@339
  3135
+
yann@339
  3136
+  target = nios2_create_target (d, target);
yann@339
  3137
+  opcode = nios2_extract_opcode (d, 1, arglist);
yann@339
  3138
+
yann@339
  3139
+  pat = GEN_FCN (d->icode) (target, opcode);
yann@339
  3140
+  if (!pat)
yann@339
  3141
+    return 0;
yann@339
  3142
+  emit_insn (pat);
yann@339
  3143
+  return target;
yann@339
  3144
+}
yann@339
  3145
+
yann@339
  3146
+static rtx
yann@339
  3147
+nios2_expand_custom_nX (const struct builtin_description *d, tree exp, 
yann@339
  3148
+                        rtx target ATTRIBUTE_UNUSED, rtx subtarget ATTRIBUTE_UNUSED, 
yann@339
  3149
+                        enum machine_mode mode ATTRIBUTE_UNUSED, int ignore ATTRIBUTE_UNUSED)
yann@339
  3150
+{
yann@339
  3151
+  tree arglist = TREE_OPERAND (exp, 1);
yann@339
  3152
+  rtx pat;
yann@339
  3153
+  rtx opcode;
yann@339
  3154
+  rtx operands[1];
yann@339
  3155
+  int i;
yann@339
  3156
+
yann@339
  3157
+
yann@339
  3158
+  /* custom_nX should have exactly two operands */
yann@339
  3159
+  if (insn_data[d->icode].n_operands != 2)
yann@339
  3160
+    abort ();
yann@339
  3161
+
yann@339
  3162
+  opcode = nios2_extract_opcode (d, 0, arglist);
yann@339
  3163
+  for (i = 0; i < 1; i++)
yann@339
  3164
+    {
yann@339
  3165
+      arglist = TREE_CHAIN (arglist);
yann@339
  3166
+      operands[i] = nios2_extract_operand (d, i + 1, i + 1, arglist);
yann@339
  3167
+    }
yann@339
  3168
+
yann@339
  3169
+  pat = GEN_FCN (d->icode) (opcode, operands[0]);
yann@339
  3170
+  if (!pat)
yann@339
  3171
+    return 0;
yann@339
  3172
+  emit_insn (pat);
yann@339
  3173
+  return 0;
yann@339
  3174
+}
yann@339
  3175
+
yann@339
  3176
+static rtx
yann@339
  3177
+nios2_expand_custom_XnX (const struct builtin_description *d, tree exp, rtx target, 
yann@339
  3178
+                         rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, 
yann@339
  3179
+                         int ignore ATTRIBUTE_UNUSED)
yann@339
  3180
+{
yann@339
  3181
+  tree arglist = TREE_OPERAND (exp, 1);
yann@339
  3182
+  rtx pat;
yann@339
  3183
+  rtx opcode;
yann@339
  3184
+  rtx operands[1];
yann@339
  3185
+  int i;
yann@339
  3186
+
yann@339
  3187
+  /* custom_Xn should have exactly three operands */
yann@339
  3188
+  if (insn_data[d->icode].n_operands != 3)
yann@339
  3189
+    abort ();
yann@339
  3190
+
yann@339
  3191
+  target = nios2_create_target (d, target);
yann@339
  3192
+  opcode = nios2_extract_opcode (d, 1, arglist);
yann@339
  3193
+
yann@339
  3194
+  for (i = 0; i < 1; i++)
yann@339
  3195
+    {
yann@339
  3196
+      arglist = TREE_CHAIN (arglist);
yann@339
  3197
+      operands[i] = nios2_extract_operand (d, i + 2, i + 1, arglist);
yann@339
  3198
+    }
yann@339
  3199
+
yann@339
  3200
+  pat = GEN_FCN (d->icode) (target, opcode, operands[0]);
yann@339
  3201
+
yann@339
  3202
+  if (!pat)
yann@339
  3203
+    return 0;
yann@339
  3204
+  emit_insn (pat);
yann@339
  3205
+  return target;
yann@339
  3206
+}
yann@339
  3207
+
yann@339
  3208
+static rtx
yann@339
  3209
+nios2_expand_custom_nXX (const struct builtin_description *d, tree exp, rtx target ATTRIBUTE_UNUSED, 
yann@339
  3210
+                         rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, 
yann@339
  3211
+                         int ignore ATTRIBUTE_UNUSED)
yann@339
  3212
+{
yann@339
  3213
+  tree arglist = TREE_OPERAND (exp, 1);
yann@339
  3214
+  rtx pat;
yann@339
  3215
+  rtx opcode;
yann@339
  3216
+  rtx operands[2];
yann@339
  3217
+  int i;
yann@339
  3218
+
yann@339
  3219
+
yann@339
  3220
+  /* custom_nX should have exactly three operands */
yann@339
  3221
+  if (insn_data[d->icode].n_operands != 3)
yann@339
  3222
+    abort ();
yann@339
  3223
+
yann@339
  3224
+  opcode = nios2_extract_opcode (d, 0, arglist);
yann@339
  3225
+  for (i = 0; i < 2; i++)
yann@339
  3226
+    {
yann@339
  3227
+      arglist = TREE_CHAIN (arglist);
yann@339
  3228
+      operands[i] = nios2_extract_operand (d, i + 1, i + 1, arglist);
yann@339
  3229
+    }
yann@339
  3230
+
yann@339
  3231
+  pat = GEN_FCN (d->icode) (opcode, operands[0], operands[1]);
yann@339
  3232
+  if (!pat)
yann@339
  3233
+    return 0;
yann@339
  3234
+  emit_insn (pat);
yann@339
  3235
+  return 0;
yann@339
  3236
+}
yann@339
  3237
+
yann@339
  3238
+static rtx
yann@339
  3239
+nios2_expand_custom_XnXX (const struct builtin_description *d, tree exp, rtx target, 
yann@339
  3240
+                          rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, 
yann@339
  3241
+                          int ignore ATTRIBUTE_UNUSED)
yann@339
  3242
+{
yann@339
  3243
+  tree arglist = TREE_OPERAND (exp, 1);
yann@339
  3244
+  rtx pat;
yann@339
  3245
+  rtx opcode;
yann@339
  3246
+  rtx operands[2];
yann@339
  3247
+  int i;
yann@339
  3248
+
yann@339
  3249
+
yann@339
  3250
+  /* custom_XnX should have exactly four operands */
yann@339
  3251
+  if (insn_data[d->icode].n_operands != 4)
yann@339
  3252
+    abort ();
yann@339
  3253
+
yann@339
  3254
+  target = nios2_create_target (d, target);
yann@339
  3255
+  opcode = nios2_extract_opcode (d, 1, arglist);
yann@339
  3256
+  for (i = 0; i < 2; i++)
yann@339
  3257
+    {
yann@339
  3258
+      arglist = TREE_CHAIN (arglist);
yann@339
  3259
+      operands[i] = nios2_extract_operand (d, i + 2, i + 1, arglist);
yann@339
  3260
+    }
yann@339
  3261
+
yann@339
  3262
+  pat = GEN_FCN (d->icode) (target, opcode, operands[0], operands[1]);
yann@339
  3263
+
yann@339
  3264
+  if (!pat)
yann@339
  3265
+    return 0;
yann@339
  3266
+  emit_insn (pat);
yann@339
  3267
+  return target;
yann@339
  3268
+}
yann@339
  3269
+
yann@339
  3270
+
yann@339
  3271
+
yann@339
  3272
+static rtx
yann@339
  3273
+nios2_expand_STXIO (const struct builtin_description *d, tree exp, rtx target ATTRIBUTE_UNUSED, 
yann@339
  3274
+                    rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, 
yann@339
  3275
+                    int ignore ATTRIBUTE_UNUSED)
yann@339
  3276
+{
yann@339
  3277
+  tree arglist = TREE_OPERAND (exp, 1);
yann@339
  3278
+  rtx pat;
yann@339
  3279
+  rtx store_dest, store_val;
yann@339
  3280
+  enum insn_code icode = d->icode;
yann@339
  3281
+
yann@339
  3282
+  /* stores should have exactly two operands */
yann@339
  3283
+  if (insn_data[icode].n_operands != 2)
yann@339
  3284
+    abort ();
yann@339
  3285
+
yann@339
  3286
+  /* process the destination of the store */
yann@339
  3287
+  {
yann@339
  3288
+    enum machine_mode mode = insn_data[icode].operand[0].mode;
yann@339
  3289
+    tree arg = TREE_VALUE (arglist);
yann@339
  3290
+    store_dest = expand_expr (arg, NULL_RTX, VOIDmode, 0);
yann@339
  3291
+    store_dest = protect_from_queue (store_dest, 0);
yann@339
  3292
+
yann@339
  3293
+    store_dest = gen_rtx_MEM (mode, copy_to_mode_reg (Pmode, store_dest));
yann@339
  3294
+
yann@339
  3295
+    /* ??? Better errors would be nice */
yann@339
  3296
+    if (!(*insn_data[icode].operand[0].predicate) (store_dest, mode))
yann@339
  3297
+      error ("Invalid argument 1 to %s", d->name);
yann@339
  3298
+  }
yann@339
  3299
+
yann@339
  3300
+
yann@339
  3301
+  /* process the value to store */
yann@339
  3302
+  {
yann@339
  3303
+    enum machine_mode mode = insn_data[icode].operand[1].mode;
yann@339
  3304
+    tree arg = TREE_VALUE (TREE_CHAIN (arglist));
yann@339
  3305
+    store_val = expand_expr (arg, NULL_RTX, mode, 0);
yann@339
  3306
+    store_val = protect_from_queue (store_val, 0);
yann@339
  3307
+
yann@339
  3308
+    if (!(*insn_data[icode].operand[1].predicate) (store_val, mode))
yann@339
  3309
+      store_val = copy_to_mode_reg (mode, store_val);
yann@339
  3310
+
yann@339
  3311
+    /* ??? Better errors would be nice */
yann@339
  3312
+    if (!(*insn_data[icode].operand[1].predicate) (store_val, mode))
yann@339
  3313
+      error ("Invalid argument 2 to %s", d->name);
yann@339
  3314
+  }
yann@339
  3315
+
yann@339
  3316
+  pat = GEN_FCN (d->icode) (store_dest, store_val);
yann@339
  3317
+  if (!pat)
yann@339
  3318
+    return 0;
yann@339
  3319
+  emit_insn (pat);
yann@339
  3320
+  return 0;
yann@339
  3321
+}
yann@339
  3322
+
yann@339
  3323
+
yann@339
  3324
+static rtx
yann@339
  3325
+nios2_expand_LDXIO (const struct builtin_description * d, tree exp, rtx target, 
yann@339
  3326
+                    rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, 
yann@339
  3327
+                    int ignore ATTRIBUTE_UNUSED)
yann@339
  3328
+{
yann@339
  3329
+  tree arglist = TREE_OPERAND (exp, 1);
yann@339
  3330
+  rtx pat;
yann@339
  3331
+  rtx ld_src;
yann@339
  3332
+  enum insn_code icode = d->icode;
yann@339
  3333
+
yann@339
  3334
+  /* loads should have exactly two operands */
yann@339
  3335
+  if (insn_data[icode].n_operands != 2)
yann@339
  3336
+    abort ();
yann@339
  3337
+
yann@339
  3338
+  target = nios2_create_target (d, target);
yann@339
  3339
+
yann@339
  3340
+  {
yann@339
  3341
+    enum machine_mode mode = insn_data[icode].operand[1].mode;
yann@339
  3342
+    tree arg = TREE_VALUE (arglist);
yann@339
  3343
+    ld_src = expand_expr (arg, NULL_RTX, VOIDmode, 0);
yann@339
  3344
+    ld_src = protect_from_queue (ld_src, 0);
yann@339
  3345
+
yann@339
  3346
+    ld_src = gen_rtx_MEM (mode, copy_to_mode_reg (Pmode, ld_src));
yann@339
  3347
+
yann@339
  3348
+    /* ??? Better errors would be nice */
yann@339
  3349
+    if (!(*insn_data[icode].operand[1].predicate) (ld_src, mode))
yann@339
  3350
+      {
yann@339
  3351
+        error ("Invalid argument 1 to %s", d->name);
yann@339
  3352
+      }
yann@339
  3353
+  }
yann@339
  3354
+
yann@339
  3355
+  pat = GEN_FCN (d->icode) (target, ld_src);
yann@339
  3356
+  if (!pat)
yann@339
  3357
+    return 0;
yann@339
  3358
+  emit_insn (pat);
yann@339
  3359
+  return target;
yann@339
  3360
+}
yann@339
  3361
+
yann@339
  3362
+
yann@339
  3363
+static rtx
yann@339
  3364
+nios2_expand_sync (const struct builtin_description * d ATTRIBUTE_UNUSED, 
yann@339
  3365
+                   tree exp ATTRIBUTE_UNUSED, rtx target ATTRIBUTE_UNUSED, 
yann@339
  3366
+                   rtx subtarget ATTRIBUTE_UNUSED, 
yann@339
  3367
+                   enum machine_mode mode ATTRIBUTE_UNUSED, 
yann@339
  3368
+                   int ignore ATTRIBUTE_UNUSED)
yann@339
  3369
+{
yann@339
  3370
+  emit_insn (gen_sync ());
yann@339
  3371
+  return 0;
yann@339
  3372
+}
yann@339
  3373
+
yann@339
  3374
+static rtx
yann@339
  3375
+nios2_expand_rdctl (const struct builtin_description * d ATTRIBUTE_UNUSED, 
yann@339
  3376
+                   tree exp ATTRIBUTE_UNUSED, rtx target ATTRIBUTE_UNUSED, 
yann@339
  3377
+                   rtx subtarget ATTRIBUTE_UNUSED, 
yann@339
  3378
+                   enum machine_mode mode ATTRIBUTE_UNUSED, 
yann@339
  3379
+                   int ignore ATTRIBUTE_UNUSED)
yann@339
  3380
+{
yann@339
  3381
+  tree arglist = TREE_OPERAND (exp, 1);
yann@339
  3382
+  rtx pat;
yann@339
  3383
+  rtx rdctl_reg;
yann@339
  3384
+  enum insn_code icode = d->icode;
yann@339
  3385
+
yann@339
  3386
+  /* rdctl should have exactly two operands */
yann@339
  3387
+  if (insn_data[icode].n_operands != 2)
yann@339
  3388
+    abort ();
yann@339
  3389
+
yann@339
  3390
+  target = nios2_create_target (d, target);
yann@339
  3391
+
yann@339
  3392
+  {
yann@339
  3393
+    enum machine_mode mode = insn_data[icode].operand[1].mode;
yann@339
  3394
+    tree arg = TREE_VALUE (arglist);
yann@339
  3395
+    rdctl_reg = expand_expr (arg, NULL_RTX, VOIDmode, 0);
yann@339
  3396
+    rdctl_reg = protect_from_queue (rdctl_reg, 0);
yann@339
  3397
+
yann@339
  3398
+    if (!(*insn_data[icode].operand[1].predicate) (rdctl_reg, mode))
yann@339
  3399
+      {
yann@339
  3400
+        error ("Control register number must be in range 0-31 for %s", d->name);
yann@339
  3401
+      }
yann@339
  3402
+  }
yann@339
  3403
+
yann@339
  3404
+  pat = GEN_FCN (d->icode) (target, rdctl_reg);
yann@339
  3405
+  if (!pat)
yann@339
  3406
+    return 0;
yann@339
  3407
+  emit_insn (pat);
yann@339
  3408
+  return target;
yann@339
  3409
+}
yann@339
  3410
+
yann@339
  3411
+static rtx
yann@339
  3412
+nios2_expand_wrctl (const struct builtin_description * d ATTRIBUTE_UNUSED, 
yann@339
  3413
+                   tree exp ATTRIBUTE_UNUSED, rtx target ATTRIBUTE_UNUSED, 
yann@339
  3414
+                   rtx subtarget ATTRIBUTE_UNUSED, 
yann@339
  3415
+                   enum machine_mode mode ATTRIBUTE_UNUSED, 
yann@339
  3416
+                   int ignore ATTRIBUTE_UNUSED)
yann@339
  3417
+{
yann@339
  3418
+  tree arglist = TREE_OPERAND (exp, 1);
yann@339
  3419
+  rtx pat;
yann@339
  3420
+  rtx wrctl_reg, store_val;
yann@339
  3421
+  enum insn_code icode = d->icode;
yann@339
  3422
+
yann@339
  3423
+  /* stores should have exactly two operands */
yann@339
  3424
+  if (insn_data[icode].n_operands != 2)
yann@339
  3425
+    abort ();
yann@339
  3426
+
yann@339
  3427
+  /* process the destination of the store */
yann@339
  3428
+  {
yann@339
  3429
+    enum machine_mode mode = insn_data[icode].operand[0].mode;
yann@339
  3430
+    tree arg = TREE_VALUE (arglist);
yann@339
  3431
+    wrctl_reg = expand_expr (arg, NULL_RTX, VOIDmode, 0);
yann@339
  3432
+    wrctl_reg = protect_from_queue (wrctl_reg, 0);
yann@339
  3433
+
yann@339
  3434
+    if (!(*insn_data[icode].operand[0].predicate) (wrctl_reg, mode))
yann@339
  3435
+      error ("Control register number must be in range 0-31 for %s", d->name);
yann@339
  3436
+  }
yann@339
  3437
+
yann@339
  3438
+
yann@339
  3439
+  /* process the value to store */
yann@339
  3440
+  {
yann@339
  3441
+    enum machine_mode mode = insn_data[icode].operand[1].mode;
yann@339
  3442
+    tree arg = TREE_VALUE (TREE_CHAIN (arglist));
yann@339
  3443
+    store_val = expand_expr (arg, NULL_RTX, mode, 0);
yann@339
  3444
+    store_val = protect_from_queue (store_val, 0);
yann@339
  3445
+
yann@339
  3446
+    if (!(*insn_data[icode].operand[1].predicate) (store_val, mode))
yann@339
  3447
+      store_val = copy_to_mode_reg (mode, store_val);
yann@339
  3448
+
yann@339
  3449
+    /* ??? Better errors would be nice */
yann@339
  3450
+    if (!(*insn_data[icode].operand[1].predicate) (store_val, mode))
yann@339
  3451
+      error ("Invalid argument 2 to %s", d->name);
yann@339
  3452
+  }
yann@339
  3453
+
yann@339
  3454
+  pat = GEN_FCN (d->icode) (wrctl_reg, store_val);
yann@339
  3455
+  if (!pat)
yann@339
  3456
+    return 0;
yann@339
  3457
+  emit_insn (pat);
yann@339
  3458
+  return 0;
yann@339
  3459
+}
yann@339
  3460
+
yann@339
  3461
+
yann@339
  3462
+#include "gt-nios2.h"
yann@339
  3463
+
yann@339
  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
yann@339
  3465
--- gcc-3.4.6.orig/gcc/config/nios2/nios2-dp-bit.c	1970-01-01 01:00:00.000000000 +0100
yann@339
  3466
+++ gcc-3.4.6/gcc/config/nios2/nios2-dp-bit.c	2007-08-15 23:09:36.000000000 +0200
yann@339
  3467
@@ -0,0 +1,1652 @@
yann@339
  3468
+
yann@339
  3469
+/* This is a software floating point library which can be used
yann@339
  3470
+   for targets without hardware floating point. 
yann@339
  3471
+   Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004
yann@339
  3472
+   Free Software Foundation, Inc.
yann@339
  3473
+
yann@339
  3474
+This file is free software; you can redistribute it and/or modify it
yann@339
  3475
+under the terms of the GNU General Public License as published by the
yann@339
  3476
+Free Software Foundation; either version 2, or (at your option) any
yann@339
  3477
+later version.
yann@339
  3478
+
yann@339
  3479
+In addition to the permissions in the GNU General Public License, the
yann@339
  3480
+Free Software Foundation gives you unlimited permission to link the
yann@339
  3481
+compiled version of this file with other programs, and to distribute
yann@339
  3482
+those programs without any restriction coming from the use of this
yann@339
  3483
+file.  (The General Public License restrictions do apply in other
yann@339
  3484
+respects; for example, they cover modification of the file, and
yann@339
  3485
+distribution when not linked into another program.)
yann@339
  3486
+
yann@339
  3487
+This file is distributed in the hope that it will be useful, but
yann@339
  3488
+WITHOUT ANY WARRANTY; without even the implied warranty of
yann@339
  3489
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
yann@339
  3490
+General Public License for more details.
yann@339
  3491
+
yann@339
  3492
+You should have received a copy of the GNU General Public License
yann@339
  3493
+along with this program; see the file COPYING.  If not, write to
yann@339
  3494
+the Free Software Foundation, 59 Temple Place - Suite 330,
yann@339
  3495
+Boston, MA 02111-1307, USA.  */
yann@339
  3496
+
yann@339
  3497
+/* As a special exception, if you link this library with other files,
yann@339
  3498
+   some of which are compiled with GCC, to produce an executable,
yann@339
  3499
+   this library does not by itself cause the resulting executable
yann@339
  3500
+   to be covered by the GNU General Public License.
yann@339
  3501
+   This exception does not however invalidate any other reasons why
yann@339
  3502
+   the executable file might be covered by the GNU General Public License.  */
yann@339
  3503
+
yann@339
  3504
+/* This implements IEEE 754 format arithmetic, but does not provide a
yann@339
  3505
+   mechanism for setting the rounding mode, or for generating or handling
yann@339
  3506
+   exceptions.
yann@339
  3507
+
yann@339
  3508
+   The original code by Steve Chamberlain, hacked by Mark Eichin and Jim
yann@339
  3509
+   Wilson, all of Cygnus Support.  */
yann@339
  3510
+
yann@339
  3511
+/* The intended way to use this file is to make two copies, add `#define FLOAT'
yann@339
  3512
+   to one copy, then compile both copies and add them to libgcc.a.  */
yann@339
  3513
+
yann@339
  3514
+#include "tconfig.h"
yann@339
  3515
+#include "coretypes.h"
yann@339
  3516
+#include "tm.h"
yann@339
  3517
+#include "config/fp-bit.h"
yann@339
  3518
+
yann@339
  3519
+/* The following macros can be defined to change the behavior of this file:
yann@339
  3520
+   FLOAT: Implement a `float', aka SFmode, fp library.  If this is not
yann@339
  3521
+     defined, then this file implements a `double', aka DFmode, fp library.
yann@339
  3522
+   FLOAT_ONLY: Used with FLOAT, to implement a `float' only library, i.e.
yann@339
  3523
+     don't include float->double conversion which requires the double library.
yann@339
  3524
+     This is useful only for machines which can't support doubles, e.g. some
yann@339
  3525
+     8-bit processors.
yann@339
  3526
+   CMPtype: Specify the type that floating point compares should return.
yann@339
  3527
+     This defaults to SItype, aka int.
yann@339
  3528
+   US_SOFTWARE_GOFAST: This makes all entry points use the same names as the
yann@339
  3529
+     US Software goFast library.
yann@339
  3530
+   _DEBUG_BITFLOAT: This makes debugging the code a little easier, by adding
yann@339
  3531
+     two integers to the FLO_union_type.
yann@339
  3532
+   NO_DENORMALS: Disable handling of denormals.
yann@339
  3533
+   NO_NANS: Disable nan and infinity handling
yann@339
  3534
+   SMALL_MACHINE: Useful when operations on QIs and HIs are faster
yann@339
  3535
+     than on an SI */
yann@339
  3536
+
yann@339
  3537
+/* We don't currently support extended floats (long doubles) on machines
yann@339
  3538
+   without hardware to deal with them.
yann@339
  3539
+
yann@339
  3540
+   These stubs are just to keep the linker from complaining about unresolved
yann@339
  3541
+   references which can be pulled in from libio & libstdc++, even if the
yann@339
  3542
+   user isn't using long doubles.  However, they may generate an unresolved
yann@339
  3543
+   external to abort if abort is not used by the function, and the stubs
yann@339
  3544
+   are referenced from within libc, since libgcc goes before and after the
yann@339
  3545
+   system library.  */
yann@339
  3546
+
yann@339
  3547
+#ifdef DECLARE_LIBRARY_RENAMES
yann@339
  3548
+  DECLARE_LIBRARY_RENAMES
yann@339
  3549
+#endif
yann@339
  3550
+
yann@339
  3551
+#ifdef EXTENDED_FLOAT_STUBS
yann@339
  3552
+extern void abort (void);
yann@339
  3553
+void __extendsfxf2 (void) { abort(); }
yann@339
  3554
+void __extenddfxf2 (void) { abort(); }
yann@339
  3555
+void __truncxfdf2 (void) { abort(); }
yann@339
  3556
+void __truncxfsf2 (void) { abort(); }
yann@339
  3557
+void __fixxfsi (void) { abort(); }
yann@339
  3558
+void __floatsixf (void) { abort(); }
yann@339
  3559
+void __addxf3 (void) { abort(); }
yann@339
  3560
+void __subxf3 (void) { abort(); }
yann@339
  3561
+void __mulxf3 (void) { abort(); }
yann@339
  3562
+void __divxf3 (void) { abort(); }
yann@339
  3563
+void __negxf2 (void) { abort(); }
yann@339
  3564
+void __eqxf2 (void) { abort(); }
yann@339
  3565
+void __nexf2 (void) { abort(); }
yann@339
  3566
+void __gtxf2 (void) { abort(); }
yann@339
  3567
+void __gexf2 (void) { abort(); }
yann@339
  3568
+void __lexf2 (void) { abort(); }
yann@339
  3569
+void __ltxf2 (void) { abort(); }
yann@339
  3570
+
yann@339
  3571
+void __extendsftf2 (void) { abort(); }
yann@339
  3572
+void __extenddftf2 (void) { abort(); }
yann@339
  3573
+void __trunctfdf2 (void) { abort(); }
yann@339
  3574
+void __trunctfsf2 (void) { abort(); }
yann@339
  3575
+void __fixtfsi (void) { abort(); }
yann@339
  3576
+void __floatsitf (void) { abort(); }
yann@339
  3577
+void __addtf3 (void) { abort(); }
yann@339
  3578
+void __subtf3 (void) { abort(); }
yann@339
  3579
+void __multf3 (void) { abort(); }
yann@339
  3580
+void __divtf3 (void) { abort(); }
yann@339
  3581
+void __negtf2 (void) { abort(); }
yann@339
  3582
+void __eqtf2 (void) { abort(); }
yann@339
  3583
+void __netf2 (void) { abort(); }
yann@339
  3584
+void __gttf2 (void) { abort(); }
yann@339
  3585
+void __getf2 (void) { abort(); }
yann@339
  3586
+void __letf2 (void) { abort(); }
yann@339
  3587
+void __lttf2 (void) { abort(); }
yann@339
  3588
+#else	/* !EXTENDED_FLOAT_STUBS, rest of file */
yann@339
  3589
+
yann@339
  3590
+/* IEEE "special" number predicates */
yann@339
  3591
+
yann@339
  3592
+#ifdef NO_NANS
yann@339
  3593
+
yann@339
  3594
+#define nan() 0
yann@339
  3595
+#define isnan(x) 0
yann@339
  3596
+#define isinf(x) 0
yann@339
  3597
+#else
yann@339
  3598
+
yann@339
  3599
+#if   defined L_thenan_sf
yann@339
  3600
+const fp_number_type __thenan_sf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
yann@339
  3601
+#elif defined L_thenan_df
yann@339
  3602
+const fp_number_type __thenan_df = { CLASS_SNAN, 0, 0, {(fractype) 0} };
yann@339
  3603
+#elif defined L_thenan_tf
yann@339
  3604
+const fp_number_type __thenan_tf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
yann@339
  3605
+#elif defined TFLOAT
yann@339
  3606
+extern const fp_number_type __thenan_tf;
yann@339
  3607
+#elif defined FLOAT
yann@339
  3608
+extern const fp_number_type __thenan_sf;
yann@339
  3609
+#else
yann@339
  3610
+extern const fp_number_type __thenan_df;
yann@339
  3611
+#endif
yann@339
  3612
+
yann@339
  3613
+INLINE
yann@339
  3614
+static fp_number_type *
yann@339
  3615
+nan (void)
yann@339
  3616
+{
yann@339
  3617
+  /* Discard the const qualifier...  */
yann@339
  3618
+#ifdef TFLOAT
yann@339
  3619
+  return (fp_number_type *) (& __thenan_tf);
yann@339
  3620
+#elif defined FLOAT  
yann@339
  3621
+  return (fp_number_type *) (& __thenan_sf);
yann@339
  3622
+#else
yann@339
  3623
+  return (fp_number_type *) (& __thenan_df);
yann@339
  3624
+#endif
yann@339
  3625
+}
yann@339
  3626
+
yann@339
  3627
+INLINE
yann@339
  3628
+static int
yann@339
  3629
+isnan ( fp_number_type *  x)
yann@339
  3630
+{
yann@339
  3631
+  return x->class == CLASS_SNAN || x->class == CLASS_QNAN;
yann@339
  3632
+}
yann@339
  3633
+
yann@339
  3634
+INLINE
yann@339
  3635
+static int
yann@339
  3636
+isinf ( fp_number_type *  x)
yann@339
  3637
+{
yann@339
  3638
+  return x->class == CLASS_INFINITY;
yann@339
  3639
+}
yann@339
  3640
+
yann@339
  3641
+#endif /* NO_NANS */
yann@339
  3642
+
yann@339
  3643
+INLINE
yann@339
  3644
+static int
yann@339
  3645
+iszero ( fp_number_type *  x)
yann@339
  3646
+{
yann@339
  3647
+  return x->class == CLASS_ZERO;
yann@339
  3648
+}
yann@339
  3649
+
yann@339
  3650
+INLINE 
yann@339
  3651
+static void
yann@339
  3652
+flip_sign ( fp_number_type *  x)
yann@339
  3653
+{
yann@339
  3654
+  x->sign = !x->sign;
yann@339
  3655
+}
yann@339
  3656
+
yann@339
  3657
+extern FLO_type pack_d ( fp_number_type * );
yann@339
  3658
+
yann@339
  3659
+#if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf)
yann@339
  3660
+FLO_type
yann@339
  3661
+pack_d ( fp_number_type *  src)
yann@339
  3662
+{
yann@339
  3663
+  FLO_union_type dst;
yann@339
  3664
+  fractype fraction = src->fraction.ll;	/* wasn't unsigned before? */
yann@339
  3665
+  int sign = src->sign;
yann@339
  3666
+  int exp = 0;
yann@339
  3667
+
yann@339
  3668
+  if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && (isnan (src) || isinf (src)))
yann@339
  3669
+    {
yann@339
  3670
+      /* We can't represent these values accurately.  By using the
yann@339
  3671
+	 largest possible magnitude, we guarantee that the conversion
yann@339
  3672
+	 of infinity is at least as big as any finite number.  */
yann@339
  3673
+      exp = EXPMAX;
yann@339
  3674
+      fraction = ((fractype) 1 << FRACBITS) - 1;
yann@339
  3675
+    }
yann@339
  3676
+  else if (isnan (src))
yann@339
  3677
+    {
yann@339
  3678
+      exp = EXPMAX;
yann@339
  3679
+      if (src->class == CLASS_QNAN || 1)
yann@339
  3680
+	{
yann@339
  3681
+#ifdef QUIET_NAN_NEGATED
yann@339
  3682
+	  fraction |= QUIET_NAN - 1;
yann@339
  3683
+#else
yann@339
  3684
+	  fraction |= QUIET_NAN;
yann@339
  3685
+#endif
yann@339
  3686
+	}
yann@339
  3687
+    }
yann@339
  3688
+  else if (isinf (src))
yann@339
  3689
+    {
yann@339
  3690
+      exp = EXPMAX;
yann@339
  3691
+      fraction = 0;
yann@339
  3692
+    }
yann@339
  3693
+  else if (iszero (src))
yann@339
  3694
+    {
yann@339
  3695
+      exp = 0;
yann@339
  3696
+      fraction = 0;
yann@339
  3697
+    }
yann@339
  3698
+  else if (fraction == 0)
yann@339
  3699
+    {
yann@339
  3700
+      exp = 0;
yann@339
  3701
+    }
yann@339
  3702
+  else
yann@339
  3703
+    {
yann@339
  3704
+      if (src->normal_exp < NORMAL_EXPMIN)
yann@339
  3705
+	{
yann@339
  3706
+#ifdef NO_DENORMALS
yann@339
  3707
+	  /* Go straight to a zero representation if denormals are not
yann@339
  3708
+ 	     supported.  The denormal handling would be harmless but
yann@339
  3709
+ 	     isn't unnecessary.  */
yann@339
  3710
+	  exp = 0;
yann@339
  3711
+	  fraction = 0;
yann@339
  3712
+#else /* NO_DENORMALS */
yann@339
  3713
+	  /* This number's exponent is too low to fit into the bits
yann@339
  3714
+	     available in the number, so we'll store 0 in the exponent and
yann@339
  3715
+	     shift the fraction to the right to make up for it.  */
yann@339
  3716
+
yann@339
  3717
+	  int shift = NORMAL_EXPMIN - src->normal_exp;
yann@339
  3718
+
yann@339
  3719
+	  exp = 0;
yann@339
  3720
+
yann@339
  3721
+	  if (shift > FRAC_NBITS - NGARDS)
yann@339
  3722
+	    {
yann@339
  3723
+	      /* No point shifting, since it's more that 64 out.  */
yann@339
  3724
+	      fraction = 0;
yann@339
  3725
+	    }
yann@339
  3726
+	  else
yann@339
  3727
+	    {
yann@339
  3728
+	      int lowbit = (fraction & (((fractype)1 << shift) - 1)) ? 1 : 0;
yann@339
  3729
+	      fraction = (fraction >> shift) | lowbit;
yann@339
  3730
+	    }
yann@339
  3731
+	  if ((fraction & GARDMASK) == GARDMSB)
yann@339
  3732
+	    {
yann@339
  3733
+	      if ((fraction & (1 << NGARDS)))
yann@339
  3734
+		fraction += GARDROUND + 1;
yann@339
  3735
+	    }
yann@339
  3736
+	  else
yann@339
  3737
+	    {
yann@339
  3738
+	      /* Add to the guards to round up.  */
yann@339
  3739
+	      fraction += GARDROUND;
yann@339
  3740
+	    }
yann@339
  3741
+	  /* Perhaps the rounding means we now need to change the
yann@339
  3742
+             exponent, because the fraction is no longer denormal.  */
yann@339
  3743
+	  if (fraction >= IMPLICIT_1)
yann@339
  3744
+	    {
yann@339
  3745
+	      exp += 1;
yann@339
  3746
+	    }
yann@339
  3747
+	  fraction >>= NGARDS;
yann@339
  3748
+#endif /* NO_DENORMALS */
yann@339
  3749
+	}
yann@339
  3750
+      else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS)
yann@339
  3751
+	       && src->normal_exp > EXPBIAS)
yann@339
  3752
+	{
yann@339
  3753
+	  exp = EXPMAX;
yann@339
  3754
+	  fraction = 0;
yann@339
  3755
+	}
yann@339
  3756
+      else
yann@339
  3757
+	{
yann@339
  3758
+	  exp = src->normal_exp + EXPBIAS;
yann@339
  3759
+	  if (!ROUND_TOWARDS_ZERO)
yann@339
  3760
+	    {
yann@339
  3761
+	      /* IF the gard bits are the all zero, but the first, then we're
yann@339
  3762
+		 half way between two numbers, choose the one which makes the
yann@339
  3763
+		 lsb of the answer 0.  */
yann@339
  3764
+	      if ((fraction & GARDMASK) == GARDMSB)
yann@339
  3765
+		{
yann@339
  3766
+		  if (fraction & (1 << NGARDS))
yann@339
  3767
+		    fraction += GARDROUND + 1;
yann@339
  3768
+		}
yann@339
  3769
+	      else
yann@339
  3770
+		{
yann@339
  3771
+		  /* Add a one to the guards to round up */
yann@339
  3772
+		  fraction += GARDROUND;
yann@339
  3773
+		}
yann@339
  3774
+	      if (fraction >= IMPLICIT_2)
yann@339
  3775
+		{
yann@339
  3776
+		  fraction >>= 1;
yann@339
  3777
+		  exp += 1;
yann@339
  3778
+		}
yann@339
  3779
+	    }
yann@339
  3780
+	  fraction >>= NGARDS;
yann@339
  3781
+
yann@339
  3782
+	  if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp > EXPMAX)
yann@339
  3783
+	    {
yann@339
  3784
+	      /* Saturate on overflow.  */
yann@339
  3785
+	      exp = EXPMAX;
yann@339
  3786
+	      fraction = ((fractype) 1 << FRACBITS) - 1;
yann@339
  3787
+	    }
yann@339
  3788
+	}
yann@339
  3789
+    }
yann@339
  3790
+
yann@339
  3791
+  /* We previously used bitfields to store the number, but this doesn't
yann@339
  3792
+     handle little/big endian systems conveniently, so use shifts and
yann@339
  3793
+     masks */
yann@339
  3794
+#ifdef FLOAT_BIT_ORDER_MISMATCH
yann@339
  3795
+  dst.bits.fraction = fraction;
yann@339
  3796
+  dst.bits.exp = exp;
yann@339
  3797
+  dst.bits.sign = sign;
yann@339
  3798
+#else
yann@339
  3799
+# if defined TFLOAT && defined HALFFRACBITS
yann@339
  3800
+ {
yann@339
  3801
+   halffractype high, low, unity;
yann@339
  3802
+   int lowsign, lowexp;
yann@339
  3803
+
yann@339
  3804
+   unity = (halffractype) 1 << HALFFRACBITS;
yann@339
  3805
+
yann@339
  3806
+   /* Set HIGH to the high double's significand, masking out the implicit 1.
yann@339
  3807
+      Set LOW to the low double's full significand.  */
yann@339
  3808
+   high = (fraction >> (FRACBITS - HALFFRACBITS)) & (unity - 1);
yann@339
  3809
+   low = fraction & (unity * 2 - 1);
yann@339
  3810
+
yann@339
  3811
+   /* Get the initial sign and exponent of the low double.  */
yann@339
  3812
+   lowexp = exp - HALFFRACBITS - 1;
yann@339
  3813
+   lowsign = sign;
yann@339
  3814
+
yann@339
  3815
+   /* HIGH should be rounded like a normal double, making |LOW| <=
yann@339
  3816
+      0.5 ULP of HIGH.  Assume round-to-nearest.  */
yann@339
  3817
+   if (exp < EXPMAX)
yann@339
  3818
+     if (low > unity || (low == unity && (high & 1) == 1))
yann@339
  3819
+       {
yann@339
  3820
+	 /* Round HIGH up and adjust LOW to match.  */
yann@339
  3821
+	 high++;
yann@339
  3822
+	 if (high == unity)
yann@339
  3823
+	   {
yann@339
  3824
+	     /* May make it infinite, but that's OK.  */
yann@339
  3825
+	     high = 0;
yann@339
  3826
+	     exp++;
yann@339
  3827
+	   }
yann@339
  3828
+	 low = unity * 2 - low;
yann@339
  3829
+	 lowsign ^= 1;
yann@339
  3830
+       }
yann@339
  3831
+
yann@339
  3832
+   high |= (halffractype) exp << HALFFRACBITS;
yann@339
  3833
+   high |= (halffractype) sign << (HALFFRACBITS + EXPBITS);
yann@339
  3834
+
yann@339
  3835
+   if (exp == EXPMAX || exp == 0 || low == 0)
yann@339
  3836
+     low = 0;
yann@339
  3837
+   else
yann@339
  3838
+     {
yann@339
  3839
+       while (lowexp > 0 && low < unity)
yann@339
  3840
+	 {
yann@339
  3841
+	   low <<= 1;
yann@339
  3842
+	   lowexp--;
yann@339
  3843
+	 }
yann@339
  3844
+
yann@339
  3845
+       if (lowexp <= 0)
yann@339
  3846
+	 {
yann@339
  3847
+	   halffractype roundmsb, round;
yann@339
  3848
+	   int shift;
yann@339
  3849
+
yann@339
  3850
+	   shift = 1 - lowexp;
yann@339
  3851
+	   roundmsb = (1 << (shift - 1));
yann@339
  3852
+	   round = low & ((roundmsb << 1) - 1);
yann@339
  3853
+
yann@339
  3854
+	   low >>= shift;
yann@339
  3855
+	   lowexp = 0;
yann@339
  3856
+
yann@339
  3857
+	   if (round > roundmsb || (round == roundmsb && (low & 1) == 1))
yann@339
  3858
+	     {
yann@339
  3859
+	       low++;
yann@339
  3860
+	       if (low == unity)
yann@339
  3861
+		 /* LOW rounds up to the smallest normal number.  */
yann@339
  3862
+		 lowexp++;
yann@339
  3863
+	     }
yann@339
  3864
+	 }
yann@339
  3865
+
yann@339
  3866
+       low &= unity - 1;
yann@339
  3867
+       low |= (halffractype) lowexp << HALFFRACBITS;
yann@339
  3868
+       low |= (halffractype) lowsign << (HALFFRACBITS + EXPBITS);
yann@339
  3869
+     }
yann@339
  3870
+   dst.value_raw = ((fractype) high << HALFSHIFT) | low;
yann@339
  3871
+ }
yann@339
  3872
+# else
yann@339
  3873
+  dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1);
yann@339
  3874
+  dst.value_raw |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << FRACBITS;
yann@339
  3875
+  dst.value_raw |= ((fractype) (sign & 1)) << (FRACBITS | EXPBITS);
yann@339
  3876
+# endif
yann@339
  3877
+#endif
yann@339
  3878
+
yann@339
  3879
+#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
yann@339
  3880
+#ifdef TFLOAT
yann@339
  3881
+  {
yann@339
  3882
+    qrtrfractype tmp1 = dst.words[0];
yann@339
  3883
+    qrtrfractype tmp2 = dst.words[1];
yann@339
  3884
+    dst.words[0] = dst.words[3];
yann@339
  3885
+    dst.words[1] = dst.words[2];
yann@339
  3886
+    dst.words[2] = tmp2;
yann@339
  3887
+    dst.words[3] = tmp1;
yann@339
  3888
+  }
yann@339
  3889
+#else
yann@339
  3890
+  {
yann@339
  3891
+    halffractype tmp = dst.words[0];
yann@339
  3892
+    dst.words[0] = dst.words[1];
yann@339
  3893
+    dst.words[1] = tmp;
yann@339
  3894
+  }
yann@339
  3895
+#endif
yann@339
  3896
+#endif
yann@339
  3897
+
yann@339
  3898
+  return dst.value;
yann@339
  3899
+}
yann@339
  3900
+#endif
yann@339
  3901
+
yann@339
  3902
+#if defined(L_unpack_df) || defined(L_unpack_sf) || defined(L_unpack_tf)
yann@339
  3903
+void
yann@339
  3904
+unpack_d (FLO_union_type * src, fp_number_type * dst)
yann@339
  3905
+{
yann@339
  3906
+  /* We previously used bitfields to store the number, but this doesn't
yann@339
  3907
+     handle little/big endian systems conveniently, so use shifts and
yann@339
  3908
+     masks */
yann@339
  3909
+  fractype fraction;
yann@339
  3910
+  int exp;
yann@339
  3911
+  int sign;
yann@339
  3912
+
yann@339
  3913
+#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
yann@339
  3914
+  FLO_union_type swapped;
yann@339
  3915
+
yann@339
  3916
+#ifdef TFLOAT
yann@339
  3917
+  swapped.words[0] = src->words[3];
yann@339
  3918
+  swapped.words[1] = src->words[2];
yann@339
  3919
+  swapped.words[2] = src->words[1];
yann@339
  3920
+  swapped.words[3] = src->words[0];
yann@339
  3921
+#else
yann@339
  3922
+  swapped.words[0] = src->words[1];
yann@339
  3923
+  swapped.words[1] = src->words[0];
yann@339
  3924
+#endif
yann@339
  3925
+  src = &swapped;
yann@339
  3926
+#endif
yann@339
  3927
+  
yann@339
  3928
+#ifdef FLOAT_BIT_ORDER_MISMATCH
yann@339
  3929
+  fraction = src->bits.fraction;
yann@339
  3930
+  exp = src->bits.exp;
yann@339
  3931
+  sign = src->bits.sign;
yann@339
  3932
+#else
yann@339
  3933
+# if defined TFLOAT && defined HALFFRACBITS
yann@339
  3934
+ {
yann@339
  3935
+   halffractype high, low;
yann@339
  3936
+   
yann@339
  3937
+   high = src->value_raw >> HALFSHIFT;
yann@339
  3938
+   low = src->value_raw & (((fractype)1 << HALFSHIFT) - 1);
yann@339
  3939
+
yann@339
  3940
+   fraction = high & ((((fractype)1) << HALFFRACBITS) - 1);
yann@339
  3941
+   fraction <<= FRACBITS - HALFFRACBITS;
yann@339
  3942
+   exp = ((int)(high >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
yann@339
  3943
+   sign = ((int)(high >> (((HALFFRACBITS + EXPBITS))))) & 1;
yann@339
  3944
+
yann@339
  3945
+   if (exp != EXPMAX && exp != 0 && low != 0)
yann@339
  3946
+     {
yann@339
  3947
+       int lowexp = ((int)(low >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
yann@339
  3948
+       int lowsign = ((int)(low >> (((HALFFRACBITS + EXPBITS))))) & 1;
yann@339
  3949
+       int shift;
yann@339
  3950
+       fractype xlow;
yann@339
  3951
+
yann@339
  3952
+       xlow = low & ((((fractype)1) << HALFFRACBITS) - 1);
yann@339
  3953
+       if (lowexp)
yann@339
  3954
+	 xlow |= (((halffractype)1) << HALFFRACBITS);
yann@339
  3955
+       else
yann@339
  3956
+	 lowexp = 1;
yann@339
  3957
+       shift = (FRACBITS - HALFFRACBITS) - (exp - lowexp);
yann@339
  3958
+       if (shift > 0)
yann@339
  3959
+	 xlow <<= shift;
yann@339
  3960
+       else if (shift < 0)
yann@339
  3961
+	 xlow >>= -shift;
yann@339
  3962
+       if (sign == lowsign)
yann@339
  3963
+	 fraction += xlow;
yann@339
  3964
+       else if (fraction >= xlow)
yann@339
  3965
+	 fraction -= xlow;
yann@339
  3966
+       else
yann@339
  3967
+	 {
yann@339
  3968
+	   /* The high part is a power of two but the full number is lower.
yann@339
  3969
+	      This code will leave the implicit 1 in FRACTION, but we'd
yann@339
  3970
+	      have added that below anyway.  */
yann@339
  3971
+	   fraction = (((fractype) 1 << FRACBITS) - xlow) << 1;
yann@339
  3972
+	   exp--;
yann@339
  3973
+	 }
yann@339
  3974
+     }
yann@339
  3975
+ }
yann@339
  3976
+# else
yann@339
  3977
+  fraction = src->value_raw & ((((fractype)1) << FRACBITS) - 1);
yann@339
  3978
+  exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1);
yann@339
  3979
+  sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1;
yann@339
  3980
+# endif
yann@339
  3981
+#endif
yann@339
  3982
+
yann@339
  3983
+  dst->sign = sign;
yann@339
  3984
+  if (exp == 0)
yann@339
  3985
+    {
yann@339
  3986
+      /* Hmm.  Looks like 0 */
yann@339
  3987
+      if (fraction == 0
yann@339
  3988
+#ifdef NO_DENORMALS
yann@339
  3989
+	  || 1
yann@339
  3990
+#endif
yann@339
  3991
+	  )
yann@339
  3992
+	{
yann@339
  3993
+	  /* tastes like zero */
yann@339
  3994
+	  dst->class = CLASS_ZERO;
yann@339
  3995
+	}
yann@339
  3996
+      else
yann@339
  3997
+	{
yann@339
  3998
+	  /* Zero exponent with nonzero fraction - it's denormalized,
yann@339
  3999
+	     so there isn't a leading implicit one - we'll shift it so
yann@339
  4000
+	     it gets one.  */
yann@339
  4001
+	  dst->normal_exp = exp - EXPBIAS + 1;
yann@339
  4002
+	  fraction <<= NGARDS;
yann@339
  4003
+
yann@339
  4004
+	  dst->class = CLASS_NUMBER;
yann@339
  4005
+#if 1
yann@339
  4006
+	  while (fraction < IMPLICIT_1)
yann@339
  4007
+	    {
yann@339
  4008
+	      fraction <<= 1;
yann@339
  4009
+	      dst->normal_exp--;
yann@339
  4010
+	    }
yann@339
  4011
+#endif
yann@339
  4012
+	  dst->fraction.ll = fraction;
yann@339
  4013
+	}
yann@339
  4014
+    }
yann@339
  4015
+  else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp == EXPMAX)
yann@339
  4016
+    {
yann@339
  4017
+      /* Huge exponent*/
yann@339
  4018
+      if (fraction == 0)
yann@339
  4019
+	{
yann@339
  4020
+	  /* Attached to a zero fraction - means infinity */
yann@339
  4021
+	  dst->class = CLASS_INFINITY;
yann@339
  4022
+	}
yann@339
  4023
+      else
yann@339
  4024
+	{
yann@339
  4025
+	  /* Nonzero fraction, means nan */
yann@339
  4026
+#ifdef QUIET_NAN_NEGATED
yann@339
  4027
+	  if ((fraction & QUIET_NAN) == 0)
yann@339
  4028
+#else
yann@339
  4029
+	  if (fraction & QUIET_NAN)
yann@339
  4030
+#endif
yann@339
  4031
+	    {
yann@339
  4032
+	      dst->class = CLASS_QNAN;
yann@339
  4033
+	    }
yann@339
  4034
+	  else
yann@339
  4035
+	    {
yann@339
  4036
+	      dst->class = CLASS_SNAN;
yann@339
  4037
+	    }
yann@339
  4038
+	  /* Keep the fraction part as the nan number */
yann@339
  4039
+	  dst->fraction.ll = fraction;
yann@339
  4040
+	}
yann@339
  4041
+    }
yann@339
  4042
+  else
yann@339
  4043
+    {
yann@339
  4044
+      /* Nothing strange about this number */
yann@339
  4045
+      dst->normal_exp = exp - EXPBIAS;
yann@339
  4046
+      dst->class = CLASS_NUMBER;
yann@339
  4047
+      dst->fraction.ll = (fraction << NGARDS) | IMPLICIT_1;
yann@339
  4048
+    }
yann@339
  4049
+}
yann@339
  4050
+#endif /* L_unpack_df || L_unpack_sf */
yann@339
  4051
+
yann@339
  4052
+#if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf)
yann@339
  4053
+static fp_number_type *
yann@339
  4054
+_fpadd_parts (fp_number_type * a,
yann@339
  4055
+	      fp_number_type * b,
yann@339
  4056
+	      fp_number_type * tmp)
yann@339
  4057
+{
yann@339
  4058
+  intfrac tfraction;
yann@339
  4059
+
yann@339
  4060
+  /* Put commonly used fields in local variables.  */
yann@339
  4061
+  int a_normal_exp;
yann@339
  4062
+  int b_normal_exp;
yann@339
  4063
+  fractype a_fraction;
yann@339
  4064
+  fractype b_fraction;
yann@339
  4065
+
yann@339
  4066
+  if (isnan (a))
yann@339
  4067
+    {
yann@339
  4068
+      return a;
yann@339
  4069
+    }
yann@339
  4070
+  if (isnan (b))
yann@339
  4071
+    {
yann@339
  4072
+      return b;
yann@339
  4073
+    }
yann@339
  4074
+  if (isinf (a))
yann@339
  4075
+    {
yann@339
  4076
+      /* Adding infinities with opposite signs yields a NaN.  */
yann@339
  4077
+      if (isinf (b) && a->sign != b->sign)
yann@339
  4078
+	return nan ();
yann@339
  4079
+      return a;
yann@339
  4080
+    }
yann@339
  4081
+  if (isinf (b))
yann@339
  4082
+    {
yann@339
  4083
+      return b;
yann@339
  4084
+    }
yann@339
  4085
+  if (iszero (b))
yann@339
  4086
+    {
yann@339
  4087
+      if (iszero (a))
yann@339
  4088
+	{
yann@339
  4089
+	  *tmp = *a;
yann@339
  4090
+	  tmp->sign = a->sign & b->sign;
yann@339
  4091
+	  return tmp;
yann@339
  4092
+	}
yann@339
  4093
+      return a;
yann@339
  4094
+    }
yann@339
  4095
+  if (iszero (a))
yann@339
  4096
+    {
yann@339
  4097
+      return b;
yann@339
  4098
+    }
yann@339
  4099
+
yann@339
  4100
+  /* Got two numbers. shift the smaller and increment the exponent till
yann@339
  4101
+     they're the same */
yann@339
  4102
+  {
yann@339
  4103
+    int diff;
yann@339
  4104
+
yann@339
  4105
+    a_normal_exp = a->normal_exp;
yann@339
  4106
+    b_normal_exp = b->normal_exp;
yann@339
  4107
+    a_fraction = a->fraction.ll;
yann@339
  4108
+    b_fraction = b->fraction.ll;
yann@339
  4109
+
yann@339
  4110
+    diff = a_normal_exp - b_normal_exp;
yann@339
  4111
+
yann@339
  4112
+    if (diff < 0)
yann@339
  4113
+      diff = -diff;
yann@339
  4114
+    if (diff < FRAC_NBITS)
yann@339
  4115
+      {
yann@339
  4116
+	/* ??? This does shifts one bit at a time.  Optimize.  */
yann@339
  4117
+	while (a_normal_exp > b_normal_exp)
yann@339
  4118
+	  {
yann@339
  4119
+	    b_normal_exp++;
yann@339
  4120
+	    LSHIFT (b_fraction);
yann@339
  4121
+	  }
yann@339
  4122
+	while (b_normal_exp > a_normal_exp)
yann@339
  4123
+	  {
yann@339
  4124
+	    a_normal_exp++;
yann@339
  4125
+	    LSHIFT (a_fraction);
yann@339
  4126
+	  }
yann@339
  4127
+      }
yann@339
  4128
+    else
yann@339
  4129
+      {
yann@339
  4130
+	/* Somethings's up.. choose the biggest */
yann@339
  4131
+	if (a_normal_exp > b_normal_exp)
yann@339
  4132
+	  {
yann@339
  4133
+	    b_normal_exp = a_normal_exp;
yann@339
  4134
+	    b_fraction = 0;
yann@339
  4135
+	  }
yann@339
  4136
+	else
yann@339
  4137
+	  {
yann@339
  4138
+	    a_normal_exp = b_normal_exp;
yann@339
  4139
+	    a_fraction = 0;
yann@339
  4140
+	  }
yann@339
  4141
+      }
yann@339
  4142
+  }
yann@339
  4143
+
yann@339
  4144
+  if (a->sign != b->sign)
yann@339
  4145
+    {
yann@339
  4146
+      if (a->sign)
yann@339
  4147
+	{
yann@339
  4148
+	  tfraction = -a_fraction + b_fraction;
yann@339
  4149
+	}
yann@339
  4150
+      else
yann@339
  4151
+	{
yann@339
  4152
+	  tfraction = a_fraction - b_fraction;
yann@339
  4153
+	}
yann@339
  4154
+      if (tfraction >= 0)
yann@339
  4155
+	{
yann@339
  4156
+	  tmp->sign = 0;
yann@339
  4157
+	  tmp->normal_exp = a_normal_exp;
yann@339
  4158
+	  tmp->fraction.ll = tfraction;
yann@339
  4159
+	}
yann@339
  4160
+      else
yann@339
  4161
+	{
yann@339
  4162
+	  tmp->sign = 1;
yann@339
  4163
+	  tmp->normal_exp = a_normal_exp;
yann@339
  4164
+	  tmp->fraction.ll = -tfraction;
yann@339
  4165
+	}
yann@339
  4166
+      /* and renormalize it */
yann@339
  4167
+
yann@339
  4168
+      while (tmp->fraction.ll < IMPLICIT_1 && tmp->fraction.ll)
yann@339
  4169
+	{
yann@339
  4170
+	  tmp->fraction.ll <<= 1;
yann@339
  4171
+	  tmp->normal_exp--;
yann@339
  4172
+	}
yann@339
  4173
+    }
yann@339
  4174
+  else
yann@339
  4175
+    {
yann@339
  4176
+      tmp->sign = a->sign;
yann@339
  4177
+      tmp->normal_exp = a_normal_exp;
yann@339
  4178
+      tmp->fraction.ll = a_fraction + b_fraction;
yann@339
  4179
+    }
yann@339
  4180
+  tmp->class = CLASS_NUMBER;
yann@339
  4181
+  /* Now the fraction is added, we have to shift down to renormalize the
yann@339
  4182
+     number */
yann@339
  4183
+
yann@339
  4184
+  if (tmp->fraction.ll >= IMPLICIT_2)
yann@339
  4185
+    {
yann@339
  4186
+      LSHIFT (tmp->fraction.ll);
yann@339
  4187
+      tmp->normal_exp++;
yann@339
  4188
+    }
yann@339
  4189
+  return tmp;
yann@339
  4190
+
yann@339
  4191
+}
yann@339
  4192
+
yann@339
  4193
+FLO_type
yann@339
  4194
+add (FLO_type arg_a, FLO_type arg_b)
yann@339
  4195
+{
yann@339
  4196
+  fp_number_type a;
yann@339
  4197
+  fp_number_type b;
yann@339
  4198
+  fp_number_type tmp;
yann@339
  4199
+  fp_number_type *res;
yann@339
  4200
+  FLO_union_type au, bu;
yann@339
  4201
+
yann@339
  4202
+  au.value = arg_a;
yann@339
  4203
+  bu.value = arg_b;
yann@339
  4204
+
yann@339
  4205
+  unpack_d (&au, &a);
yann@339
  4206
+  unpack_d (&bu, &b);
yann@339
  4207
+
yann@339
  4208
+  res = _fpadd_parts (&a, &b, &tmp);
yann@339
  4209
+
yann@339
  4210
+  return pack_d (res);
yann@339
  4211
+}
yann@339
  4212
+
yann@339
  4213
+FLO_type
yann@339
  4214
+sub (FLO_type arg_a, FLO_type arg_b)
yann@339
  4215
+{
yann@339
  4216
+  fp_number_type a;
yann@339
  4217
+  fp_number_type b;
yann@339
  4218
+  fp_number_type tmp;
yann@339
  4219
+  fp_number_type *res;
yann@339
  4220
+  FLO_union_type au, bu;
yann@339
  4221
+
yann@339
  4222
+  au.value = arg_a;
yann@339
  4223
+  bu.value = arg_b;
yann@339
  4224
+
yann@339
  4225
+  unpack_d (&au, &a);
yann@339
  4226
+  unpack_d (&bu, &b);
yann@339
  4227
+
yann@339
  4228
+  b.sign ^= 1;
yann@339
  4229
+
yann@339
  4230
+  res = _fpadd_parts (&a, &b, &tmp);
yann@339
  4231
+
yann@339
  4232
+  return pack_d (res);
yann@339
  4233
+}
yann@339
  4234
+#endif /* L_addsub_sf || L_addsub_df */
yann@339
  4235
+
yann@339
  4236
+#if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf)
yann@339
  4237
+static inline __attribute__ ((__always_inline__)) fp_number_type *
yann@339
  4238
+_fpmul_parts ( fp_number_type *  a,
yann@339
  4239
+	       fp_number_type *  b,
yann@339
  4240
+	       fp_number_type * tmp)
yann@339
  4241
+{
yann@339
  4242
+  fractype low = 0;
yann@339
  4243
+  fractype high = 0;
yann@339
  4244
+
yann@339
  4245
+  if (isnan (a))
yann@339
  4246
+    {
yann@339
  4247
+      a->sign = a->sign != b->sign;
yann@339
  4248
+      return a;
yann@339
  4249
+    }
yann@339
  4250
+  if (isnan (b))
yann@339
  4251
+    {
yann@339
  4252
+      b->sign = a->sign != b->sign;
yann@339
  4253
+      return b;
yann@339
  4254
+    }
yann@339
  4255
+  if (isinf (a))
yann@339
  4256
+    {
yann@339
  4257
+      if (iszero (b))
yann@339
  4258
+	return nan ();
yann@339
  4259
+      a->sign = a->sign != b->sign;
yann@339
  4260
+      return a;
yann@339
  4261
+    }
yann@339
  4262
+  if (isinf (b))
yann@339
  4263
+    {
yann@339
  4264
+      if (iszero (a))
yann@339
  4265
+	{
yann@339
  4266
+	  return nan ();
yann@339
  4267
+	}
yann@339
  4268
+      b->sign = a->sign != b->sign;
yann@339
  4269
+      return b;
yann@339
  4270
+    }
yann@339
  4271
+  if (iszero (a))
yann@339
  4272
+    {
yann@339
  4273
+      a->sign = a->sign != b->sign;
yann@339
  4274
+      return a;
yann@339
  4275
+    }
yann@339
  4276
+  if (iszero (b))
yann@339
  4277
+    {
yann@339
  4278
+      b->sign = a->sign != b->sign;
yann@339
  4279
+      return b;
yann@339
  4280
+    }
yann@339
  4281
+
yann@339
  4282
+  /* Calculate the mantissa by multiplying both numbers to get a
yann@339
  4283
+     twice-as-wide number.  */
yann@339
  4284
+  {
yann@339
  4285
+#if defined(NO_DI_MODE) || defined(TFLOAT)
yann@339
  4286
+    {
yann@339
  4287
+      fractype x = a->fraction.ll;
yann@339
  4288
+      fractype ylow = b->fraction.ll;
yann@339
  4289
+      fractype yhigh = 0;
yann@339
  4290
+      int bit;
yann@339
  4291
+
yann@339
  4292
+      /* ??? This does multiplies one bit at a time.  Optimize.  */
yann@339
  4293
+      for (bit = 0; bit < FRAC_NBITS; bit++)
yann@339
  4294
+	{
yann@339
  4295
+	  int carry;
yann@339
  4296
+
yann@339
  4297
+	  if (x & 1)
yann@339
  4298
+	    {
yann@339
  4299
+	      carry = (low += ylow) < ylow;
yann@339
  4300
+	      high += yhigh + carry;
yann@339
  4301
+	    }
yann@339
  4302
+	  yhigh <<= 1;
yann@339
  4303
+	  if (ylow & FRACHIGH)
yann@339
  4304
+	    {
yann@339
  4305
+	      yhigh |= 1;
yann@339
  4306
+	    }
yann@339
  4307
+	  ylow <<= 1;
yann@339
  4308
+	  x >>= 1;
yann@339
  4309
+	}
yann@339
  4310
+    }
yann@339
  4311
+#elif defined(FLOAT) 
yann@339
  4312
+    /* Multiplying two USIs to get a UDI, we're safe.  */
yann@339
  4313
+    {
yann@339
  4314
+      UDItype answer = (UDItype)a->fraction.ll * (UDItype)b->fraction.ll;
yann@339
  4315
+      
yann@339
  4316
+      high = answer >> BITS_PER_SI;
yann@339
  4317
+      low = answer;
yann@339
  4318
+    }
yann@339
  4319
+#else
yann@339
  4320
+    /* fractype is DImode, but we need the result to be twice as wide.
yann@339
  4321
+       Assuming a widening multiply from DImode to TImode is not
yann@339
  4322
+       available, build one by hand.  */
yann@339
  4323
+    {
yann@339
  4324
+      USItype nl = a->fraction.ll;
yann@339
  4325
+      USItype nh = a->fraction.ll >> BITS_PER_SI;
yann@339
  4326
+      USItype ml = b->fraction.ll;
yann@339
  4327
+      USItype mh = b->fraction.ll >> BITS_PER_SI;
yann@339
  4328
+      UDItype pp_ll = (UDItype) ml * nl;
yann@339
  4329
+      UDItype pp_hl = (UDItype) mh * nl;
yann@339
  4330
+      UDItype pp_lh = (UDItype) ml * nh;
yann@339
  4331
+      UDItype pp_hh = (UDItype) mh * nh;
yann@339
  4332
+      UDItype res2 = 0;
yann@339
  4333
+      UDItype res0 = 0;
yann@339
  4334
+      UDItype ps_hh__ = pp_hl + pp_lh;
yann@339
  4335
+      if (ps_hh__ < pp_hl)
yann@339
  4336
+	res2 += (UDItype)1 << BITS_PER_SI;
yann@339
  4337
+      pp_hl = (UDItype)(USItype)ps_hh__ << BITS_PER_SI;
yann@339
  4338
+      res0 = pp_ll + pp_hl;
yann@339
  4339
+      if (res0 < pp_ll)
yann@339
  4340
+	res2++;
yann@339
  4341
+      res2 += (ps_hh__ >> BITS_PER_SI) + pp_hh;
yann@339
  4342
+      high = res2;
yann@339
  4343
+      low = res0;
yann@339
  4344
+    }
yann@339
  4345
+#endif
yann@339
  4346
+  }
yann@339
  4347
+
yann@339
  4348
+  tmp->normal_exp = a->normal_exp + b->normal_exp
yann@339
  4349
+    + FRAC_NBITS - (FRACBITS + NGARDS);
yann@339
  4350
+  tmp->sign = a->sign != b->sign;
yann@339
  4351
+  while (high >= IMPLICIT_2)
yann@339
  4352
+    {
yann@339
  4353
+      tmp->normal_exp++;
yann@339
  4354
+      if (high & 1)
yann@339
  4355
+	{
yann@339
  4356
+	  low >>= 1;
yann@339
  4357
+	  low |= FRACHIGH;
yann@339
  4358
+	}
yann@339
  4359
+      high >>= 1;
yann@339
  4360
+    }
yann@339
  4361
+  while (high < IMPLICIT_1)
yann@339
  4362
+    {
yann@339
  4363
+      tmp->normal_exp--;
yann@339
  4364
+
yann@339
  4365
+      high <<= 1;
yann@339
  4366
+      if (low & FRACHIGH)
yann@339
  4367
+	high |= 1;
yann@339
  4368
+      low <<= 1;
yann@339
  4369
+    }
yann@339
  4370
+  /* rounding is tricky. if we only round if it won't make us round later.  */
yann@339
  4371
+#if 0
yann@339
  4372
+  if (low & FRACHIGH2)
yann@339
  4373
+    {
yann@339
  4374
+      if (((high & GARDMASK) != GARDMSB)
yann@339
  4375
+	  && (((high + 1) & GARDMASK) == GARDMSB))
yann@339
  4376
+	{
yann@339
  4377
+	  /* don't round, it gets done again later.  */
yann@339
  4378
+	}
yann@339
  4379
+      else
yann@339
  4380
+	{
yann@339
  4381
+	  high++;
yann@339
  4382
+	}
yann@339
  4383
+    }
yann@339
  4384
+#endif
yann@339
  4385
+  if (!ROUND_TOWARDS_ZERO && (high & GARDMASK) == GARDMSB)
yann@339
  4386
+    {
yann@339
  4387
+      if (high & (1 << NGARDS))
yann@339
  4388
+	{
yann@339
  4389
+	  /* half way, so round to even */
yann@339
  4390
+	  high += GARDROUND + 1;
yann@339
  4391
+	}
yann@339
  4392
+      else if (low)
yann@339
  4393
+	{
yann@339
  4394
+	  /* but we really weren't half way */
yann@339
  4395
+	  high += GARDROUND + 1;
yann@339
  4396
+	}
yann@339
  4397
+    }
yann@339
  4398
+  tmp->fraction.ll = high;
yann@339
  4399
+  tmp->class = CLASS_NUMBER;
yann@339
  4400
+  return tmp;
yann@339
  4401
+}
yann@339
  4402
+
yann@339
  4403
+FLO_type
yann@339
  4404
+multiply (FLO_type arg_a, FLO_type arg_b)
yann@339
  4405
+{
yann@339
  4406
+  fp_number_type a;
yann@339
  4407
+  fp_number_type b;
yann@339
  4408
+  fp_number_type tmp;
yann@339
  4409
+  fp_number_type *res;
yann@339
  4410
+  FLO_union_type au, bu;
yann@339
  4411
+
yann@339
  4412
+  au.value = arg_a;
yann@339
  4413
+  bu.value = arg_b;
yann@339
  4414
+
yann@339
  4415
+  unpack_d (&au, &a);
yann@339
  4416
+  unpack_d (&bu, &b);
yann@339
  4417
+
yann@339
  4418
+  res = _fpmul_parts (&a, &b, &tmp);
yann@339
  4419
+
yann@339
  4420
+  return pack_d (res);
yann@339
  4421
+}
yann@339
  4422
+#endif /* L_mul_sf || L_mul_df */
yann@339
  4423
+
yann@339
  4424
+#if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf)
yann@339
  4425
+static inline __attribute__ ((__always_inline__)) fp_number_type *
yann@339
  4426
+_fpdiv_parts (fp_number_type * a,
yann@339
  4427
+	      fp_number_type * b)
yann@339
  4428
+{
yann@339
  4429
+  fractype bit;
yann@339
  4430
+  fractype numerator;
yann@339
  4431
+  fractype denominator;
yann@339
  4432
+  fractype quotient;
yann@339
  4433
+
yann@339
  4434
+  if (isnan (a))
yann@339
  4435
+    {
yann@339
  4436
+      return a;
yann@339
  4437
+    }
yann@339
  4438
+  if (isnan (b))
yann@339
  4439
+    {
yann@339
  4440
+      return b;
yann@339
  4441
+    }
yann@339
  4442
+
yann@339
  4443
+  a->sign = a->sign ^ b->sign;
yann@339
  4444
+
yann@339
  4445
+  if (isinf (a) || iszero (a))
yann@339
  4446
+    {
yann@339
  4447
+      if (a->class == b->class)
yann@339
  4448
+	return nan ();
yann@339
  4449
+      return a;
yann@339
  4450
+    }
yann@339
  4451
+
yann@339
  4452
+  if (isinf (b))
yann@339
  4453
+    {
yann@339
  4454
+      a->fraction.ll = 0;
yann@339
  4455
+      a->normal_exp = 0;
yann@339
  4456
+      return a;
yann@339
  4457
+    }
yann@339
  4458
+  if (iszero (b))
yann@339
  4459
+    {
yann@339
  4460
+      a->class = CLASS_INFINITY;
yann@339
  4461
+      return a;
yann@339
  4462
+    }
yann@339
  4463
+
yann@339
  4464
+  /* Calculate the mantissa by multiplying both 64bit numbers to get a
yann@339
  4465
+     128 bit number */
yann@339
  4466
+  {
yann@339
  4467
+    /* quotient =
yann@339
  4468
+       ( numerator / denominator) * 2^(numerator exponent -  denominator exponent)
yann@339
  4469
+     */
yann@339
  4470
+
yann@339
  4471
+    a->normal_exp = a->normal_exp - b->normal_exp;
yann@339
  4472
+    numerator = a->fraction.ll;
yann@339
  4473
+    denominator = b->fraction.ll;
yann@339
  4474
+
yann@339
  4475
+    if (numerator < denominator)
yann@339
  4476
+      {
yann@339
  4477
+	/* Fraction will be less than 1.0 */
yann@339
  4478
+	numerator *= 2;
yann@339
  4479
+	a->normal_exp--;
yann@339
  4480
+      }
yann@339
  4481
+    bit = IMPLICIT_1;
yann@339
  4482
+    quotient = 0;
yann@339
  4483
+    /* ??? Does divide one bit at a time.  Optimize.  */
yann@339
  4484
+    while (bit)
yann@339
  4485
+      {
yann@339
  4486
+	if (numerator >= denominator)
yann@339
  4487
+	  {
yann@339
  4488
+	    quotient |= bit;
yann@339
  4489
+	    numerator -= denominator;
yann@339
  4490
+	  }
yann@339
  4491
+	bit >>= 1;
yann@339
  4492
+	numerator *= 2;
yann@339
  4493
+      }
yann@339
  4494
+
yann@339
  4495
+    if (!ROUND_TOWARDS_ZERO && (quotient & GARDMASK) == GARDMSB)
yann@339
  4496
+      {
yann@339
  4497
+	if (quotient & (1 << NGARDS))
yann@339
  4498
+	  {
yann@339
  4499
+	    /* half way, so round to even */
yann@339
  4500
+	    quotient += GARDROUND + 1;
yann@339
  4501
+	  }
yann@339
  4502
+	else if (numerator)
yann@339
  4503
+	  {
yann@339
  4504
+	    /* but we really weren't half way, more bits exist */
yann@339
  4505
+	    quotient += GARDROUND + 1;
yann@339
  4506
+	  }
yann@339
  4507
+      }
yann@339
  4508
+
yann@339
  4509
+    a->fraction.ll = quotient;
yann@339
  4510
+    return (a);
yann@339
  4511
+  }
yann@339
  4512
+}
yann@339
  4513
+
yann@339
  4514
+FLO_type
yann@339
  4515
+divide (FLO_type arg_a, FLO_type arg_b)
yann@339
  4516
+{
yann@339
  4517
+  fp_number_type a;
yann@339
  4518
+  fp_number_type b;
yann@339
  4519
+  fp_number_type *res;
yann@339
  4520
+  FLO_union_type au, bu;
yann@339
  4521
+
yann@339
  4522
+  au.value = arg_a;
yann@339
  4523
+  bu.value = arg_b;
yann@339
  4524
+
yann@339
  4525
+  unpack_d (&au, &a);
yann@339
  4526
+  unpack_d (&bu, &b);
yann@339
  4527
+
yann@339
  4528
+  res = _fpdiv_parts (&a, &b);
yann@339
  4529
+
yann@339
  4530
+  return pack_d (res);
yann@339
  4531
+}
yann@339
  4532
+#endif /* L_div_sf || L_div_df */
yann@339
  4533
+
yann@339
  4534
+#if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) \
yann@339
  4535
+    || defined(L_fpcmp_parts_tf)
yann@339
  4536
+/* according to the demo, fpcmp returns a comparison with 0... thus
yann@339
  4537
+   a<b -> -1
yann@339
  4538
+   a==b -> 0
yann@339
  4539
+   a>b -> +1
yann@339
  4540
+ */
yann@339
  4541
+
yann@339
  4542
+int
yann@339
  4543
+__fpcmp_parts (fp_number_type * a, fp_number_type * b)
yann@339
  4544
+{
yann@339
  4545
+#if 0
yann@339
  4546
+  /* either nan -> unordered. Must be checked outside of this routine.  */
yann@339
  4547
+  if (isnan (a) && isnan (b))
yann@339
  4548
+    {
yann@339
  4549
+      return 1;			/* still unordered! */
yann@339
  4550
+    }
yann@339
  4551
+#endif
yann@339
  4552
+
yann@339
  4553
+  if (isnan (a) || isnan (b))
yann@339
  4554
+    {
yann@339
  4555
+      return 1;			/* how to indicate unordered compare? */
yann@339
  4556
+    }
yann@339
  4557
+  if (isinf (a) && isinf (b))
yann@339
  4558
+    {
yann@339
  4559
+      /* +inf > -inf, but +inf != +inf */
yann@339
  4560
+      /* b    \a| +inf(0)| -inf(1)
yann@339
  4561
+       ______\+--------+--------
yann@339
  4562
+       +inf(0)| a==b(0)| a<b(-1)
yann@339
  4563
+       -------+--------+--------
yann@339
  4564
+       -inf(1)| a>b(1) | a==b(0)
yann@339
  4565
+       -------+--------+--------
yann@339
  4566
+       So since unordered must be nonzero, just line up the columns...
yann@339
  4567
+       */
yann@339
  4568
+      return b->sign - a->sign;
yann@339
  4569
+    }
yann@339
  4570
+  /* but not both...  */
yann@339
  4571
+  if (isinf (a))
yann@339
  4572
+    {
yann@339
  4573
+      return a->sign ? -1 : 1;
yann@339
  4574
+    }
yann@339
  4575
+  if (isinf (b))
yann@339
  4576
+    {
yann@339
  4577
+      return b->sign ? 1 : -1;
yann@339
  4578
+    }
yann@339
  4579
+  if (iszero (a) && iszero (b))
yann@339
  4580
+    {
yann@339
  4581
+      return 0;
yann@339
  4582
+    }
yann@339
  4583
+  if (iszero (a))
yann@339
  4584
+    {
yann@339
  4585
+      return b->sign ? 1 : -1;
yann@339
  4586
+    }
yann@339
  4587
+  if (iszero (b))
yann@339
  4588
+    {
yann@339
  4589
+      return a->sign ? -1 : 1;
yann@339
  4590
+    }
yann@339
  4591
+  /* now both are "normal".  */
yann@339
  4592
+  if (a->sign != b->sign)
yann@339
  4593
+    {
yann@339
  4594
+      /* opposite signs */
yann@339
  4595
+      return a->sign ? -1 : 1;
yann@339
  4596
+    }
yann@339
  4597
+  /* same sign; exponents? */
yann@339
  4598
+  if (a->normal_exp > b->normal_exp)
yann@339
  4599
+    {
yann@339
  4600
+      return a->sign ? -1 : 1;
yann@339
  4601
+    }
yann@339
  4602
+  if (a->normal_exp < b->normal_exp)
yann@339
  4603
+    {
yann@339
  4604
+      return a->sign ? 1 : -1;
yann@339
  4605
+    }
yann@339
  4606
+  /* same exponents; check size.  */
yann@339
  4607
+  if (a->fraction.ll > b->fraction.ll)
yann@339
  4608
+    {
yann@339
  4609
+      return a->sign ? -1 : 1;
yann@339
  4610
+    }
yann@339
  4611
+  if (a->fraction.ll < b->fraction.ll)
yann@339
  4612
+    {
yann@339
  4613
+      return a->sign ? 1 : -1;
yann@339
  4614
+    }
yann@339
  4615
+  /* after all that, they're equal.  */
yann@339
  4616
+  return 0;
yann@339
  4617
+}
yann@339
  4618
+#endif
yann@339
  4619
+
yann@339
  4620
+#if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compoare_tf)
yann@339
  4621
+CMPtype
yann@339
  4622
+compare (FLO_type arg_a, FLO_type arg_b)
yann@339
  4623
+{
yann@339
  4624
+  fp_number_type a;
yann@339
  4625
+  fp_number_type b;
yann@339
  4626
+  FLO_union_type au, bu;
yann@339
  4627
+
yann@339
  4628
+  au.value = arg_a;
yann@339
  4629
+  bu.value = arg_b;
yann@339
  4630
+
yann@339
  4631
+  unpack_d (&au, &a);
yann@339
  4632
+  unpack_d (&bu, &b);
yann@339
  4633
+
yann@339
  4634
+  return __fpcmp_parts (&a, &b);
yann@339
  4635
+}
yann@339
  4636
+#endif /* L_compare_sf || L_compare_df */
yann@339
  4637
+
yann@339
  4638
+#ifndef US_SOFTWARE_GOFAST
yann@339
  4639
+
yann@339
  4640
+/* These should be optimized for their specific tasks someday.  */
yann@339
  4641
+
yann@339
  4642
+#if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf)
yann@339
  4643
+CMPtype
yann@339
  4644
+_eq_f2 (FLO_type arg_a, FLO_type arg_b)
yann@339
  4645
+{
yann@339
  4646
+  fp_number_type a;
yann@339
  4647
+  fp_number_type b;
yann@339
  4648
+  FLO_union_type au, bu;
yann@339
  4649
+
yann@339
  4650
+  au.value = arg_a;
yann@339
  4651
+  bu.value = arg_b;
yann@339
  4652
+
yann@339
  4653
+  unpack_d (&au, &a);
yann@339
  4654
+  unpack_d (&bu, &b);
yann@339
  4655
+
yann@339
  4656
+  if (isnan (&a) || isnan (&b))
yann@339
  4657
+    return 1;			/* false, truth == 0 */
yann@339
  4658
+
yann@339
  4659
+  return __fpcmp_parts (&a, &b) ;
yann@339
  4660
+}
yann@339
  4661
+#endif /* L_eq_sf || L_eq_df */
yann@339
  4662
+
yann@339
  4663
+#if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf)
yann@339
  4664
+CMPtype
yann@339
  4665
+_ne_f2 (FLO_type arg_a, FLO_type arg_b)
yann@339
  4666
+{
yann@339
  4667
+  fp_number_type a;
yann@339
  4668
+  fp_number_type b;
yann@339
  4669
+  FLO_union_type au, bu;
yann@339
  4670
+
yann@339
  4671
+  au.value = arg_a;
yann@339
  4672
+  bu.value = arg_b;
yann@339
  4673
+
yann@339
  4674
+  unpack_d (&au, &a);
yann@339
  4675
+  unpack_d (&bu, &b);
yann@339
  4676
+
yann@339
  4677
+  if (isnan (&a) || isnan (&b))
yann@339
  4678
+    return 1;			/* true, truth != 0 */
yann@339
  4679
+
yann@339
  4680
+  return  __fpcmp_parts (&a, &b) ;
yann@339
  4681
+}
yann@339
  4682
+#endif /* L_ne_sf || L_ne_df */
yann@339
  4683
+
yann@339
  4684
+#if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf)
yann@339
  4685
+CMPtype
yann@339
  4686
+_gt_f2 (FLO_type arg_a, FLO_type arg_b)
yann@339
  4687
+{
yann@339
  4688
+  fp_number_type a;
yann@339
  4689
+  fp_number_type b;
yann@339
  4690
+  FLO_union_type au, bu;
yann@339
  4691
+
yann@339
  4692
+  au.value = arg_a;
yann@339
  4693
+  bu.value = arg_b;
yann@339
  4694
+
yann@339
  4695
+  unpack_d (&au, &a);
yann@339
  4696
+  unpack_d (&bu, &b);
yann@339
  4697
+
yann@339
  4698
+  if (isnan (&a) || isnan (&b))
yann@339
  4699
+    return -1;			/* false, truth > 0 */
yann@339
  4700
+
yann@339
  4701
+  return __fpcmp_parts (&a, &b);
yann@339
  4702
+}
yann@339
  4703
+#endif /* L_gt_sf || L_gt_df */
yann@339
  4704
+
yann@339
  4705
+#if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf)
yann@339
  4706
+CMPtype
yann@339
  4707
+_ge_f2 (FLO_type arg_a, FLO_type arg_b)
yann@339
  4708
+{
yann@339
  4709
+  fp_number_type a;
yann@339
  4710
+  fp_number_type b;
yann@339
  4711
+  FLO_union_type au, bu;
yann@339
  4712
+
yann@339
  4713
+  au.value = arg_a;
yann@339
  4714
+  bu.value = arg_b;
yann@339
  4715
+
yann@339
  4716
+  unpack_d (&au, &a);
yann@339
  4717
+  unpack_d (&bu, &b);
yann@339
  4718
+
yann@339
  4719
+  if (isnan (&a) || isnan (&b))
yann@339
  4720
+    return -1;			/* false, truth >= 0 */
yann@339
  4721
+  return __fpcmp_parts (&a, &b) ;
yann@339
  4722
+}
yann@339
  4723
+#endif /* L_ge_sf || L_ge_df */
yann@339
  4724
+
yann@339
  4725
+#if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf)
yann@339
  4726
+CMPtype
yann@339
  4727
+_lt_f2 (FLO_type arg_a, FLO_type arg_b)
yann@339
  4728
+{
yann@339
  4729
+  fp_number_type a;
yann@339
  4730
+  fp_number_type b;
yann@339
  4731
+  FLO_union_type au, bu;
yann@339
  4732
+
yann@339
  4733
+  au.value = arg_a;
yann@339
  4734
+  bu.value = arg_b;
yann@339
  4735
+
yann@339
  4736
+  unpack_d (&au, &a);
yann@339
  4737
+  unpack_d (&bu, &b);
yann@339
  4738
+
yann@339
  4739
+  if (isnan (&a) || isnan (&b))
yann@339
  4740
+    return 1;			/* false, truth < 0 */
yann@339
  4741
+
yann@339
  4742
+  return __fpcmp_parts (&a, &b);
yann@339
  4743
+}
yann@339
  4744
+#endif /* L_lt_sf || L_lt_df */
yann@339
  4745
+
yann@339
  4746
+#if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf)
yann@339
  4747
+CMPtype
yann@339
  4748
+_le_f2 (FLO_type arg_a, FLO_type arg_b)
yann@339
  4749
+{
yann@339
  4750
+  fp_number_type a;
yann@339
  4751
+  fp_number_type b;
yann@339
  4752
+  FLO_union_type au, bu;
yann@339
  4753
+
yann@339
  4754
+  au.value = arg_a;
yann@339
  4755
+  bu.value = arg_b;
yann@339
  4756
+
yann@339
  4757
+  unpack_d (&au, &a);
yann@339
  4758
+  unpack_d (&bu, &b);
yann@339
  4759
+
yann@339
  4760
+  if (isnan (&a) || isnan (&b))
yann@339
  4761
+    return 1;			/* false, truth <= 0 */
yann@339
  4762
+
yann@339
  4763
+  return __fpcmp_parts (&a, &b) ;
yann@339
  4764
+}
yann@339
  4765
+#endif /* L_le_sf || L_le_df */
yann@339
  4766
+
yann@339
  4767
+#endif /* ! US_SOFTWARE_GOFAST */
yann@339
  4768
+
yann@339
  4769
+#if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf)
yann@339
  4770
+CMPtype
yann@339
  4771
+_unord_f2 (FLO_type arg_a, FLO_type arg_b)
yann@339
  4772
+{
yann@339
  4773
+  fp_number_type a;
yann@339
  4774
+  fp_number_type b;
yann@339
  4775
+  FLO_union_type au, bu;
yann@339
  4776
+
yann@339
  4777
+  au.value = arg_a;
yann@339
  4778
+  bu.value = arg_b;
yann@339
  4779
+
yann@339
  4780
+  unpack_d (&au, &a);
yann@339
  4781
+  unpack_d (&bu, &b);
yann@339
  4782
+
yann@339
  4783
+  return (isnan (&a) || isnan (&b));
yann@339
  4784
+}
yann@339
  4785
+#endif /* L_unord_sf || L_unord_df */
yann@339
  4786
+
yann@339
  4787
+#if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf)
yann@339
  4788
+FLO_type
yann@339
  4789
+si_to_float (SItype arg_a)
yann@339
  4790
+{
yann@339
  4791
+  fp_number_type in;
yann@339
  4792
+
yann@339
  4793
+  in.class = CLASS_NUMBER;
yann@339
  4794
+  in.sign = arg_a < 0;
yann@339
  4795
+  if (!arg_a)
yann@339
  4796
+    {
yann@339
  4797
+      in.class = CLASS_ZERO;
yann@339
  4798
+    }
yann@339
  4799
+  else
yann@339
  4800
+    {
yann@339
  4801
+      in.normal_exp = FRACBITS + NGARDS;
yann@339
  4802
+      if (in.sign) 
yann@339
  4803
+	{
yann@339
  4804
+	  /* Special case for minint, since there is no +ve integer
yann@339
  4805
+	     representation for it */
yann@339
  4806
+	  if (arg_a == (- MAX_SI_INT - 1))
yann@339
  4807
+	    {
yann@339
  4808
+	      return (FLO_type)(- MAX_SI_INT - 1);
yann@339
  4809
+	    }
yann@339
  4810
+	  in.fraction.ll = (-arg_a);
yann@339
  4811
+	}
yann@339
  4812
+      else
yann@339
  4813
+	in.fraction.ll = arg_a;
yann@339
  4814
+
yann@339
  4815
+      while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS)))
yann@339
  4816
+	{
yann@339
  4817
+	  in.fraction.ll <<= 1;
yann@339
  4818
+	  in.normal_exp -= 1;
yann@339
  4819
+	}
yann@339
  4820
+    }
yann@339
  4821
+  return pack_d (&in);
yann@339
  4822
+}
yann@339
  4823
+#endif /* L_si_to_sf || L_si_to_df */
yann@339
  4824
+
yann@339
  4825
+#if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf)
yann@339
  4826
+FLO_type
yann@339
  4827
+usi_to_float (USItype arg_a)
yann@339
  4828
+{
yann@339
  4829
+  fp_number_type in;
yann@339
  4830
+
yann@339
  4831
+  in.sign = 0;
yann@339
  4832
+  if (!arg_a)
yann@339
  4833
+    {
yann@339
  4834
+      in.class = CLASS_ZERO;
yann@339
  4835
+    }
yann@339
  4836
+  else
yann@339
  4837
+    {
yann@339
  4838
+      in.class = CLASS_NUMBER;
yann@339
  4839
+      in.normal_exp = FRACBITS + NGARDS;
yann@339
  4840
+      in.fraction.ll = arg_a;
yann@339
  4841
+
yann@339
  4842
+      while (in.fraction.ll > ((fractype)1 << (FRACBITS + NGARDS)))
yann@339
  4843
+        {
yann@339
  4844
+          in.fraction.ll >>= 1;
yann@339
  4845
+          in.normal_exp += 1;
yann@339
  4846
+        }
yann@339
  4847
+      while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS)))
yann@339
  4848
+	{
yann@339
  4849
+	  in.fraction.ll <<= 1;
yann@339
  4850
+	  in.normal_exp -= 1;
yann@339
  4851
+	}
yann@339
  4852
+    }
yann@339
  4853
+  return pack_d (&in);
yann@339
  4854
+}
yann@339
  4855
+#endif
yann@339
  4856
+
yann@339
  4857
+#if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si)
yann@339
  4858
+SItype
yann@339
  4859
+float_to_si (FLO_type arg_a)
yann@339
  4860
+{
yann@339
  4861
+  fp_number_type a;
yann@339
  4862
+  SItype tmp;
yann@339
  4863
+  FLO_union_type au;
yann@339
  4864
+
yann@339
  4865
+  au.value = arg_a;
yann@339
  4866
+  unpack_d (&au, &a);
yann@339
  4867
+
yann@339
  4868
+  if (iszero (&a))
yann@339
  4869
+    return 0;
yann@339
  4870
+  if (isnan (&a))
yann@339
  4871
+    return 0;
yann@339
  4872
+  /* get reasonable MAX_SI_INT...  */
yann@339
  4873
+  if (isinf (&a))
yann@339
  4874
+    return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
yann@339
  4875
+  /* it is a number, but a small one */
yann@339
  4876
+  if (a.normal_exp < 0)
yann@339
  4877
+    return 0;
yann@339
  4878
+  if (a.normal_exp > BITS_PER_SI - 2)
yann@339
  4879
+    return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
yann@339
  4880
+  tmp = a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
yann@339
  4881
+  return a.sign ? (-tmp) : (tmp);
yann@339
  4882
+}
yann@339
  4883
+#endif /* L_sf_to_si || L_df_to_si */
yann@339
  4884
+
yann@339
  4885
+#if defined(L_sf_to_usi) || defined(L_df_to_usi) || defined(L_tf_to_usi)
yann@339
  4886
+#if defined US_SOFTWARE_GOFAST || defined(L_tf_to_usi)
yann@339
  4887
+/* While libgcc2.c defines its own __fixunssfsi and __fixunsdfsi routines,
yann@339
  4888
+   we also define them for GOFAST because the ones in libgcc2.c have the
yann@339
  4889
+   wrong names and I'd rather define these here and keep GOFAST CYG-LOC's
yann@339
  4890
+   out of libgcc2.c.  We can't define these here if not GOFAST because then
yann@339
  4891
+   there'd be duplicate copies.  */
yann@339
  4892
+
yann@339
  4893
+USItype
yann@339
  4894
+float_to_usi (FLO_type arg_a)
yann@339
  4895
+{
yann@339
  4896
+  fp_number_type a;
yann@339
  4897
+  FLO_union_type au;
yann@339
  4898
+
yann@339
  4899
+  au.value = arg_a;
yann@339
  4900
+  unpack_d (&au, &a);
yann@339
  4901
+
yann@339
  4902
+  if (iszero (&a))
yann@339
  4903
+    return 0;
yann@339
  4904
+  if (isnan (&a))
yann@339
  4905
+    return 0;
yann@339
  4906
+  /* it is a negative number */
yann@339
  4907
+  if (a.sign)
yann@339
  4908
+    return 0;
yann@339
  4909
+  /* get reasonable MAX_USI_INT...  */
yann@339
  4910
+  if (isinf (&a))
yann@339
  4911
+    return MAX_USI_INT;
yann@339
  4912
+  /* it is a number, but a small one */
yann@339
  4913
+  if (a.normal_exp < 0)
yann@339
  4914
+    return 0;
yann@339
  4915
+  if (a.normal_exp > BITS_PER_SI - 1)
yann@339
  4916
+    return MAX_USI_INT;
yann@339
  4917
+  else if (a.normal_exp > (FRACBITS + NGARDS))
yann@339
  4918
+    return a.fraction.ll << (a.normal_exp - (FRACBITS + NGARDS));
yann@339
  4919
+  else
yann@339
  4920
+    return a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
yann@339
  4921
+}
yann@339
  4922
+#endif /* US_SOFTWARE_GOFAST */
yann@339
  4923
+#endif /* L_sf_to_usi || L_df_to_usi */
yann@339
  4924
+
yann@339
  4925
+#if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf)
yann@339
  4926
+FLO_type
yann@339
  4927
+negate (FLO_type arg_a)
yann@339
  4928
+{
yann@339
  4929
+  fp_number_type a;
yann@339
  4930
+  FLO_union_type au;
yann@339
  4931
+
yann@339
  4932
+  au.value = arg_a;
yann@339
  4933
+  unpack_d (&au, &a);
yann@339
  4934
+
yann@339
  4935
+  flip_sign (&a);
yann@339
  4936
+  return pack_d (&a);
yann@339
  4937
+}
yann@339
  4938
+#endif /* L_negate_sf || L_negate_df */
yann@339
  4939
+
yann@339
  4940
+#ifdef FLOAT
yann@339
  4941
+
yann@339
  4942
+#if defined(L_make_sf)
yann@339
  4943
+SFtype
yann@339
  4944
+__make_fp(fp_class_type class,
yann@339
  4945
+	     unsigned int sign,
yann@339
  4946
+	     int exp, 
yann@339
  4947
+	     USItype frac)
yann@339
  4948
+{
yann@339
  4949
+  fp_number_type in;
yann@339
  4950
+
yann@339
  4951
+  in.class = class;
yann@339
  4952
+  in.sign = sign;
yann@339
  4953
+  in.normal_exp = exp;
yann@339
  4954
+  in.fraction.ll = frac;
yann@339
  4955
+  return pack_d (&in);
yann@339
  4956
+}
yann@339
  4957
+#endif /* L_make_sf */
yann@339
  4958
+
yann@339
  4959
+#ifndef FLOAT_ONLY
yann@339
  4960
+
yann@339
  4961
+/* This enables one to build an fp library that supports float but not double.
yann@339
  4962
+   Otherwise, we would get an undefined reference to __make_dp.
yann@339
  4963
+   This is needed for some 8-bit ports that can't handle well values that
yann@339
  4964
+   are 8-bytes in size, so we just don't support double for them at all.  */
yann@339
  4965
+
yann@339
  4966
+#if defined(L_sf_to_df)
yann@339
  4967
+DFtype
yann@339
  4968
+sf_to_df (SFtype arg_a)
yann@339
  4969
+{
yann@339
  4970
+  fp_number_type in;
yann@339
  4971
+  FLO_union_type au;
yann@339
  4972
+
yann@339
  4973
+  au.value = arg_a;
yann@339
  4974
+  unpack_d (&au, &in);
yann@339
  4975
+
yann@339
  4976
+  return __make_dp (in.class, in.sign, in.normal_exp,
yann@339
  4977
+		    ((UDItype) in.fraction.ll) << F_D_BITOFF);
yann@339
  4978
+}
yann@339
  4979
+#endif /* L_sf_to_df */
yann@339
  4980
+
yann@339
  4981
+#if defined(L_sf_to_tf) && defined(TMODES)
yann@339
  4982
+TFtype
yann@339
  4983
+sf_to_tf (SFtype arg_a)
yann@339
  4984
+{
yann@339
  4985
+  fp_number_type in;
yann@339
  4986
+  FLO_union_type au;
yann@339
  4987
+
yann@339
  4988
+  au.value = arg_a;
yann@339
  4989
+  unpack_d (&au, &in);
yann@339
  4990
+
yann@339
  4991
+  return __make_tp (in.class, in.sign, in.normal_exp,
yann@339
  4992
+		    ((UTItype) in.fraction.ll) << F_T_BITOFF);
yann@339
  4993
+}
yann@339
  4994
+#endif /* L_sf_to_df */
yann@339
  4995
+
yann@339
  4996
+#endif /* ! FLOAT_ONLY */
yann@339
  4997
+#endif /* FLOAT */
yann@339
  4998
+
yann@339
  4999
+#ifndef FLOAT
yann@339
  5000
+
yann@339
  5001
+extern SFtype __make_fp (fp_class_type, unsigned int, int, USItype);
yann@339
  5002
+
yann@339
  5003
+#if defined(L_make_df)
yann@339
  5004
+DFtype
yann@339
  5005
+__make_dp (fp_class_type class, unsigned int sign, int exp, UDItype frac)
yann@339
  5006
+{
yann@339
  5007
+  fp_number_type in;
yann@339
  5008
+
yann@339
  5009
+  in.class = class;
yann@339
  5010
+  in.sign = sign;
yann@339
  5011
+  in.normal_exp = exp;
yann@339
  5012
+  in.fraction.ll = frac;
yann@339
  5013
+  return pack_d (&in);
yann@339
  5014
+}
yann@339
  5015
+#endif /* L_make_df */
yann@339
  5016
+
yann@339
  5017
+#if defined(L_df_to_sf)
yann@339
  5018
+SFtype
yann@339
  5019
+df_to_sf (DFtype arg_a)
yann@339
  5020
+{
yann@339
  5021
+  fp_number_type in;
yann@339
  5022
+  USItype sffrac;
yann@339
  5023
+  FLO_union_type au;
yann@339
  5024
+
yann@339
  5025
+  au.value = arg_a;
yann@339
  5026
+  unpack_d (&au, &in);
yann@339
  5027
+
yann@339
  5028
+  sffrac = in.fraction.ll >> F_D_BITOFF;
yann@339
  5029
+
yann@339
  5030
+  /* We set the lowest guard bit in SFFRAC if we discarded any non
yann@339
  5031
+     zero bits.  */
yann@339
  5032
+  if ((in.fraction.ll & (((USItype) 1 << F_D_BITOFF) - 1)) != 0)
yann@339
  5033
+    sffrac |= 1;
yann@339
  5034
+
yann@339
  5035
+  return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
yann@339
  5036
+}
yann@339
  5037
+#endif /* L_df_to_sf */
yann@339
  5038
+
yann@339
  5039
+#if defined(L_df_to_tf) && defined(TMODES) \
yann@339
  5040
+    && !defined(FLOAT) && !defined(TFLOAT)
yann@339
  5041
+TFtype
yann@339
  5042
+df_to_tf (DFtype arg_a)
yann@339
  5043
+{
yann@339
  5044
+  fp_number_type in;
yann@339
  5045
+  FLO_union_type au;
yann@339
  5046
+
yann@339
  5047
+  au.value = arg_a;
yann@339
  5048
+  unpack_d (&au, &in);
yann@339
  5049
+
yann@339
  5050
+  return __make_tp (in.class, in.sign, in.normal_exp,
yann@339
  5051
+		    ((UTItype) in.fraction.ll) << D_T_BITOFF);
yann@339
  5052
+}
yann@339
  5053
+#endif /* L_sf_to_df */
yann@339
  5054
+
yann@339
  5055
+#ifdef TFLOAT
yann@339
  5056
+#if defined(L_make_tf)
yann@339
  5057
+TFtype
yann@339
  5058
+__make_tp(fp_class_type class,
yann@339
  5059
+	     unsigned int sign,
yann@339
  5060
+	     int exp, 
yann@339
  5061
+	     UTItype frac)
yann@339
  5062
+{
yann@339
  5063
+  fp_number_type in;
yann@339
  5064
+
yann@339
  5065
+  in.class = class;
yann@339
  5066
+  in.sign = sign;
yann@339
  5067
+  in.normal_exp = exp;
yann@339
  5068
+  in.fraction.ll = frac;
yann@339
  5069
+  return pack_d (&in);
yann@339
  5070
+}
yann@339
  5071
+#endif /* L_make_tf */
yann@339
  5072
+
yann@339
  5073
+#if defined(L_tf_to_df)
yann@339
  5074
+DFtype
yann@339
  5075
+tf_to_df (TFtype arg_a)
yann@339
  5076
+{
yann@339
  5077
+  fp_number_type in;
yann@339
  5078
+  UDItype sffrac;
yann@339
  5079
+  FLO_union_type au;
yann@339
  5080
+
yann@339
  5081
+  au.value = arg_a;
yann@339
  5082
+  unpack_d (&au, &in);
yann@339
  5083
+
yann@339
  5084
+  sffrac = in.fraction.ll >> D_T_BITOFF;
yann@339
  5085
+
yann@339
  5086
+  /* We set the lowest guard bit in SFFRAC if we discarded any non
yann@339
  5087
+     zero bits.  */
yann@339
  5088
+  if ((in.fraction.ll & (((UTItype) 1 << D_T_BITOFF) - 1)) != 0)
yann@339
  5089
+    sffrac |= 1;
yann@339
  5090
+
yann@339
  5091
+  return __make_dp (in.class, in.sign, in.normal_exp, sffrac);
yann@339
  5092
+}
yann@339
  5093
+#endif /* L_tf_to_df */
yann@339
  5094
+
yann@339
  5095
+#if defined(L_tf_to_sf)
yann@339
  5096
+SFtype
yann@339
  5097
+tf_to_sf (TFtype arg_a)
yann@339
  5098
+{
yann@339
  5099
+  fp_number_type in;
yann@339
  5100
+  USItype sffrac;
yann@339
  5101
+  FLO_union_type au;
yann@339
  5102
+
yann@339
  5103
+  au.value = arg_a;
yann@339
  5104
+  unpack_d (&au, &in);
yann@339
  5105
+
yann@339
  5106
+  sffrac = in.fraction.ll >> F_T_BITOFF;
yann@339
  5107
+
yann@339
  5108
+  /* We set the lowest guard bit in SFFRAC if we discarded any non
yann@339
  5109
+     zero bits.  */
yann@339
  5110
+  if ((in.fraction.ll & (((UTItype) 1 << F_T_BITOFF) - 1)) != 0)
yann@339
  5111
+    sffrac |= 1;
yann@339
  5112
+
yann@339
  5113
+  return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
yann@339
  5114
+}
yann@339
  5115
+#endif /* L_tf_to_sf */
yann@339
  5116
+#endif /* TFLOAT */
yann@339
  5117
+
yann@339
  5118
+#endif /* ! FLOAT */
yann@339
  5119
+#endif /* !EXTENDED_FLOAT_STUBS */
yann@339
  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
yann@339
  5121
--- gcc-3.4.6.orig/gcc/config/nios2/nios2-fp-bit.c	1970-01-01 01:00:00.000000000 +0100
yann@339
  5122
+++ gcc-3.4.6/gcc/config/nios2/nios2-fp-bit.c	2007-08-15 23:09:36.000000000 +0200
yann@339
  5123
@@ -0,0 +1,1652 @@
yann@339
  5124
+#define FLOAT
yann@339
  5125
+/* This is a software floating point library which can be used
yann@339
  5126
+   for targets without hardware floating point. 
yann@339
  5127
+   Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004
yann@339
  5128
+   Free Software Foundation, Inc.
yann@339
  5129
+
yann@339
  5130
+This file is free software; you can redistribute it and/or modify it
yann@339
  5131
+under the terms of the GNU General Public License as published by the
yann@339
  5132
+Free Software Foundation; either version 2, or (at your option) any
yann@339
  5133
+later version.
yann@339
  5134
+
yann@339
  5135
+In addition to the permissions in the GNU General Public License, the
yann@339
  5136
+Free Software Foundation gives you unlimited permission to link the
yann@339
  5137
+compiled version of this file with other programs, and to distribute
yann@339
  5138
+those programs without any restriction coming from the use of this
yann@339
  5139
+file.  (The General Public License restrictions do apply in other
yann@339
  5140
+respects; for example, they cover modification of the file, and
yann@339
  5141
+distribution when not linked into another program.)
yann@339
  5142
+
yann@339
  5143
+This file is distributed in the hope that it will be useful, but
yann@339
  5144
+WITHOUT ANY WARRANTY; without even the implied warranty of
yann@339
  5145
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
yann@339
  5146
+General Public License for more details.
yann@339
  5147
+
yann@339
  5148
+You should have received a copy of the GNU General Public License
yann@339
  5149
+along with this program; see the file COPYING.  If not, write to
yann@339
  5150
+the Free Software Foundation, 59 Temple Place - Suite 330,
yann@339
  5151
+Boston, MA 02111-1307, USA.  */
yann@339
  5152
+
yann@339
  5153
+/* As a special exception, if you link this library with other files,
yann@339
  5154
+   some of which are compiled with GCC, to produce an executable,
yann@339
  5155
+   this library does not by itself cause the resulting executable
yann@339
  5156
+   to be covered by the GNU General Public License.
yann@339
  5157
+   This exception does not however invalidate any other reasons why
yann@339
  5158
+   the executable file might be covered by the GNU General Public License.  */
yann@339
  5159
+
yann@339
  5160
+/* This implements IEEE 754 format arithmetic, but does not provide a
yann@339
  5161
+   mechanism for setting the rounding mode, or for generating or handling
yann@339
  5162
+   exceptions.
yann@339
  5163
+
yann@339
  5164
+   The original code by Steve Chamberlain, hacked by Mark Eichin and Jim
yann@339
  5165
+   Wilson, all of Cygnus Support.  */
yann@339
  5166
+
yann@339
  5167
+/* The intended way to use this file is to make two copies, add `#define FLOAT'
yann@339
  5168
+   to one copy, then compile both copies and add them to libgcc.a.  */
yann@339
  5169
+
yann@339
  5170
+#include "tconfig.h"
yann@339
  5171
+#include "coretypes.h"
yann@339
  5172
+#include "tm.h"
yann@339
  5173
+#include "config/fp-bit.h"
yann@339
  5174
+
yann@339
  5175
+/* The following macros can be defined to change the behavior of this file:
yann@339
  5176
+   FLOAT: Implement a `float', aka SFmode, fp library.  If this is not
yann@339
  5177
+     defined, then this file implements a `double', aka DFmode, fp library.
yann@339
  5178
+   FLOAT_ONLY: Used with FLOAT, to implement a `float' only library, i.e.
yann@339
  5179
+     don't include float->double conversion which requires the double library.
yann@339
  5180
+     This is useful only for machines which can't support doubles, e.g. some
yann@339
  5181
+     8-bit processors.
yann@339
  5182
+   CMPtype: Specify the type that floating point compares should return.
yann@339
  5183
+     This defaults to SItype, aka int.
yann@339
  5184
+   US_SOFTWARE_GOFAST: This makes all entry points use the same names as the
yann@339
  5185
+     US Software goFast library.
yann@339
  5186
+   _DEBUG_BITFLOAT: This makes debugging the code a little easier, by adding
yann@339
  5187
+     two integers to the FLO_union_type.
yann@339
  5188
+   NO_DENORMALS: Disable handling of denormals.
yann@339
  5189
+   NO_NANS: Disable nan and infinity handling
yann@339
  5190
+   SMALL_MACHINE: Useful when operations on QIs and HIs are faster
yann@339
  5191
+     than on an SI */
yann@339
  5192
+
yann@339
  5193
+/* We don't currently support extended floats (long doubles) on machines
yann@339
  5194
+   without hardware to deal with them.
yann@339
  5195
+
yann@339
  5196
+   These stubs are just to keep the linker from complaining about unresolved
yann@339
  5197
+   references which can be pulled in from libio & libstdc++, even if the
yann@339
  5198
+   user isn't using long doubles.  However, they may generate an unresolved
yann@339
  5199
+   external to abort if abort is not used by the function, and the stubs
yann@339
  5200
+   are referenced from within libc, since libgcc goes before and after the
yann@339
  5201
+   system library.  */
yann@339
  5202
+
yann@339
  5203
+#ifdef DECLARE_LIBRARY_RENAMES
yann@339
  5204
+  DECLARE_LIBRARY_RENAMES
yann@339
  5205
+#endif
yann@339
  5206
+
yann@339
  5207
+#ifdef EXTENDED_FLOAT_STUBS
yann@339
  5208
+extern void abort (void);
yann@339
  5209
+void __extendsfxf2 (void) { abort(); }
yann@339
  5210
+void __extenddfxf2 (void) { abort(); }
yann@339
  5211
+void __truncxfdf2 (void) { abort(); }
yann@339
  5212
+void __truncxfsf2 (void) { abort(); }
yann@339
  5213
+void __fixxfsi (void) { abort(); }
yann@339
  5214
+void __floatsixf (void) { abort(); }
yann@339
  5215
+void __addxf3 (void) { abort(); }
yann@339
  5216
+void __subxf3 (void) { abort(); }
yann@339
  5217
+void __mulxf3 (void) { abort(); }
yann@339
  5218
+void __divxf3 (void) { abort(); }
yann@339
  5219
+void __negxf2 (void) { abort(); }
yann@339
  5220
+void __eqxf2 (void) { abort(); }
yann@339
  5221
+void __nexf2 (void) { abort(); }
yann@339
  5222
+void __gtxf2 (void) { abort(); }
yann@339
  5223
+void __gexf2 (void) { abort(); }
yann@339
  5224
+void __lexf2 (void) { abort(); }
yann@339
  5225
+void __ltxf2 (void) { abort(); }
yann@339
  5226
+
yann@339
  5227
+void __extendsftf2 (void) { abort(); }
yann@339
  5228
+void __extenddftf2 (void) { abort(); }
yann@339
  5229
+void __trunctfdf2 (void) { abort(); }
yann@339
  5230
+void __trunctfsf2 (void) { abort(); }
yann@339
  5231
+void __fixtfsi (void) { abort(); }
yann@339
  5232
+void __floatsitf (void) { abort(); }
yann@339
  5233
+void __addtf3 (void) { abort(); }
yann@339
  5234
+void __subtf3 (void) { abort(); }
yann@339
  5235
+void __multf3 (void) { abort(); }
yann@339
  5236
+void __divtf3 (void) { abort(); }
yann@339
  5237
+void __negtf2 (void) { abort(); }
yann@339
  5238
+void __eqtf2 (void) { abort(); }
yann@339
  5239
+void __netf2 (void) { abort(); }
yann@339
  5240
+void __gttf2 (void) { abort(); }
yann@339
  5241
+void __getf2 (void) { abort(); }
yann@339
  5242
+void __letf2 (void) { abort(); }
yann@339
  5243
+void __lttf2 (void) { abort(); }
yann@339
  5244
+#else	/* !EXTENDED_FLOAT_STUBS, rest of file */
yann@339
  5245
+
yann@339
  5246
+/* IEEE "special" number predicates */
yann@339
  5247
+
yann@339
  5248
+#ifdef NO_NANS
yann@339
  5249
+
yann@339
  5250
+#define nan() 0
yann@339
  5251
+#define isnan(x) 0
yann@339
  5252
+#define isinf(x) 0
yann@339
  5253
+#else
yann@339
  5254
+
yann@339
  5255
+#if   defined L_thenan_sf
yann@339
  5256
+const fp_number_type __thenan_sf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
yann@339
  5257
+#elif defined L_thenan_df
yann@339
  5258
+const fp_number_type __thenan_df = { CLASS_SNAN, 0, 0, {(fractype) 0} };
yann@339
  5259
+#elif defined L_thenan_tf
yann@339
  5260
+const fp_number_type __thenan_tf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
yann@339
  5261
+#elif defined TFLOAT
yann@339
  5262
+extern const fp_number_type __thenan_tf;
yann@339
  5263
+#elif defined FLOAT
yann@339
  5264
+extern const fp_number_type __thenan_sf;
yann@339
  5265
+#else
yann@339
  5266
+extern const fp_number_type __thenan_df;
yann@339
  5267
+#endif
yann@339
  5268
+
yann@339
  5269
+INLINE
yann@339
  5270
+static fp_number_type *
yann@339
  5271
+nan (void)
yann@339
  5272
+{
yann@339
  5273
+  /* Discard the const qualifier...  */
yann@339
  5274
+#ifdef TFLOAT
yann@339
  5275
+  return (fp_number_type *) (& __thenan_tf);
yann@339
  5276
+#elif defined FLOAT  
yann@339
  5277
+  return (fp_number_type *) (& __thenan_sf);
yann@339
  5278
+#else
yann@339
  5279
+  return (fp_number_type *) (& __thenan_df);
yann@339
  5280
+#endif
yann@339
  5281
+}
yann@339
  5282
+
yann@339
  5283
+INLINE
yann@339
  5284
+static int
yann@339
  5285
+isnan ( fp_number_type *  x)
yann@339
  5286
+{
yann@339
  5287
+  return x->class == CLASS_SNAN || x->class == CLASS_QNAN;
yann@339
  5288
+}
yann@339
  5289
+
yann@339
  5290
+INLINE
yann@339
  5291
+static int
yann@339
  5292
+isinf ( fp_number_type *  x)
yann@339
  5293
+{
yann@339
  5294
+  return x->class == CLASS_INFINITY;
yann@339
  5295
+}
yann@339
  5296
+
yann@339
  5297
+#endif /* NO_NANS */
yann@339
  5298
+
yann@339
  5299
+INLINE
yann@339
  5300
+static int
yann@339
  5301
+iszero ( fp_number_type *  x)
yann@339
  5302
+{
yann@339
  5303
+  return x->class == CLASS_ZERO;
yann@339
  5304
+}
yann@339
  5305
+
yann@339
  5306
+INLINE 
yann@339
  5307
+static void
yann@339
  5308
+flip_sign ( fp_number_type *  x)
yann@339
  5309
+{
yann@339
  5310
+  x->sign = !x->sign;
yann@339
  5311
+}
yann@339
  5312
+
yann@339
  5313
+extern FLO_type pack_d ( fp_number_type * );
yann@339
  5314
+
yann@339
  5315
+#if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf)
yann@339
  5316
+FLO_type
yann@339
  5317
+pack_d ( fp_number_type *  src)
yann@339
  5318
+{
yann@339
  5319
+  FLO_union_type dst;
yann@339
  5320
+  fractype fraction = src->fraction.ll;	/* wasn't unsigned before? */
yann@339
  5321
+  int sign = src->sign;
yann@339
  5322
+  int exp = 0;
yann@339
  5323
+
yann@339
  5324
+  if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && (isnan (src) || isinf (src)))
yann@339
  5325
+    {
yann@339
  5326
+      /* We can't represent these values accurately.  By using the
yann@339
  5327
+	 largest possible magnitude, we guarantee that the conversion
yann@339
  5328
+	 of infinity is at least as big as any finite number.  */
yann@339
  5329
+      exp = EXPMAX;
yann@339
  5330
+      fraction = ((fractype) 1 << FRACBITS) - 1;
yann@339
  5331
+    }
yann@339
  5332
+  else if (isnan (src))
yann@339
  5333
+    {
yann@339
  5334
+      exp = EXPMAX;
yann@339
  5335
+      if (src->class == CLASS_QNAN || 1)
yann@339
  5336
+	{
yann@339
  5337
+#ifdef QUIET_NAN_NEGATED
yann@339
  5338
+	  fraction |= QUIET_NAN - 1;
yann@339
  5339
+#else
yann@339
  5340
+	  fraction |= QUIET_NAN;
yann@339
  5341
+#endif
yann@339
  5342
+	}
yann@339
  5343
+    }
yann@339
  5344
+  else if (isinf (src))
yann@339
  5345
+    {
yann@339
  5346
+      exp = EXPMAX;
yann@339
  5347
+      fraction = 0;
yann@339
  5348
+    }
yann@339
  5349
+  else if (iszero (src))
yann@339
  5350
+    {
yann@339
  5351
+      exp = 0;
yann@339
  5352
+      fraction = 0;
yann@339
  5353
+    }
yann@339
  5354
+  else if (fraction == 0)
yann@339
  5355
+    {
yann@339
  5356
+      exp = 0;
yann@339
  5357
+    }
yann@339
  5358
+  else
yann@339
  5359
+    {
yann@339
  5360
+      if (src->normal_exp < NORMAL_EXPMIN)
yann@339
  5361
+	{
yann@339
  5362
+#ifdef NO_DENORMALS
yann@339
  5363
+	  /* Go straight to a zero representation if denormals are not
yann@339
  5364
+ 	     supported.  The denormal handling would be harmless but
yann@339
  5365
+ 	     isn't unnecessary.  */
yann@339
  5366
+	  exp = 0;
yann@339
  5367
+	  fraction = 0;
yann@339
  5368
+#else /* NO_DENORMALS */
yann@339
  5369
+	  /* This number's exponent is too low to fit into the bits
yann@339
  5370
+	     available in the number, so we'll store 0 in the exponent and
yann@339
  5371
+	     shift the fraction to the right to make up for it.  */
yann@339
  5372
+
yann@339
  5373
+	  int shift = NORMAL_EXPMIN - src->normal_exp;
yann@339
  5374
+
yann@339
  5375
+	  exp = 0;
yann@339
  5376
+
yann@339
  5377
+	  if (shift > FRAC_NBITS - NGARDS)
yann@339
  5378
+	    {
yann@339
  5379
+	      /* No point shifting, since it's more that 64 out.  */
yann@339
  5380
+	      fraction = 0;
yann@339
  5381
+	    }
yann@339
  5382
+	  else
yann@339
  5383
+	    {
yann@339
  5384
+	      int lowbit = (fraction & (((fractype)1 << shift) - 1)) ? 1 : 0;
yann@339
  5385
+	      fraction = (fraction >> shift) | lowbit;
yann@339
  5386
+	    }
yann@339
  5387
+	  if ((fraction & GARDMASK) == GARDMSB)
yann@339
  5388
+	    {
yann@339
  5389
+	      if ((fraction & (1 << NGARDS)))
yann@339
  5390
+		fraction += GARDROUND + 1;
yann@339
  5391
+	    }
yann@339
  5392
+	  else
yann@339
  5393
+	    {
yann@339
  5394
+	      /* Add to the guards to round up.  */
yann@339
  5395
+	      fraction += GARDROUND;
yann@339
  5396
+	    }
yann@339
  5397
+	  /* Perhaps the rounding means we now need to change the
yann@339
  5398
+             exponent, because the fraction is no longer denormal.  */
yann@339
  5399
+	  if (fraction >= IMPLICIT_1)
yann@339
  5400
+	    {
yann@339
  5401
+	      exp += 1;
yann@339
  5402
+	    }
yann@339
  5403
+	  fraction >>= NGARDS;
yann@339
  5404
+#endif /* NO_DENORMALS */
yann@339
  5405
+	}
yann@339
  5406
+      else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS)
yann@339
  5407
+	       && src->normal_exp > EXPBIAS)
yann@339
  5408
+	{
yann@339
  5409
+	  exp = EXPMAX;
yann@339
  5410
+	  fraction = 0;
yann@339
  5411
+	}
yann@339
  5412
+      else
yann@339
  5413
+	{
yann@339
  5414
+	  exp = src->normal_exp + EXPBIAS;
yann@339
  5415
+	  if (!ROUND_TOWARDS_ZERO)
yann@339
  5416
+	    {
yann@339
  5417
+	      /* IF the gard bits are the all zero, but the first, then we're
yann@339
  5418
+		 half way between two numbers, choose the one which makes the
yann@339
  5419
+		 lsb of the answer 0.  */
yann@339
  5420
+	      if ((fraction & GARDMASK) == GARDMSB)
yann@339
  5421
+		{
yann@339
  5422
+		  if (fraction & (1 << NGARDS))
yann@339
  5423
+		    fraction += GARDROUND + 1;
yann@339
  5424
+		}
yann@339
  5425
+	      else
yann@339
  5426
+		{
yann@339
  5427
+		  /* Add a one to the guards to round up */
yann@339
  5428
+		  fraction += GARDROUND;
yann@339
  5429
+		}
yann@339
  5430
+	      if (fraction >= IMPLICIT_2)
yann@339
  5431
+		{
yann@339
  5432
+		  fraction >>= 1;
yann@339
  5433
+		  exp += 1;
yann@339
  5434
+		}
yann@339
  5435
+	    }
yann@339
  5436
+	  fraction >>= NGARDS;
yann@339
  5437
+
yann@339
  5438
+	  if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp > EXPMAX)
yann@339
  5439
+	    {
yann@339
  5440
+	      /* Saturate on overflow.  */
yann@339
  5441
+	      exp = EXPMAX;
yann@339
  5442
+	      fraction = ((fractype) 1 << FRACBITS) - 1;
yann@339
  5443
+	    }
yann@339
  5444
+	}
yann@339
  5445
+    }
yann@339
  5446
+
yann@339
  5447
+  /* We previously used bitfields to store the number, but this doesn't
yann@339
  5448
+     handle little/big endian systems conveniently, so use shifts and
yann@339
  5449
+     masks */
yann@339
  5450
+#ifdef FLOAT_BIT_ORDER_MISMATCH
yann@339
  5451
+  dst.bits.fraction = fraction;
yann@339
  5452
+  dst.bits.exp = exp;
yann@339
  5453
+  dst.bits.sign = sign;
yann@339
  5454
+#else
yann@339
  5455
+# if defined TFLOAT && defined HALFFRACBITS
yann@339
  5456
+ {
yann@339
  5457
+   halffractype high, low, unity;
yann@339
  5458
+   int lowsign, lowexp;
yann@339
  5459
+
yann@339
  5460
+   unity = (halffractype) 1 << HALFFRACBITS;
yann@339
  5461
+
yann@339
  5462
+   /* Set HIGH to the high double's significand, masking out the implicit 1.
yann@339
  5463
+      Set LOW to the low double's full significand.  */
yann@339
  5464
+   high = (fraction >> (FRACBITS - HALFFRACBITS)) & (unity - 1);
yann@339
  5465
+   low = fraction & (unity * 2 - 1);
yann@339
  5466
+
yann@339
  5467
+   /* Get the initial sign and exponent of the low double.  */
yann@339
  5468
+   lowexp = exp - HALFFRACBITS - 1;
yann@339
  5469
+   lowsign = sign;
yann@339
  5470
+
yann@339
  5471
+   /* HIGH should be rounded like a normal double, making |LOW| <=
yann@339
  5472
+      0.5 ULP of HIGH.  Assume round-to-nearest.  */
yann@339
  5473
+   if (exp < EXPMAX)
yann@339
  5474
+     if (low > unity || (low == unity && (high & 1) == 1))
yann@339
  5475
+       {
yann@339
  5476
+	 /* Round HIGH up and adjust LOW to match.  */
yann@339
  5477
+	 high++;
yann@339
  5478
+	 if (high == unity)
yann@339
  5479
+	   {
yann@339
  5480
+	     /* May make it infinite, but that's OK.  */
yann@339
  5481
+	     high = 0;
yann@339
  5482
+	     exp++;
yann@339
  5483
+	   }
yann@339
  5484
+	 low = unity * 2 - low;
yann@339
  5485
+	 lowsign ^= 1;
yann@339
  5486
+       }
yann@339
  5487
+
yann@339
  5488
+   high |= (halffractype) exp << HALFFRACBITS;
yann@339
  5489
+   high |= (halffractype) sign << (HALFFRACBITS + EXPBITS);
yann@339
  5490
+
yann@339
  5491
+   if (exp == EXPMAX || exp == 0 || low == 0)
yann@339
  5492
+     low = 0;
yann@339
  5493
+   else
yann@339
  5494
+     {
yann@339
  5495
+       while (lowexp > 0 && low < unity)
yann@339
  5496
+	 {
yann@339
  5497
+	   low <<= 1;
yann@339
  5498
+	   lowexp--;
yann@339
  5499
+	 }
yann@339
  5500
+
yann@339
  5501
+       if (lowexp <= 0)
yann@339
  5502
+	 {
yann@339
  5503
+	   halffractype roundmsb, round;
yann@339
  5504
+	   int shift;
yann@339
  5505
+
yann@339
  5506
+	   shift = 1 - lowexp;
yann@339
  5507
+	   roundmsb = (1 << (shift - 1));
yann@339
  5508
+	   round = low & ((roundmsb << 1) - 1);
yann@339
  5509
+
yann@339
  5510
+	   low >>= shift;
yann@339
  5511
+	   lowexp = 0;
yann@339
  5512
+
yann@339
  5513
+	   if (round > roundmsb || (round == roundmsb && (low & 1) == 1))
yann@339
  5514
+	     {
yann@339
  5515
+	       low++;
yann@339
  5516
+	       if (low == unity)
yann@339
  5517
+		 /* LOW rounds up to the smallest normal number.  */
yann@339
  5518
+		 lowexp++;
yann@339
  5519
+	     }
yann@339
  5520
+	 }
yann@339
  5521
+
yann@339
  5522
+       low &= unity - 1;
yann@339
  5523
+       low |= (halffractype) lowexp << HALFFRACBITS;
yann@339
  5524
+       low |= (halffractype) lowsign << (HALFFRACBITS + EXPBITS);
yann@339
  5525
+     }
yann@339
  5526
+   dst.value_raw = ((fractype) high << HALFSHIFT) | low;
yann@339
  5527
+ }
yann@339
  5528
+# else
yann@339
  5529
+  dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1);
yann@339
  5530
+  dst.value_raw |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << FRACBITS;
yann@339
  5531
+  dst.value_raw |= ((fractype) (sign & 1)) << (FRACBITS | EXPBITS);
yann@339
  5532
+# endif
yann@339
  5533
+#endif
yann@339
  5534
+
yann@339
  5535
+#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
yann@339
  5536
+#ifdef TFLOAT
yann@339
  5537
+  {
yann@339
  5538
+    qrtrfractype tmp1 = dst.words[0];
yann@339
  5539
+    qrtrfractype tmp2 = dst.words[1];
yann@339
  5540
+    dst.words[0] = dst.words[3];
yann@339
  5541
+    dst.words[1] = dst.words[2];
yann@339
  5542
+    dst.words[2] = tmp2;
yann@339
  5543
+    dst.words[3] = tmp1;
yann@339
  5544
+  }
yann@339
  5545
+#else
yann@339
  5546
+  {
yann@339
  5547
+    halffractype tmp = dst.words[0];
yann@339
  5548
+    dst.words[0] = dst.words[1];
yann@339
  5549
+    dst.words[1] = tmp;
yann@339
  5550
+  }
yann@339
  5551
+#endif
yann@339
  5552
+#endif
yann@339
  5553
+
yann@339
  5554
+  return dst.value;
yann@339
  5555
+}
yann@339
  5556
+#endif
yann@339
  5557
+
yann@339
  5558
+#if defined(L_unpack_df) || defined(L_unpack_sf) || defined(L_unpack_tf)
yann@339
  5559
+void
yann@339
  5560
+unpack_d (FLO_union_type * src, fp_number_type * dst)
yann@339
  5561
+{
yann@339
  5562
+  /* We previously used bitfields to store the number, but this doesn't
yann@339
  5563
+     handle little/big endian systems conveniently, so use shifts and
yann@339
  5564
+     masks */
yann@339
  5565
+  fractype fraction;
yann@339
  5566
+  int exp;
yann@339
  5567
+  int sign;
yann@339
  5568
+
yann@339
  5569
+#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
yann@339
  5570
+  FLO_union_type swapped;
yann@339
  5571
+
yann@339
  5572
+#ifdef TFLOAT
yann@339
  5573
+  swapped.words[0] = src->words[3];
yann@339
  5574
+  swapped.words[1] = src->words[2];
yann@339
  5575
+  swapped.words[2] = src->words[1];
yann@339
  5576
+  swapped.words[3] = src->words[0];
yann@339
  5577
+#else
yann@339
  5578
+  swapped.words[0] = src->words[1];
yann@339
  5579
+  swapped.words[1] = src->words[0];
yann@339
  5580
+#endif
yann@339
  5581
+  src = &swapped;
yann@339
  5582
+#endif
yann@339
  5583
+  
yann@339
  5584
+#ifdef FLOAT_BIT_ORDER_MISMATCH
yann@339
  5585
+  fraction = src->bits.fraction;
yann@339
  5586
+  exp = src->bits.exp;
yann@339
  5587
+  sign = src->bits.sign;
yann@339
  5588
+#else
yann@339
  5589
+# if defined TFLOAT && defined HALFFRACBITS
yann@339
  5590
+ {
yann@339
  5591
+   halffractype high, low;
yann@339
  5592
+   
yann@339
  5593
+   high = src->value_raw >> HALFSHIFT;
yann@339
  5594
+   low = src->value_raw & (((fractype)1 << HALFSHIFT) - 1);
yann@339
  5595
+
yann@339
  5596
+   fraction = high & ((((fractype)1) << HALFFRACBITS) - 1);
yann@339
  5597
+   fraction <<= FRACBITS - HALFFRACBITS;
yann@339
  5598
+   exp = ((int)(high >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
yann@339
  5599
+   sign = ((int)(high >> (((HALFFRACBITS + EXPBITS))))) & 1;
yann@339
  5600
+
yann@339
  5601
+   if (exp != EXPMAX && exp != 0 && low != 0)
yann@339
  5602
+     {
yann@339
  5603
+       int lowexp = ((int)(low >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
yann@339
  5604
+       int lowsign = ((int)(low >> (((HALFFRACBITS + EXPBITS))))) & 1;
yann@339
  5605
+       int shift;
yann@339
  5606
+       fractype xlow;
yann@339
  5607
+
yann@339
  5608
+       xlow = low & ((((fractype)1) << HALFFRACBITS) - 1);
yann@339
  5609
+       if (lowexp)
yann@339
  5610
+	 xlow |= (((halffractype)1) << HALFFRACBITS);
yann@339
  5611
+       else
yann@339
  5612
+	 lowexp = 1;
yann@339
  5613
+       shift = (FRACBITS - HALFFRACBITS) - (exp - lowexp);
yann@339
  5614
+       if (shift > 0)
yann@339
  5615
+	 xlow <<= shift;
yann@339
  5616
+       else if (shift < 0)
yann@339
  5617
+	 xlow >>= -shift;
yann@339
  5618
+       if (sign == lowsign)
yann@339
  5619
+	 fraction += xlow;
yann@339
  5620
+       else if (fraction >= xlow)
yann@339
  5621
+	 fraction -= xlow;
yann@339
  5622
+       else
yann@339
  5623
+	 {
yann@339
  5624
+	   /* The high part is a power of two but the full number is lower.
yann@339
  5625
+	      This code will leave the implicit 1 in FRACTION, but we'd
yann@339
  5626
+	      have added that below anyway.  */
yann@339
  5627
+	   fraction = (((fractype) 1 << FRACBITS) - xlow) << 1;
yann@339
  5628
+	   exp--;
yann@339
  5629
+	 }
yann@339
  5630
+     }
yann@339
  5631
+ }
yann@339
  5632
+# else
yann@339
  5633
+  fraction = src->value_raw & ((((fractype)1) << FRACBITS) - 1);
yann@339
  5634
+  exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1);
yann@339
  5635
+  sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1;
yann@339
  5636
+# endif
yann@339
  5637
+#endif
yann@339
  5638
+
yann@339
  5639
+  dst->sign = sign;
yann@339
  5640
+  if (exp == 0)
yann@339
  5641
+    {
yann@339
  5642
+      /* Hmm.  Looks like 0 */
yann@339
  5643
+      if (fraction == 0
yann@339
  5644
+#ifdef NO_DENORMALS
yann@339
  5645
+	  || 1
yann@339
  5646
+#endif
yann@339
  5647
+	  )
yann@339
  5648
+	{
yann@339
  5649
+	  /* tastes like zero */
yann@339
  5650
+	  dst->class = CLASS_ZERO;
yann@339
  5651
+	}
yann@339
  5652
+      else
yann@339
  5653
+	{
yann@339
  5654
+	  /* Zero exponent with nonzero fraction - it's denormalized,
yann@339
  5655
+	     so there isn't a leading implicit one - we'll shift it so
yann@339
  5656
+	     it gets one.  */
yann@339
  5657
+	  dst->normal_exp = exp - EXPBIAS + 1;
yann@339
  5658
+	  fraction <<= NGARDS;
yann@339
  5659
+
yann@339
  5660
+	  dst->class = CLASS_NUMBER;
yann@339
  5661
+#if 1
yann@339
  5662
+	  while (fraction < IMPLICIT_1)
yann@339
  5663
+	    {
yann@339
  5664
+	      fraction <<= 1;
yann@339
  5665
+	      dst->normal_exp--;
yann@339
  5666
+	    }
yann@339
  5667
+#endif
yann@339
  5668
+	  dst->fraction.ll = fraction;
yann@339
  5669
+	}
yann@339
  5670
+    }
yann@339
  5671
+  else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp == EXPMAX)
yann@339
  5672
+    {
yann@339
  5673
+      /* Huge exponent*/
yann@339
  5674
+      if (fraction == 0)
yann@339
  5675
+	{
yann@339
  5676
+	  /* Attached to a zero fraction - means infinity */
yann@339
  5677
+	  dst->class = CLASS_INFINITY;
yann@339
  5678
+	}
yann@339
  5679
+      else
yann@339
  5680
+	{
yann@339
  5681
+	  /* Nonzero fraction, means nan */
yann@339
  5682
+#ifdef QUIET_NAN_NEGATED
yann@339
  5683
+	  if ((fraction & QUIET_NAN) == 0)
yann@339
  5684
+#else
yann@339
  5685
+	  if (fraction & QUIET_NAN)
yann@339
  5686
+#endif
yann@339
  5687
+	    {
yann@339
  5688
+	      dst->class = CLASS_QNAN;
yann@339
  5689
+	    }
yann@339
  5690
+	  else
yann@339
  5691
+	    {
yann@339
  5692
+	      dst->class = CLASS_SNAN;
yann@339
  5693
+	    }
yann@339
  5694
+	  /* Keep the fraction part as the nan number */
yann@339
  5695
+	  dst->fraction.ll = fraction;
yann@339
  5696
+	}
yann@339
  5697
+    }
yann@339
  5698
+  else
yann@339
  5699
+    {
yann@339
  5700
+      /* Nothing strange about this number */
yann@339
  5701
+      dst->normal_exp = exp - EXPBIAS;
yann@339
  5702
+      dst->class = CLASS_NUMBER;
yann@339
  5703
+      dst->fraction.ll = (fraction << NGARDS) | IMPLICIT_1;
yann@339
  5704
+    }
yann@339
  5705
+}
yann@339
  5706
+#endif /* L_unpack_df || L_unpack_sf */
yann@339
  5707
+
yann@339
  5708
+#if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf)
yann@339
  5709
+static fp_number_type *
yann@339
  5710
+_fpadd_parts (fp_number_type * a,
yann@339
  5711
+	      fp_number_type * b,
yann@339
  5712
+	      fp_number_type * tmp)
yann@339
  5713
+{
yann@339
  5714
+  intfrac tfraction;
yann@339
  5715
+
yann@339
  5716
+  /* Put commonly used fields in local variables.  */
yann@339
  5717
+  int a_normal_exp;
yann@339
  5718
+  int b_normal_exp;
yann@339
  5719
+  fractype a_fraction;
yann@339
  5720
+  fractype b_fraction;
yann@339
  5721
+
yann@339
  5722
+  if (isnan (a))
yann@339
  5723
+    {
yann@339
  5724
+      return a;
yann@339
  5725
+    }
yann@339
  5726
+  if (isnan (b))
yann@339
  5727
+    {
yann@339
  5728
+      return b;
yann@339
  5729
+    }
yann@339
  5730
+  if (isinf (a))
yann@339
  5731
+    {
yann@339
  5732
+      /* Adding infinities with opposite signs yields a NaN.  */
yann@339
  5733
+      if (isinf (b) && a->sign != b->sign)
yann@339
  5734
+	return nan ();
yann@339
  5735
+      return a;
yann@339
  5736
+    }
yann@339
  5737
+  if (isinf (b))
yann@339
  5738
+    {
yann@339
  5739
+      return b;
yann@339
  5740
+    }
yann@339
  5741
+  if (iszero (b))
yann@339
  5742
+    {
yann@339
  5743
+      if (iszero (a))
yann@339
  5744
+	{
yann@339
  5745
+	  *tmp = *a;
yann@339
  5746
+	  tmp->sign = a->sign & b->sign;
yann@339
  5747
+	  return tmp;
yann@339
  5748
+	}
yann@339
  5749
+      return a;
yann@339
  5750
+    }
yann@339
  5751
+  if (iszero (a))
yann@339
  5752
+    {
yann@339
  5753
+      return b;
yann@339
  5754
+    }
yann@339
  5755
+
yann@339
  5756
+  /* Got two numbers. shift the smaller and increment the exponent till
yann@339
  5757
+     they're the same */
yann@339
  5758
+  {
yann@339
  5759
+    int diff;
yann@339
  5760
+
yann@339
  5761
+    a_normal_exp = a->normal_exp;
yann@339
  5762
+    b_normal_exp = b->normal_exp;
yann@339
  5763
+    a_fraction = a->fraction.ll;
yann@339
  5764
+    b_fraction = b->fraction.ll;
yann@339
  5765
+
yann@339
  5766
+    diff = a_normal_exp - b_normal_exp;
yann@339
  5767
+
yann@339
  5768
+    if (diff < 0)
yann@339
  5769
+      diff = -diff;
yann@339
  5770
+    if (diff < FRAC_NBITS)
yann@339
  5771
+      {
yann@339
  5772
+	/* ??? This does shifts one bit at a time.  Optimize.  */
yann@339
  5773
+	while (a_normal_exp > b_normal_exp)
yann@339
  5774
+	  {
yann@339
  5775
+	    b_normal_exp++;
yann@339
  5776
+	    LSHIFT (b_fraction);
yann@339
  5777
+	  }
yann@339
  5778
+	while (b_normal_exp > a_normal_exp)
yann@339
  5779
+	  {
yann@339
  5780
+	    a_normal_exp++;
yann@339
  5781
+	    LSHIFT (a_fraction);
yann@339
  5782
+	  }
yann@339
  5783
+      }
yann@339
  5784
+    else
yann@339
  5785
+      {
yann@339
  5786
+	/* Somethings's up.. choose the biggest */
yann@339
  5787
+	if (a_normal_exp > b_normal_exp)
yann@339
  5788
+	  {
yann@339
  5789
+	    b_normal_exp = a_normal_exp;
yann@339
  5790
+	    b_fraction = 0;
yann@339
  5791
+	  }
yann@339
  5792
+	else
yann@339
  5793
+	  {
yann@339
  5794
+	    a_normal_exp = b_normal_exp;
yann@339
  5795
+	    a_fraction = 0;
yann@339
  5796
+	  }
yann@339
  5797
+      }
yann@339
  5798
+  }
yann@339
  5799
+
yann@339
  5800
+  if (a->sign != b->sign)
yann@339
  5801
+    {
yann@339
  5802
+      if (a->sign)
yann@339
  5803
+	{
yann@339
  5804
+	  tfraction = -a_fraction + b_fraction;
yann@339
  5805
+	}
yann@339
  5806
+      else
yann@339
  5807
+	{
yann@339
  5808
+	  tfraction = a_fraction - b_fraction;
yann@339
  5809
+	}
yann@339
  5810
+      if (tfraction >= 0)
yann@339
  5811
+	{
yann@339
  5812
+	  tmp->sign = 0;
yann@339
  5813
+	  tmp->normal_exp = a_normal_exp;
yann@339
  5814
+	  tmp->fraction.ll = tfraction;
yann@339
  5815
+	}
yann@339
  5816
+      else
yann@339
  5817
+	{
yann@339
  5818
+	  tmp->sign = 1;
yann@339
  5819
+	  tmp->normal_exp = a_normal_exp;
yann@339
  5820
+	  tmp->fraction.ll = -tfraction;
yann@339
  5821
+	}
yann@339
  5822
+      /* and renormalize it */
yann@339
  5823
+
yann@339
  5824
+      while (tmp->fraction.ll < IMPLICIT_1 && tmp->fraction.ll)
yann@339
  5825
+	{
yann@339
  5826
+	  tmp->fraction.ll <<= 1;
yann@339
  5827
+	  tmp->normal_exp--;
yann@339
  5828
+	}
yann@339
  5829
+    }
yann@339
  5830
+  else
yann@339
  5831
+    {
yann@339
  5832
+      tmp->sign = a->sign;
yann@339
  5833
+      tmp->normal_exp = a_normal_exp;
yann@339
  5834
+      tmp->fraction.ll = a_fraction + b_fraction;
yann@339
  5835
+    }
yann@339
  5836
+  tmp->class = CLASS_NUMBER;
yann@339
  5837
+  /* Now the fraction is added, we have to shift down to renormalize the
yann@339
  5838
+     number */
yann@339
  5839
+
yann@339
  5840
+  if (tmp->fraction.ll >= IMPLICIT_2)
yann@339
  5841
+    {
yann@339
  5842
+      LSHIFT (tmp->fraction.ll);
yann@339
  5843
+      tmp->normal_exp++;
yann@339
  5844
+    }
yann@339
  5845
+  return tmp;
yann@339
  5846
+
yann@339
  5847
+}
yann@339
  5848
+
yann@339
  5849
+FLO_type
yann@339
  5850
+add (FLO_type arg_a, FLO_type arg_b)
yann@339
  5851
+{
yann@339
  5852
+  fp_number_type a;
yann@339
  5853
+  fp_number_type b;
yann@339
  5854
+  fp_number_type tmp;
yann@339
  5855
+  fp_number_type *res;
yann@339
  5856
+  FLO_union_type au, bu;
yann@339
  5857
+
yann@339
  5858
+  au.value = arg_a;
yann@339
  5859
+  bu.value = arg_b;
yann@339
  5860
+
yann@339
  5861
+  unpack_d (&au, &a);
yann@339
  5862
+  unpack_d (&bu, &b);
yann@339
  5863
+
yann@339
  5864
+  res = _fpadd_parts (&a, &b, &tmp);
yann@339
  5865
+
yann@339
  5866
+  return pack_d (res);
yann@339
  5867
+}
yann@339
  5868
+
yann@339
  5869
+FLO_type
yann@339
  5870
+sub (FLO_type arg_a, FLO_type arg_b)
yann@339
  5871
+{
yann@339
  5872
+  fp_number_type a;
yann@339
  5873
+  fp_number_type b;
yann@339
  5874
+  fp_number_type tmp;
yann@339
  5875
+  fp_number_type *res;
yann@339
  5876
+  FLO_union_type au, bu;
yann@339
  5877
+
yann@339
  5878
+  au.value = arg_a;
yann@339
  5879
+  bu.value = arg_b;
yann@339
  5880
+
yann@339
  5881
+  unpack_d (&au, &a);
yann@339
  5882
+  unpack_d (&bu, &b);
yann@339
  5883
+
yann@339
  5884
+  b.sign ^= 1;
yann@339
  5885
+
yann@339
  5886
+  res = _fpadd_parts (&a, &b, &tmp);
yann@339
  5887
+
yann@339
  5888
+  return pack_d (res);
yann@339
  5889
+}
yann@339
  5890
+#endif /* L_addsub_sf || L_addsub_df */
yann@339
  5891
+
yann@339
  5892
+#if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf)
yann@339
  5893
+static inline __attribute__ ((__always_inline__)) fp_number_type *
yann@339
  5894
+_fpmul_parts ( fp_number_type *  a,
yann@339
  5895
+	       fp_number_type *  b,
yann@339
  5896
+	       fp_number_type * tmp)
yann@339
  5897
+{
yann@339
  5898
+  fractype low = 0;
yann@339
  5899
+  fractype high = 0;
yann@339
  5900
+
yann@339
  5901
+  if (isnan (a))
yann@339
  5902
+    {
yann@339
  5903
+      a->sign = a->sign != b->sign;
yann@339
  5904
+      return a;
yann@339
  5905
+    }
yann@339
  5906
+  if (isnan (b))
yann@339
  5907
+    {
yann@339
  5908
+      b->sign = a->sign != b->sign;
yann@339
  5909
+      return b;
yann@339
  5910
+    }
yann@339
  5911
+  if (isinf (a))
yann@339
  5912
+    {
yann@339
  5913
+      if (iszero (b))
yann@339
  5914
+	return nan ();
yann@339
  5915
+      a->sign = a->sign != b->sign;
yann@339
  5916
+      return a;
yann@339
  5917
+    }
yann@339
  5918
+  if (isinf (b))
yann@339
  5919
+    {
yann@339
  5920
+      if (iszero (a))
yann@339
  5921
+	{
yann@339
  5922
+	  return nan ();
yann@339
  5923
+	}
yann@339
  5924
+      b->sign = a->sign != b->sign;
yann@339
  5925
+      return b;
yann@339
  5926
+    }
yann@339
  5927
+  if (iszero (a))
yann@339
  5928
+    {
yann@339
  5929
+      a->sign = a->sign != b->sign;
yann@339
  5930
+      return a;
yann@339
  5931
+    }
yann@339
  5932
+  if (iszero (b))
yann@339
  5933
+    {
yann@339
  5934
+      b->sign = a->sign != b->sign;
yann@339
  5935
+      return b;
yann@339
  5936
+    }
yann@339
  5937
+
yann@339
  5938
+  /* Calculate the mantissa by multiplying both numbers to get a
yann@339
  5939
+     twice-as-wide number.  */
yann@339
  5940
+  {
yann@339
  5941
+#if defined(NO_DI_MODE) || defined(TFLOAT)
yann@339
  5942
+    {
yann@339
  5943
+      fractype x = a->fraction.ll;
yann@339
  5944
+      fractype ylow = b->fraction.ll;
yann@339
  5945
+      fractype yhigh = 0;
yann@339
  5946
+      int bit;
yann@339
  5947
+
yann@339
  5948
+      /* ??? This does multiplies one bit at a time.  Optimize.  */
yann@339
  5949
+      for (bit = 0; bit < FRAC_NBITS; bit++)
yann@339
  5950
+	{
yann@339
  5951
+	  int carry;
yann@339
  5952
+
yann@339
  5953
+	  if (x & 1)
yann@339
  5954
+	    {
yann@339
  5955
+	      carry = (low += ylow) < ylow;
yann@339
  5956
+	      high += yhigh + carry;
yann@339
  5957
+	    }
yann@339
  5958
+	  yhigh <<= 1;
yann@339
  5959
+	  if (ylow & FRACHIGH)
yann@339
  5960
+	    {
yann@339
  5961
+	      yhigh |= 1;
yann@339
  5962
+	    }
yann@339
  5963
+	  ylow <<= 1;
yann@339
  5964
+	  x >>= 1;
yann@339
  5965
+	}
yann@339
  5966
+    }
yann@339
  5967
+#elif defined(FLOAT) 
yann@339
  5968
+    /* Multiplying two USIs to get a UDI, we're safe.  */
yann@339
  5969
+    {
yann@339
  5970
+      UDItype answer = (UDItype)a->fraction.ll * (UDItype)b->fraction.ll;
yann@339
  5971
+      
yann@339
  5972
+      high = answer >> BITS_PER_SI;
yann@339
  5973
+      low = answer;
yann@339
  5974
+    }
yann@339
  5975
+#else
yann@339
  5976
+    /* fractype is DImode, but we need the result to be twice as wide.
yann@339
  5977
+       Assuming a widening multiply from DImode to TImode is not
yann@339
  5978
+       available, build one by hand.  */
yann@339
  5979
+    {
yann@339
  5980
+      USItype nl = a->fraction.ll;
yann@339
  5981
+      USItype nh = a->fraction.ll >> BITS_PER_SI;
yann@339
  5982
+      USItype ml = b->fraction.ll;
yann@339
  5983
+      USItype mh = b->fraction.ll >> BITS_PER_SI;
yann@339
  5984
+      UDItype pp_ll = (UDItype) ml * nl;
yann@339
  5985
+      UDItype pp_hl = (UDItype) mh * nl;
yann@339
  5986
+      UDItype pp_lh = (UDItype) ml * nh;
yann@339
  5987
+      UDItype pp_hh = (UDItype) mh * nh;
yann@339
  5988
+      UDItype res2 = 0;
yann@339
  5989
+      UDItype res0 = 0;
yann@339
  5990
+      UDItype ps_hh__ = pp_hl + pp_lh;
yann@339
  5991
+      if (ps_hh__ < pp_hl)
yann@339
  5992
+	res2 += (UDItype)1 << BITS_PER_SI;
yann@339
  5993
+      pp_hl = (UDItype)(USItype)ps_hh__ << BITS_PER_SI;
yann@339
  5994
+      res0 = pp_ll + pp_hl;
yann@339
  5995
+      if (res0 < pp_ll)
yann@339
  5996
+	res2++;
yann@339
  5997
+      res2 += (ps_hh__ >> BITS_PER_SI) + pp_hh;
yann@339
  5998
+      high = res2;
yann@339
  5999
+      low = res0;
yann@339
  6000
+    }
yann@339
  6001
+#endif
yann@339
  6002
+  }
yann@339
  6003
+
yann@339
  6004
+  tmp->normal_exp = a->normal_exp + b->normal_exp
yann@339
  6005
+    + FRAC_NBITS - (FRACBITS + NGARDS);
yann@339
  6006
+  tmp->sign = a->sign != b->sign;
yann@339
  6007
+  while (high >= IMPLICIT_2)
yann@339
  6008
+    {
yann@339
  6009
+      tmp->normal_exp++;
yann@339
  6010
+      if (high & 1)
yann@339
  6011
+	{
yann@339
  6012
+	  low >>= 1;
yann@339
  6013
+	  low |= FRACHIGH;
yann@339
  6014
+	}
yann@339
  6015
+      high >>= 1;
yann@339
  6016
+    }
yann@339
  6017
+  while (high < IMPLICIT_1)
yann@339
  6018
+    {
yann@339
  6019
+      tmp->normal_exp--;
yann@339
  6020
+
yann@339
  6021
+      high <<= 1;
yann@339
  6022
+      if (low & FRACHIGH)
yann@339
  6023
+	high |= 1;
yann@339
  6024
+      low <<= 1;
yann@339
  6025
+    }
yann@339
  6026
+  /* rounding is tricky. if we only round if it won't make us round later.  */
yann@339
  6027
+#if 0
yann@339
  6028
+  if (low & FRACHIGH2)
yann@339
  6029
+    {
yann@339
  6030
+      if (((high & GARDMASK) != GARDMSB)
yann@339
  6031
+	  && (((high + 1) & GARDMASK) == GARDMSB))
yann@339
  6032
+	{
yann@339
  6033
+	  /* don't round, it gets done again later.  */
yann@339
  6034
+	}
yann@339
  6035
+      else
yann@339
  6036
+	{
yann@339
  6037
+	  high++;
yann@339
  6038
+	}
yann@339
  6039
+    }
yann@339
  6040
+#endif
yann@339
  6041
+  if (!ROUND_TOWARDS_ZERO && (high & GARDMASK) == GARDMSB)
yann@339
  6042
+    {
yann@339
  6043
+      if (high & (1 << NGARDS))
yann@339
  6044
+	{
yann@339
  6045
+	  /* half way, so round to even */
yann@339
  6046
+	  high += GARDROUND + 1;
yann@339
  6047
+	}
yann@339
  6048
+      else if (low)
yann@339
  6049
+	{
yann@339
  6050
+	  /* but we really weren't half way */
yann@339
  6051
+	  high += GARDROUND + 1;
yann@339
  6052
+	}
yann@339
  6053
+    }
yann@339
  6054
+  tmp->fraction.ll = high;
yann@339
  6055
+  tmp->class = CLASS_NUMBER;
yann@339
  6056
+  return tmp;
yann@339
  6057
+}
yann@339
  6058
+
yann@339
  6059
+FLO_type
yann@339
  6060
+multiply (FLO_type arg_a, FLO_type arg_b)
yann@339
  6061
+{
yann@339
  6062
+  fp_number_type a;
yann@339
  6063
+  fp_number_type b;
yann@339
  6064
+  fp_number_type tmp;
yann@339
  6065
+  fp_number_type *res;
yann@339
  6066
+  FLO_union_type au, bu;
yann@339
  6067
+
yann@339
  6068
+  au.value = arg_a;
yann@339
  6069
+  bu.value = arg_b;
yann@339
  6070
+
yann@339
  6071
+  unpack_d (&au, &a);
yann@339
  6072
+  unpack_d (&bu, &b);
yann@339
  6073
+
yann@339
  6074
+  res = _fpmul_parts (&a, &b, &tmp);
yann@339
  6075
+
yann@339
  6076
+  return pack_d (res);
yann@339
  6077
+}
yann@339
  6078
+#endif /* L_mul_sf || L_mul_df */
yann@339
  6079
+
yann@339
  6080
+#if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf)
yann@339
  6081
+static inline __attribute__ ((__always_inline__)) fp_number_type *
yann@339
  6082
+_fpdiv_parts (fp_number_type * a,
yann@339
  6083
+	      fp_number_type * b)
yann@339
  6084
+{
yann@339
  6085
+  fractype bit;
yann@339
  6086
+  fractype numerator;
yann@339
  6087
+  fractype denominator;
yann@339
  6088
+  fractype quotient;
yann@339
  6089
+
yann@339
  6090
+  if (isnan (a))
yann@339
  6091
+    {
yann@339
  6092
+      return a;
yann@339
  6093
+    }
yann@339
  6094
+  if (isnan (b))
yann@339
  6095
+    {
yann@339
  6096
+      return b;
yann@339
  6097
+    }
yann@339
  6098
+
yann@339
  6099
+  a->sign = a->sign ^ b->sign;
yann@339
  6100
+
yann@339
  6101
+  if (isinf (a) || iszero (a))
yann@339
  6102
+    {
yann@339
  6103
+      if (a->class == b->class)
yann@339
  6104
+	return nan ();
yann@339
  6105
+      return a;
yann@339
  6106
+    }
yann@339
  6107
+
yann@339
  6108
+  if (isinf (b))
yann@339
  6109
+    {
yann@339
  6110
+      a->fraction.ll = 0;
yann@339
  6111
+      a->normal_exp = 0;
yann@339
  6112
+      return a;
yann@339
  6113
+    }
yann@339
  6114
+  if (iszero (b))
yann@339
  6115
+    {
yann@339
  6116
+      a->class = CLASS_INFINITY;
yann@339
  6117
+      return a;
yann@339
  6118
+    }
yann@339
  6119
+
yann@339
  6120
+  /* Calculate the mantissa by multiplying both 64bit numbers to get a
yann@339
  6121
+     128 bit number */
yann@339
  6122
+  {
yann@339
  6123
+    /* quotient =
yann@339
  6124
+       ( numerator / denominator) * 2^(numerator exponent -  denominator exponent)
yann@339
  6125
+     */
yann@339
  6126
+
yann@339
  6127
+    a->normal_exp = a->normal_exp - b->normal_exp;
yann@339
  6128
+    numerator = a->fraction.ll;
yann@339
  6129
+    denominator = b->fraction.ll;
yann@339
  6130
+
yann@339
  6131
+    if (numerator < denominator)
yann@339
  6132
+      {
yann@339
  6133
+	/* Fraction will be less than 1.0 */
yann@339
  6134
+	numerator *= 2;
yann@339
  6135
+	a->normal_exp--;
yann@339
  6136
+      }
yann@339
  6137
+    bit = IMPLICIT_1;
yann@339
  6138
+    quotient = 0;
yann@339
  6139
+    /* ??? Does divide one bit at a time.  Optimize.  */
yann@339
  6140
+    while (bit)
yann@339
  6141
+      {
yann@339
  6142
+	if (numerator >= denominator)
yann@339
  6143
+	  {
yann@339
  6144
+	    quotient |= bit;
yann@339
  6145
+	    numerator -= denominator;
yann@339
  6146
+	  }
yann@339
  6147
+	bit >>= 1;
yann@339
  6148
+	numerator *= 2;
yann@339
  6149
+      }
yann@339
  6150
+
yann@339
  6151
+    if (!ROUND_TOWARDS_ZERO && (quotient & GARDMASK) == GARDMSB)
yann@339
  6152
+      {
yann@339
  6153
+	if (quotient & (1 << NGARDS))
yann@339
  6154
+	  {
yann@339
  6155
+	    /* half way, so round to even */
yann@339
  6156
+	    quotient += GARDROUND + 1;
yann@339
  6157
+	  }
yann@339
  6158
+	else if (numerator)
yann@339
  6159
+	  {
yann@339
  6160
+	    /* but we really weren't half way, more bits exist */
yann@339
  6161
+	    quotient += GARDROUND + 1;
yann@339
  6162
+	  }
yann@339
  6163
+      }
yann@339
  6164
+
yann@339
  6165
+    a->fraction.ll = quotient;
yann@339
  6166
+    return (a);
yann@339
  6167
+  }
yann@339
  6168
+}
yann@339
  6169
+
yann@339
  6170
+FLO_type
yann@339
  6171
+divide (FLO_type arg_a, FLO_type arg_b)
yann@339
  6172
+{
yann@339
  6173
+  fp_number_type a;
yann@339
  6174
+  fp_number_type b;
yann@339
  6175
+  fp_number_type *res;
yann@339
  6176
+  FLO_union_type au, bu;
yann@339
  6177
+
yann@339
  6178
+  au.value = arg_a;
yann@339
  6179
+  bu.value = arg_b;
yann@339
  6180
+
yann@339
  6181
+  unpack_d (&au, &a);
yann@339
  6182
+  unpack_d (&bu, &b);
yann@339
  6183
+
yann@339
  6184
+  res = _fpdiv_parts (&a, &b);
yann@339
  6185
+
yann@339
  6186
+  return pack_d (res);
yann@339
  6187
+}
yann@339
  6188
+#endif /* L_div_sf || L_div_df */
yann@339
  6189
+
yann@339
  6190
+#if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) \
yann@339
  6191
+    || defined(L_fpcmp_parts_tf)
yann@339
  6192
+/* according to the demo, fpcmp returns a comparison with 0... thus
yann@339
  6193
+   a<b -> -1
yann@339
  6194
+   a==b -> 0
yann@339
  6195
+   a>b -> +1
yann@339
  6196
+ */
yann@339
  6197
+
yann@339
  6198
+int
yann@339
  6199
+__fpcmp_parts (fp_number_type * a, fp_number_type * b)
yann@339
  6200
+{
yann@339
  6201
+#if 0
yann@339
  6202
+  /* either nan -> unordered. Must be checked outside of this routine.  */
yann@339
  6203
+  if (isnan (a) && isnan (b))
yann@339
  6204
+    {
yann@339
  6205
+      return 1;			/* still unordered! */
yann@339
  6206
+    }
yann@339
  6207
+#endif
yann@339
  6208
+
yann@339
  6209
+  if (isnan (a) || isnan (b))
yann@339
  6210
+    {
yann@339
  6211
+      return 1;			/* how to indicate unordered compare? */
yann@339
  6212
+    }
yann@339
  6213
+  if (isinf (a) && isinf (b))
yann@339
  6214
+    {
yann@339
  6215
+      /* +inf > -inf, but +inf != +inf */
yann@339
  6216
+      /* b    \a| +inf(0)| -inf(1)
yann@339
  6217
+       ______\+--------+--------
yann@339
  6218
+       +inf(0)| a==b(0)| a<b(-1)
yann@339
  6219
+       -------+--------+--------
yann@339
  6220
+       -inf(1)| a>b(1) | a==b(0)
yann@339
  6221
+       -------+--------+--------
yann@339
  6222
+       So since unordered must be nonzero, just line up the columns...
yann@339
  6223
+       */
yann@339
  6224
+      return b->sign - a->sign;
yann@339
  6225
+    }
yann@339
  6226
+  /* but not both...  */
yann@339
  6227
+  if (isinf (a))
yann@339
  6228
+    {
yann@339
  6229
+      return a->sign ? -1 : 1;
yann@339
  6230
+    }
yann@339
  6231
+  if (isinf (b))
yann@339
  6232
+    {
yann@339
  6233
+      return b->sign ? 1 : -1;
yann@339
  6234
+    }
yann@339
  6235
+  if (iszero (a) && iszero (b))
yann@339
  6236
+    {
yann@339
  6237
+      return 0;
yann@339
  6238
+    }
yann@339
  6239
+  if (iszero (a))
yann@339
  6240
+    {
yann@339
  6241
+      return b->sign ? 1 : -1;
yann@339
  6242
+    }
yann@339
  6243
+  if (iszero (b))
yann@339
  6244
+    {
yann@339
  6245
+      return a->sign ? -1 : 1;
yann@339
  6246
+    }
yann@339
  6247
+  /* now both are "normal".  */
yann@339
  6248
+  if (a->sign != b->sign)
yann@339
  6249
+    {
yann@339
  6250
+      /* opposite signs */
yann@339
  6251
+      return a->sign ? -1 : 1;
yann@339
  6252
+    }
yann@339
  6253
+  /* same sign; exponents? */
yann@339
  6254
+  if (a->normal_exp > b->normal_exp)
yann@339
  6255
+    {
yann@339
  6256
+      return a->sign ? -1 : 1;
yann@339
  6257
+    }
yann@339
  6258
+  if (a->normal_exp < b->normal_exp)
yann@339
  6259
+    {
yann@339
  6260
+      return a->sign ? 1 : -1;
yann@339
  6261
+    }
yann@339
  6262
+  /* same exponents; check size.  */
yann@339
  6263
+  if (a->fraction.ll > b->fraction.ll)
yann@339
  6264
+    {
yann@339
  6265
+      return a->sign ? -1 : 1;
yann@339
  6266
+    }
yann@339
  6267
+  if (a->fraction.ll < b->fraction.ll)
yann@339
  6268
+    {
yann@339
  6269
+      return a->sign ? 1 : -1;
yann@339
  6270
+    }
yann@339
  6271
+  /* after all that, they're equal.  */
yann@339
  6272
+  return 0;
yann@339
  6273
+}
yann@339
  6274
+#endif
yann@339
  6275
+
yann@339
  6276
+#if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compoare_tf)
yann@339
  6277
+CMPtype
yann@339
  6278
+compare (FLO_type arg_a, FLO_type arg_b)
yann@339
  6279
+{
yann@339
  6280
+  fp_number_type a;
yann@339
  6281
+  fp_number_type b;
yann@339
  6282
+  FLO_union_type au, bu;
yann@339
  6283
+
yann@339
  6284
+  au.value = arg_a;
yann@339
  6285
+  bu.value = arg_b;
yann@339
  6286
+
yann@339
  6287
+  unpack_d (&au, &a);
yann@339
  6288
+  unpack_d (&bu, &b);
yann@339
  6289
+
yann@339
  6290
+  return __fpcmp_parts (&a, &b);
yann@339
  6291
+}
yann@339
  6292
+#endif /* L_compare_sf || L_compare_df */
yann@339
  6293
+
yann@339
  6294
+#ifndef US_SOFTWARE_GOFAST
yann@339
  6295
+
yann@339
  6296
+/* These should be optimized for their specific tasks someday.  */
yann@339
  6297
+
yann@339
  6298
+#if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf)
yann@339
  6299
+CMPtype
yann@339
  6300
+_eq_f2 (FLO_type arg_a, FLO_type arg_b)
yann@339
  6301
+{
yann@339
  6302
+  fp_number_type a;
yann@339
  6303
+  fp_number_type b;
yann@339
  6304
+  FLO_union_type au, bu;
yann@339
  6305
+
yann@339
  6306
+  au.value = arg_a;
yann@339
  6307
+  bu.value = arg_b;
yann@339
  6308
+
yann@339
  6309
+  unpack_d (&au, &a);
yann@339
  6310
+  unpack_d (&bu, &b);
yann@339
  6311
+
yann@339
  6312
+  if (isnan (&a) || isnan (&b))
yann@339
  6313
+    return 1;			/* false, truth == 0 */
yann@339
  6314
+
yann@339
  6315
+  return __fpcmp_parts (&a, &b) ;
yann@339
  6316
+}
yann@339
  6317
+#endif /* L_eq_sf || L_eq_df */
yann@339
  6318
+
yann@339
  6319
+#if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf)
yann@339
  6320
+CMPtype
yann@339
  6321
+_ne_f2 (FLO_type arg_a, FLO_type arg_b)
yann@339
  6322
+{
yann@339
  6323
+  fp_number_type a;
yann@339
  6324
+  fp_number_type b;
yann@339
  6325
+  FLO_union_type au, bu;
yann@339
  6326
+
yann@339
  6327
+  au.value = arg_a;
yann@339
  6328
+  bu.value = arg_b;
yann@339
  6329
+
yann@339
  6330
+  unpack_d (&au, &a);
yann@339
  6331
+  unpack_d (&bu, &b);
yann@339
  6332
+
yann@339
  6333
+  if (isnan (&a) || isnan (&b))
yann@339
  6334
+    return 1;			/* true, truth != 0 */
yann@339
  6335
+
yann@339
  6336
+  return  __fpcmp_parts (&a, &b) ;
yann@339
  6337
+}
yann@339
  6338
+#endif /* L_ne_sf || L_ne_df */
yann@339
  6339
+
yann@339
  6340
+#if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf)
yann@339
  6341
+CMPtype
yann@339
  6342
+_gt_f2 (FLO_type arg_a, FLO_type arg_b)
yann@339
  6343
+{
yann@339
  6344
+  fp_number_type a;
yann@339
  6345
+  fp_number_type b;
yann@339
  6346
+  FLO_union_type au, bu;
yann@339
  6347
+
yann@339
  6348
+  au.value = arg_a;
yann@339
  6349
+  bu.value = arg_b;
yann@339
  6350
+
yann@339
  6351
+  unpack_d (&au, &a);
yann@339
  6352
+  unpack_d (&bu, &b);
yann@339
  6353
+
yann@339
  6354
+  if (isnan (&a) || isnan (&b))
yann@339
  6355
+    return -1;			/* false, truth > 0 */
yann@339
  6356
+
yann@339
  6357
+  return __fpcmp_parts (&a, &b);
yann@339
  6358
+}
yann@339
  6359
+#endif /* L_gt_sf || L_gt_df */
yann@339
  6360
+
yann@339
  6361
+#if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf)
yann@339
  6362
+CMPtype
yann@339
  6363
+_ge_f2 (FLO_type arg_a, FLO_type arg_b)
yann@339
  6364
+{
yann@339
  6365
+  fp_number_type a;
yann@339
  6366
+  fp_number_type b;
yann@339
  6367
+  FLO_union_type au, bu;
yann@339
  6368
+
yann@339
  6369
+  au.value = arg_a;
yann@339
  6370
+  bu.value = arg_b;
yann@339
  6371
+
yann@339
  6372
+  unpack_d (&au, &a);
yann@339
  6373
+  unpack_d (&bu, &b);
yann@339
  6374
+
yann@339
  6375
+  if (isnan (&a) || isnan (&b))
yann@339
  6376
+    return -1;			/* false, truth >= 0 */
yann@339
  6377
+  return __fpcmp_parts (&a, &b) ;
yann@339
  6378
+}
yann@339
  6379
+#endif /* L_ge_sf || L_ge_df */
yann@339
  6380
+
yann@339
  6381
+#if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf)
yann@339
  6382
+CMPtype
yann@339
  6383
+_lt_f2 (FLO_type arg_a, FLO_type arg_b)
yann@339
  6384
+{
yann@339
  6385
+  fp_number_type a;
yann@339
  6386
+  fp_number_type b;
yann@339
  6387
+  FLO_union_type au, bu;
yann@339
  6388
+
yann@339
  6389
+  au.value = arg_a;
yann@339
  6390
+  bu.value = arg_b;
yann@339
  6391
+
yann@339
  6392
+  unpack_d (&au, &a);
yann@339
  6393
+  unpack_d (&bu, &b);
yann@339
  6394
+
yann@339
  6395
+  if (isnan (&a) || isnan (&b))
yann@339
  6396
+    return 1;			/* false, truth < 0 */
yann@339
  6397
+
yann@339
  6398
+  return __fpcmp_parts (&a, &b);
yann@339
  6399
+}
yann@339
  6400
+#endif /* L_lt_sf || L_lt_df */
yann@339
  6401
+
yann@339
  6402
+#if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf)
yann@339
  6403
+CMPtype
yann@339
  6404
+_le_f2 (FLO_type arg_a, FLO_type arg_b)
yann@339
  6405
+{
yann@339
  6406
+  fp_number_type a;
yann@339
  6407
+  fp_number_type b;
yann@339
  6408
+  FLO_union_type au, bu;
yann@339
  6409
+
yann@339
  6410
+  au.value = arg_a;
yann@339
  6411
+  bu.value = arg_b;
yann@339
  6412
+
yann@339
  6413
+  unpack_d (&au, &a);
yann@339
  6414
+  unpack_d (&bu, &b);
yann@339
  6415
+
yann@339
  6416
+  if (isnan (&a) || isnan (&b))
yann@339
  6417
+    return 1;			/* false, truth <= 0 */
yann@339
  6418
+
yann@339
  6419
+  return __fpcmp_parts (&a, &b) ;
yann@339
  6420
+}
yann@339
  6421
+#endif /* L_le_sf || L_le_df */
yann@339
  6422
+
yann@339
  6423
+#endif /* ! US_SOFTWARE_GOFAST */
yann@339
  6424
+
yann@339
  6425
+#if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf)
yann@339
  6426
+CMPtype
yann@339
  6427
+_unord_f2 (FLO_type arg_a, FLO_type arg_b)
yann@339
  6428
+{
yann@339
  6429
+  fp_number_type a;
yann@339
  6430
+  fp_number_type b;
yann@339
  6431
+  FLO_union_type au, bu;
yann@339
  6432
+
yann@339
  6433
+  au.value = arg_a;
yann@339
  6434
+  bu.value = arg_b;
yann@339
  6435
+
yann@339
  6436
+  unpack_d (&au, &a);
yann@339
  6437
+  unpack_d (&bu, &b);
yann@339
  6438
+
yann@339
  6439
+  return (isnan (&a) || isnan (&b));
yann@339
  6440
+}
yann@339
  6441
+#endif /* L_unord_sf || L_unord_df */
yann@339
  6442
+
yann@339
  6443
+#if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf)
yann@339
  6444
+FLO_type
yann@339
  6445
+si_to_float (SItype arg_a)
yann@339
  6446
+{
yann@339
  6447
+  fp_number_type in;
yann@339
  6448
+
yann@339
  6449
+  in.class = CLASS_NUMBER;
yann@339
  6450
+  in.sign = arg_a < 0;
yann@339
  6451
+  if (!arg_a)
yann@339
  6452
+    {
yann@339
  6453
+      in.class = CLASS_ZERO;
yann@339
  6454
+    }
yann@339
  6455
+  else
yann@339
  6456
+    {
yann@339
  6457
+      in.normal_exp = FRACBITS + NGARDS;
yann@339
  6458
+      if (in.sign) 
yann@339
  6459
+	{
yann@339
  6460
+	  /* Special case for minint, since there is no +ve integer
yann@339
  6461
+	     representation for it */
yann@339
  6462
+	  if (arg_a == (- MAX_SI_INT - 1))
yann@339
  6463
+	    {
yann@339
  6464
+	      return (FLO_type)(- MAX_SI_INT - 1);
yann@339
  6465
+	    }
yann@339
  6466
+	  in.fraction.ll = (-arg_a);
yann@339
  6467
+	}
yann@339
  6468
+      else
yann@339
  6469
+	in.fraction.ll = arg_a;
yann@339
  6470
+
yann@339
  6471
+      while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS)))
yann@339
  6472
+	{
yann@339
  6473
+	  in.fraction.ll <<= 1;
yann@339
  6474
+	  in.normal_exp -= 1;
yann@339
  6475
+	}
yann@339
  6476
+    }
yann@339
  6477
+  return pack_d (&in);
yann@339
  6478
+}
yann@339
  6479
+#endif /* L_si_to_sf || L_si_to_df */
yann@339
  6480
+
yann@339
  6481
+#if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf)
yann@339
  6482
+FLO_type
yann@339
  6483
+usi_to_float (USItype arg_a)
yann@339
  6484
+{
yann@339
  6485
+  fp_number_type in;
yann@339
  6486
+
yann@339
  6487
+  in.sign = 0;
yann@339
  6488
+  if (!arg_a)
yann@339
  6489
+    {
yann@339
  6490
+      in.class = CLASS_ZERO;
yann@339
  6491
+    }
yann@339
  6492
+  else
yann@339
  6493
+    {
yann@339
  6494
+      in.class = CLASS_NUMBER;
yann@339
  6495
+      in.normal_exp = FRACBITS + NGARDS;
yann@339
  6496
+      in.fraction.ll = arg_a;
yann@339
  6497
+
yann@339
  6498
+      while (in.fraction.ll > ((fractype)1 << (FRACBITS + NGARDS)))
yann@339
  6499
+        {
yann@339
  6500
+          in.fraction.ll >>= 1;
yann@339
  6501
+          in.normal_exp += 1;
yann@339
  6502
+        }
yann@339
  6503
+      while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS)))
yann@339
  6504
+	{
yann@339
  6505
+	  in.fraction.ll <<= 1;
yann@339
  6506
+	  in.normal_exp -= 1;
yann@339
  6507
+	}
yann@339
  6508
+    }
yann@339
  6509
+  return pack_d (&in);
yann@339
  6510
+}
yann@339
  6511
+#endif
yann@339
  6512
+
yann@339
  6513
+#if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si)
yann@339
  6514
+SItype
yann@339
  6515
+float_to_si (FLO_type arg_a)
yann@339
  6516
+{
yann@339
  6517
+  fp_number_type a;
yann@339
  6518
+  SItype tmp;
yann@339
  6519
+  FLO_union_type au;
yann@339
  6520
+
yann@339
  6521
+  au.value = arg_a;
yann@339
  6522
+  unpack_d (&au, &a);
yann@339
  6523
+
yann@339
  6524
+  if (iszero (&a))
yann@339
  6525
+    return 0;
yann@339
  6526
+  if (isnan (&a))
yann@339
  6527
+    return 0;
yann@339
  6528
+  /* get reasonable MAX_SI_INT...  */
yann@339
  6529
+  if (isinf (&a))
yann@339
  6530
+    return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
yann@339
  6531
+  /* it is a number, but a small one */
yann@339
  6532
+  if (a.normal_exp < 0)
yann@339
  6533
+    return 0;
yann@339
  6534
+  if (a.normal_exp > BITS_PER_SI - 2)
yann@339
  6535
+    return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
yann@339
  6536
+  tmp = a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
yann@339
  6537
+  return a.sign ? (-tmp) : (tmp);
yann@339
  6538
+}
yann@339
  6539
+#endif /* L_sf_to_si || L_df_to_si */
yann@339
  6540
+
yann@339
  6541
+#if defined(L_sf_to_usi) || defined(L_df_to_usi) || defined(L_tf_to_usi)
yann@339
  6542
+#if defined US_SOFTWARE_GOFAST || defined(L_tf_to_usi)
yann@339
  6543
+/* While libgcc2.c defines its own __fixunssfsi and __fixunsdfsi routines,
yann@339
  6544
+   we also define them for GOFAST because the ones in libgcc2.c have the
yann@339
  6545
+   wrong names and I'd rather define these here and keep GOFAST CYG-LOC's
yann@339
  6546
+   out of libgcc2.c.  We can't define these here if not GOFAST because then
yann@339
  6547
+   there'd be duplicate copies.  */
yann@339
  6548
+
yann@339
  6549
+USItype
yann@339
  6550
+float_to_usi (FLO_type arg_a)
yann@339
  6551
+{
yann@339
  6552
+  fp_number_type a;
yann@339
  6553
+  FLO_union_type au;
yann@339
  6554
+
yann@339
  6555
+  au.value = arg_a;
yann@339
  6556
+  unpack_d (&au, &a);
yann@339
  6557
+
yann@339
  6558
+  if (iszero (&a))
yann@339
  6559
+    return 0;
yann@339
  6560
+  if (isnan (&a))
yann@339
  6561
+    return 0;
yann@339
  6562
+  /* it is a negative number */
yann@339
  6563
+  if (a.sign)
yann@339
  6564
+    return 0;
yann@339
  6565
+  /* get reasonable MAX_USI_INT...  */
yann@339
  6566
+  if (isinf (&a))
yann@339
  6567
+    return MAX_USI_INT;
yann@339
  6568
+  /* it is a number, but a small one */
yann@339
  6569
+  if (a.normal_exp < 0)
yann@339
  6570
+    return 0;
yann@339
  6571
+  if (a.normal_exp > BITS_PER_SI - 1)
yann@339
  6572
+    return MAX_USI_INT;
yann@339
  6573
+  else if (a.normal_exp > (FRACBITS + NGARDS))
yann@339
  6574
+    return a.fraction.ll << (a.normal_exp - (FRACBITS + NGARDS));
yann@339
  6575
+  else
yann@339
  6576
+    return a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
yann@339
  6577
+}
yann@339
  6578
+#endif /* US_SOFTWARE_GOFAST */
yann@339
  6579
+#endif /* L_sf_to_usi || L_df_to_usi */
yann@339
  6580
+
yann@339
  6581
+#if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf)
yann@339
  6582
+FLO_type
yann@339
  6583
+negate (FLO_type arg_a)
yann@339
  6584
+{
yann@339
  6585
+  fp_number_type a;
yann@339
  6586
+  FLO_union_type au;
yann@339
  6587
+
yann@339
  6588
+  au.value = arg_a;
yann@339
  6589
+  unpack_d (&au, &a);
yann@339
  6590
+
yann@339
  6591
+  flip_sign (&a);
yann@339
  6592
+  return pack_d (&a);
yann@339
  6593
+}
yann@339
  6594
+#endif /* L_negate_sf || L_negate_df */
yann@339
  6595
+
yann@339
  6596
+#ifdef FLOAT
yann@339
  6597
+
yann@339
  6598
+#if defined(L_make_sf)
yann@339
  6599
+SFtype
yann@339
  6600
+__make_fp(fp_class_type class,
yann@339
  6601
+	     unsigned int sign,
yann@339
  6602
+	     int exp, 
yann@339
  6603
+	     USItype frac)
yann@339
  6604
+{
yann@339
  6605
+  fp_number_type in;
yann@339
  6606
+
yann@339
  6607
+  in.class = class;
yann@339
  6608
+  in.sign = sign;
yann@339
  6609
+  in.normal_exp = exp;
yann@339
  6610
+  in.fraction.ll = frac;
yann@339
  6611
+  return pack_d (&in);
yann@339
  6612
+}
yann@339
  6613
+#endif /* L_make_sf */
yann@339
  6614
+
yann@339
  6615
+#ifndef FLOAT_ONLY
yann@339
  6616
+
yann@339
  6617
+/* This enables one to build an fp library that supports float but not double.
yann@339
  6618
+   Otherwise, we would get an undefined reference to __make_dp.
yann@339
  6619
+   This is needed for some 8-bit ports that can't handle well values that
yann@339
  6620
+   are 8-bytes in size, so we just don't support double for them at all.  */
yann@339
  6621
+
yann@339
  6622
+#if defined(L_sf_to_df)
yann@339
  6623
+DFtype
yann@339
  6624
+sf_to_df (SFtype arg_a)
yann@339
  6625
+{
yann@339
  6626
+  fp_number_type in;
yann@339
  6627
+  FLO_union_type au;
yann@339
  6628
+
yann@339
  6629
+  au.value = arg_a;
yann@339
  6630
+  unpack_d (&au, &in);
yann@339
  6631
+
yann@339
  6632
+  return __make_dp (in.class, in.sign, in.normal_exp,
yann@339
  6633
+		    ((UDItype) in.fraction.ll) << F_D_BITOFF);
yann@339
  6634
+}
yann@339
  6635
+#endif /* L_sf_to_df */
yann@339
  6636
+
yann@339
  6637
+#if defined(L_sf_to_tf) && defined(TMODES)
yann@339
  6638
+TFtype
yann@339
  6639
+sf_to_tf (SFtype arg_a)
yann@339
  6640
+{
yann@339
  6641
+  fp_number_type in;
yann@339
  6642
+  FLO_union_type au;
yann@339
  6643
+
yann@339
  6644
+  au.value = arg_a;
yann@339
  6645
+  unpack_d (&au, &in);
yann@339
  6646
+
yann@339
  6647
+  return __make_tp (in.class, in.sign, in.normal_exp,
yann@339
  6648
+		    ((UTItype) in.fraction.ll) << F_T_BITOFF);
yann@339
  6649
+}
yann@339
  6650
+#endif /* L_sf_to_df */
yann@339
  6651
+
yann@339
  6652
+#endif /* ! FLOAT_ONLY */
yann@339
  6653
+#endif /* FLOAT */
yann@339
  6654
+
yann@339
  6655
+#ifndef FLOAT
yann@339
  6656
+
yann@339
  6657
+extern SFtype __make_fp (fp_class_type, unsigned int, int, USItype);
yann@339
  6658
+
yann@339
  6659
+#if defined(L_make_df)
yann@339
  6660
+DFtype
yann@339
  6661
+__make_dp (fp_class_type class, unsigned int sign, int exp, UDItype frac)
yann@339
  6662
+{
yann@339
  6663
+  fp_number_type in;
yann@339
  6664
+
yann@339
  6665
+  in.class = class;
yann@339
  6666
+  in.sign = sign;
yann@339
  6667
+  in.normal_exp = exp;
yann@339
  6668
+  in.fraction.ll = frac;
yann@339
  6669
+  return pack_d (&in);
yann@339
  6670
+}
yann@339
  6671
+#endif /* L_make_df */
yann@339
  6672
+
yann@339
  6673
+#if defined(L_df_to_sf)
yann@339
  6674
+SFtype
yann@339
  6675
+df_to_sf (DFtype arg_a)
yann@339
  6676
+{
yann@339
  6677
+  fp_number_type in;
yann@339
  6678
+  USItype sffrac;
yann@339
  6679
+  FLO_union_type au;
yann@339
  6680
+
yann@339
  6681
+  au.value = arg_a;
yann@339
  6682
+  unpack_d (&au, &in);
yann@339
  6683
+
yann@339
  6684
+  sffrac = in.fraction.ll >> F_D_BITOFF;
yann@339
  6685
+
yann@339
  6686
+  /* We set the lowest guard bit in SFFRAC if we discarded any non
yann@339
  6687
+     zero bits.  */
yann@339
  6688
+  if ((in.fraction.ll & (((USItype) 1 << F_D_BITOFF) - 1)) != 0)
yann@339
  6689
+    sffrac |= 1;
yann@339
  6690
+
yann@339
  6691
+  return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
yann@339
  6692
+}
yann@339
  6693
+#endif /* L_df_to_sf */
yann@339
  6694
+
yann@339
  6695
+#if defined(L_df_to_tf) && defined(TMODES) \
yann@339
  6696
+    && !defined(FLOAT) && !defined(TFLOAT)
yann@339
  6697
+TFtype
yann@339
  6698
+df_to_tf (DFtype arg_a)
yann@339
  6699
+{
yann@339
  6700
+  fp_number_type in;
yann@339
  6701
+  FLO_union_type au;
yann@339
  6702
+
yann@339
  6703
+  au.value = arg_a;
yann@339
  6704
+  unpack_d (&au, &in);
yann@339
  6705
+
yann@339
  6706
+  return __make_tp (in.class, in.sign, in.normal_exp,
yann@339
  6707
+		    ((UTItype) in.fraction.ll) << D_T_BITOFF);
yann@339
  6708
+}
yann@339
  6709
+#endif /* L_sf_to_df */
yann@339
  6710
+
yann@339
  6711
+#ifdef TFLOAT
yann@339
  6712
+#if defined(L_make_tf)
yann@339
  6713
+TFtype
yann@339
  6714
+__make_tp(fp_class_type class,
yann@339
  6715
+	     unsigned int sign,
yann@339
  6716
+	     int exp, 
yann@339
  6717
+	     UTItype frac)
yann@339
  6718
+{
yann@339
  6719
+  fp_number_type in;
yann@339
  6720
+
yann@339
  6721
+  in.class = class;
yann@339
  6722
+  in.sign = sign;
yann@339
  6723
+  in.normal_exp = exp;
yann@339
  6724
+  in.fraction.ll = frac;
yann@339
  6725
+  return pack_d (&in);
yann@339
  6726
+}
yann@339
  6727
+#endif /* L_make_tf */
yann@339
  6728
+
yann@339
  6729
+#if defined(L_tf_to_df)
yann@339
  6730
+DFtype
yann@339
  6731
+tf_to_df (TFtype arg_a)
yann@339
  6732
+{
yann@339
  6733
+  fp_number_type in;
yann@339
  6734
+  UDItype sffrac;
yann@339
  6735
+  FLO_union_type au;
yann@339
  6736
+
yann@339
  6737
+  au.value = arg_a;
yann@339
  6738
+  unpack_d (&au, &in);
yann@339
  6739
+
yann@339
  6740
+  sffrac = in.fraction.ll >> D_T_BITOFF;
yann@339
  6741
+
yann@339
  6742
+  /* We set the lowest guard bit in SFFRAC if we discarded any non
yann@339
  6743
+     zero bits.  */
yann@339
  6744
+  if ((in.fraction.ll & (((UTItype) 1 << D_T_BITOFF) - 1)) != 0)
yann@339
  6745
+    sffrac |= 1;
yann@339
  6746
+
yann@339
  6747
+  return __make_dp (in.class, in.sign, in.normal_exp, sffrac);
yann@339
  6748
+}
yann@339
  6749
+#endif /* L_tf_to_df */
yann@339
  6750
+
yann@339
  6751
+#if defined(L_tf_to_sf)
yann@339
  6752
+SFtype
yann@339
  6753
+tf_to_sf (TFtype arg_a)
yann@339
  6754
+{
yann@339
  6755
+  fp_number_type in;
yann@339
  6756
+  USItype sffrac;
yann@339
  6757
+  FLO_union_type au;
yann@339
  6758
+
yann@339
  6759
+  au.value = arg_a;
yann@339
  6760
+  unpack_d (&au, &in);
yann@339
  6761
+
yann@339
  6762
+  sffrac = in.fraction.ll >> F_T_BITOFF;
yann@339
  6763
+
yann@339
  6764
+  /* We set the lowest guard bit in SFFRAC if we discarded any non
yann@339
  6765
+     zero bits.  */
yann@339
  6766
+  if ((in.fraction.ll & (((UTItype) 1 << F_T_BITOFF) - 1)) != 0)
yann@339
  6767
+    sffrac |= 1;
yann@339
  6768
+
yann@339
  6769
+  return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
yann@339
  6770
+}
yann@339
  6771
+#endif /* L_tf_to_sf */
yann@339
  6772
+#endif /* TFLOAT */
yann@339
  6773
+
yann@339
  6774
+#endif /* ! FLOAT */
yann@339
  6775
+#endif /* !EXTENDED_FLOAT_STUBS */
yann@339
  6776
diff -durN gcc-3.4.6.orig/gcc/config/nios2/nios2.h gcc-3.4.6/gcc/config/nios2/nios2.h
yann@339
  6777
--- gcc-3.4.6.orig/gcc/config/nios2/nios2.h	1970-01-01 01:00:00.000000000 +0100
yann@339
  6778
+++ gcc-3.4.6/gcc/config/nios2/nios2.h	2007-08-15 23:09:36.000000000 +0200
yann@339
  6779
@@ -0,0 +1,824 @@
yann@339
  6780
+/* Definitions of target machine for Altera NIOS 2G NIOS2 version.
yann@339
  6781
+   Copyright (C) 2003 Altera 
yann@339
  6782
+   Contributed by Jonah Graham (jgraham@altera.com).
yann@339
  6783
+
yann@339
  6784
+This file is part of GNU CC.
yann@339
  6785
+
yann@339
  6786
+GNU CC is free software; you can redistribute it and/or modify
yann@339
  6787
+it under the terms of the GNU General Public License as published by
yann@339
  6788
+the Free Software Foundation; either version 2, or (at your option)
yann@339
  6789
+any later version.
yann@339
  6790
+
yann@339
  6791
+GNU CC is distributed in the hope that it will be useful,
yann@339
  6792
+but WITHOUT ANY WARRANTY; without even the implied warranty of
yann@339
  6793
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
yann@339
  6794
+GNU General Public License for more details.
yann@339
  6795
+
yann@339
  6796
+You should have received a copy of the GNU General Public License
yann@339
  6797
+along with GNU CC; see the file COPYING.  If not, write to
yann@339
  6798
+the Free Software Foundation, 59 Temple Place - Suite 330,
yann@339
  6799
+Boston, MA 02111-1307, USA.  */
yann@339
  6800
+
yann@339
  6801
+
yann@339
  6802
+
yann@339
  6803
+#define TARGET_CPU_CPP_BUILTINS()		\
yann@339
  6804
+  do						\
yann@339
  6805
+    {						\
yann@339
  6806
+      builtin_define_std ("NIOS2");		\
yann@339
  6807
+      builtin_define_std ("nios2");		\
yann@339
  6808
+      builtin_define ("_GNU_SOURCE");		\
yann@339
  6809
+    }						\
yann@339
  6810
+  while (0)
yann@339
  6811
+#define TARGET_VERSION fprintf (stderr, " (Altera Nios II)")
yann@339
  6812
+
yann@339
  6813
+
yann@339
  6814
+
yann@339
  6815
+
yann@339
  6816
+
yann@339
  6817
+/*********************************
yann@339
  6818
+ * Run-time Target Specification
yann@339
  6819
+ *********************************/
yann@339
  6820
+
yann@339
  6821
+#define HAS_DIV_FLAG 0x0001
yann@339
  6822
+#define HAS_MUL_FLAG 0x0002
yann@339
  6823
+#define HAS_MULX_FLAG 0x0004
yann@339
  6824
+#define FAST_SW_DIV_FLAG 0x0008
yann@339
  6825
+#define INLINE_MEMCPY_FLAG 0x00010
yann@339
  6826
+#define CACHE_VOLATILE_FLAG 0x0020
yann@339
  6827
+#define BYPASS_CACHE_FLAG 0x0040
yann@339
  6828
+
yann@339
  6829
+extern int target_flags;
yann@339
  6830
+#define TARGET_HAS_DIV (target_flags & HAS_DIV_FLAG)
yann@339
  6831
+#define TARGET_HAS_MUL (target_flags & HAS_MUL_FLAG)
yann@339
  6832
+#define TARGET_HAS_MULX (target_flags & HAS_MULX_FLAG)
yann@339
  6833
+#define TARGET_FAST_SW_DIV (target_flags & FAST_SW_DIV_FLAG)
yann@339
  6834
+#define TARGET_INLINE_MEMCPY (target_flags & INLINE_MEMCPY_FLAG)
yann@339
  6835
+#define TARGET_CACHE_VOLATILE (target_flags & CACHE_VOLATILE_FLAG)
yann@339
  6836
+#define TARGET_BYPASS_CACHE (target_flags & BYPASS_CACHE_FLAG)
yann@339
  6837
+
yann@339
  6838
+#define TARGET_SWITCHES					\
yann@339
  6839
+{							\
yann@339
  6840
+    { "hw-div", HAS_DIV_FLAG,				\
yann@339
  6841
+      N_("Enable DIV, DIVU") },				\
yann@339
  6842
+    { "no-hw-div", -HAS_DIV_FLAG,			\
yann@339
  6843
+      N_("Disable DIV, DIVU (default)") },		\
yann@339
  6844
+    { "hw-mul", HAS_MUL_FLAG,				\
yann@339
  6845
+      N_("Enable MUL instructions (default)") },				\
yann@339
  6846
+    { "hw-mulx", HAS_MULX_FLAG,				\
yann@339
  6847
+      N_("Enable MULX instructions, assume fast shifter") },				\
yann@339
  6848
+    { "no-hw-mul", -HAS_MUL_FLAG,			\
yann@339
  6849
+      N_("Disable MUL instructions") },		\
yann@339
  6850
+    { "no-hw-mulx", -HAS_MULX_FLAG,			\
yann@339
  6851
+      N_("Disable MULX instructions, assume slow shifter (default and implied by -mno-hw-mul)") },		\
yann@339
  6852
+    { "fast-sw-div", FAST_SW_DIV_FLAG,				\
yann@339
  6853
+      N_("Use table based fast divide (default at -O3)") },				\
yann@339
  6854
+    { "no-fast-sw-div", -FAST_SW_DIV_FLAG,			\
yann@339
  6855
+      N_("Don't use table based fast divide ever") },		\
yann@339
  6856
+    { "inline-memcpy", INLINE_MEMCPY_FLAG,				\
yann@339
  6857
+      N_("Inline small memcpy (default when optimizing)") },				\
yann@339
  6858
+    { "no-inline-memcpy", -INLINE_MEMCPY_FLAG,			\
yann@339
  6859
+      N_("Don't Inline small memcpy") },		\
yann@339
  6860
+    { "cache-volatile", CACHE_VOLATILE_FLAG,				\
yann@339
  6861
+      N_("Volatile accesses use non-io variants of instructions (default)") },				\
yann@339
  6862
+    { "no-cache-volatile", -CACHE_VOLATILE_FLAG,			\
yann@339
  6863
+      N_("Volatile accesses use io variants of instructions") },		\
yann@339
  6864
+    { "bypass-cache", BYPASS_CACHE_FLAG,				\
yann@339
  6865
+      N_("All ld/st instructins use io variants") },				\
yann@339
  6866
+    { "no-bypass-cache", -BYPASS_CACHE_FLAG,			\
yann@339
  6867
+      N_("All ld/st instructins do not use io variants (default)") },		\
yann@339
  6868
+    { "smallc", 0,			\
yann@339
  6869
+      N_("Link with a limited version of the C library") },		\
yann@339
  6870
+    { "ctors-in-init", 0,			\
yann@339
  6871
+      "" /* undocumented: N_("Link with static constructors and destructors in init") */ },		\
yann@339
  6872
+    { "", TARGET_DEFAULT, 0 }				\
yann@339
  6873
+}
yann@339
  6874
+
yann@339
  6875
+
yann@339
  6876
+extern const char *nios2_sys_nosys_string;    /* for -msys=nosys */
yann@339
  6877
+extern const char *nios2_sys_lib_string;    /* for -msys-lib= */
yann@339
  6878
+extern const char *nios2_sys_crt0_string;    /* for -msys-crt0= */
yann@339
  6879
+
yann@339
  6880
+#define TARGET_OPTIONS					\
yann@339
  6881
+{							\
yann@339
  6882
+  { "sys=nosys",    &nios2_sys_nosys_string,		\
yann@339
  6883
+      N_("Use stub versions of OS library calls (default)"), 0},	\
yann@339
  6884
+  { "sys-lib=",    &nios2_sys_lib_string,		\
yann@339
  6885
+      N_("Name of System Library to link against. (Converted to a -l option)"), 0},	\
yann@339
  6886
+  { "sys-crt0=",    &nios2_sys_crt0_string,		\
yann@339
  6887
+      N_("Name of the startfile. (default is a crt0 for the ISS only)"), 0},	\
yann@339
  6888
+}
yann@339
  6889
+
yann@339
  6890
+
yann@339
  6891
+/* Default target_flags if no switches specified.  */
yann@339
  6892
+#ifndef TARGET_DEFAULT
yann@339
  6893
+# define TARGET_DEFAULT (HAS_MUL_FLAG | CACHE_VOLATILE_FLAG)
yann@339
  6894
+#endif
yann@339
  6895
+
yann@339
  6896
+/* Switch  Recognition by gcc.c.  Add -G xx support */
yann@339
  6897
+#undef  SWITCH_TAKES_ARG
yann@339
  6898
+#define SWITCH_TAKES_ARG(CHAR)						\
yann@339
  6899
+  (DEFAULT_SWITCH_TAKES_ARG (CHAR) || (CHAR) == 'G')
yann@339
  6900
+
yann@339
  6901
+#define OVERRIDE_OPTIONS override_options ()
yann@339
  6902
+#define OPTIMIZATION_OPTIONS(LEVEL, SIZE) optimization_options (LEVEL, SIZE)
yann@339
  6903
+#define CAN_DEBUG_WITHOUT_FP
yann@339
  6904
+ 
yann@339
  6905
+#define CC1_SPEC "\
yann@339
  6906
+%{G*}"
yann@339
  6907
+
yann@339
  6908
+#undef LIB_SPEC
yann@339
  6909
+#define LIB_SPEC \
yann@339
  6910
+"--start-group %{msmallc: -lsmallc} %{!msmallc: -lc} -lgcc \
yann@339
  6911
+ %{msys-lib=*: -l%*} \
yann@339
  6912
+ %{!msys-lib=*: -lc } \
yann@339
  6913
+ --end-group \
yann@339
  6914
+ %{msys-lib=: %eYou need a library name for -msys-lib=} \
yann@339
  6915
+"
yann@339
  6916
+
yann@339
  6917
+
yann@339
  6918
+#undef STARTFILE_SPEC 
yann@339
  6919
+#define STARTFILE_SPEC  \
yann@339
  6920
+"%{msys-crt0=*: %*} %{!msys-crt0=*: crt1%O%s} \
yann@339
  6921
+ %{msys-crt0=: %eYou need a C startup file for -msys-crt0=} \
yann@339
  6922
+ %{mctors-in-init: crti%O%s crtbegin%O%s} \
yann@339
  6923
+"
yann@339
  6924
+
yann@339
  6925
+#undef ENDFILE_SPEC 
yann@339
  6926
+#define ENDFILE_SPEC \
yann@339
  6927
+ "%{mctors-in-init: crtend%O%s crtn%O%s}"
yann@339
  6928
+
yann@339
  6929
+
yann@339
  6930
+/***********************
yann@339
  6931
+ * Storage Layout
yann@339
  6932
+ ***********************/
yann@339
  6933
+
yann@339
  6934
+#define DEFAULT_SIGNED_CHAR 1
yann@339
  6935
+#define BITS_BIG_ENDIAN 0
yann@339
  6936
+#define BYTES_BIG_ENDIAN 0
yann@339
  6937
+#define WORDS_BIG_ENDIAN 0
yann@339
  6938
+#define BITS_PER_UNIT 8
yann@339
  6939
+#define BITS_PER_WORD 32
yann@339
  6940
+#define UNITS_PER_WORD 4
yann@339
  6941
+#define POINTER_SIZE 32
yann@339
  6942
+#define BIGGEST_ALIGNMENT 32
yann@339
  6943
+#define STRICT_ALIGNMENT 1
yann@339
  6944
+#define FUNCTION_BOUNDARY 32
yann@339
  6945
+#define PARM_BOUNDARY 32
yann@339
  6946
+#define STACK_BOUNDARY 32
yann@339
  6947
+#define PREFERRED_STACK_BOUNDARY 32
yann@339
  6948
+#define MAX_FIXED_MODE_SIZE 64
yann@339
  6949
+
yann@339
  6950
+#define CONSTANT_ALIGNMENT(EXP, ALIGN)				\
yann@339
  6951
+  ((TREE_CODE (EXP) == STRING_CST) 				\
yann@339
  6952
+   && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
yann@339
  6953
+
yann@339
  6954
+
yann@339
  6955
+/**********************
yann@339
  6956
+ * Layout of Source Language Data Types
yann@339
  6957
+ **********************/
yann@339
  6958
+
yann@339
  6959
+#define INT_TYPE_SIZE 32
yann@339
  6960
+#define SHORT_TYPE_SIZE 16
yann@339
  6961
+#define LONG_TYPE_SIZE 32
yann@339
  6962
+#define LONG_LONG_TYPE_SIZE 64
yann@339
  6963
+#define FLOAT_TYPE_SIZE 32
yann@339
  6964
+#define DOUBLE_TYPE_SIZE 64
yann@339
  6965
+#define LONG_DOUBLE_TYPE_SIZE DOUBLE_TYPE_SIZE
yann@339
  6966
+
yann@339
  6967
+
yann@339
  6968
+/*************************
yann@339
  6969
+ * Condition Code Status
yann@339
  6970
+ ************************/
yann@339
  6971
+
yann@339
  6972
+/* comparison type */
yann@339
  6973
+/* ??? currently only CMP_SI is used */
yann@339
  6974
+enum cmp_type {
yann@339
  6975
+  CMP_SI,				/* compare four byte integers */
yann@339
  6976
+  CMP_DI,				/* compare eight byte integers */
yann@339
  6977
+  CMP_SF,				/* compare single precision floats */
yann@339
  6978
+  CMP_DF,				/* compare double precision floats */
yann@339
  6979
+  CMP_MAX				/* max comparison type */
yann@339
  6980
+};
yann@339
  6981
+
yann@339
  6982
+extern GTY(()) rtx branch_cmp[2];	/* operands for compare */
yann@339
  6983
+extern enum cmp_type branch_type;	/* what type of branch to use */
yann@339
  6984
+
yann@339
  6985
+/**********************
yann@339
  6986
+ * Register Usage
yann@339
  6987
+ **********************/
yann@339
  6988
+
yann@339
  6989
+/* ---------------------------------- *
yann@339
  6990
+ * Basic Characteristics of Registers
yann@339
  6991
+ * ---------------------------------- */
yann@339
  6992
+
yann@339
  6993
+/*
yann@339
  6994
+Register Number
yann@339
  6995
+      Register Name
yann@339
  6996
+          Alternate Name
yann@339
  6997
+                Purpose
yann@339
  6998
+0     r0  zero  always zero
yann@339
  6999
+1     r1  at    Assembler Temporary
yann@339
  7000
+2-3   r2-r3     Return Location
yann@339
  7001
+4-7   r4-r7     Register Arguments
yann@339
  7002
+8-15  r8-r15    Caller Saved Registers
yann@339
  7003
+16-22 r16-r22   Callee Saved Registers
yann@339
  7004
+23    r23 sc    Static Chain (Callee Saved)
yann@339
  7005
+                ??? Does $sc want to be caller or callee 
yann@339
  7006
+                saved. If caller, 15, else 23. 
yann@339
  7007
+24    r24       Exception Temporary
yann@339
  7008
+25    r25       Breakpoint Temporary
yann@339
  7009
+26    r26 gp    Global Pointer
yann@339
  7010
+27    r27 sp    Stack Pointer
yann@339
  7011
+28    r28 fp    Frame Pointer
yann@339
  7012
+29    r29 ea    Exception Return Address
yann@339
  7013
+30    r30 ba    Breakpoint Return Address
yann@339
  7014
+31    r31 ra    Return Address
yann@339
  7015
+
yann@339
  7016
+32    ctl0 status
yann@339
  7017
+33    ctl1 estatus STATUS saved by exception ? 	
yann@339
  7018
+34    ctl2 bstatus STATUS saved by break ? 	
yann@339
  7019
+35    ctl3 ipri    Interrupt Priority Mask ?	
yann@339
  7020
+36    ctl4 ecause  Exception Cause ? 	
yann@339
  7021
+
yann@339
  7022
+37         pc   Not an actual register	
yann@339
  7023
+
yann@339
  7024
+38    rap      Return address pointer, this does not
yann@339
  7025
+                   actually exist and will be eliminated
yann@339
  7026
+
yann@339
  7027
+39    fake_fp  Fake Frame Pointer which will always be eliminated.
yann@339
  7028
+40    fake_ap  Fake Argument Pointer which will always be eliminated.
yann@339
  7029
+
yann@339
  7030
+41             First Pseudo Register
yann@339
  7031
+
yann@339
  7032
+
yann@339
  7033
+The definitions for all the hard register numbers
yann@339
  7034
+are located in nios2.md.
yann@339
  7035
+*/
yann@339
  7036
+
yann@339
  7037
+#define FIRST_PSEUDO_REGISTER 41
yann@339
  7038
+#define NUM_ARG_REGS (LAST_ARG_REGNO - FIRST_ARG_REGNO + 1)
yann@339
  7039
+
yann@339
  7040
+
yann@339
  7041
+
yann@339
  7042
+/* also see CONDITIONAL_REGISTER_USAGE */
yann@339
  7043
+#define FIXED_REGISTERS			     \
yann@339
  7044
+    {					     \
yann@339
  7045
+/*        +0  1  2  3  4  5  6  7  8  9 */   \
yann@339
  7046
+/*   0 */  1, 1, 0, 0, 0, 0, 0, 0, 0, 0,     \
yann@339
  7047
+/*  10 */  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     \
yann@339
  7048
+/*  20 */  0, 0, 0, 0, 1, 1, 1, 1, 0, 1,     \
yann@339
  7049
+/*  30 */  1, 0, 1, 1, 1, 1, 1, 1, 1, 1,     \
yann@339
  7050
+/*  40 */  1,                                \
yann@339
  7051
+    }
yann@339
  7052
+
yann@339
  7053
+/* call used is the same as caller saved
yann@339
  7054
+   + fixed regs + args + ret vals */
yann@339
  7055
+#define CALL_USED_REGISTERS		     \
yann@339
  7056
+    { 					     \
yann@339
  7057
+/*        +0  1  2  3  4  5  6  7  8  9 */   \
yann@339
  7058
+/*   0 */  1, 1, 1, 1, 1, 1, 1, 1, 1, 1,     \
yann@339
  7059
+/*  10 */  1, 1, 1, 1, 1, 1, 0, 0, 0, 0,     \
yann@339
  7060
+/*  20 */  0, 0, 0, 0, 1, 1, 1, 1, 0, 1,     \
yann@339
  7061
+/*  30 */  1, 0, 1, 1, 1, 1, 1, 1, 1, 1,     \
yann@339
  7062
+/*  40 */  1,                                \
yann@339
  7063
+    }
yann@339
  7064
+
yann@339
  7065
+#define HARD_REGNO_NREGS(REGNO, MODE)            \
yann@339
  7066
+   ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1)  \
yann@339
  7067
+    / UNITS_PER_WORD)
yann@339
  7068
+
yann@339
  7069
+/* --------------------------- *
yann@339
  7070
+ * How Values Fit in Registers
yann@339
  7071
+ * --------------------------- */
yann@339
  7072
+
yann@339
  7073
+#define HARD_REGNO_MODE_OK(REGNO, MODE) 1
yann@339
  7074
+
yann@339
  7075
+#define MODES_TIEABLE_P(MODE1, MODE2) 1
yann@339
  7076
+
yann@339
  7077
+
yann@339
  7078
+/*************************
yann@339
  7079
+ * Register Classes
yann@339
  7080
+ *************************/
yann@339
  7081
+
yann@339
  7082
+enum reg_class
yann@339
  7083
+{
yann@339
  7084
+    NO_REGS,
yann@339
  7085
+    ALL_REGS,
yann@339
  7086
+    LIM_REG_CLASSES
yann@339
  7087
+};
yann@339
  7088
+
yann@339
  7089
+#define N_REG_CLASSES (int) LIM_REG_CLASSES
yann@339
  7090
+
yann@339
  7091
+#define REG_CLASS_NAMES   \
yann@339
  7092
+    {"NO_REGS",           \
yann@339
  7093
+     "ALL_REGS"}
yann@339
  7094
+
yann@339
  7095
+#define GENERAL_REGS ALL_REGS
yann@339
  7096
+
yann@339
  7097
+#define REG_CLASS_CONTENTS   \
yann@339
  7098
+/* NO_REGS  */       {{ 0, 0},     \
yann@339
  7099
+/* ALL_REGS */        {~0,~0}}    \
yann@339
  7100
+
yann@339
  7101
+#define REGNO_REG_CLASS(REGNO) ALL_REGS
yann@339
  7102
+
yann@339
  7103
+#define BASE_REG_CLASS ALL_REGS
yann@339
  7104
+#define INDEX_REG_CLASS ALL_REGS
yann@339
  7105
+
yann@339
  7106
+/* only one reg class, 'r', is handled automatically */
yann@339
  7107
+#define REG_CLASS_FROM_LETTER(CHAR) NO_REGS
yann@339
  7108
+
yann@339
  7109
+#define REGNO_OK_FOR_BASE_P2(REGNO, STRICT) \
yann@339
  7110
+    ((STRICT) \
yann@339
  7111
+     ? (REGNO) < FIRST_PSEUDO_REGISTER \
yann@339
  7112
+     : (REGNO) < FIRST_PSEUDO_REGISTER || (reg_renumber && reg_renumber[REGNO] < FIRST_PSEUDO_REGISTER))
yann@339
  7113
+
yann@339
  7114
+#define REGNO_OK_FOR_INDEX_P2(REGNO, STRICT) \
yann@339
  7115
+    (REGNO_OK_FOR_BASE_P2 (REGNO, STRICT))
yann@339
  7116
+
yann@339
  7117
+#define REGNO_OK_FOR_BASE_P(REGNO) \
yann@339
  7118
+    (REGNO_OK_FOR_BASE_P2 (REGNO, 1))
yann@339
  7119
+
yann@339
  7120
+#define REGNO_OK_FOR_INDEX_P(REGNO) \
yann@339
  7121
+    (REGNO_OK_FOR_INDEX_P2 (REGNO, 1))
yann@339
  7122
+
yann@339
  7123
+#define REG_OK_FOR_BASE_P2(X, STRICT)                                   \
yann@339
  7124
+    (STRICT                                                             \
yann@339
  7125
+     ? REGNO_OK_FOR_BASE_P2 (REGNO (X), 1)                              \
yann@339
  7126
+     : REGNO_OK_FOR_BASE_P2 (REGNO (X), 1) || REGNO(X) >= FIRST_PSEUDO_REGISTER)
yann@339
  7127
+
yann@339
  7128
+#define REG_OK_FOR_INDEX_P2(X, STRICT)                                  \
yann@339
  7129
+    (STRICT                                                             \
yann@339
  7130
+     ? REGNO_OK_FOR_INDEX_P2 (REGNO (X), 1)                             \
yann@339
  7131
+     : REGNO_OK_FOR_INDEX_P2 (REGNO (X), 1) || REGNO(X) >= FIRST_PSEUDO_REGISTER)
yann@339
  7132
+
yann@339
  7133
+#define CLASS_MAX_NREGS(CLASS, MODE)             \
yann@339
  7134
+   ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1)  \
yann@339
  7135
+    / UNITS_PER_WORD)
yann@339
  7136
+
yann@339
  7137
+
yann@339
  7138
+#define SMALL_INT(X) ((unsigned HOST_WIDE_INT) ((X) + 0x8000) < 0x10000)
yann@339
  7139
+#define SMALL_INT_UNSIGNED(X) ((unsigned HOST_WIDE_INT) (X) < 0x10000)
yann@339
  7140
+#define UPPER16_INT(X) (((X) & 0xffff) == 0)
yann@339
  7141
+#define SHIFT_INT(X) ((X) >= 0 && (X) <= 31)
yann@339
  7142
+#define RDWRCTL_INT(X) ((X) >= 0 && (X) <= 31)
yann@339
  7143
+#define CUSTOM_INSN_OPCODE(X) ((X) >= 0 && (X) <= 255)
yann@339
  7144
+
yann@339
  7145
+#define CONST_OK_FOR_LETTER_P(VALUE, C)			\
yann@339
  7146
+ (							\
yann@339
  7147
+  (C) == 'I' ? SMALL_INT (VALUE) :			\
yann@339
  7148
+  (C) == 'J' ? SMALL_INT_UNSIGNED (VALUE) :		\
yann@339
  7149
+  (C) == 'K' ? UPPER16_INT (VALUE) :         		\
yann@339
  7150
+  (C) == 'L' ? SHIFT_INT (VALUE) :			\
yann@339
  7151
+  (C) == 'M' ? (VALUE) == 0 :				\
yann@339
  7152
+  (C) == 'N' ? CUSTOM_INSN_OPCODE (VALUE) :		\
yann@339
  7153
+  (C) == 'O' ? RDWRCTL_INT (VALUE) :			\
yann@339
  7154
+  0)
yann@339
  7155
+
yann@339
  7156
+#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) 0
yann@339
  7157
+
yann@339
  7158
+#define PREFERRED_RELOAD_CLASS(X, CLASS) \
yann@339
  7159
+    ((CLASS) == NO_REGS ? GENERAL_REGS : (CLASS))
yann@339
  7160
+
yann@339
  7161
+/* 'S' matches immediates which are in small data 
yann@339
  7162
+   and therefore can be added to gp to create a 
yann@339
  7163
+   32-bit value. */
yann@339
  7164
+#define EXTRA_CONSTRAINT(VALUE, C)		\
yann@339
  7165
+  ((C) == 'S' 					\
yann@339
  7166
+   && (GET_CODE (VALUE) == SYMBOL_REF)   	\
yann@339
  7167
+   && SYMBOL_REF_IN_NIOS2_SMALL_DATA_P (VALUE))
yann@339
  7168
+
yann@339
  7169
+
yann@339
  7170
+
yann@339
  7171
+
yann@339
  7172
+/* Say that the epilogue uses the return address register.  Note that
yann@339
  7173
+   in the case of sibcalls, the values "used by the epilogue" are
yann@339
  7174
+   considered live at the start of the called function.  */
yann@339
  7175
+#define EPILOGUE_USES(REGNO) ((REGNO) == RA_REGNO)
yann@339
  7176
+
yann@339
  7177
+
yann@339
  7178
+#define DEFAULT_MAIN_RETURN  c_expand_return (integer_zero_node)
yann@339
  7179
+
yann@339
  7180
+/**********************************
yann@339
  7181
+ * Trampolines for Nested Functions
yann@339
  7182
+ ***********************************/
yann@339
  7183
+
yann@339
  7184
+#define TRAMPOLINE_TEMPLATE(FILE) \
yann@339
  7185
+    error ("trampolines not yet implemented")
yann@339
  7186
+#define TRAMPOLINE_SIZE 20
yann@339
  7187
+#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
yann@339
  7188
+    error ("trampolines not yet implemented")
yann@339
  7189
+
yann@339
  7190
+/***************************
yann@339
  7191
+ * Stack Layout and Calling Conventions
yann@339
  7192
+ ***************************/
yann@339
  7193
+
yann@339
  7194
+/* ------------------ *
yann@339
  7195
+ * Basic Stack Layout
yann@339
  7196
+ * ------------------ */
yann@339
  7197
+
yann@339
  7198
+/* The downward variants are used by the compiler,
yann@339
  7199
+   the upward ones serve as documentation */
yann@339
  7200
+#define STACK_GROWS_DOWNWARD
yann@339
  7201
+#define FRAME_GROWS_UPWARD
yann@339
  7202
+#define ARGS_GROW_UPWARD
yann@339
  7203
+
yann@339
  7204
+#define STARTING_FRAME_OFFSET current_function_outgoing_args_size
yann@339
  7205
+#define FIRST_PARM_OFFSET(FUNDECL) 0
yann@339
  7206
+
yann@339
  7207
+/* Before the prologue, RA lives in r31.  */
yann@339
  7208
+#define INCOMING_RETURN_ADDR_RTX  gen_rtx_REG (VOIDmode, RA_REGNO)
yann@339
  7209
+
yann@339
  7210
+/* -------------------------------------- *
yann@339
  7211
+ * Registers That Address the Stack Frame
yann@339
  7212
+ * -------------------------------------- */
yann@339
  7213
+
yann@339
  7214
+#define STACK_POINTER_REGNUM SP_REGNO
yann@339
  7215
+#define STATIC_CHAIN_REGNUM SC_REGNO
yann@339
  7216
+#define PC_REGNUM PC_REGNO
yann@339
  7217
+#define DWARF_FRAME_RETURN_COLUMN RA_REGNO
yann@339
  7218
+
yann@339
  7219
+/* Base register for access to local variables of the function.  We
yann@339
  7220
+   pretend that the frame pointer is a non-existent hard register, and 
yann@339
  7221
+   then eliminate it to HARD_FRAME_POINTER_REGNUM. */
yann@339
  7222
+#define FRAME_POINTER_REGNUM FAKE_FP_REGNO
yann@339
  7223
+
yann@339
  7224
+#define HARD_FRAME_POINTER_REGNUM FP_REGNO
yann@339
  7225
+#define RETURN_ADDRESS_POINTER_REGNUM RAP_REGNO
yann@339
  7226
+/* the argumnet pointer needs to always be eliminated
yann@339
  7227
+   so it is set to a fake hard register. */
yann@339
  7228
+#define ARG_POINTER_REGNUM FAKE_AP_REGNO
yann@339
  7229
+
yann@339
  7230
+/* ----------------------------------------- *
yann@339
  7231
+ * Eliminating Frame Pointer and Arg Pointer
yann@339
  7232
+ * ----------------------------------------- */
yann@339
  7233
+
yann@339
  7234
+#define FRAME_POINTER_REQUIRED 0
yann@339
  7235
+
yann@339
  7236
+#define ELIMINABLE_REGS							\
yann@339
  7237
+{{ ARG_POINTER_REGNUM,   STACK_POINTER_REGNUM},				\
yann@339
  7238
+ { ARG_POINTER_REGNUM,   HARD_FRAME_POINTER_REGNUM},			\
yann@339
  7239
+ { RETURN_ADDRESS_POINTER_REGNUM, STACK_POINTER_REGNUM},		\
yann@339
  7240
+ { RETURN_ADDRESS_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM},		\
yann@339
  7241
+ { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},				\
yann@339
  7242
+ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
yann@339
  7243
+
yann@339
  7244
+#define CAN_ELIMINATE(FROM, TO)	1
yann@339
  7245
+
yann@339
  7246
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
yann@339
  7247
+	(OFFSET) = nios2_initial_elimination_offset ((FROM), (TO))
yann@339
  7248
+
yann@339
  7249
+#define MUST_SAVE_REGISTER(regno) \
yann@339
  7250
+ ((regs_ever_live[regno] && !call_used_regs[regno])			\
yann@339
  7251
+  || (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)	\
yann@339
  7252
+  || (regno == RA_REGNO && regs_ever_live[RA_REGNO]))
yann@339
  7253
+
yann@339
  7254
+/* Treat LOC as a byte offset from the stack pointer and round it up
yann@339
  7255
+   to the next fully-aligned offset.  */
yann@339
  7256
+#define STACK_ALIGN(LOC)						\
yann@339
  7257
+  (((LOC) + ((PREFERRED_STACK_BOUNDARY / 8) - 1)) & ~((PREFERRED_STACK_BOUNDARY / 8) - 1))
yann@339
  7258
+
yann@339
  7259
+
yann@339
  7260
+/* ------------------------------ *
yann@339
  7261
+ * Passing Arguments in Registers
yann@339
  7262
+ * ------------------------------ */
yann@339
  7263
+
yann@339
  7264
+/* see nios2.c */
yann@339
  7265
+#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
yann@339
  7266
+  (function_arg (&CUM, MODE, TYPE, NAMED))
yann@339
  7267
+
yann@339
  7268
+#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
yann@339
  7269
+  (function_arg_partial_nregs (&CUM, MODE, TYPE, NAMED))
yann@339
  7270
+
yann@339
  7271
+#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) 0
yann@339
  7272
+
yann@339
  7273
+#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) 0
yann@339
  7274
+
yann@339
  7275
+typedef struct nios2_args
yann@339
  7276
+{
yann@339
  7277
+    int regs_used;
yann@339
  7278
+} CUMULATIVE_ARGS;
yann@339
  7279
+
yann@339
  7280
+/* This is to initialize the above unused CUM data type */
yann@339
  7281
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \
yann@339
  7282
+    (init_cumulative_args (&CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS))
yann@339
  7283
+
yann@339
  7284
+#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
yann@339
  7285
+    (function_arg_advance (&CUM, MODE, TYPE, NAMED))
yann@339
  7286
+
yann@339
  7287
+#define FUNCTION_ARG_REGNO_P(REGNO) \
yann@339
  7288
+    ((REGNO) >= FIRST_ARG_REGNO && (REGNO) <= LAST_ARG_REGNO)
yann@339
  7289
+
yann@339
  7290
+#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL)   \
yann@339
  7291
+  {								    \
yann@339
  7292
+    int pret_size = nios2_setup_incoming_varargs (&(CUM), (MODE),	    \
yann@339
  7293
+						(TYPE), (NO_RTL));  \
yann@339
  7294
+    if (pret_size)						    \
yann@339
  7295
+      (PRETEND_SIZE) = pret_size;				    \
yann@339
  7296
+  }
yann@339
  7297
+
yann@339
  7298
+/* ----------------------------- *
yann@339
  7299
+ * Generating Code for Profiling
yann@339
  7300
+ * ----------------------------- */
yann@339
  7301
+
yann@339
  7302
+#define PROFILE_BEFORE_PROLOGUE
yann@339
  7303
+
yann@339
  7304
+#define FUNCTION_PROFILER(FILE, LABELNO) \
yann@339
  7305
+  function_profiler ((FILE), (LABELNO))
yann@339
  7306
+
yann@339
  7307
+/* --------------------------------------- *
yann@339
  7308
+ * Passing Function Arguments on the Stack
yann@339
  7309
+ * --------------------------------------- */
yann@339
  7310
+
yann@339
  7311
+#define PROMOTE_PROTOTYPES 1
yann@339
  7312
+
yann@339
  7313
+#define PUSH_ARGS 0
yann@339
  7314
+#define ACCUMULATE_OUTGOING_ARGS 1
yann@339
  7315
+
yann@339
  7316
+#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACKSIZE) 0
yann@339
  7317
+
yann@339
  7318
+/* --------------------------------------- *
yann@339
  7319
+ * How Scalar Function Values Are Returned
yann@339
  7320
+ * --------------------------------------- */
yann@339
  7321
+
yann@339
  7322
+#define FUNCTION_VALUE(VALTYPE, FUNC) \
yann@339
  7323
+    gen_rtx(REG, TYPE_MODE(VALTYPE), FIRST_RETVAL_REGNO)
yann@339
  7324
+
yann@339
  7325
+#define LIBCALL_VALUE(MODE) \
yann@339
  7326
+    gen_rtx(REG, MODE, FIRST_RETVAL_REGNO)
yann@339
  7327
+
yann@339
  7328
+#define FUNCTION_VALUE_REGNO_P(REGNO) ((REGNO) == FIRST_RETVAL_REGNO)
yann@339
  7329
+
yann@339
  7330
+/* ----------------------------- *
yann@339
  7331
+ * How Large Values Are Returned
yann@339
  7332
+ * ----------------------------- */
yann@339
  7333
+
yann@339
  7334
+
yann@339
  7335
+#define RETURN_IN_MEMORY(TYPE)	\
yann@339
  7336
+  nios2_return_in_memory (TYPE)
yann@339
  7337
+
yann@339
  7338
+
yann@339
  7339
+#define STRUCT_VALUE 0
yann@339
  7340
+
yann@339
  7341
+#define DEFAULT_PCC_STRUCT_RETURN 0
yann@339
  7342
+
yann@339
  7343
+/*******************
yann@339
  7344
+ * Addressing Modes
yann@339
  7345
+ *******************/
yann@339
  7346
+
yann@339
  7347
+
yann@339
  7348
+#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)
yann@339
  7349
+
yann@339
  7350
+#define CONSTANT_ADDRESS_P(X) (CONSTANT_P (X))
yann@339
  7351
+
yann@339
  7352
+#define MAX_REGS_PER_ADDRESS 1
yann@339
  7353
+
yann@339
  7354
+/* Go to ADDR if X is a valid address.  */
yann@339
  7355
+#ifndef REG_OK_STRICT
yann@339
  7356
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)        \
yann@339
  7357
+    {                                                  \
yann@339
  7358
+        if (nios2_legitimate_address ((X), (MODE), 0))  \
yann@339
  7359
+            goto ADDR;                                 \
yann@339
  7360
+    }
yann@339
  7361
+#else
yann@339
  7362
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)        \
yann@339
  7363
+    {                                                  \
yann@339
  7364
+        if (nios2_legitimate_address ((X), (MODE), 1))  \
yann@339
  7365
+            goto ADDR;                                 \
yann@339
  7366
+    }
yann@339
  7367
+#endif
yann@339
  7368
+
yann@339
  7369
+#ifndef REG_OK_STRICT
yann@339
  7370
+#define REG_OK_FOR_BASE_P(X)   REGNO_OK_FOR_BASE_P2 (REGNO (X), 0)
yann@339
  7371
+#define REG_OK_FOR_INDEX_P(X)  REGNO_OK_FOR_INDEX_P2 (REGNO (X), 0)
yann@339
  7372
+#else
yann@339
  7373
+#define REG_OK_FOR_BASE_P(X)   REGNO_OK_FOR_BASE_P2 (REGNO (X), 1)
yann@339
  7374
+#define REG_OK_FOR_INDEX_P(X)  REGNO_OK_FOR_INDEX_P2 (REGNO (X), 1)
yann@339
  7375
+#endif
yann@339
  7376
+
yann@339
  7377
+#define LEGITIMATE_CONSTANT_P(X) 1
yann@339
  7378
+
yann@339
  7379
+/* Nios II has no mode dependent addresses.  */
yann@339
  7380
+#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)
yann@339
  7381
+
yann@339
  7382
+/* Set if this has a weak declaration  */
yann@339
  7383
+#define SYMBOL_FLAG_WEAK_DECL	(1 << SYMBOL_FLAG_MACH_DEP_SHIFT)
yann@339
  7384
+#define SYMBOL_REF_WEAK_DECL_P(RTX) \
yann@339
  7385
+  ((SYMBOL_REF_FLAGS (RTX) & SYMBOL_FLAG_WEAK_DECL) != 0)
yann@339
  7386
+
yann@339
  7387
+
yann@339
  7388
+/* true if a symbol is both small and not weak. In this case, gp
yann@339
  7389
+   relative access can be used */
yann@339
  7390
+#define SYMBOL_REF_IN_NIOS2_SMALL_DATA_P(RTX) \
yann@339
  7391
+   (SYMBOL_REF_SMALL_P(RTX) && !SYMBOL_REF_WEAK_DECL_P(RTX))
yann@339
  7392
+
yann@339
  7393
+/*****************
yann@339
  7394
+ * Describing Relative Costs of Operations
yann@339
  7395
+ *****************/
yann@339
  7396
+
yann@339
  7397
+#define SLOW_BYTE_ACCESS 1
yann@339
  7398
+
yann@339
  7399
+/* It is as good to call a constant function address as to call an address
yann@339
  7400
+   kept in a register.
yann@339
  7401
+   ??? Not true anymore really. Now that call cannot address full range
yann@339
  7402
+   of memory callr may need to be used */
yann@339
  7403
+
yann@339
  7404
+#define NO_FUNCTION_CSE
yann@339
  7405
+#define NO_RECURSIVE_FUNCTION_CSE
yann@339
  7406
+
yann@339
  7407
+
yann@339
  7408
+
yann@339
  7409
+/*****************************************
yann@339
  7410
+ * Defining the Output Assembler Language
yann@339
  7411
+ *****************************************/
yann@339
  7412
+
yann@339
  7413
+/* ------------------------------------------ *
yann@339
  7414
+ * The Overall Framework of an Assembler File
yann@339
  7415
+ * ------------------------------------------ */
yann@339
  7416
+
yann@339
  7417
+#define ASM_APP_ON "#APP\n"
yann@339
  7418
+#define ASM_APP_OFF "#NO_APP\n"
yann@339
  7419
+
yann@339
  7420
+#define ASM_COMMENT_START "# "
yann@339
  7421
+
yann@339
  7422
+/* ------------------------------- *
yann@339
  7423
+ * Output and Generation of Labels
yann@339
  7424
+ * ------------------------------- */
yann@339
  7425
+
yann@339
  7426
+#define GLOBAL_ASM_OP "\t.global\t"
yann@339
  7427
+
yann@339
  7428
+
yann@339
  7429
+/* -------------- *
yann@339
  7430
+ * Output of Data
yann@339
  7431
+ * -------------- */
yann@339
  7432
+
yann@339
  7433
+#define DWARF2_UNWIND_INFO 0
yann@339
  7434
+
yann@339
  7435
+
yann@339
  7436
+/* -------------------------------- *
yann@339
  7437
+ * Assembler Commands for Alignment
yann@339
  7438
+ * -------------------------------- */
yann@339
  7439
+
yann@339
  7440
+#define ASM_OUTPUT_ALIGN(FILE, LOG) \
yann@339
  7441
+  do { \
yann@339
  7442
+    fprintf ((FILE), "%s%d\n", ALIGN_ASM_OP, (LOG)); \
yann@339
  7443
+  } while (0)
yann@339
  7444
+
yann@339
  7445
+
yann@339
  7446
+/* -------------------------------- *
yann@339
  7447
+ * Output of Assembler Instructions
yann@339
  7448
+ * -------------------------------- */
yann@339
  7449
+
yann@339
  7450
+#define REGISTER_NAMES \
yann@339
  7451
+{ \
yann@339
  7452
+    "zero", \
yann@339
  7453
+    "at", \
yann@339
  7454
+    "r2", \
yann@339
  7455
+    "r3", \
yann@339
  7456
+    "r4", \
yann@339
  7457
+    "r5", \
yann@339
  7458
+    "r6", \
yann@339
  7459
+    "r7", \
yann@339
  7460
+    "r8", \
yann@339
  7461
+    "r9", \
yann@339
  7462
+    "r10", \
yann@339
  7463
+    "r11", \
yann@339
  7464
+    "r12", \
yann@339
  7465
+    "r13", \
yann@339
  7466
+    "r14", \
yann@339
  7467
+    "r15", \
yann@339
  7468
+    "r16", \
yann@339
  7469
+    "r17", \
yann@339
  7470
+    "r18", \
yann@339
  7471
+    "r19", \
yann@339
  7472
+    "r20", \
yann@339
  7473
+    "r21", \
yann@339
  7474
+    "r22", \
yann@339
  7475
+    "r23", \
yann@339
  7476
+    "r24", \
yann@339
  7477
+    "r25", \
yann@339
  7478
+    "gp", \
yann@339
  7479
+    "sp", \
yann@339
  7480
+    "fp", \
yann@339
  7481
+    "ta", \
yann@339
  7482
+    "ba", \
yann@339
  7483
+    "ra", \
yann@339
  7484
+    "status", \
yann@339
  7485
+    "estatus", \
yann@339
  7486
+    "bstatus", \
yann@339
  7487
+    "ipri", \
yann@339
  7488
+    "ecause", \
yann@339
  7489
+    "pc", \
yann@339
  7490
+    "rap", \
yann@339
  7491
+    "fake_fp", \
yann@339
  7492
+    "fake_ap", \
yann@339
  7493
+}
yann@339
  7494
+
yann@339
  7495
+#define ASM_OUTPUT_OPCODE(STREAM, PTR)\
yann@339
  7496
+   (PTR) = asm_output_opcode (STREAM, PTR)
yann@339
  7497
+
yann@339
  7498
+#define PRINT_OPERAND(STREAM, X, CODE) \
yann@339
  7499
+    nios2_print_operand (STREAM, X, CODE)
yann@339
  7500
+
yann@339
  7501
+#define PRINT_OPERAND_ADDRESS(STREAM, X) \
yann@339
  7502
+    nios2_print_operand_address (STREAM, X)
yann@339
  7503
+
yann@339
  7504
+#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)  \
yann@339
  7505
+do { fputs (integer_asm_op (POINTER_SIZE / BITS_PER_UNIT, TRUE), FILE); \
yann@339
  7506
+     fprintf (FILE, ".L%u\n", (unsigned) (VALUE));               \
yann@339
  7507
+   } while (0)
yann@339
  7508
+
yann@339
  7509
+
yann@339
  7510
+/* ------------ *
yann@339
  7511
+ * Label Output
yann@339
  7512
+ * ------------ */
yann@339
  7513
+
yann@339
  7514
+
yann@339
  7515
+/* ---------------------------------------------------- *
yann@339
  7516
+ * Dividing the Output into Sections (Texts, Data, ...)
yann@339
  7517
+ * ---------------------------------------------------- */
yann@339
  7518
+
yann@339
  7519
+/* Output before read-only data.  */
yann@339
  7520
+#define TEXT_SECTION_ASM_OP ("\t.section\t.text")
yann@339
  7521
+
yann@339
  7522
+/* Output before writable data.  */
yann@339
  7523
+#define DATA_SECTION_ASM_OP ("\t.section\t.data")
yann@339
  7524
+
yann@339
  7525
+
yann@339
  7526
+/* Default the definition of "small data" to 8 bytes. */
yann@339
  7527
+/* ??? How come I can't use HOST_WIDE_INT here? */
yann@339
  7528
+extern unsigned long nios2_section_threshold;
yann@339
  7529
+#define NIOS2_DEFAULT_GVALUE 8
yann@339
  7530
+
yann@339
  7531
+
yann@339
  7532
+
yann@339
  7533
+/* This says how to output assembler code to declare an
yann@339
  7534
+   uninitialized external linkage data object.  Under SVR4,
yann@339
  7535
+   the linker seems to want the alignment of data objects
yann@339
  7536
+   to depend on their types.  We do exactly that here.  */
yann@339
  7537
+
yann@339
  7538
+#undef COMMON_ASM_OP
yann@339
  7539
+#define COMMON_ASM_OP	"\t.comm\t"
yann@339
  7540
+
yann@339
  7541
+#undef  ASM_OUTPUT_ALIGNED_COMMON
yann@339
  7542
+#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN)		\
yann@339
  7543
+do 									\
yann@339
  7544
+{									\
yann@339
  7545
+  if ((SIZE) <= nios2_section_threshold)				\
yann@339
  7546
+    {									\
yann@339
  7547
+      named_section (0, ".sbss", 0);					\
yann@339
  7548
+      (*targetm.asm_out.globalize_label) (FILE, NAME);			\
yann@339
  7549
+      ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");			\
yann@339
  7550
+      if (!flag_inhibit_size_directive)					\
yann@339
  7551
+	ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE);			\
yann@339
  7552
+      ASM_OUTPUT_ALIGN ((FILE), exact_log2((ALIGN) / BITS_PER_UNIT));	\
yann@339
  7553
+      ASM_OUTPUT_LABEL(FILE, NAME);					\
yann@339
  7554
+      ASM_OUTPUT_SKIP((FILE), (SIZE) ? (SIZE) : 1);			\
yann@339
  7555
+    }									\
yann@339
  7556
+  else									\
yann@339
  7557
+    {									\
yann@339
  7558
+      fprintf ((FILE), "%s", COMMON_ASM_OP);				\
yann@339
  7559
+      assemble_name ((FILE), (NAME));					\
yann@339
  7560
+      fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT);	\
yann@339
  7561
+    }									\
yann@339
  7562
+}									\
yann@339
  7563
+while (0)
yann@339
  7564
+
yann@339
  7565
+
yann@339
  7566
+/* This says how to output assembler code to declare an
yann@339
  7567
+   uninitialized internal linkage data object.  Under SVR4,
yann@339
  7568
+   the linker seems to want the alignment of data objects
yann@339
  7569
+   to depend on their types.  We do exactly that here.  */
yann@339
  7570
+
yann@339
  7571
+#undef  ASM_OUTPUT_ALIGNED_LOCAL
yann@339
  7572
+#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN)		\
yann@339
  7573
+do {									\
yann@339
  7574
+  if ((SIZE) <= nios2_section_threshold)				\
yann@339
  7575
+    named_section (0, ".sbss", 0);					\
yann@339
  7576
+  else									\
yann@339
  7577
+    named_section (0, ".bss", 0);					\
yann@339
  7578
+  ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");			\
yann@339
  7579
+  if (!flag_inhibit_size_directive)					\
yann@339
  7580
+    ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE);			\
yann@339
  7581
+  ASM_OUTPUT_ALIGN ((FILE), exact_log2((ALIGN) / BITS_PER_UNIT));	\
yann@339
  7582
+  ASM_OUTPUT_LABEL(FILE, NAME);						\
yann@339
  7583
+  ASM_OUTPUT_SKIP((FILE), (SIZE) ? (SIZE) : 1);				\
yann@339
  7584
+} while (0)
yann@339
  7585
+
yann@339
  7586
+
yann@339
  7587
+
yann@339
  7588
+/***************************
yann@339
  7589
+ * Miscellaneous Parameters
yann@339
  7590
+ ***************************/
yann@339
  7591
+
yann@339
  7592
+#define MOVE_MAX 4
yann@339
  7593
+
yann@339
  7594
+#define Pmode SImode
yann@339
  7595
+#define FUNCTION_MODE QImode
yann@339
  7596
+
yann@339
  7597
+#define CASE_VECTOR_MODE Pmode
yann@339
  7598
+
yann@339
  7599
+#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
yann@339
  7600
+
yann@339
  7601
+#define LOAD_EXTEND_OP(MODE) (ZERO_EXTEND)
yann@339
  7602
+
yann@339
  7603
+#define WORD_REGISTER_OPERATIONS
yann@339
  7604
diff -durN gcc-3.4.6.orig/gcc/config/nios2/nios2.md gcc-3.4.6/gcc/config/nios2/nios2.md
yann@339
  7605
--- gcc-3.4.6.orig/gcc/config/nios2/nios2.md	1970-01-01 01:00:00.000000000 +0100
yann@339
  7606
+++ gcc-3.4.6/gcc/config/nios2/nios2.md	2007-08-15 23:09:36.000000000 +0200
yann@339
  7607
@@ -0,0 +1,2078 @@
yann@339
  7608
+;; Machine Description for Altera NIOS 2G NIOS2 version.
yann@339
  7609
+;;    Copyright (C) 2003 Altera 
yann@339
  7610
+;;    Contributed by Jonah Graham (jgraham@altera.com).
yann@339
  7611
+;; 
yann@339
  7612
+;; This file is part of GNU CC.
yann@339
  7613
+;; 
yann@339
  7614
+;; GNU CC is free software; you can redistribute it and/or modify
yann@339
  7615
+;; it under the terms of the GNU General Public License as published by
yann@339
  7616
+;; the Free Software Foundation; either version 2, or (at your option)
yann@339
  7617
+;; any later version.
yann@339
  7618
+;; 
yann@339
  7619
+;; GNU CC is distributed in the hope that it will be useful,
yann@339
  7620
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
yann@339
  7621
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
yann@339
  7622
+;; GNU General Public License for more details.
yann@339
  7623
+;; 
yann@339
  7624
+;; You should have received a copy of the GNU General Public License
yann@339
  7625
+;; along with GNU CC; see the file COPYING.  If not, write to
yann@339
  7626
+;; the Free Software Foundation, 59 Temple Place - Suite 330,
yann@339
  7627
+;; Boston, MA 02111-1307, USA.  */
yann@339
  7628
+
yann@339
  7629
+
yann@339
  7630
+
yann@339
  7631
+;*****************************************************************************
yann@339
  7632
+;*
yann@339
  7633
+;* constants
yann@339
  7634
+;*
yann@339
  7635
+;*****************************************************************************
yann@339
  7636
+(define_constants [
yann@339
  7637
+  (GP_REGNO 26)
yann@339
  7638
+  (SP_REGNO 27)
yann@339
  7639
+  (FP_REGNO 28)
yann@339
  7640
+  (RA_REGNO 31)
yann@339
  7641
+  (RAP_REGNO 38)
yann@339
  7642
+  (FIRST_RETVAL_REGNO 2)
yann@339
  7643
+  (LAST_RETVAL_REGNO 3)
yann@339
  7644
+  (FIRST_ARG_REGNO 4)
yann@339
  7645
+  (LAST_ARG_REGNO 7)
yann@339
  7646
+  (SC_REGNO 23)
yann@339
  7647
+  (PC_REGNO 37)
yann@339
  7648
+  (FAKE_FP_REGNO 39)
yann@339
  7649
+  (FAKE_AP_REGNO 40)
yann@339
  7650
+
yann@339
  7651
+
yann@339
  7652
+  (UNSPEC_BLOCKAGE 0)
yann@339
  7653
+  (UNSPEC_LDBIO 1)
yann@339
  7654
+  (UNSPEC_LDBUIO 2)
yann@339
  7655
+  (UNSPEC_LDHIO 3)
yann@339
  7656
+  (UNSPEC_LDHUIO 4)
yann@339
  7657
+  (UNSPEC_LDWIO 5)
yann@339
  7658
+  (UNSPEC_STBIO 6)
yann@339
  7659
+  (UNSPEC_STHIO 7)
yann@339
  7660
+  (UNSPEC_STWIO 8)
yann@339
  7661
+  (UNSPEC_SYNC 9)
yann@339
  7662
+  (UNSPEC_WRCTL 10)
yann@339
  7663
+  (UNSPEC_RDCTL 11)
yann@339
  7664
+  
yann@339
  7665
+])
yann@339
  7666
+
yann@339
  7667
+
yann@339
  7668
+
yann@339
  7669
+;*****************************************************************************
yann@339
  7670
+;*
yann@339
  7671
+;* instruction scheduler
yann@339
  7672
+;*
yann@339
  7673
+;*****************************************************************************
yann@339
  7674
+
yann@339
  7675
+; No schedule info is currently available, using an assumption that no
yann@339
  7676
+; instruction can use the results of the previous instruction without
yann@339
  7677
+; incuring a stall.
yann@339
  7678
+
yann@339
  7679
+; length of an instruction (in bytes)
yann@339
  7680
+(define_attr "length" "" (const_int 4))
yann@339
  7681
+(define_attr "type" "unknown,complex,control,alu,cond_alu,st,ld,shift,mul,div,custom" (const_string "complex"))
yann@339
  7682
+
yann@339
  7683
+(define_asm_attributes
yann@339
  7684
+ [(set_attr "length" "4")
yann@339
  7685
+  (set_attr "type" "complex")])
yann@339
  7686
+
yann@339
  7687
+(define_automaton "nios2")
yann@339
  7688
+(automata_option "v")
yann@339
  7689
+;(automata_option "no-minimization")
yann@339
  7690
+(automata_option "ndfa")
yann@339
  7691
+
yann@339
  7692
+; The nios2 pipeline is fairly straightforward for the fast model.
yann@339
  7693
+; Every alu operation is pipelined so that an instruction can
yann@339
  7694
+; be issued every cycle. However, there are still potential
yann@339
  7695
+; stalls which this description tries to deal with.
yann@339
  7696
+
yann@339
  7697
+(define_cpu_unit "cpu" "nios2")
yann@339
  7698
+
yann@339
  7699
+(define_insn_reservation "complex" 1
yann@339
  7700
+  (eq_attr "type" "complex")
yann@339
  7701
+  "cpu")
yann@339
  7702
+
yann@339
  7703
+(define_insn_reservation "control" 1
yann@339
  7704
+  (eq_attr "type" "control")
yann@339
  7705
+  "cpu")
yann@339
  7706
+
yann@339
  7707
+(define_insn_reservation "alu" 1
yann@339
  7708
+  (eq_attr "type" "alu")
yann@339
  7709
+  "cpu")
yann@339
  7710
+
yann@339
  7711
+(define_insn_reservation "cond_alu" 1
yann@339
  7712
+  (eq_attr "type" "cond_alu")
yann@339
  7713
+  "cpu")
yann@339
  7714
+
yann@339
  7715
+(define_insn_reservation "st" 1
yann@339
  7716
+  (eq_attr "type" "st")
yann@339
  7717
+  "cpu")
yann@339
  7718
+  
yann@339
  7719
+(define_insn_reservation "custom" 1
yann@339
  7720
+  (eq_attr "type" "custom")
yann@339
  7721
+  "cpu")
yann@339
  7722
+
yann@339
  7723
+; shifts, muls and lds have three cycle latency
yann@339
  7724
+(define_insn_reservation "ld" 3
yann@339
  7725
+  (eq_attr "type" "ld")
yann@339
  7726
+  "cpu")
yann@339
  7727
+
yann@339
  7728
+(define_insn_reservation "shift" 3
yann@339
  7729
+  (eq_attr "type" "shift")
yann@339
  7730
+  "cpu")
yann@339
  7731
+
yann@339
  7732
+(define_insn_reservation "mul" 3
yann@339
  7733
+  (eq_attr "type" "mul")
yann@339
  7734
+  "cpu")
yann@339
  7735
+
yann@339
  7736
+(define_insn_reservation "div" 1
yann@339
  7737
+  (eq_attr "type" "div")
yann@339
  7738
+  "cpu")
yann@339
  7739
+
yann@339
  7740
+
yann@339
  7741
+;*****************************************************************************
yann@339
  7742
+;*
yann@339
  7743
+;* MOV Instructions
yann@339
  7744
+;*
yann@339
  7745
+;*****************************************************************************
yann@339
  7746
+
yann@339
  7747
+(define_expand "movqi"
yann@339
  7748
+  [(set (match_operand:QI 0 "nonimmediate_operand" "")
yann@339
  7749
+        (match_operand:QI 1 "general_operand" ""))]
yann@339
  7750
+  ""
yann@339
  7751
+{
yann@339
  7752
+  if (nios2_emit_move_sequence (operands, QImode))
yann@339
  7753
+    DONE;
yann@339
  7754
+})
yann@339
  7755
+
yann@339
  7756
+(define_insn "movqi_internal"
yann@339
  7757
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=m, r,r, r")
yann@339
  7758
+        (match_operand:QI 1 "general_operand"       "rM,m,rM,I"))]
yann@339
  7759
+  "(register_operand (operands[0], QImode)
yann@339
  7760
+    || register_operand (operands[1], QImode)
yann@339
  7761
+    || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
yann@339
  7762
+  "@
yann@339
  7763
+    stb%o0\\t%z1, %0
yann@339
  7764
+    ldbu%o1\\t%0, %1
yann@339
  7765
+    mov\\t%0, %z1
yann@339
  7766
+    movi\\t%0, %1"
yann@339
  7767
+  [(set_attr "type" "st,ld,alu,alu")])
yann@339
  7768
+
yann@339
  7769
+(define_insn "ldbio"
yann@339
  7770
+  [(set (match_operand:SI 0 "register_operand" "=r")
yann@339
  7771
+	(unspec_volatile:SI [(const_int 0)] UNSPEC_LDBIO))
yann@339
  7772
+   (use (match_operand:SI 1 "memory_operand" "m"))]
yann@339
  7773
+  ""
yann@339
  7774
+  "ldbio\\t%0, %1"
yann@339
  7775
+  [(set_attr "type" "ld")])
yann@339
  7776
+
yann@339
  7777
+(define_insn "ldbuio"
yann@339
  7778
+  [(set (match_operand:SI 0 "register_operand" "=r")
yann@339
  7779
+	(unspec_volatile:SI [(const_int 0)] UNSPEC_LDBUIO))
yann@339
  7780
+   (use (match_operand:SI 1 "memory_operand" "m"))]
yann@339
  7781
+  ""
yann@339
  7782
+  "ldbuio\\t%0, %1"
yann@339
  7783
+  [(set_attr "type" "ld")])
yann@339
  7784
+
yann@339
  7785
+(define_insn "stbio"
yann@339
  7786
+  [(set (match_operand:SI 0 "memory_operand" "=m")
yann@339
  7787
+	(match_operand:SI 1 "register_operand"   "r"))
yann@339
  7788
+   (unspec_volatile:SI [(const_int 0)] UNSPEC_STBIO)]
yann@339
  7789
+  ""
yann@339
  7790
+  "stbio\\t%z1, %0"
yann@339
  7791
+  [(set_attr "type" "st")])
yann@339
  7792
+
yann@339
  7793
+
yann@339
  7794
+(define_expand "movhi"
yann@339
  7795
+  [(set (match_operand:HI 0 "nonimmediate_operand" "")
yann@339
  7796
+        (match_operand:HI 1 "general_operand" ""))]
yann@339
  7797
+  ""
yann@339
  7798
+{
yann@339
  7799
+  if (nios2_emit_move_sequence (operands, HImode))
yann@339
  7800
+    DONE;
yann@339
  7801
+})
yann@339
  7802
+
yann@339
  7803
+(define_insn "movhi_internal"
yann@339
  7804
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=m, r,r, r,r")
yann@339
  7805
+        (match_operand:HI 1 "general_operand"       "rM,m,rM,I,J"))]
yann@339
  7806
+  "(register_operand (operands[0], HImode)
yann@339
  7807
+    || register_operand (operands[1], HImode)
yann@339
  7808
+    || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
yann@339
  7809
+  "@
yann@339
  7810
+    sth%o0\\t%z1, %0
yann@339
  7811
+    ldhu%o1\\t%0, %1
yann@339
  7812
+    mov\\t%0, %z1
yann@339
  7813
+    movi\\t%0, %1
yann@339
  7814
+    movui\\t%0, %1"
yann@339
  7815
+  [(set_attr "type" "st,ld,alu,alu,alu")])
yann@339
  7816
+
yann@339
  7817
+(define_insn "ldhio"
yann@339
  7818
+  [(set (match_operand:SI 0 "register_operand" "=r")
yann@339
  7819
+	(unspec_volatile:SI [(const_int 0)] UNSPEC_LDHIO))
yann@339
  7820
+   (use (match_operand:SI 1 "memory_operand" "m"))]
yann@339
  7821
+  ""
yann@339
  7822
+  "ldhio\\t%0, %1"
yann@339
  7823
+  [(set_attr "type" "ld")])
yann@339
  7824
+
yann@339
  7825
+(define_insn "ldhuio"
yann@339
  7826
+  [(set (match_operand:SI 0 "register_operand" "=r")
yann@339
  7827
+	(unspec_volatile:SI [(const_int 0)] UNSPEC_LDHUIO))
yann@339
  7828
+   (use (match_operand:SI 1 "memory_operand" "m"))]
yann@339
  7829
+  ""
yann@339
  7830
+  "ldhuio\\t%0, %1"
yann@339
  7831
+  [(set_attr "type" "ld")])
yann@339
  7832
+
yann@339
  7833
+(define_insn "sthio"
yann@339
  7834
+  [(set (match_operand:SI 0 "memory_operand" "=m")
yann@339
  7835
+	(match_operand:SI 1 "register_operand"   "r"))
yann@339
  7836
+   (unspec_volatile:SI [(const_int 0)] UNSPEC_STHIO)]
yann@339
  7837
+  ""
yann@339
  7838
+  "sthio\\t%z1, %0"
yann@339
  7839
+  [(set_attr "type" "st")])
yann@339
  7840
+
yann@339
  7841
+(define_expand "movsi"
yann@339
  7842
+  [(set (match_operand:SI 0 "nonimmediate_operand" "")
yann@339
  7843
+        (match_operand:SI 1 "general_operand" ""))]
yann@339
  7844
+  ""
yann@339
  7845
+{
yann@339
  7846
+  if (nios2_emit_move_sequence (operands, SImode))
yann@339
  7847
+    DONE;
yann@339
  7848
+})
yann@339
  7849
+
yann@339
  7850
+(define_insn "movsi_internal"
yann@339
  7851
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=m, r,r, r,r,r,r")
yann@339
  7852
+        (match_operand:SI 1 "general_operand"       "rM,m,rM,I,J,S,i"))]
yann@339
  7853
+  "(register_operand (operands[0], SImode)
yann@339
  7854
+    || register_operand (operands[1], SImode)
yann@339
  7855
+    || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
yann@339
  7856
+  "@
yann@339
  7857
+    stw%o0\\t%z1, %0
yann@339
  7858
+    ldw%o1\\t%0, %1
yann@339
  7859
+    mov\\t%0, %z1
yann@339
  7860
+    movi\\t%0, %1
yann@339
  7861
+    movui\\t%0, %1
yann@339
  7862
+    addi\\t%0, gp, %%gprel(%1)
yann@339
  7863
+    movhi\\t%0, %H1\;addi\\t%0, %0, %L1"
yann@339
  7864
+  [(set_attr "type" "st,ld,alu,alu,alu,alu,alu")])
yann@339
  7865
+
yann@339
  7866
+(define_insn "ldwio"
yann@339
  7867
+  [(set (match_operand:SI 0 "register_operand" "=r")
yann@339
  7868
+	(unspec_volatile:SI [(const_int 0)] UNSPEC_LDWIO))
yann@339
  7869
+   (use (match_operand:SI 1 "memory_operand" "m"))]
yann@339
  7870
+  ""
yann@339
  7871
+  "ldwio\\t%0, %1"
yann@339
  7872
+  [(set_attr "type" "ld")])
yann@339
  7873
+
yann@339
  7874
+(define_insn "stwio"
yann@339
  7875
+  [(set (match_operand:SI 0 "memory_operand" "=m")
yann@339
  7876
+	(match_operand:SI 1 "register_operand"   "r"))
yann@339
  7877
+   (unspec_volatile:SI [(const_int 0)] UNSPEC_STWIO)]
yann@339
  7878
+  ""
yann@339
  7879
+  "stwio\\t%z1, %0"
yann@339
  7880
+  [(set_attr "type" "st")])
yann@339
  7881
+
yann@339
  7882
+
yann@339
  7883
+
yann@339
  7884
+;*****************************************************************************
yann@339
  7885
+;*
yann@339
  7886
+;* zero extension
yann@339
  7887
+;*
yann@339
  7888
+;*****************************************************************************
yann@339
  7889
+
yann@339
  7890
+
yann@339
  7891
+(define_insn "zero_extendhisi2"
yann@339
  7892
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
yann@339
  7893
+	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
yann@339
  7894
+  ""
yann@339
  7895
+  "@
yann@339
  7896
+    andi\\t%0, %1, 0xffff
yann@339
  7897
+    ldhu%o1\\t%0, %1"
yann@339
  7898
+  [(set_attr "type"	"alu,ld")])
yann@339
  7899
+
yann@339
  7900
+(define_insn "zero_extendqihi2"
yann@339
  7901
+  [(set (match_operand:HI 0 "register_operand" "=r,r")
yann@339
  7902
+	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
yann@339
  7903
+  ""
yann@339
  7904
+  "@
yann@339
  7905
+    andi\\t%0, %1, 0xff
yann@339
  7906
+    ldbu%o1\\t%0, %1"
yann@339
  7907
+  [(set_attr "type"	"alu,ld")])
yann@339
  7908
+
yann@339
  7909
+(define_insn "zero_extendqisi2"
yann@339
  7910
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
yann@339
  7911
+	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
yann@339
  7912
+  ""
yann@339
  7913
+  "@
yann@339
  7914
+    andi\\t%0, %1, 0xff
yann@339
  7915
+    ldbu%o1\\t%0, %1"
yann@339
  7916
+  [(set_attr "type"	"alu,ld")])
yann@339
  7917
+
yann@339
  7918
+
yann@339
  7919
+
yann@339
  7920
+;*****************************************************************************
yann@339
  7921
+;*
yann@339
  7922
+;* sign extension
yann@339
  7923
+;*
yann@339
  7924
+;*****************************************************************************
yann@339
  7925
+
yann@339
  7926
+(define_expand "extendhisi2"
yann@339
  7927
+  [(set (match_operand:SI 0 "register_operand" "")
yann@339
  7928
+	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
yann@339
  7929
+  ""
yann@339
  7930
+{
yann@339
  7931
+  if (optimize && GET_CODE (operands[1]) == MEM)
yann@339
  7932
+    operands[1] = force_not_mem (operands[1]);
yann@339
  7933
+
yann@339
  7934
+  if (GET_CODE (operands[1]) != MEM)
yann@339
  7935
+    {
yann@339
  7936
+      rtx op1   = gen_lowpart (SImode, operands[1]);
yann@339
  7937
+      rtx temp  = gen_reg_rtx (SImode);
yann@339
  7938
+      rtx shift = GEN_INT (16);
yann@339
  7939
+
yann@339
  7940
+      emit_insn (gen_ashlsi3 (temp, op1, shift));
yann@339
  7941
+      emit_insn (gen_ashrsi3 (operands[0], temp, shift));
yann@339
  7942
+      DONE;
yann@339
  7943
+    }
yann@339
  7944
+})
yann@339
  7945
+
yann@339
  7946
+(define_insn "extendhisi2_internal"
yann@339
  7947
+  [(set (match_operand:SI 0 "register_operand" "=r")
yann@339
  7948
+	(sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
yann@339
  7949
+  ""
yann@339
  7950
+  "ldh%o1\\t%0, %1"
yann@339
  7951
+  [(set_attr "type"	"ld")])
yann@339
  7952
+
yann@339
  7953
+(define_expand "extendqihi2"
yann@339
  7954
+  [(set (match_operand:HI 0 "register_operand" "")
yann@339
  7955
+	(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
yann@339
  7956
+  ""
yann@339
  7957
+{
yann@339
  7958
+  if (optimize && GET_CODE (operands[1]) == MEM)
yann@339
  7959
+    operands[1] = force_not_mem (operands[1]);
yann@339
  7960
+
yann@339
  7961
+  if (GET_CODE (operands[1]) != MEM)
yann@339
  7962
+    {
yann@339
  7963
+      rtx op0   = gen_lowpart (SImode, operands[0]);
yann@339
  7964
+      rtx op1   = gen_lowpart (SImode, operands[1]);
yann@339
  7965
+      rtx temp  = gen_reg_rtx (SImode);
yann@339
  7966
+      rtx shift = GEN_INT (24);
yann@339
  7967
+
yann@339
  7968
+      emit_insn (gen_ashlsi3 (temp, op1, shift));
yann@339
  7969
+      emit_insn (gen_ashrsi3 (op0, temp, shift));
yann@339
  7970
+      DONE;
yann@339
  7971
+    }
yann@339
  7972
+})
yann@339
  7973
+
yann@339
  7974
+(define_insn "extendqihi2_internal"
yann@339
  7975
+  [(set (match_operand:HI 0 "register_operand" "=r")
yann@339
  7976
+	(sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
yann@339
  7977
+  ""
yann@339
  7978
+  "ldb%o1\\t%0, %1"
yann@339
  7979
+  [(set_attr "type"	"ld")])
yann@339
  7980
+
yann@339
  7981
+
yann@339
  7982
+(define_expand "extendqisi2"
yann@339
  7983
+  [(set (match_operand:SI 0 "register_operand" "")
yann@339
  7984
+	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
yann@339
  7985
+  ""
yann@339
  7986
+{
yann@339
  7987
+  if (optimize && GET_CODE (operands[1]) == MEM)
yann@339
  7988
+    operands[1] = force_not_mem (operands[1]);
yann@339
  7989
+
yann@339
  7990
+  if (GET_CODE (operands[1]) != MEM)
yann@339
  7991
+    {
yann@339
  7992
+      rtx op1   = gen_lowpart (SImode, operands[1]);
yann@339
  7993
+      rtx temp  = gen_reg_rtx (SImode);
yann@339
  7994
+      rtx shift = GEN_INT (24);
yann@339
  7995
+
yann@339
  7996
+      emit_insn (gen_ashlsi3 (temp, op1, shift));
yann@339
  7997
+      emit_insn (gen_ashrsi3 (operands[0], temp, shift));
yann@339
  7998
+      DONE;
yann@339
  7999
+    }
yann@339
  8000
+})
yann@339
  8001
+
yann@339
  8002
+(define_insn "extendqisi2_insn"
yann@339
  8003
+  [(set (match_operand:SI 0 "register_operand" "=r")
yann@339
  8004
+	(sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
yann@339
  8005
+  ""
yann@339
  8006
+  "ldb%o1\\t%0, %1"
yann@339
  8007
+  [(set_attr "type"	"ld")])
yann@339
  8008
+
yann@339
  8009
+
yann@339
  8010
+
yann@339
  8011
+;*****************************************************************************
yann@339
  8012
+;*
yann@339
  8013
+;* Arithmetic Operations
yann@339
  8014
+;*
yann@339
  8015
+;*****************************************************************************
yann@339
  8016
+
yann@339
  8017
+(define_insn "addsi3"
yann@339
  8018
+  [(set (match_operand:SI 0 "register_operand"          "=r,r")
yann@339
  8019
+        (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
yann@339
  8020
+                 (match_operand:SI 2 "arith_operand"     "r,I")))]
yann@339
  8021
+  ""
yann@339
  8022
+  "add%i2\\t%0, %1, %z2"
yann@339
  8023
+  [(set_attr "type" "alu")])
yann@339
  8024
+
yann@339
  8025
+(define_insn "subsi3"
yann@339
  8026
+  [(set (match_operand:SI 0 "register_operand"           "=r")
yann@339
  8027
+        (minus:SI (match_operand:SI 1 "reg_or_0_operand"  "rM")
yann@339
  8028
+                  (match_operand:SI 2 "register_operand"  "r")))]
yann@339
  8029
+  ""
yann@339
  8030
+  "sub\\t%0, %z1, %2"
yann@339
  8031
+  [(set_attr "type" "alu")])
yann@339
  8032
+
yann@339
  8033
+(define_insn "mulsi3"
yann@339
  8034
+  [(set (match_operand:SI 0 "register_operand"            "=r,r")
yann@339
  8035
+        (mult:SI (match_operand:SI 1 "register_operand"    "r,r")
yann@339
  8036
+                 (match_operand:SI 2 "arith_operand"       "r,I")))]
yann@339
  8037
+  "TARGET_HAS_MUL"
yann@339
  8038
+  "mul%i2\\t%0, %1, %z2"
yann@339
  8039
+  [(set_attr "type" "mul")])
yann@339
  8040
+
yann@339
  8041
+(define_expand "divsi3"
yann@339
  8042
+  [(set (match_operand:SI 0 "register_operand"            "=r")
yann@339
  8043
+        (div:SI (match_operand:SI 1 "register_operand"     "r")
yann@339
  8044
+                (match_operand:SI 2 "register_operand"     "r")))]
yann@339
  8045
+  ""
yann@339
  8046
+{
yann@339
  8047
+  if (!TARGET_HAS_DIV)
yann@339
  8048
+    {
yann@339
  8049
+      if (!TARGET_FAST_SW_DIV)
yann@339
  8050
+	FAIL;
yann@339
  8051
+      else
yann@339
  8052
+        {
yann@339
  8053
+	  if (nios2_emit_expensive_div (operands, SImode))
yann@339
  8054
+	    DONE;
yann@339
  8055
+	}
yann@339
  8056
+    }
yann@339
  8057
+})
yann@339
  8058
+
yann@339
  8059
+(define_insn "divsi3_insn"
yann@339
  8060
+  [(set (match_operand:SI 0 "register_operand"            "=r")
yann@339
  8061
+        (div:SI (match_operand:SI 1 "register_operand"     "r")
yann@339
  8062
+                (match_operand:SI 2 "register_operand"     "r")))]
yann@339
  8063
+  "TARGET_HAS_DIV"
yann@339
  8064
+  "div\\t%0, %1, %2"
yann@339
  8065
+  [(set_attr "type" "div")])
yann@339
  8066
+
yann@339
  8067
+(define_insn "udivsi3"
yann@339
  8068
+  [(set (match_operand:SI 0 "register_operand"            "=r")
yann@339
  8069
+        (udiv:SI (match_operand:SI 1 "register_operand"     "r")
yann@339
  8070
+                (match_operand:SI 2 "register_operand"     "r")))]
yann@339
  8071
+  "TARGET_HAS_DIV"
yann@339
  8072
+  "divu\\t%0, %1, %2"
yann@339
  8073
+  [(set_attr "type" "div")])
yann@339
  8074
+
yann@339
  8075
+(define_insn "smulsi3_highpart"
yann@339
  8076
+  [(set (match_operand:SI 0 "register_operand"                            "=r")
yann@339
  8077
+	(truncate:SI
yann@339
  8078
+	 (lshiftrt:DI
yann@339
  8079
+	  (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand"  "r"))
yann@339
  8080
+		   (sign_extend:DI (match_operand:SI 2 "register_operand"  "r")))
yann@339
  8081
+	  (const_int 32))))]
yann@339
  8082
+  "TARGET_HAS_MULX"
yann@339
  8083
+  "mulxss\\t%0, %1, %2"
yann@339
  8084
+  [(set_attr "type" "mul")])
yann@339
  8085
+
yann@339
  8086
+(define_insn "umulsi3_highpart"
yann@339
  8087
+  [(set (match_operand:SI 0 "register_operand"                            "=r")
yann@339
  8088
+	(truncate:SI
yann@339
  8089
+	 (lshiftrt:DI
yann@339
  8090
+	  (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand"  "r"))
yann@339
  8091
+		   (zero_extend:DI (match_operand:SI 2 "register_operand"  "r")))
yann@339
  8092
+	  (const_int 32))))]
yann@339
  8093
+  "TARGET_HAS_MULX"
yann@339
  8094
+  "mulxuu\\t%0, %1, %2"
yann@339
  8095
+  [(set_attr "type" "mul")])
yann@339
  8096
+
yann@339
  8097
+
yann@339
  8098
+(define_expand "mulsidi3"
yann@339
  8099
+    [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 0)
yann@339
  8100
+	  (mult:SI (match_operand:SI 1 "register_operand" "")
yann@339
  8101
+		   (match_operand:SI 2 "register_operand" "")))
yann@339
  8102
+     (set (subreg:SI (match_dup 0) 4)
yann@339
  8103
+	  (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
yann@339
  8104
+					     (sign_extend:DI (match_dup 2)))
yann@339
  8105
+				    (const_int 32))))]
yann@339
  8106
+  "TARGET_HAS_MULX"
yann@339
  8107
+  "")
yann@339
  8108
+
yann@339
  8109
+(define_expand "umulsidi3"
yann@339
  8110
+    [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 0)
yann@339
  8111
+	  (mult:SI (match_operand:SI 1 "register_operand" "")
yann@339
  8112
+		   (match_operand:SI 2 "register_operand" "")))
yann@339
  8113
+     (set (subreg:SI (match_dup 0) 4)
yann@339
  8114
+	  (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
yann@339
  8115
+					     (zero_extend:DI (match_dup 2)))
yann@339
  8116
+				    (const_int 32))))]
yann@339
  8117
+  "TARGET_HAS_MULX"
yann@339
  8118
+  "")
yann@339
  8119
+
yann@339
  8120
+
yann@339
  8121
+
yann@339
  8122
+;*****************************************************************************
yann@339
  8123
+;*
yann@339
  8124
+;* Negate and ones complement
yann@339
  8125
+;*
yann@339
  8126
+;*****************************************************************************
yann@339
  8127
+
yann@339
  8128
+(define_insn "negsi2"
yann@339
  8129
+  [(set (match_operand:SI 0 "register_operand"        "=r")
yann@339
  8130
+	(neg:SI (match_operand:SI 1 "register_operand" "r")))]
yann@339
  8131
+  ""
yann@339
  8132
+{
yann@339
  8133
+  operands[2] = const0_rtx;
yann@339
  8134
+  return "sub\\t%0, %z2, %1";
yann@339
  8135
+}
yann@339
  8136
+  [(set_attr "type" "alu")])
yann@339
  8137
+
yann@339
  8138
+(define_insn "one_cmplsi2"
yann@339
  8139
+  [(set (match_operand:SI 0 "register_operand"        "=r")
yann@339
  8140
+	(not:SI (match_operand:SI 1 "register_operand" "r")))]
yann@339
  8141
+  ""
yann@339
  8142
+{
yann@339
  8143
+  operands[2] = const0_rtx;
yann@339
  8144
+  return "nor\\t%0, %z2, %1";
yann@339
  8145
+}
yann@339
  8146
+  [(set_attr "type" "alu")])
yann@339
  8147
+
yann@339
  8148
+
yann@339
  8149
+
yann@339
  8150
+; Logical Operantions
yann@339
  8151
+
yann@339
  8152
+(define_insn "andsi3"
yann@339
  8153
+  [(set (match_operand:SI 0 "register_operand"         "=r, r,r")
yann@339
  8154
+        (and:SI (match_operand:SI 1 "register_operand" "%r, r,r")
yann@339
  8155
+                (match_operand:SI 2 "logical_operand"   "rM,J,K")))]
yann@339
  8156
+  ""
yann@339
  8157
+  "@
yann@339
  8158
+    and\\t%0, %1, %z2
yann@339
  8159
+    and%i2\\t%0, %1, %2
yann@339
  8160
+    andh%i2\\t%0, %1, %U2"
yann@339
  8161
+  [(set_attr "type" "alu")])
yann@339
  8162
+
yann@339
  8163
+(define_insn "iorsi3"
yann@339
  8164
+  [(set (match_operand:SI 0 "register_operand"          "=r, r,r")
yann@339
  8165
+        (ior:SI (match_operand:SI 1 "register_operand"  "%r, r,r")
yann@339
  8166
+                (match_operand:SI 2 "logical_operand"    "rM,J,K")))]
yann@339
  8167
+  ""
yann@339
  8168
+  "@
yann@339
  8169
+    or\\t%0, %1, %z2
yann@339
  8170
+    or%i2\\t%0, %1, %2
yann@339
  8171
+    orh%i2\\t%0, %1, %U2"
yann@339
  8172
+  [(set_attr "type" "alu")])
yann@339
  8173
+
yann@339
  8174
+(define_insn "*norsi3"
yann@339
  8175
+  [(set (match_operand:SI 0 "register_operand"                  "=r")
yann@339
  8176
+        (and:SI (not:SI (match_operand:SI 1 "register_operand"  "%r"))
yann@339
  8177
+                (not:SI (match_operand:SI 2 "reg_or_0_operand"   "rM"))))]
yann@339
  8178
+  ""
yann@339
  8179
+  "nor\\t%0, %1, %z2"
yann@339
  8180
+  [(set_attr "type" "alu")])
yann@339
  8181
+
yann@339
  8182
+(define_insn "xorsi3"
yann@339
  8183
+  [(set (match_operand:SI 0 "register_operand"          "=r, r,r")
yann@339
  8184
+        (xor:SI (match_operand:SI 1 "register_operand"  "%r, r,r")
yann@339
  8185
+                (match_operand:SI 2 "logical_operand"    "rM,J,K")))]
yann@339
  8186
+  ""
yann@339
  8187
+  "@
yann@339
  8188
+    xor\\t%0, %1, %z2
yann@339
  8189
+    xor%i2\\t%0, %1, %2
yann@339
  8190
+    xorh%i2\\t%0, %1, %U2"
yann@339
  8191
+  [(set_attr "type" "alu")])
yann@339
  8192
+
yann@339
  8193
+
yann@339
  8194
+
yann@339
  8195
+;*****************************************************************************
yann@339
  8196
+;*
yann@339
  8197
+;* Shifts
yann@339
  8198
+;*
yann@339
  8199
+;*****************************************************************************
yann@339
  8200
+
yann@339
  8201
+(define_insn "ashlsi3"
yann@339
  8202
+  [(set (match_operand:SI 0 "register_operand"           "=r,r")
yann@339
  8203
+	(ashift:SI (match_operand:SI 1 "register_operand" "r,r")
yann@339
  8204
+		   (match_operand:SI 2 "shift_operand"    "r,L")))]
yann@339
  8205
+  ""
yann@339
  8206
+  "sll%i2\\t%0, %1, %z2"
yann@339
  8207
+  [(set_attr "type" "shift")])
yann@339
  8208
+
yann@339
  8209
+(define_insn "ashrsi3"
yann@339
  8210
+  [(set (match_operand:SI 0 "register_operand"             "=r,r")
yann@339
  8211
+	(ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
yann@339
  8212
+		     (match_operand:SI 2 "shift_operand"    "r,L")))]
yann@339
  8213
+  ""
yann@339
  8214
+  "sra%i2\\t%0, %1, %z2"
yann@339
  8215
+  [(set_attr "type" "shift")])
yann@339
  8216
+
yann@339
  8217
+(define_insn "lshrsi3"
yann@339
  8218
+  [(set (match_operand:SI 0 "register_operand"             "=r,r")
yann@339
  8219
+	(lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
yann@339
  8220
+		     (match_operand:SI 2 "shift_operand"    "r,L")))]
yann@339
  8221
+  ""
yann@339
  8222
+  "srl%i2\\t%0, %1, %z2"
yann@339
  8223
+  [(set_attr "type" "shift")])
yann@339
  8224
+
yann@339
  8225
+(define_insn "rotlsi3"
yann@339
  8226
+  [(set (match_operand:SI 0 "register_operand"           "=r,r")
yann@339
  8227
+	(rotate:SI (match_operand:SI 1 "register_operand" "r,r")
yann@339
  8228
+		   (match_operand:SI 2 "shift_operand"    "r,L")))]
yann@339
  8229
+  ""
yann@339
  8230
+  "rol%i2\\t%0, %1, %z2"
yann@339
  8231
+  [(set_attr "type" "shift")])
yann@339
  8232
+
yann@339
  8233
+(define_insn "rotrsi3"
yann@339
  8234
+  [(set (match_operand:SI 0 "register_operand"             "=r,r")
yann@339
  8235
+	(rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
yann@339
  8236
+		     (match_operand:SI 2 "register_operand" "r,r")))]
yann@339
  8237
+  ""
yann@339
  8238
+  "ror\\t%0, %1, %2"
yann@339
  8239
+  [(set_attr "type" "shift")])
yann@339
  8240
+
yann@339
  8241
+(define_insn "*shift_mul_constants"
yann@339
  8242
+  [(set (match_operand:SI 0 "register_operand"                     "=r")
yann@339
  8243
+	(ashift:SI (mult:SI (match_operand:SI 1 "register_operand"  "r")
yann@339
  8244
+		            (match_operand:SI 2 "const_int_operand" "I"))
yann@339
  8245
+		   (match_operand:SI 3          "const_int_operand" "I")))]
yann@339
  8246
+  "TARGET_HAS_MUL && SMALL_INT (INTVAL (operands[2]) << INTVAL (operands[3]))"
yann@339
  8247
+{
yann@339
  8248
+  HOST_WIDE_INT mul = INTVAL (operands[2]) << INTVAL (operands[3]);
yann@339
  8249
+  rtx ops[3];
yann@339
  8250
+  
yann@339
  8251
+  ops[0] = operands[0];
yann@339
  8252
+  ops[1] = operands[1];
yann@339
  8253
+  ops[2] = GEN_INT (mul);
yann@339
  8254
+  
yann@339
  8255
+  output_asm_insn ("muli\t%0, %1, %2", ops);
yann@339
  8256
+  return "";
yann@339
  8257
+}
yann@339
  8258
+  [(set_attr "type" "mul")])
yann@339
  8259
+
yann@339
  8260
+
yann@339
  8261
+
yann@339
  8262
+
yann@339
  8263
+;*****************************************************************************
yann@339
  8264
+;*
yann@339
  8265
+;* Prologue, Epilogue and Return
yann@339
  8266
+;*
yann@339
  8267
+;*****************************************************************************
yann@339
  8268
+
yann@339
  8269
+(define_expand "prologue"
yann@339
  8270
+  [(const_int 1)]
yann@339
  8271
+  ""
yann@339
  8272
+{
yann@339
  8273
+  expand_prologue ();
yann@339
  8274
+  DONE;
yann@339
  8275
+})
yann@339
  8276
+
yann@339
  8277
+(define_expand "epilogue"
yann@339
  8278
+  [(return)]
yann@339
  8279
+  ""
yann@339
  8280
+{
yann@339
  8281
+  expand_epilogue (false);
yann@339
  8282
+  DONE;
yann@339
  8283
+})
yann@339
  8284
+
yann@339
  8285
+(define_expand "sibcall_epilogue"
yann@339
  8286
+  [(return)]
yann@339
  8287
+  ""
yann@339
  8288
+{
yann@339
  8289
+  expand_epilogue (true);
yann@339
  8290
+  DONE;
yann@339
  8291
+})
yann@339
  8292
+
yann@339
  8293
+(define_insn "return"
yann@339
  8294
+  [(return)]
yann@339
  8295
+  "reload_completed && nios2_can_use_return_insn ()"
yann@339
  8296
+  "ret\\t"
yann@339
  8297
+)
yann@339
  8298
+
yann@339
  8299
+(define_insn "return_from_epilogue"
yann@339
  8300
+  [(use (match_operand 0 "pmode_register_operand" ""))
yann@339
  8301
+   (return)]
yann@339
  8302
+  "reload_completed"
yann@339
  8303
+  "ret\\t"
yann@339
  8304
+)
yann@339
  8305
+
yann@339
  8306
+;; Block any insns from being moved before this point, since the
yann@339
  8307
+;; profiling call to mcount can use various registers that aren't
yann@339
  8308
+;; saved or used to pass arguments.
yann@339
  8309
+
yann@339
  8310
+(define_insn "blockage"
yann@339
  8311
+  [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
yann@339
  8312
+  ""
yann@339
  8313
+  ""
yann@339
  8314
+  [(set_attr "type" "unknown")
yann@339
  8315
+   (set_attr "length" "0")])
yann@339
  8316
+
yann@339
  8317
+
yann@339
  8318
+
yann@339
  8319
+;*****************************************************************************
yann@339
  8320
+;*
yann@339
  8321
+;* Jumps and Calls
yann@339
  8322
+;*
yann@339
  8323
+;*****************************************************************************
yann@339
  8324
+
yann@339
  8325
+(define_insn "indirect_jump"
yann@339
  8326
+  [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
yann@339
  8327
+  ""
yann@339
  8328
+  "jmp\\t%0"
yann@339
  8329
+  [(set_attr "type" "control")])
yann@339
  8330
+
yann@339
  8331
+(define_insn "jump"
yann@339
  8332
+  [(set (pc)
yann@339
  8333
+        (label_ref (match_operand 0 "" "")))]
yann@339
  8334
+  ""
yann@339
  8335
+  "br\\t%0"
yann@339
  8336
+  [(set_attr "type" "control")])
yann@339
  8337
+
yann@339
  8338
+
yann@339
  8339
+(define_insn "indirect_call"
yann@339
  8340
+  [(call (mem:QI (match_operand:SI 0 "register_operand" "r"))
yann@339
  8341
+         (match_operand 1 "" ""))
yann@339
  8342
+   (clobber (reg:SI RA_REGNO))]
yann@339
  8343
+  ""
yann@339
  8344
+  "callr\\t%0"
yann@339
  8345
+  [(set_attr "type" "control")])
yann@339
  8346
+
yann@339
  8347
+(define_insn "indirect_call_value"
yann@339
  8348
+  [(set (match_operand 0 "" "")
yann@339
  8349
+        (call (mem:QI (match_operand:SI 1 "register_operand" "r"))
yann@339
  8350
+              (match_operand 2 "" "")))
yann@339
  8351
+   (clobber (reg:SI RA_REGNO))]
yann@339
  8352
+  ""
yann@339
  8353
+  "callr\\t%1"
yann@339
  8354
+)
yann@339
  8355
+
yann@339
  8356
+(define_expand "call"
yann@339
  8357
+  [(parallel [(call (match_operand 0 "" "")
yann@339
  8358
+                    (match_operand 1 "" ""))
yann@339
  8359
+              (clobber (reg:SI RA_REGNO))])]
yann@339
  8360
+  ""
yann@339
  8361
+  "")
yann@339
  8362
+
yann@339
  8363
+(define_expand "call_value"
yann@339
  8364
+  [(parallel [(set (match_operand 0 "" "")
yann@339
  8365
+                   (call (match_operand 1 "" "")
yann@339
  8366
+                         (match_operand 2 "" "")))
yann@339
  8367
+              (clobber (reg:SI RA_REGNO))])]
yann@339
  8368
+  ""
yann@339
  8369
+  "")
yann@339
  8370
+
yann@339
  8371
+(define_insn "*call"
yann@339
  8372
+  [(call (mem:QI (match_operand:SI 0 "immediate_operand" "i"))
yann@339
  8373
+         (match_operand 1 "" ""))
yann@339
  8374
+   (clobber (match_operand:SI 2 "register_operand" "=r"))]
yann@339
  8375
+  ""
yann@339
  8376
+  "call\\t%0"
yann@339
  8377
+  [(set_attr "type" "control")])
yann@339
  8378
+
yann@339
  8379
+(define_insn "*call_value"
yann@339
  8380
+  [(set (match_operand 0 "" "")
yann@339
  8381
+        (call (mem:QI (match_operand:SI 1 "immediate_operand" "i"))
yann@339
  8382
+              (match_operand 2 "" "")))
yann@339
  8383
+   (clobber (match_operand:SI 3 "register_operand" "=r"))]
yann@339
  8384
+  ""
yann@339
  8385
+  "call\\t%1"
yann@339
  8386
+  [(set_attr "type" "control")])
yann@339
  8387
+
yann@339
  8388
+(define_expand "sibcall"
yann@339
  8389
+  [(parallel [(call (match_operand 0 "" "")
yann@339
  8390
+		    (match_operand 1 "" ""))
yann@339
  8391
+	      (return)
yann@339
  8392
+	      (use (match_operand 2 "" ""))])]
yann@339
  8393
+  ""
yann@339
  8394
+  {
yann@339
  8395
+    XEXP (operands[0], 0) = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
yann@339
  8396
+
yann@339
  8397
+    if (operands[2] == NULL_RTX)
yann@339
  8398
+      operands[2] = const0_rtx;
yann@339
  8399
+  }
yann@339
  8400
+)
yann@339
  8401
+
yann@339
  8402
+(define_expand "sibcall_value"
yann@339
  8403
+  [(parallel [(set (match_operand 0 "" "")
yann@339
  8404
+		   (call (match_operand 1 "" "")
yann@339
  8405
+			 (match_operand 2 "" "")))
yann@339
  8406
+	      (return)
yann@339
  8407
+	      (use (match_operand 3 "" ""))])]
yann@339
  8408
+  ""
yann@339
  8409
+  {
yann@339
  8410
+    XEXP (operands[1], 0) = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
yann@339
  8411
+
yann@339
  8412
+    if (operands[3] == NULL_RTX)
yann@339
  8413
+      operands[3] = const0_rtx;
yann@339
  8414
+  }
yann@339
  8415
+)
yann@339
  8416
+
yann@339
  8417
+(define_insn "sibcall_insn"
yann@339
  8418
+ [(call (mem:QI (match_operand:SI 0 "register_operand" "r"))
yann@339
  8419
+	(match_operand 1 "" ""))
yann@339
  8420
+  (return)
yann@339
  8421
+  (use (match_operand 2 "" ""))]
yann@339
  8422
+  ""
yann@339
  8423
+  "jmp\\t%0"
yann@339
  8424
+)
yann@339
  8425
+
yann@339
  8426
+(define_insn "sibcall_value_insn"
yann@339
  8427
+ [(set (match_operand 0 "register_operand" "")
yann@339
  8428
+       (call (mem:QI (match_operand:SI 1 "register_operand" "r"))
yann@339
  8429
+	     (match_operand 2 "" "")))
yann@339
  8430
+  (return)
yann@339
  8431
+  (use (match_operand 3 "" ""))]
yann@339
  8432
+  ""
yann@339
  8433
+  "jmp\\t%1"
yann@339
  8434
+)
yann@339
  8435
+
yann@339
  8436
+
yann@339
  8437
+
yann@339
  8438
+
yann@339
  8439
+(define_expand "tablejump"
yann@339
  8440
+  [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
yann@339
  8441
+              (use (label_ref (match_operand 1 "" "")))])]
yann@339
  8442
+  ""
yann@339
  8443
+  ""
yann@339
  8444
+)
yann@339
  8445
+
yann@339
  8446
+(define_insn "*tablejump"
yann@339
  8447
+  [(set (pc)
yann@339
  8448
+	(match_operand:SI 0 "register_operand" "r"))
yann@339
  8449
+   (use (label_ref (match_operand 1 "" "")))]
yann@339
  8450
+  ""
yann@339
  8451
+  "jmp\\t%0"
yann@339
  8452
+  [(set_attr "type" "control")])
yann@339
  8453
+
yann@339
  8454
+
yann@339
  8455
+
yann@339
  8456
+;*****************************************************************************
yann@339
  8457
+;*
yann@339
  8458
+;* Comparisons
yann@339
  8459
+;*
yann@339
  8460
+;*****************************************************************************
yann@339
  8461
+;; Flow here is rather complex (based on MIPS):
yann@339
  8462
+;;
yann@339
  8463
+;;  1)	The cmp{si,di,sf,df} routine is called.  It deposits the
yann@339
  8464
+;;	arguments into the branch_cmp array, and the type into
yann@339
  8465
+;;	branch_type.  No RTL is generated.
yann@339
  8466
+;;
yann@339
  8467
+;;  2)	The appropriate branch define_expand is called, which then
yann@339
  8468
+;;	creates the appropriate RTL for the comparison and branch.
yann@339
  8469
+;;	Different CC modes are used, based on what type of branch is
yann@339
  8470
+;;	done, so that we can constrain things appropriately.  There
yann@339
  8471
+;;	are assumptions in the rest of GCC that break if we fold the
yann@339
  8472
+;;	operands into the branchs for integer operations, and use cc0
yann@339
  8473
+;;	for floating point, so we use the fp status register instead.
yann@339
  8474
+;;	If needed, an appropriate temporary is created to hold the
yann@339
  8475
+;;	of the integer compare.
yann@339
  8476
+
yann@339
  8477
+(define_expand "cmpsi"
yann@339
  8478
+  [(set (cc0)
yann@339
  8479
+	(compare:CC (match_operand:SI 0 "register_operand" "")
yann@339
  8480
+		    (match_operand:SI 1 "arith_operand" "")))]
yann@339
  8481
+  ""
yann@339
  8482
+{
yann@339
  8483
+  branch_cmp[0] = operands[0];
yann@339
  8484
+  branch_cmp[1] = operands[1];
yann@339
  8485
+  branch_type = CMP_SI;
yann@339
  8486
+  DONE;
yann@339
  8487
+})
yann@339
  8488
+
yann@339
  8489
+(define_expand "tstsi"
yann@339
  8490
+  [(set (cc0)
yann@339
  8491
+	(match_operand:SI 0 "register_operand" ""))]
yann@339
  8492
+  ""
yann@339
  8493
+{
yann@339
  8494
+  branch_cmp[0] = operands[0];
yann@339
  8495
+  branch_cmp[1] = const0_rtx;
yann@339
  8496
+  branch_type = CMP_SI;
yann@339
  8497
+  DONE;
yann@339
  8498
+})
yann@339
  8499
+
yann@339
  8500
+
yann@339
  8501
+;*****************************************************************************
yann@339
  8502
+;*
yann@339
  8503
+;* setting a register from a comparison
yann@339
  8504
+;*
yann@339
  8505
+;*****************************************************************************
yann@339
  8506
+
yann@339
  8507
+(define_expand "seq"
yann@339
  8508
+  [(set (match_operand:SI 0 "register_operand" "=r")
yann@339
  8509
+	(eq:SI (match_dup 1)
yann@339
  8510
+	       (match_dup 2)))]
yann@339
  8511
+  ""
yann@339
  8512
+{
yann@339
  8513
+  if (branch_type != CMP_SI)
yann@339
  8514
+    FAIL;
yann@339
  8515
+
yann@339
  8516
+  /* set up operands from compare.  */
yann@339
  8517
+  operands[1] = branch_cmp[0];
yann@339
  8518
+  operands[2] = branch_cmp[1];
yann@339
  8519
+
yann@339
  8520
+  gen_int_relational (EQ, operands[0], operands[1], operands[2], NULL_RTX);
yann@339
  8521
+  DONE;
yann@339
  8522
+})
yann@339
  8523
+
yann@339
  8524
+
yann@339
  8525
+(define_insn "*seq"
yann@339
  8526
+  [(set (match_operand:SI 0 "register_operand"        "=r")
yann@339
  8527
+	(eq:SI (match_operand:SI 1 "reg_or_0_operand" "%rM")
yann@339
  8528
+	       (match_operand:SI 2 "arith_operand"     "rI")))]
yann@339
  8529
+  ""
yann@339
  8530
+  "cmpeq%i2\\t%0, %z1, %z2"
yann@339
  8531
+  [(set_attr "type" "alu")])
yann@339
  8532
+
yann@339
  8533
+
yann@339
  8534
+(define_expand "sne"
yann@339
  8535
+  [(set (match_operand:SI 0 "register_operand" "=r")
yann@339
  8536
+	(ne:SI (match_dup 1)
yann@339
  8537
+	       (match_dup 2)))]
yann@339
  8538
+  ""
yann@339
  8539
+{
yann@339
  8540
+  if (branch_type != CMP_SI)
yann@339
  8541
+    FAIL;
yann@339
  8542
+
yann@339
  8543
+  /* set up operands from compare.  */
yann@339
  8544
+  operands[1] = branch_cmp[0];
yann@339
  8545
+  operands[2] = branch_cmp[1];
yann@339
  8546
+
yann@339
  8547
+  gen_int_relational (NE, operands[0], operands[1], operands[2], NULL_RTX);
yann@339
  8548
+  DONE;
yann@339
  8549
+})
yann@339
  8550
+
yann@339
  8551
+
yann@339
  8552
+(define_insn "*sne"
yann@339
  8553
+  [(set (match_operand:SI 0 "register_operand"        "=r")
yann@339
  8554
+	(ne:SI (match_operand:SI 1 "reg_or_0_operand" "%rM")
yann@339
  8555
+	       (match_operand:SI 2 "arith_operand"     "rI")))]
yann@339
  8556
+  ""
yann@339
  8557
+  "cmpne%i2\\t%0, %z1, %z2"
yann@339
  8558
+  [(set_attr "type" "alu")])
yann@339
  8559
+
yann@339
  8560
+
yann@339
  8561
+(define_expand "sgt"
yann@339
  8562
+  [(set (match_operand:SI 0 "register_operand" "=r")
yann@339
  8563
+	(gt:SI (match_dup 1)
yann@339
  8564
+	       (match_dup 2)))]
yann@339
  8565
+  ""
yann@339
  8566
+{
yann@339
  8567
+  if (branch_type != CMP_SI)
yann@339
  8568
+    FAIL;
yann@339
  8569
+
yann@339
  8570
+  /* set up operands from compare.  */
yann@339
  8571
+  operands[1] = branch_cmp[0];
yann@339
  8572
+  operands[2] = branch_cmp[1];
yann@339
  8573
+
yann@339
  8574
+  gen_int_relational (GT, operands[0], operands[1], operands[2], NULL_RTX);
yann@339
  8575
+  DONE;
yann@339
  8576
+})
yann@339
  8577
+
yann@339
  8578
+
yann@339
  8579
+(define_insn "*sgt"
yann@339
  8580
+  [(set (match_operand:SI 0 "register_operand"        "=r")
yann@339
  8581
+	(gt:SI (match_operand:SI 1 "reg_or_0_operand"  "rM")
yann@339
  8582
+	       (match_operand:SI 2 "reg_or_0_operand"  "rM")))]
yann@339
  8583
+  ""
yann@339
  8584
+  "cmplt\\t%0, %z2, %z1"
yann@339
  8585
+  [(set_attr "type" "alu")])
yann@339
  8586
+
yann@339
  8587
+
yann@339
  8588
+(define_expand "sge"
yann@339
  8589
+  [(set (match_operand:SI 0 "register_operand" "=r")
yann@339
  8590
+	(ge:SI (match_dup 1)
yann@339
  8591
+	       (match_dup 2)))]
yann@339
  8592
+  ""
yann@339
  8593
+{
yann@339
  8594
+  if (branch_type != CMP_SI)
yann@339
  8595
+    FAIL;
yann@339
  8596
+
yann@339
  8597
+  /* set up operands from compare.  */
yann@339
  8598
+  operands[1] = branch_cmp[0];
yann@339
  8599
+  operands[2] = branch_cmp[1];
yann@339
  8600
+
yann@339
  8601
+  gen_int_relational (GE, operands[0], operands[1], operands[2], NULL_RTX);
yann@339
  8602
+  DONE;
yann@339
  8603
+})
yann@339
  8604
+
yann@339
  8605
+
yann@339
  8606
+(define_insn "*sge"
yann@339
  8607
+  [(set (match_operand:SI 0 "register_operand"        "=r")
yann@339
  8608
+	(ge:SI (match_operand:SI 1 "reg_or_0_operand"  "rM")
yann@339
  8609
+	       (match_operand:SI 2 "arith_operand"     "rI")))]
yann@339
  8610
+  ""
yann@339
  8611
+  "cmpge%i2\\t%0, %z1, %z2"
yann@339
  8612
+  [(set_attr "type" "alu")])
yann@339
  8613
+
yann@339
  8614
+(define_expand "sle"
yann@339
  8615
+  [(set (match_operand:SI 0 "register_operand" "=r")
yann@339
  8616
+	(le:SI (match_dup 1)
yann@339
  8617
+	       (match_dup 2)))]
yann@339
  8618
+  ""
yann@339
  8619
+{
yann@339
  8620
+  if (branch_type != CMP_SI)
yann@339
  8621
+    FAIL;
yann@339
  8622
+
yann@339
  8623
+  /* set up operands from compare.  */
yann@339
  8624
+  operands[1] = branch_cmp[0];
yann@339
  8625
+  operands[2] = branch_cmp[1];
yann@339
  8626
+
yann@339
  8627
+  gen_int_relational (LE, operands[0], operands[1], operands[2], NULL_RTX);
yann@339
  8628
+  DONE;
yann@339
  8629
+})
yann@339
  8630
+
yann@339
  8631
+
yann@339
  8632
+(define_insn "*sle"
yann@339
  8633
+  [(set (match_operand:SI 0 "register_operand"        "=r")
yann@339
  8634
+	(le:SI (match_operand:SI 1 "reg_or_0_operand"  "rM")
yann@339
  8635
+	       (match_operand:SI 2 "reg_or_0_operand"  "rM")))]
yann@339
  8636
+  ""
yann@339
  8637
+  "cmpge\\t%0, %z2, %z1"
yann@339
  8638
+  [(set_attr "type" "alu")])
yann@339
  8639
+
yann@339
  8640
+
yann@339
  8641
+(define_expand "slt"
yann@339
  8642
+  [(set (match_operand:SI 0 "register_operand" "=r")
yann@339
  8643
+	(lt:SI (match_dup 1)
yann@339
  8644
+	       (match_dup 2)))]
yann@339
  8645
+  ""
yann@339
  8646
+{
yann@339
  8647
+  if (branch_type != CMP_SI)
yann@339
  8648
+    FAIL;
yann@339
  8649
+
yann@339
  8650
+  /* set up operands from compare.  */
yann@339
  8651
+  operands[1] = branch_cmp[0];
yann@339
  8652
+  operands[2] = branch_cmp[1];
yann@339
  8653
+
yann@339
  8654
+  gen_int_relational (LT, operands[0], operands[1], operands[2], NULL_RTX);
yann@339
  8655
+  DONE;
yann@339
  8656
+})
yann@339
  8657
+
yann@339
  8658
+
yann@339
  8659
+(define_insn "*slt"
yann@339
  8660
+  [(set (match_operand:SI 0 "register_operand"        "=r")
yann@339
  8661
+	(lt:SI (match_operand:SI 1 "reg_or_0_operand"  "rM")
yann@339
  8662
+	       (match_operand:SI 2 "arith_operand"     "rI")))]
yann@339
  8663
+  ""
yann@339
  8664
+  "cmplt%i2\\t%0, %z1, %z2"
yann@339
  8665
+  [(set_attr "type" "alu")])
yann@339
  8666
+
yann@339
  8667
+
yann@339
  8668
+(define_expand "sgtu"
yann@339
  8669
+  [(set (match_operand:SI 0 "register_operand" "=r")
yann@339
  8670
+	(gtu:SI (match_dup 1)
yann@339
  8671
+	        (match_dup 2)))]
yann@339
  8672
+  ""
yann@339
  8673
+{
yann@339
  8674
+  if (branch_type != CMP_SI)
yann@339
  8675
+    FAIL;
yann@339
  8676
+
yann@339
  8677
+  /* set up operands from compare.  */
yann@339
  8678
+  operands[1] = branch_cmp[0];
yann@339
  8679
+  operands[2] = branch_cmp[1];
yann@339
  8680
+
yann@339
  8681
+  gen_int_relational (GTU, operands[0], operands[1], operands[2], NULL_RTX);
yann@339
  8682
+  DONE;
yann@339
  8683
+})
yann@339
  8684
+
yann@339
  8685
+
yann@339
  8686
+(define_insn "*sgtu"
yann@339
  8687
+  [(set (match_operand:SI 0 "register_operand"        "=r")
yann@339
  8688
+	(gtu:SI (match_operand:SI 1 "reg_or_0_operand"  "rM")
yann@339
  8689
+	        (match_operand:SI 2 "reg_or_0_operand"  "rM")))]
yann@339
  8690
+  ""
yann@339
  8691
+  "cmpltu\\t%0, %z2, %z1"
yann@339
  8692
+  [(set_attr "type" "alu")])
yann@339
  8693
+
yann@339
  8694
+
yann@339
  8695
+(define_expand "sgeu"
yann@339
  8696
+  [(set (match_operand:SI 0 "register_operand" "=r")
yann@339
  8697
+	(geu:SI (match_dup 1)
yann@339
  8698
+	        (match_dup 2)))]
yann@339
  8699
+  ""
yann@339
  8700
+{
yann@339
  8701
+  if (branch_type != CMP_SI)
yann@339
  8702
+    FAIL;
yann@339
  8703
+
yann@339
  8704
+  /* set up operands from compare.  */
yann@339
  8705
+  operands[1] = branch_cmp[0];
yann@339
  8706
+  operands[2] = branch_cmp[1];
yann@339
  8707
+
yann@339
  8708
+  gen_int_relational (GEU, operands[0], operands[1], operands[2], NULL_RTX);
yann@339
  8709
+  DONE;
yann@339
  8710
+})
yann@339
  8711
+
yann@339
  8712
+
yann@339
  8713
+(define_insn "*sgeu"
yann@339
  8714
+  [(set (match_operand:SI 0 "register_operand"        "=r")
yann@339
  8715
+	(geu:SI (match_operand:SI 1 "reg_or_0_operand"  "rM")
yann@339
  8716
+	        (match_operand:SI 2 "uns_arith_operand"     "rJ")))]
yann@339
  8717
+  ""
yann@339
  8718
+  "cmpgeu%i2\\t%0, %z1, %z2"
yann@339
  8719
+  [(set_attr "type" "alu")])
yann@339
  8720
+
yann@339
  8721
+(define_expand "sleu"
yann@339
  8722
+  [(set (match_operand:SI 0 "register_operand" "=r")
yann@339
  8723
+	(leu:SI (match_dup 1)
yann@339
  8724
+	        (match_dup 2)))]
yann@339
  8725
+  ""
yann@339
  8726
+{
yann@339
  8727
+  if (branch_type != CMP_SI)
yann@339
  8728
+    FAIL;
yann@339
  8729
+
yann@339
  8730
+  /* set up operands from compare.  */
yann@339
  8731
+  operands[1] = branch_cmp[0];
yann@339
  8732
+  operands[2] = branch_cmp[1];
yann@339
  8733
+
yann@339
  8734
+  gen_int_relational (LEU, operands[0], operands[1], operands[2], NULL_RTX);
yann@339
  8735
+  DONE;
yann@339
  8736
+})
yann@339
  8737
+
yann@339
  8738
+
yann@339
  8739
+(define_insn "*sleu"
yann@339
  8740
+  [(set (match_operand:SI 0 "register_operand"        "=r")
yann@339
  8741
+	(leu:SI (match_operand:SI 1 "reg_or_0_operand"  "rM")
yann@339
  8742
+	        (match_operand:SI 2 "reg_or_0_operand"  "rM")))]
yann@339
  8743
+  ""
yann@339
  8744
+  "cmpgeu\\t%0, %z2, %z1"
yann@339
  8745
+  [(set_attr "type" "alu")])
yann@339
  8746
+
yann@339
  8747
+
yann@339
  8748
+(define_expand "sltu"
yann@339
  8749
+  [(set (match_operand:SI 0 "register_operand" "=r")
yann@339
  8750
+	(ltu:SI (match_dup 1)
yann@339
  8751
+	        (match_dup 2)))]
yann@339
  8752
+  ""
yann@339
  8753
+{
yann@339
  8754
+  if (branch_type != CMP_SI)
yann@339
  8755
+    FAIL;
yann@339
  8756
+
yann@339
  8757
+  /* set up operands from compare.  */
yann@339
  8758
+  operands[1] = branch_cmp[0];
yann@339
  8759
+  operands[2] = branch_cmp[1];
yann@339
  8760
+
yann@339
  8761
+  gen_int_relational (LTU, operands[0], operands[1], operands[2], NULL_RTX);
yann@339
  8762
+  DONE;
yann@339
  8763
+})
yann@339
  8764
+
yann@339
  8765
+
yann@339
  8766
+(define_insn "*sltu"
yann@339
  8767
+  [(set (match_operand:SI 0 "register_operand"        "=r")
yann@339
  8768
+	(ltu:SI (match_operand:SI 1 "reg_or_0_operand"  "rM")
yann@339
  8769
+	        (match_operand:SI 2 "uns_arith_operand"     "rJ")))]
yann@339
  8770
+  ""
yann@339
  8771
+  "cmpltu%i2\\t%0, %z1, %z2"
yann@339
  8772
+  [(set_attr "type" "alu")])
yann@339
  8773
+
yann@339
  8774
+
yann@339
  8775
+
yann@339
  8776
+
yann@339
  8777
+;*****************************************************************************
yann@339
  8778
+;*
yann@339
  8779
+;* branches
yann@339
  8780
+;*
yann@339
  8781
+;*****************************************************************************
yann@339
  8782
+
yann@339
  8783
+(define_insn "*cbranch"
yann@339
  8784
+  [(set (pc)
yann@339
  8785
+	(if_then_else
yann@339
  8786
+         (match_operator:SI 0 "comparison_operator"
yann@339
  8787
+			    [(match_operand:SI 2 "reg_or_0_operand" "rM")
yann@339
  8788
+			     (match_operand:SI 3 "reg_or_0_operand" "rM")])
yann@339
  8789
+        (label_ref (match_operand 1 "" ""))
yann@339
  8790
+        (pc)))]
yann@339
  8791
+  ""
yann@339
  8792
+  "b%0\\t%z2, %z3, %l1"
yann@339
  8793
+  [(set_attr "type" "control")])
yann@339
  8794
+
yann@339
  8795
+
yann@339
  8796
+(define_expand "beq"
yann@339
  8797
+  [(set (pc)
yann@339
  8798
+	(if_then_else (eq:CC (cc0)
yann@339
  8799
+			     (const_int 0))
yann@339
  8800
+		      (label_ref (match_operand 0 "" ""))
yann@339
  8801
+		      (pc)))]
yann@339
  8802
+  ""
yann@339
  8803
+{
yann@339
  8804
+  gen_int_relational (EQ, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
yann@339
  8805
+  DONE;
yann@339
  8806
+})
yann@339
  8807
+
yann@339
  8808
+
yann@339
  8809
+(define_expand "bne"
yann@339
  8810
+  [(set (pc)
yann@339
  8811
+	(if_then_else (ne:CC (cc0)
yann@339
  8812
+			     (const_int 0))
yann@339
  8813
+		      (label_ref (match_operand 0 "" ""))
yann@339
  8814
+		      (pc)))]
yann@339
  8815
+  ""
yann@339
  8816
+{
yann@339
  8817
+  gen_int_relational (NE, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
yann@339
  8818
+  DONE;
yann@339
  8819
+})
yann@339
  8820
+
yann@339
  8821
+
yann@339
  8822
+(define_expand "bgt"
yann@339
  8823
+  [(set (pc)
yann@339
  8824
+	(if_then_else (gt:CC (cc0)
yann@339
  8825
+			     (const_int 0))
yann@339
  8826
+		      (label_ref (match_operand 0 "" ""))
yann@339
  8827
+		      (pc)))]
yann@339
  8828
+  ""
yann@339
  8829
+{
yann@339
  8830
+  gen_int_relational (GT, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
yann@339
  8831
+  DONE;
yann@339
  8832
+})
yann@339
  8833
+
yann@339
  8834
+(define_expand "bge"
yann@339
  8835
+  [(set (pc)
yann@339
  8836
+	(if_then_else (ge:CC (cc0)
yann@339
  8837
+			     (const_int 0))
yann@339
  8838
+		      (label_ref (match_operand 0 "" ""))
yann@339
  8839
+		      (pc)))]
yann@339
  8840
+  ""
yann@339
  8841
+{
yann@339
  8842
+  gen_int_relational (GE, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
yann@339
  8843
+  DONE;
yann@339
  8844
+})
yann@339
  8845
+
yann@339
  8846
+(define_expand "ble"
yann@339
  8847
+  [(set (pc)
yann@339
  8848
+	(if_then_else (le:CC (cc0)
yann@339
  8849
+			     (const_int 0))
yann@339
  8850
+		      (label_ref (match_operand 0 "" ""))
yann@339
  8851
+		      (pc)))]
yann@339
  8852
+  ""
yann@339
  8853
+{
yann@339
  8854
+  gen_int_relational (LE, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
yann@339
  8855
+  DONE;
yann@339
  8856
+})
yann@339
  8857
+
yann@339
  8858
+(define_expand "blt"
yann@339
  8859
+  [(set (pc)
yann@339
  8860
+	(if_then_else (lt:CC (cc0)
yann@339
  8861
+			     (const_int 0))
yann@339
  8862
+		      (label_ref (match_operand 0 "" ""))
yann@339
  8863
+		      (pc)))]
yann@339
  8864
+  ""
yann@339
  8865
+{
yann@339
  8866
+  gen_int_relational (LT, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
yann@339
  8867
+  DONE;
yann@339
  8868
+})
yann@339
  8869
+
yann@339
  8870
+
yann@339
  8871
+(define_expand "bgtu"
yann@339
  8872
+  [(set (pc)
yann@339
  8873
+	(if_then_else (gtu:CC (cc0)
yann@339
  8874
+		 	      (const_int 0))
yann@339
  8875
+		      (label_ref (match_operand 0 "" ""))
yann@339
  8876
+		      (pc)))]
yann@339
  8877
+  ""
yann@339
  8878
+{
yann@339
  8879
+  gen_int_relational (GTU, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
yann@339
  8880
+  DONE;
yann@339
  8881
+})
yann@339
  8882
+
yann@339
  8883
+(define_expand "bgeu"
yann@339
  8884
+  [(set (pc)
yann@339
  8885
+	(if_then_else (geu:CC (cc0)
yann@339
  8886
+			      (const_int 0))
yann@339
  8887
+		      (label_ref (match_operand 0 "" ""))
yann@339
  8888
+		      (pc)))]
yann@339
  8889
+  ""
yann@339
  8890
+{
yann@339
  8891
+  gen_int_relational (GEU, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
yann@339
  8892
+  DONE;
yann@339
  8893
+})
yann@339
  8894
+
yann@339
  8895
+(define_expand "bleu"
yann@339
  8896
+  [(set (pc)
yann@339
  8897
+	(if_then_else (leu:CC (cc0)
yann@339
  8898
+			      (const_int 0))
yann@339
  8899
+		      (label_ref (match_operand 0 "" ""))
yann@339
  8900
+		      (pc)))]
yann@339
  8901
+  ""
yann@339
  8902
+{
yann@339
  8903
+  gen_int_relational (LEU, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
yann@339
  8904
+  DONE;
yann@339
  8905
+})
yann@339
  8906
+
yann@339
  8907
+(define_expand "bltu"
yann@339
  8908
+  [(set (pc)
yann@339
  8909
+	(if_then_else (ltu:CC (cc0)
yann@339
  8910
+			      (const_int 0))
yann@339
  8911
+		      (label_ref (match_operand 0 "" ""))
yann@339
  8912
+		      (pc)))]
yann@339
  8913
+  ""
yann@339
  8914
+{
yann@339
  8915
+  gen_int_relational (LTU, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
yann@339
  8916
+  DONE;
yann@339
  8917
+})
yann@339
  8918
+
yann@339
  8919
+
yann@339
  8920
+;*****************************************************************************
yann@339
  8921
+;*
yann@339
  8922
+;* String and Block Operations
yann@339
  8923
+;*
yann@339
  8924
+;*****************************************************************************
yann@339
  8925
+
yann@339
  8926
+; ??? This is all really a hack to get Dhrystone to work as fast as possible
yann@339
  8927
+;     things to be fixed:
yann@339
  8928
+;        * let the compiler core handle all of this, for that to work the extra
yann@339
  8929
+;          aliasing needs to be addressed.
yann@339
  8930
+;        * we use three temporary registers for loading and storing to ensure no
yann@339
  8931
+;          ld use stalls, this is excessive, because after the first ld/st only
yann@339
  8932
+;          two are needed. Only two would be needed all the way through if 
yann@339
  8933
+;          we could schedule with other code. Consider:
yann@339
  8934
+;           1  ld $1, 0($src)
yann@339
  8935
+;           2  ld $2, 4($src)
yann@339
  8936
+;           3  ld $3, 8($src)
yann@339
  8937
+;           4  st $1, 0($dest)
yann@339
  8938
+;           5  ld $1, 12($src)
yann@339
  8939
+;           6  st $2, 4($src)
yann@339
  8940
+;           7  etc.
yann@339
  8941
+;          The first store has to wait until 4. If it does not there will be one
yann@339
  8942
+;          cycle of stalling. However, if any other instruction could be placed
yann@339
  8943
+;          between 1 and 4, $3 would not be needed.
yann@339
  8944
+;        * In small we probably don't want to ever do this ourself because there
yann@339
  8945
+;          is no ld use stall.
yann@339
  8946
+
yann@339
  8947
+(define_expand "movstrsi"
yann@339
  8948
+  [(parallel [(set (match_operand:BLK 0 "general_operand"  "")
yann@339
  8949
+		   (match_operand:BLK 1 "general_operand"  ""))
yann@339
  8950
+	      (use (match_operand:SI 2 "const_int_operand" ""))
yann@339
  8951
+	      (use (match_operand:SI 3 "const_int_operand" ""))
yann@339
  8952
+	      (clobber (match_scratch:SI 4                "=&r"))
yann@339
  8953
+	      (clobber (match_scratch:SI 5                "=&r"))
yann@339
  8954
+	      (clobber (match_scratch:SI 6                "=&r"))])]
yann@339
  8955
+  "TARGET_INLINE_MEMCPY"
yann@339
  8956
+{
yann@339
  8957
+  rtx ld_addr_reg, st_addr_reg;
yann@339
  8958
+
yann@339
  8959
+  /* If the predicate for op2 fails in expr.c:emit_block_move_via_movstr 
yann@339
  8960
+     it trys to copy to a register, but does not re-try the predicate.
yann@339
  8961
+     ??? Intead of fixing expr.c, I fix it here. */
yann@339
  8962
+  if (!const_int_operand (operands[2], SImode))
yann@339
  8963
+    FAIL;
yann@339
  8964
+
yann@339
  8965
+  /* ??? there are some magic numbers which need to be sorted out here.
yann@339
  8966
+         the basis for them is not increasing code size hugely or going
yann@339
  8967
+         out of range of offset addressing */
yann@339
  8968
+  if (INTVAL (operands[3]) < 4)
yann@339
  8969
+    FAIL;
yann@339
  8970
+  if (!optimize
yann@339
  8971
+      || (optimize_size && INTVAL (operands[2]) > 12)
yann@339
  8972
+      || (optimize < 3 && INTVAL (operands[2]) > 100)
yann@339
  8973
+      || INTVAL (operands[2]) > 200)
yann@339
  8974
+    FAIL;
yann@339
  8975
+
yann@339
  8976
+  st_addr_reg
yann@339
  8977
+    = replace_equiv_address (operands[0],
yann@339
  8978
+			     copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
yann@339
  8979
+  ld_addr_reg
yann@339
  8980
+    = replace_equiv_address (operands[1],
yann@339
  8981
+			     copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
yann@339
  8982
+  emit_insn (gen_movstrsi_internal (st_addr_reg, ld_addr_reg,
yann@339
  8983
+				    operands[2], operands[3]));
yann@339
  8984
+
yann@339
  8985
+  DONE;
yann@339
  8986
+})
yann@339
  8987
+
yann@339
  8988
+
yann@339
  8989
+(define_insn "movstrsi_internal"
yann@339
  8990
+  [(set (match_operand:BLK 0 "memory_operand"   "=o")
yann@339
  8991
+	(match_operand:BLK 1 "memory_operand"    "o"))
yann@339
  8992
+   (use (match_operand:SI 2 "const_int_operand"  "i"))
yann@339
  8993
+   (use (match_operand:SI 3 "const_int_operand"  "i"))
yann@339
  8994
+   (clobber (match_scratch:SI 4                "=&r"))
yann@339
  8995
+   (clobber (match_scratch:SI 5                "=&r"))
yann@339
  8996
+   (clobber (match_scratch:SI 6                "=&r"))]
yann@339
  8997
+  "TARGET_INLINE_MEMCPY"
yann@339
  8998
+{
yann@339
  8999
+  int ld_offset = INTVAL (operands[2]);
yann@339
  9000
+  int ld_len = INTVAL (operands[2]);
yann@339
  9001
+  int ld_reg = 0;
yann@339
  9002
+  rtx ld_addr_reg = XEXP (operands[1], 0);
yann@339
  9003
+  int st_offset = INTVAL (operands[2]);
yann@339
  9004
+  int st_len = INTVAL (operands[2]);
yann@339
  9005
+  int st_reg = 0;
yann@339
  9006
+  rtx st_addr_reg = XEXP (operands[0], 0);
yann@339
  9007
+  int delay_count = 0;
yann@339
  9008
+  
yann@339
  9009
+  /* ops[0] is the address used by the insn
yann@339
  9010
+     ops[1] is the register being loaded or stored */
yann@339
  9011
+  rtx ops[2];
yann@339
  9012
+  
yann@339
  9013
+  if (INTVAL (operands[3]) < 4)
yann@339
  9014
+    abort ();
yann@339
  9015
+  
yann@339
  9016
+  while (ld_offset >= 4)
yann@339
  9017
+    {
yann@339
  9018
+      /* if the load use delay has been met, I can start
yann@339
  9019
+         storing */
yann@339
  9020
+      if (delay_count >= 3)
yann@339
  9021
+        {
yann@339
  9022
+	  ops[0] = gen_rtx (MEM, SImode, 
yann@339
  9023
+			    plus_constant (st_addr_reg, st_len - st_offset));
yann@339
  9024
+	  ops[1] = operands[st_reg + 4];			 
yann@339
  9025
+	  output_asm_insn ("stw\t%1, %0", ops);
yann@339
  9026
+	  
yann@339
  9027
+	  st_reg = (st_reg + 1) % 3;
yann@339
  9028
+	  st_offset -= 4;
yann@339
  9029
+        }
yann@339
  9030
+    
yann@339
  9031
+      ops[0] = gen_rtx (MEM, SImode, 
yann@339
  9032
+			plus_constant (ld_addr_reg, ld_len - ld_offset));
yann@339
  9033
+      ops[1] = operands[ld_reg + 4];			 
yann@339
  9034
+      output_asm_insn ("ldw\t%1, %0", ops);
yann@339
  9035
+      
yann@339
  9036
+      ld_reg = (ld_reg + 1) % 3;
yann@339
  9037
+      ld_offset -= 4;
yann@339
  9038
+      delay_count++;
yann@339
  9039
+    }
yann@339
  9040
+  
yann@339
  9041
+  if (ld_offset >= 2)
yann@339
  9042
+    {
yann@339
  9043
+      /* if the load use delay has been met, I can start
yann@339
  9044
+         storing */
yann@339
  9045
+      if (delay_count >= 3)
yann@339
  9046
+        {
yann@339
  9047
+	  ops[0] = gen_rtx (MEM, SImode, 
yann@339
  9048
+			    plus_constant (st_addr_reg, st_len - st_offset));
yann@339
  9049
+	  ops[1] = operands[st_reg + 4];			 
yann@339
  9050
+	  output_asm_insn ("stw\t%1, %0", ops);
yann@339
  9051
+	  
yann@339
  9052
+	  st_reg = (st_reg + 1) % 3;
yann@339
  9053
+	  st_offset -= 4;
yann@339
  9054
+        }
yann@339
  9055
+    
yann@339
  9056
+      ops[0] = gen_rtx (MEM, HImode, 
yann@339
  9057
+			plus_constant (ld_addr_reg, ld_len - ld_offset));
yann@339
  9058
+      ops[1] = operands[ld_reg + 4];			 
yann@339
  9059
+      output_asm_insn ("ldh\t%1, %0", ops);
yann@339
  9060
+      
yann@339
  9061
+      ld_reg = (ld_reg + 1) % 3;
yann@339
  9062
+      ld_offset -= 2;
yann@339
  9063
+      delay_count++;
yann@339
  9064
+    }
yann@339
  9065
+  
yann@339
  9066
+  if (ld_offset >= 1)
yann@339
  9067
+    {
yann@339
  9068
+      /* if the load use delay has been met, I can start
yann@339
  9069
+         storing */
yann@339
  9070
+      if (delay_count >= 3)
yann@339
  9071
+        {
yann@339
  9072
+	  ops[0] = gen_rtx (MEM, SImode, 
yann@339
  9073
+			    plus_constant (st_addr_reg, st_len - st_offset));
yann@339
  9074
+	  ops[1] = operands[st_reg + 4];			 
yann@339
  9075
+	  output_asm_insn ("stw\t%1, %0", ops);
yann@339
  9076
+	  
yann@339
  9077
+	  st_reg = (st_reg + 1) % 3;
yann@339
  9078
+	  st_offset -= 4;
yann@339
  9079
+        }
yann@339
  9080
+    
yann@339
  9081
+      ops[0] = gen_rtx (MEM, QImode, 
yann@339
  9082
+			plus_constant (ld_addr_reg, ld_len - ld_offset));
yann@339
  9083
+      ops[1] = operands[ld_reg + 4];			 
yann@339
  9084
+      output_asm_insn ("ldb\t%1, %0", ops);
yann@339
  9085
+      
yann@339
  9086
+      ld_reg = (ld_reg + 1) % 3;
yann@339
  9087
+      ld_offset -= 1;
yann@339
  9088
+      delay_count++;
yann@339
  9089
+    }
yann@339
  9090
+
yann@339
  9091
+    while (st_offset >= 4)
yann@339
  9092
+      {
yann@339
  9093
+	ops[0] = gen_rtx (MEM, SImode, 
yann@339
  9094
+			  plus_constant (st_addr_reg, st_len - st_offset));
yann@339
  9095
+	ops[1] = operands[st_reg + 4];			 
yann@339
  9096
+	output_asm_insn ("stw\t%1, %0", ops);
yann@339
  9097
+
yann@339
  9098
+	st_reg = (st_reg + 1) % 3;
yann@339
  9099
+	st_offset -= 4;
yann@339
  9100
+      }
yann@339
  9101
+  
yann@339
  9102
+    while (st_offset >= 2)
yann@339
  9103
+      {
yann@339
  9104
+	ops[0] = gen_rtx (MEM, HImode, 
yann@339
  9105
+			  plus_constant (st_addr_reg, st_len - st_offset));
yann@339
  9106
+	ops[1] = operands[st_reg + 4];			 
yann@339
  9107
+	output_asm_insn ("sth\t%1, %0", ops);
yann@339
  9108
+
yann@339
  9109
+	st_reg = (st_reg + 1) % 3;
yann@339
  9110
+	st_offset -= 2;
yann@339
  9111
+      }
yann@339
  9112
+  
yann@339
  9113
+    while (st_offset >= 1)
yann@339
  9114
+      {
yann@339
  9115
+	ops[0] = gen_rtx (MEM, QImode, 
yann@339
  9116
+			  plus_constant (st_addr_reg, st_len - st_offset));
yann@339
  9117
+	ops[1] = operands[st_reg + 4];			 
yann@339
  9118
+	output_asm_insn ("stb\t%1, %0", ops);
yann@339
  9119
+
yann@339
  9120
+	st_reg = (st_reg + 1) % 3;
yann@339
  9121
+	st_offset -= 1;
yann@339
  9122
+      }
yann@339
  9123
+  
yann@339
  9124
+  return "";
yann@339
  9125
+}
yann@339
  9126
+; ??? lengths are not being used yet, but I will probably forget
yann@339
  9127
+; to update this once I am using lengths, so set it to something
yann@339
  9128
+; definetely big enough to cover it. 400 allows for 200 bytes
yann@339
  9129
+; of motion.
yann@339
  9130
+  [(set_attr "length" "400")])
yann@339
  9131
+
yann@339
  9132
+
yann@339
  9133
+
yann@339
  9134
+;*****************************************************************************
yann@339
  9135
+;*
yann@339
  9136
+;* Custom instructions
yann@339
  9137
+;*
yann@339
  9138
+;*****************************************************************************
yann@339
  9139
+
yann@339
  9140
+(define_constants [
yann@339
  9141
+  (CUSTOM_N 100)
yann@339
  9142
+  (CUSTOM_NI 101)
yann@339
  9143
+  (CUSTOM_NF 102)
yann@339
  9144
+  (CUSTOM_NP 103)
yann@339
  9145
+  (CUSTOM_NII 104)
yann@339
  9146
+  (CUSTOM_NIF 105)
yann@339
  9147
+  (CUSTOM_NIP 106)
yann@339
  9148
+  (CUSTOM_NFI 107)
yann@339
  9149
+  (CUSTOM_NFF 108)
yann@339
  9150
+  (CUSTOM_NFP 109)
yann@339
  9151
+  (CUSTOM_NPI 110)
yann@339
  9152
+  (CUSTOM_NPF 111)
yann@339
  9153
+  (CUSTOM_NPP 112)
yann@339
  9154
+  (CUSTOM_IN 113)
yann@339
  9155
+  (CUSTOM_INI 114)
yann@339
  9156
+  (CUSTOM_INF 115)
yann@339
  9157
+  (CUSTOM_INP 116)
yann@339
  9158
+  (CUSTOM_INII 117)
yann@339
  9159
+  (CUSTOM_INIF 118)
yann@339
  9160
+  (CUSTOM_INIP 119)
yann@339
  9161
+  (CUSTOM_INFI 120)
yann@339
  9162
+  (CUSTOM_INFF 121)
yann@339
  9163
+  (CUSTOM_INFP 122)
yann@339
  9164
+  (CUSTOM_INPI 123)
yann@339
  9165
+  (CUSTOM_INPF 124)
yann@339
  9166
+  (CUSTOM_INPP 125)
yann@339
  9167
+  (CUSTOM_FN 126)
yann@339
  9168
+  (CUSTOM_FNI 127)
yann@339
  9169
+  (CUSTOM_FNF 128)
yann@339
  9170
+  (CUSTOM_FNP 129)
yann@339
  9171
+  (CUSTOM_FNII 130)
yann@339
  9172
+  (CUSTOM_FNIF 131)
yann@339
  9173
+  (CUSTOM_FNIP 132)
yann@339
  9174
+  (CUSTOM_FNFI 133)
yann@339
  9175
+  (CUSTOM_FNFF 134)
yann@339
  9176
+  (CUSTOM_FNFP 135)
yann@339
  9177
+  (CUSTOM_FNPI 136)
yann@339
  9178
+  (CUSTOM_FNPF 137)
yann@339
  9179
+  (CUSTOM_FNPP 138)
yann@339
  9180
+  (CUSTOM_PN 139)
yann@339
  9181
+  (CUSTOM_PNI 140)
yann@339
  9182
+  (CUSTOM_PNF 141)
yann@339
  9183
+  (CUSTOM_PNP 142)
yann@339
  9184
+  (CUSTOM_PNII 143)
yann@339
  9185
+  (CUSTOM_PNIF 144)
yann@339
  9186
+  (CUSTOM_PNIP 145)
yann@339
  9187
+  (CUSTOM_PNFI 146)
yann@339
  9188
+  (CUSTOM_PNFF 147)
yann@339
  9189
+  (CUSTOM_PNFP 148)
yann@339
  9190
+  (CUSTOM_PNPI 149)
yann@339
  9191
+  (CUSTOM_PNPF 150)
yann@339
  9192
+  (CUSTOM_PNPP 151)
yann@339
  9193
+])
yann@339
  9194
+
yann@339
  9195
+
yann@339
  9196
+(define_insn "custom_n"
yann@339
  9197
+  [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")] CUSTOM_N)]
yann@339
  9198
+  ""
yann@339
  9199
+  "custom\\t%0, zero, zero, zero"
yann@339
  9200
+  [(set_attr "type" "custom")])
yann@339
  9201
+
yann@339
  9202
+(define_insn "custom_ni"
yann@339
  9203
+  [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
yann@339
  9204
+                     (match_operand:SI 1 "register_operand"   "r")] CUSTOM_NI)]
yann@339
  9205
+  ""
yann@339
  9206
+  "custom\\t%0, zero, %1, zero"
yann@339
  9207
+  [(set_attr "type" "custom")])
yann@339
  9208
+
yann@339
  9209
+(define_insn "custom_nf"
yann@339
  9210
+  [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
yann@339
  9211
+                     (match_operand:SF 1 "register_operand"   "r")] CUSTOM_NF)]
yann@339
  9212
+  ""
yann@339
  9213
+  "custom\\t%0, zero, %1, zero"
yann@339
  9214
+  [(set_attr "type" "custom")])
yann@339
  9215
+
yann@339
  9216
+(define_insn "custom_np"
yann@339
  9217
+  [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
yann@339
  9218
+                     (match_operand:SI 1 "register_operand"   "r")] CUSTOM_NP)]
yann@339
  9219
+  ""
yann@339
  9220
+  "custom\\t%0, zero, %1, zero"
yann@339
  9221
+  [(set_attr "type" "custom")])
yann@339
  9222
+
yann@339
  9223
+(define_insn "custom_nii"
yann@339
  9224
+  [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
yann@339
  9225
+                     (match_operand:SI 1 "register_operand"   "r")
yann@339
  9226
+                     (match_operand:SI 2 "register_operand"   "r")] CUSTOM_NII)]
yann@339
  9227
+  ""
yann@339
  9228
+  "custom\\t%0, zero, %1, %2"
yann@339
  9229
+  [(set_attr "type" "custom")])
yann@339
  9230
+
yann@339
  9231
+(define_insn "custom_nif"
yann@339
  9232
+  [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
yann@339
  9233
+                     (match_operand:SI 1 "register_operand"   "r")
yann@339
  9234
+                     (match_operand:SF 2 "register_operand"   "r")] CUSTOM_NIF)]
yann@339
  9235
+  ""
yann@339
  9236
+  "custom\\t%0, zero, %1, %2"
yann@339
  9237
+  [(set_attr "type" "custom")])
yann@339
  9238
+
yann@339
  9239
+(define_insn "custom_nip"
yann@339
  9240
+  [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
yann@339
  9241
+                     (match_operand:SI 1 "register_operand"   "r")
yann@339
  9242
+                     (match_operand:SI 2 "register_operand"   "r")] CUSTOM_NIP)]
yann@339
  9243
+  ""
yann@339
  9244
+  "custom\\t%0, zero, %1, %2"
yann@339
  9245
+  [(set_attr "type" "custom")])
yann@339
  9246
+
yann@339
  9247
+(define_insn "custom_nfi"
yann@339
  9248
+  [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
yann@339
  9249
+                     (match_operand:SF 1 "register_operand"   "r")
yann@339
  9250
+                     (match_operand:SI 2 "register_operand"   "r")] CUSTOM_NFI)]
yann@339
  9251
+  ""
yann@339
  9252
+  "custom\\t%0, zero, %1, %2"
yann@339
  9253
+  [(set_attr "type" "custom")])
yann@339
  9254
+
yann@339
  9255
+(define_insn "custom_nff"
yann@339
  9256
+  [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
yann@339
  9257
+                     (match_operand:SF 1 "register_operand"   "r")
yann@339
  9258
+                     (match_operand:SF 2 "register_operand"   "r")] CUSTOM_NFF)]
yann@339
  9259
+  ""
yann@339
  9260
+  "custom\\t%0, zero, %1, %2"
yann@339
  9261
+  [(set_attr "type" "custom")])
yann@339
  9262
+
yann@339
  9263
+(define_insn "custom_nfp"
yann@339
  9264
+  [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
yann@339
  9265
+                     (match_operand:SF 1 "register_operand"   "r")
yann@339
  9266
+                     (match_operand:SI 2 "register_operand"   "r")] CUSTOM_NFP)]
yann@339
  9267
+  ""
yann@339
  9268
+  "custom\\t%0, zero, %1, %2"
yann@339
  9269
+  [(set_attr "type" "custom")])
yann@339
  9270
+
yann@339
  9271
+(define_insn "custom_npi"
yann@339
  9272
+  [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
yann@339
  9273
+                     (match_operand:SI 1 "register_operand"   "r")
yann@339
  9274
+                     (match_operand:SI 2 "register_operand"   "r")] CUSTOM_NPI)]
yann@339
  9275
+  ""
yann@339
  9276
+  "custom\\t%0, zero, %1, %2"
yann@339
  9277
+  [(set_attr "type" "custom")])
yann@339
  9278
+
yann@339
  9279
+(define_insn "custom_npf"
yann@339
  9280
+  [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
yann@339
  9281
+                     (match_operand:SI 1 "register_operand"   "r")
yann@339
  9282
+                     (match_operand:SF 2 "register_operand"   "r")] CUSTOM_NPF)]
yann@339
  9283
+  ""
yann@339
  9284
+  "custom\\t%0, zero, %1, %2"
yann@339
  9285
+  [(set_attr "type" "custom")])
yann@339
  9286
+
yann@339
  9287
+(define_insn "custom_npp"
yann@339
  9288
+  [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
yann@339
  9289
+                     (match_operand:SI 1 "register_operand"   "r")
yann@339
  9290
+                     (match_operand:SI 2 "register_operand"   "r")] CUSTOM_NPP)]
yann@339
  9291
+  ""
yann@339
  9292
+  "custom\\t%0, zero, %1, %2"
yann@339
  9293
+  [(set_attr "type" "custom")])
yann@339
  9294
+
yann@339
  9295
+
yann@339
  9296
+
yann@339
  9297
+(define_insn "custom_in"
yann@339
  9298
+  [(set (match_operand:SI 0 "register_operand"   "=r")
yann@339
  9299
+        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")] CUSTOM_IN))]
yann@339
  9300
+  ""
yann@339
  9301
+  "custom\\t%1, %0, zero, zero"
yann@339
  9302
+  [(set_attr "type" "custom")])
yann@339
  9303
+
yann@339
  9304
+(define_insn "custom_ini"
yann@339
  9305
+  [(set (match_operand:SI 0 "register_operand"   "=r")
yann@339
  9306
+        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9307
+                          (match_operand:SI 2 "register_operand"   "r")] CUSTOM_INI))]
yann@339
  9308
+  ""
yann@339
  9309
+  "custom\\t%1, %0, %2, zero"
yann@339
  9310
+  [(set_attr "type" "custom")])
yann@339
  9311
+
yann@339
  9312
+(define_insn "custom_inf"
yann@339
  9313
+  [(set (match_operand:SI 0 "register_operand"   "=r")
yann@339
  9314
+        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9315
+                          (match_operand:SF 2 "register_operand"   "r")] CUSTOM_INF))]
yann@339
  9316
+  ""
yann@339
  9317
+  "custom\\t%1, %0, %2, zero"
yann@339
  9318
+  [(set_attr "type" "custom")])
yann@339
  9319
+
yann@339
  9320
+(define_insn "custom_inp"
yann@339
  9321
+  [(set (match_operand:SI 0 "register_operand"   "=r")
yann@339
  9322
+        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9323
+                          (match_operand:SI 2 "register_operand"   "r")] CUSTOM_INP))]
yann@339
  9324
+  ""
yann@339
  9325
+  "custom\\t%1, %0, %2, zero"
yann@339
  9326
+  [(set_attr "type" "custom")])
yann@339
  9327
+
yann@339
  9328
+(define_insn "custom_inii"
yann@339
  9329
+  [(set (match_operand:SI 0 "register_operand"   "=r")
yann@339
  9330
+        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9331
+                          (match_operand:SI 2 "register_operand"   "r")
yann@339
  9332
+                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_INII))]
yann@339
  9333
+  ""
yann@339
  9334
+  "custom\\t%1, %0, %2, %3"
yann@339
  9335
+  [(set_attr "type" "custom")])
yann@339
  9336
+
yann@339
  9337
+(define_insn "custom_inif"
yann@339
  9338
+  [(set (match_operand:SI 0 "register_operand"   "=r")
yann@339
  9339
+        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9340
+                          (match_operand:SI 2 "register_operand"   "r")
yann@339
  9341
+                          (match_operand:SF 3 "register_operand"   "r")] CUSTOM_INIF))]
yann@339
  9342
+  ""
yann@339
  9343
+  "custom\\t%1, %0, %2, %3"
yann@339
  9344
+  [(set_attr "type" "custom")])
yann@339
  9345
+
yann@339
  9346
+(define_insn "custom_inip"
yann@339
  9347
+  [(set (match_operand:SI 0 "register_operand"   "=r")
yann@339
  9348
+        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9349
+                          (match_operand:SI 2 "register_operand"   "r")
yann@339
  9350
+                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_INIP))]
yann@339
  9351
+  ""
yann@339
  9352
+  "custom\\t%1, %0, %2, %3"
yann@339
  9353
+  [(set_attr "type" "custom")])
yann@339
  9354
+
yann@339
  9355
+(define_insn "custom_infi"
yann@339
  9356
+  [(set (match_operand:SI 0 "register_operand"   "=r")
yann@339
  9357
+        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9358
+                          (match_operand:SF 2 "register_operand"   "r")
yann@339
  9359
+                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_INFI))]
yann@339
  9360
+  ""
yann@339
  9361
+  "custom\\t%1, %0, %2, %3"
yann@339
  9362
+  [(set_attr "type" "custom")])
yann@339
  9363
+
yann@339
  9364
+(define_insn "custom_inff"
yann@339
  9365
+  [(set (match_operand:SI 0 "register_operand"   "=r")
yann@339
  9366
+        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9367
+                          (match_operand:SF 2 "register_operand"   "r")
yann@339
  9368
+                          (match_operand:SF 3 "register_operand"   "r")] CUSTOM_INFF))]
yann@339
  9369
+  ""
yann@339
  9370
+  "custom\\t%1, %0, %2, %3"
yann@339
  9371
+  [(set_attr "type" "custom")])
yann@339
  9372
+
yann@339
  9373
+(define_insn "custom_infp"
yann@339
  9374
+  [(set (match_operand:SI 0 "register_operand"   "=r")
yann@339
  9375
+        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9376
+                          (match_operand:SF 2 "register_operand"   "r")
yann@339
  9377
+                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_INFP))]
yann@339
  9378
+  ""
yann@339
  9379
+  "custom\\t%1, %0, %2, %3"
yann@339
  9380
+  [(set_attr "type" "custom")])
yann@339
  9381
+
yann@339
  9382
+(define_insn "custom_inpi"
yann@339
  9383
+  [(set (match_operand:SI 0 "register_operand"   "=r")
yann@339
  9384
+        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9385
+                          (match_operand:SI 2 "register_operand"   "r")
yann@339
  9386
+                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_INPI))]
yann@339
  9387
+  ""
yann@339
  9388
+  "custom\\t%1, %0, %2, %3"
yann@339
  9389
+  [(set_attr "type" "custom")])
yann@339
  9390
+
yann@339
  9391
+(define_insn "custom_inpf"
yann@339
  9392
+  [(set (match_operand:SI 0 "register_operand"   "=r")
yann@339
  9393
+        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9394
+                          (match_operand:SI 2 "register_operand"   "r")
yann@339
  9395
+                          (match_operand:SF 3 "register_operand"   "r")] CUSTOM_INPF))]
yann@339
  9396
+  ""
yann@339
  9397
+  "custom\\t%1, %0, %2, %3"
yann@339
  9398
+  [(set_attr "type" "custom")])
yann@339
  9399
+
yann@339
  9400
+(define_insn "custom_inpp"
yann@339
  9401
+  [(set (match_operand:SI 0 "register_operand"   "=r")
yann@339
  9402
+        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9403
+                          (match_operand:SI 2 "register_operand"   "r")
yann@339
  9404
+                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_INPP))]
yann@339
  9405
+  ""
yann@339
  9406
+  "custom\\t%1, %0, %2, %3"
yann@339
  9407
+  [(set_attr "type" "custom")])
yann@339
  9408
+
yann@339
  9409
+
yann@339
  9410
+
yann@339
  9411
+
yann@339
  9412
+
yann@339
  9413
+(define_insn "custom_fn"
yann@339
  9414
+  [(set (match_operand:SF 0 "register_operand"   "=r")
yann@339
  9415
+        (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")] CUSTOM_FN))]
yann@339
  9416
+  ""
yann@339
  9417
+  "custom\\t%1, %0, zero, zero"
yann@339
  9418
+  [(set_attr "type" "custom")])
yann@339
  9419
+
yann@339
  9420
+(define_insn "custom_fni"
yann@339
  9421
+  [(set (match_operand:SF 0 "register_operand"   "=r")
yann@339
  9422
+        (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9423
+                          (match_operand:SI 2 "register_operand"   "r")] CUSTOM_FNI))]
yann@339
  9424
+  ""
yann@339
  9425
+  "custom\\t%1, %0, %2, zero"
yann@339
  9426
+  [(set_attr "type" "custom")])
yann@339
  9427
+
yann@339
  9428
+(define_insn "custom_fnf"
yann@339
  9429
+  [(set (match_operand:SF 0 "register_operand"   "=r")
yann@339
  9430
+        (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9431
+                          (match_operand:SF 2 "register_operand"   "r")] CUSTOM_FNF))]
yann@339
  9432
+  ""
yann@339
  9433
+  "custom\\t%1, %0, %2, zero"
yann@339
  9434
+  [(set_attr "type" "custom")])
yann@339
  9435
+
yann@339
  9436
+(define_insn "custom_fnp"
yann@339
  9437
+  [(set (match_operand:SF 0 "register_operand"   "=r")
yann@339
  9438
+        (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9439
+                          (match_operand:SI 2 "register_operand"   "r")] CUSTOM_FNP))]
yann@339
  9440
+  ""
yann@339
  9441
+  "custom\\t%1, %0, %2, zero"
yann@339
  9442
+  [(set_attr "type" "custom")])
yann@339
  9443
+
yann@339
  9444
+(define_insn "custom_fnii"
yann@339
  9445
+  [(set (match_operand:SF 0 "register_operand"   "=r")
yann@339
  9446
+        (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9447
+                          (match_operand:SI 2 "register_operand"   "r")
yann@339
  9448
+                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_FNII))]
yann@339
  9449
+  ""
yann@339
  9450
+  "custom\\t%1, %0, %2, %3"
yann@339
  9451
+  [(set_attr "type" "custom")])
yann@339
  9452
+
yann@339
  9453
+(define_insn "custom_fnif"
yann@339
  9454
+  [(set (match_operand:SF 0 "register_operand"   "=r")
yann@339
  9455
+        (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9456
+                          (match_operand:SI 2 "register_operand"   "r")
yann@339
  9457
+                          (match_operand:SF 3 "register_operand"   "r")] CUSTOM_FNIF))]
yann@339
  9458
+  ""
yann@339
  9459
+  "custom\\t%1, %0, %2, %3"
yann@339
  9460
+  [(set_attr "type" "custom")])
yann@339
  9461
+
yann@339
  9462
+(define_insn "custom_fnip"
yann@339
  9463
+  [(set (match_operand:SF 0 "register_operand"   "=r")
yann@339
  9464
+        (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9465
+                          (match_operand:SI 2 "register_operand"   "r")
yann@339
  9466
+                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_FNIP))]
yann@339
  9467
+  ""
yann@339
  9468
+  "custom\\t%1, %0, %2, %3"
yann@339
  9469
+  [(set_attr "type" "custom")])
yann@339
  9470
+
yann@339
  9471
+(define_insn "custom_fnfi"
yann@339
  9472
+  [(set (match_operand:SF 0 "register_operand"   "=r")
yann@339
  9473
+        (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9474
+                          (match_operand:SF 2 "register_operand"   "r")
yann@339
  9475
+                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_FNFI))]
yann@339
  9476
+  ""
yann@339
  9477
+  "custom\\t%1, %0, %2, %3"
yann@339
  9478
+  [(set_attr "type" "custom")])
yann@339
  9479
+
yann@339
  9480
+(define_insn "custom_fnff"
yann@339
  9481
+  [(set (match_operand:SF 0 "register_operand"   "=r")
yann@339
  9482
+        (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9483
+                          (match_operand:SF 2 "register_operand"   "r")
yann@339
  9484
+                          (match_operand:SF 3 "register_operand"   "r")] CUSTOM_FNFF))]
yann@339
  9485
+  ""
yann@339
  9486
+  "custom\\t%1, %0, %2, %3"
yann@339
  9487
+  [(set_attr "type" "custom")])
yann@339
  9488
+
yann@339
  9489
+(define_insn "custom_fnfp"
yann@339
  9490
+  [(set (match_operand:SF 0 "register_operand"   "=r")
yann@339
  9491
+        (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9492
+                          (match_operand:SF 2 "register_operand"   "r")
yann@339
  9493
+                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_FNFP))]
yann@339
  9494
+  ""
yann@339
  9495
+  "custom\\t%1, %0, %2, %3"
yann@339
  9496
+  [(set_attr "type" "custom")])
yann@339
  9497
+
yann@339
  9498
+(define_insn "custom_fnpi"
yann@339
  9499
+  [(set (match_operand:SF 0 "register_operand"   "=r")
yann@339
  9500
+        (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9501
+                          (match_operand:SI 2 "register_operand"   "r")
yann@339
  9502
+                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_FNPI))]
yann@339
  9503
+  ""
yann@339
  9504
+  "custom\\t%1, %0, %2, %3"
yann@339
  9505
+  [(set_attr "type" "custom")])
yann@339
  9506
+
yann@339
  9507
+(define_insn "custom_fnpf"
yann@339
  9508
+  [(set (match_operand:SF 0 "register_operand"   "=r")
yann@339
  9509
+        (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9510
+                          (match_operand:SI 2 "register_operand"   "r")
yann@339
  9511
+                          (match_operand:SF 3 "register_operand"   "r")] CUSTOM_FNPF))]
yann@339
  9512
+  ""
yann@339
  9513
+  "custom\\t%1, %0, %2, %3"
yann@339
  9514
+  [(set_attr "type" "custom")])
yann@339
  9515
+
yann@339
  9516
+(define_insn "custom_fnpp"
yann@339
  9517
+  [(set (match_operand:SF 0 "register_operand"   "=r")
yann@339
  9518
+        (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9519
+                          (match_operand:SI 2 "register_operand"   "r")
yann@339
  9520
+                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_FNPP))]
yann@339
  9521
+  ""
yann@339
  9522
+  "custom\\t%1, %0, %2, %3"
yann@339
  9523
+  [(set_attr "type" "custom")])
yann@339
  9524
+
yann@339
  9525
+
yann@339
  9526
+
yann@339
  9527
+(define_insn "custom_pn"
yann@339
  9528
+  [(set (match_operand:SI 0 "register_operand"   "=r")
yann@339
  9529
+        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")] CUSTOM_PN))]
yann@339
  9530
+  ""
yann@339
  9531
+  "custom\\t%1, %0, zero, zero"
yann@339
  9532
+  [(set_attr "type" "custom")])
yann@339
  9533
+
yann@339
  9534
+(define_insn "custom_pni"
yann@339
  9535
+  [(set (match_operand:SI 0 "register_operand"   "=r")
yann@339
  9536
+        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9537
+                          (match_operand:SI 2 "register_operand"   "r")] CUSTOM_PNI))]
yann@339
  9538
+  ""
yann@339
  9539
+  "custom\\t%1, %0, %2, zero"
yann@339
  9540
+  [(set_attr "type" "custom")])
yann@339
  9541
+
yann@339
  9542
+(define_insn "custom_pnf"
yann@339
  9543
+  [(set (match_operand:SI 0 "register_operand"   "=r")
yann@339
  9544
+        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9545
+                          (match_operand:SF 2 "register_operand"   "r")] CUSTOM_PNF))]
yann@339
  9546
+  ""
yann@339
  9547
+  "custom\\t%1, %0, %2, zero"
yann@339
  9548
+  [(set_attr "type" "custom")])
yann@339
  9549
+
yann@339
  9550
+(define_insn "custom_pnp"
yann@339
  9551
+  [(set (match_operand:SI 0 "register_operand"   "=r")
yann@339
  9552
+        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9553
+                          (match_operand:SI 2 "register_operand"   "r")] CUSTOM_PNP))]
yann@339
  9554
+  ""
yann@339
  9555
+  "custom\\t%1, %0, %2, zero"
yann@339
  9556
+  [(set_attr "type" "custom")])
yann@339
  9557
+
yann@339
  9558
+(define_insn "custom_pnii"
yann@339
  9559
+  [(set (match_operand:SI 0 "register_operand"   "=r")
yann@339
  9560
+        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9561
+                          (match_operand:SI 2 "register_operand"   "r")
yann@339
  9562
+                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_PNII))]
yann@339
  9563
+  ""
yann@339
  9564
+  "custom\\t%1, %0, %2, %3"
yann@339
  9565
+  [(set_attr "type" "custom")])
yann@339
  9566
+
yann@339
  9567
+(define_insn "custom_pnif"
yann@339
  9568
+  [(set (match_operand:SI 0 "register_operand"   "=r")
yann@339
  9569
+        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9570
+                          (match_operand:SI 2 "register_operand"   "r")
yann@339
  9571
+                          (match_operand:SF 3 "register_operand"   "r")] CUSTOM_PNIF))]
yann@339
  9572
+  ""
yann@339
  9573
+  "custom\\t%1, %0, %2, %3"
yann@339
  9574
+  [(set_attr "type" "custom")])
yann@339
  9575
+
yann@339
  9576
+(define_insn "custom_pnip"
yann@339
  9577
+  [(set (match_operand:SI 0 "register_operand"   "=r")
yann@339
  9578
+        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9579
+                          (match_operand:SI 2 "register_operand"   "r")
yann@339
  9580
+                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_PNIP))]
yann@339
  9581
+  ""
yann@339
  9582
+  "custom\\t%1, %0, %2, %3"
yann@339
  9583
+  [(set_attr "type" "custom")])
yann@339
  9584
+
yann@339
  9585
+(define_insn "custom_pnfi"
yann@339
  9586
+  [(set (match_operand:SI 0 "register_operand"   "=r")
yann@339
  9587
+        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9588
+                          (match_operand:SF 2 "register_operand"   "r")
yann@339
  9589
+                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_PNFI))]
yann@339
  9590
+  ""
yann@339
  9591
+  "custom\\t%1, %0, %2, %3"
yann@339
  9592
+  [(set_attr "type" "custom")])
yann@339
  9593
+
yann@339
  9594
+(define_insn "custom_pnff"
yann@339
  9595
+  [(set (match_operand:SI 0 "register_operand"   "=r")
yann@339
  9596
+        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9597
+                          (match_operand:SF 2 "register_operand"   "r")
yann@339
  9598
+                          (match_operand:SF 3 "register_operand"   "r")] CUSTOM_PNFF))]
yann@339
  9599
+  ""
yann@339
  9600
+  "custom\\t%1, %0, %2, %3"
yann@339
  9601
+  [(set_attr "type" "custom")])
yann@339
  9602
+
yann@339
  9603
+(define_insn "custom_pnfp"
yann@339
  9604
+  [(set (match_operand:SI 0 "register_operand"   "=r")
yann@339
  9605
+        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9606
+                          (match_operand:SF 2 "register_operand"   "r")
yann@339
  9607
+                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_PNFP))]
yann@339
  9608
+  ""
yann@339
  9609
+  "custom\\t%1, %0, %2, %3"
yann@339
  9610
+  [(set_attr "type" "custom")])
yann@339
  9611
+
yann@339
  9612
+(define_insn "custom_pnpi"
yann@339
  9613
+  [(set (match_operand:SI 0 "register_operand"   "=r")
yann@339
  9614
+        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9615
+                          (match_operand:SI 2 "register_operand"   "r")
yann@339
  9616
+                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_PNPI))]
yann@339
  9617
+  ""
yann@339
  9618
+  "custom\\t%1, %0, %2, %3"
yann@339
  9619
+  [(set_attr "type" "custom")])
yann@339
  9620
+
yann@339
  9621
+(define_insn "custom_pnpf"
yann@339
  9622
+  [(set (match_operand:SI 0 "register_operand"   "=r")
yann@339
  9623
+        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9624
+                          (match_operand:SI 2 "register_operand"   "r")
yann@339
  9625
+                          (match_operand:SF 3 "register_operand"   "r")] CUSTOM_PNPF))]
yann@339
  9626
+  ""
yann@339
  9627
+  "custom\\t%1, %0, %2, %3"
yann@339
  9628
+  [(set_attr "type" "custom")])
yann@339
  9629
+
yann@339
  9630
+(define_insn "custom_pnpp"
yann@339
  9631
+  [(set (match_operand:SI 0 "register_operand"   "=r")
yann@339
  9632
+        (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
yann@339
  9633
+                          (match_operand:SI 2 "register_operand"   "r")
yann@339
  9634
+                          (match_operand:SI 3 "register_operand"   "r")] CUSTOM_PNPP))]
yann@339
  9635
+  ""
yann@339
  9636
+  "custom\\t%1, %0, %2, %3"
yann@339
  9637
+  [(set_attr "type" "custom")])
yann@339
  9638
+
yann@339
  9639
+
yann@339
  9640
+
yann@339
  9641
+
yann@339
  9642
+
yann@339
  9643
+
yann@339
  9644
+;*****************************************************************************
yann@339
  9645
+;*
yann@339
  9646
+;* Misc
yann@339
  9647
+;*
yann@339
  9648
+;*****************************************************************************
yann@339
  9649
+
yann@339
  9650
+(define_insn "nop"
yann@339
  9651
+  [(const_int 0)]
yann@339
  9652
+  ""
yann@339
  9653
+  "nop\\t"
yann@339
  9654
+  [(set_attr "type" "alu")])
yann@339
  9655
+
yann@339
  9656
+(define_insn "sync"
yann@339
  9657
+  [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)]
yann@339
  9658
+  ""
yann@339
  9659
+  "sync\\t"
yann@339
  9660
+  [(set_attr "type" "control")])
yann@339
  9661
+
yann@339
  9662
+
yann@339
  9663
+(define_insn "rdctl"
yann@339
  9664
+  [(set (match_operand:SI 0 "register_operand" "=r")
yann@339
  9665
+	(unspec_volatile:SI [(match_operand:SI 1 "rdwrctl_operand" "O")] UNSPEC_RDCTL))]
yann@339
  9666
+  ""
yann@339
  9667
+  "rdctl\\t%0, ctl%1"
yann@339
  9668
+  [(set_attr "type" "control")])
yann@339
  9669
+
yann@339
  9670
+(define_insn "wrctl"
yann@339
  9671
+  [(unspec_volatile:SI [(match_operand:SI 0 "rdwrctl_operand"  "O")
yann@339
  9672
+                        (match_operand:SI 1 "register_operand" "r")] UNSPEC_WRCTL)]
yann@339
  9673
+  ""
yann@339
  9674
+  "wrctl\\tctl%0, %1"
yann@339
  9675
+  [(set_attr "type" "control")])
yann@339
  9676
+
yann@339
  9677
+
yann@339
  9678
+
yann@339
  9679
+;*****************************************************************************
yann@339
  9680
+;*
yann@339
  9681
+;* Peepholes
yann@339
  9682
+;*
yann@339
  9683
+;*****************************************************************************
yann@339
  9684
+
yann@339
  9685
+
yann@339
  9686
diff -durN gcc-3.4.6.orig/gcc/config/nios2/nios2-protos.h gcc-3.4.6/gcc/config/nios2/nios2-protos.h
yann@339
  9687
--- gcc-3.4.6.orig/gcc/config/nios2/nios2-protos.h	1970-01-01 01:00:00.000000000 +0100
yann@339
  9688
+++ gcc-3.4.6/gcc/config/nios2/nios2-protos.h	2007-08-15 23:09:36.000000000 +0200
yann@339
  9689
@@ -0,0 +1,70 @@
yann@339
  9690
+/* Subroutines for assembler code output for Altera NIOS 2G NIOS2 version.
yann@339
  9691
+   Copyright (C) 2003 Altera 
yann@339
  9692
+   Contributed by Jonah Graham (jgraham@altera.com).
yann@339
  9693
+
yann@339
  9694
+This file is part of GNU CC.
yann@339
  9695
+
yann@339
  9696
+GNU CC is free software; you can redistribute it and/or modify
yann@339
  9697
+it under the terms of the GNU General Public License as published by
yann@339
  9698
+the Free Software Foundation; either version 2, or (at your option)
yann@339
  9699
+any later version.
yann@339
  9700
+
yann@339
  9701
+GNU CC is distributed in the hope that it will be useful,
yann@339
  9702
+but WITHOUT ANY WARRANTY; without even the implied warranty of
yann@339
  9703
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
yann@339
  9704
+GNU General Public License for more details.
yann@339
  9705
+
yann@339
  9706
+You should have received a copy of the GNU General Public License
yann@339
  9707
+along with GNU CC; see the file COPYING.  If not, write to
yann@339
  9708
+the Free Software Foundation, 59 Temple Place - Suite 330,
yann@339
  9709
+Boston, MA 02111-1307, USA.  */
yann@339
  9710
+
yann@339
  9711
+extern void dump_frame_size (FILE *);
yann@339
  9712
+extern HOST_WIDE_INT compute_frame_size (void);
yann@339
  9713
+extern int nios2_initial_elimination_offset (int, int);
yann@339
  9714
+extern void override_options (void);
yann@339
  9715
+extern void optimization_options (int, int);
yann@339
  9716
+extern int nios2_can_use_return_insn (void);
yann@339
  9717
+extern void expand_prologue (void);
yann@339
  9718
+extern void expand_epilogue (bool);
yann@339
  9719
+extern void function_profiler (FILE *, int);
yann@339
  9720
+
yann@339
  9721
+
yann@339
  9722
+#ifdef RTX_CODE
yann@339
  9723
+extern int nios2_legitimate_address (rtx, enum machine_mode, int);
yann@339
  9724
+extern void nios2_print_operand (FILE *, rtx, int);
yann@339
  9725
+extern void nios2_print_operand_address (FILE *, rtx);
yann@339
  9726
+
yann@339
  9727
+extern int nios2_emit_move_sequence (rtx *, enum machine_mode);
yann@339
  9728
+extern int nios2_emit_expensive_div (rtx *, enum machine_mode);
yann@339
  9729
+
yann@339
  9730
+extern void gen_int_relational (enum rtx_code, rtx, rtx, rtx, rtx);
yann@339
  9731
+extern void gen_conditional_move (rtx *, enum machine_mode);
yann@339
  9732
+extern const char *asm_output_opcode (FILE *, const char *);
yann@339
  9733
+
yann@339
  9734
+/* predicates */
yann@339
  9735
+extern int arith_operand (rtx, enum machine_mode);
yann@339
  9736
+extern int uns_arith_operand (rtx, enum machine_mode);
yann@339
  9737
+extern int logical_operand (rtx, enum machine_mode);
yann@339
  9738
+extern int shift_operand (rtx, enum machine_mode);
yann@339
  9739
+extern int reg_or_0_operand (rtx, enum machine_mode);
yann@339
  9740
+extern int equality_op (rtx, enum machine_mode);
yann@339
  9741
+extern int custom_insn_opcode (rtx, enum machine_mode);
yann@339
  9742
+extern int rdwrctl_operand (rtx, enum machine_mode);
yann@339
  9743
+
yann@339
  9744
+# ifdef HAVE_MACHINE_MODES
yann@339
  9745
+#  if defined TREE_CODE
yann@339
  9746
+extern void function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
yann@339
  9747
+extern rtx function_arg (const CUMULATIVE_ARGS *, enum machine_mode, tree, int);
yann@339
  9748
+extern int function_arg_partial_nregs (const CUMULATIVE_ARGS *, enum machine_mode, tree, int);
yann@339
  9749
+extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree, int);
yann@339
  9750
+extern int nios2_setup_incoming_varargs (const CUMULATIVE_ARGS *, enum machine_mode, tree, int);
yann@339
  9751
+
yann@339
  9752
+#  endif /* TREE_CODE */
yann@339
  9753
+# endif	/* HAVE_MACHINE_MODES */
yann@339
  9754
+#endif
yann@339
  9755
+
yann@339
  9756
+#ifdef TREE_CODE
yann@339
  9757
+extern int nios2_return_in_memory (tree);
yann@339
  9758
+
yann@339
  9759
+#endif /* TREE_CODE */
yann@339
  9760
diff -durN gcc-3.4.6.orig/gcc/config/nios2/t-nios2 gcc-3.4.6/gcc/config/nios2/t-nios2
yann@339
  9761
--- gcc-3.4.6.orig/gcc/config/nios2/t-nios2	1970-01-01 01:00:00.000000000 +0100
yann@339
  9762
+++ gcc-3.4.6/gcc/config/nios2/t-nios2	2007-08-15 23:09:36.000000000 +0200
yann@339
  9763
@@ -0,0 +1,123 @@
yann@339
  9764
+##
yann@339
  9765
+## Compiler flags to use when compiling libgcc2.c.
yann@339
  9766
+##
yann@339
  9767
+## LIB2FUNCS_EXTRA
yann@339
  9768
+## A list of source file names to be compiled or assembled and inserted into libgcc.a.
yann@339
  9769
+
yann@339
  9770
+LIB2FUNCS_EXTRA=$(srcdir)/config/nios2/lib2-divmod.c \
yann@339
  9771
+  $(srcdir)/config/nios2/lib2-divmod-hi.c \
yann@339
  9772
+  $(srcdir)/config/nios2/lib2-divtable.c \
yann@339
  9773
+  $(srcdir)/config/nios2/lib2-mul.c
yann@339
  9774
+
yann@339
  9775
+##
yann@339
  9776
+## Floating Point Emulation
yann@339
  9777
+## To have GCC include software floating point libraries in libgcc.a define FPBIT
yann@339
  9778
+## and DPBIT along with a few rules as follows:
yann@339
  9779
+##
yann@339
  9780
+## # We want fine grained libraries, so use the new code
yann@339
  9781
+## # to build the floating point emulation libraries.
yann@339
  9782
+FPBIT=$(srcdir)/config/nios2/nios2-fp-bit.c
yann@339
  9783
+DPBIT=$(srcdir)/config/nios2/nios2-dp-bit.c
yann@339
  9784
+
yann@339
  9785
+TARGET_LIBGCC2_CFLAGS = -O2
yann@339
  9786
+
yann@339
  9787
+# FLOAT_ONLY - no doubles
yann@339
  9788
+# SMALL_MACHINE - QI/HI is faster than SI
yann@339
  9789
+#     Actually SMALL_MACHINE uses chars and shorts instead of ints
yann@339
  9790
+#     since ints (16-bit ones as they are today) are at least as fast
yann@339
  9791
+#     as chars and shorts, don't define SMALL_MACHINE
yann@339
  9792
+# CMPtype - type returned by FP compare, i.e. INT (hard coded in fp-bit - see code )
yann@339
  9793
+
yann@339
  9794
+$(FPBIT): $(srcdir)/config/fp-bit.c Makefile
yann@339
  9795
+	echo '#define FLOAT'          >  ${FPBIT}
yann@339
  9796
+	cat $(srcdir)/config/fp-bit.c >> ${FPBIT}
yann@339
  9797
+
yann@339
  9798
+$(DPBIT): $(srcdir)/config/fp-bit.c Makefile
yann@339
  9799
+	echo ''          >  ${DPBIT}
yann@339
  9800
+	cat $(srcdir)/config/fp-bit.c >> ${DPBIT}
yann@339
  9801
+
yann@339
  9802
+EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crti.o crtn.o 
yann@339
  9803
+
yann@339
  9804
+# Assemble startup files. 
yann@339
  9805
+$(T)crti.o: $(srcdir)/config/nios2/crti.asm $(GCC_PASSES) 
yann@339
  9806
+	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
yann@339
  9807
+	-c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/nios2/crti.asm 
yann@339
  9808
+
yann@339
  9809
+$(T)crtn.o: $(srcdir)/config/nios2/crtn.asm $(GCC_PASSES) 
yann@339
  9810
+	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
yann@339
  9811
+	-c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/nios2/crtn.asm 
yann@339
  9812
+
yann@339
  9813
+
yann@339
  9814
+## You may need to provide additional #defines at the beginning of
yann@339
  9815
+## fp-bit.c and dp-bit.c to control target endianness and other options
yann@339
  9816
+##
yann@339
  9817
+## CRTSTUFF_T_CFLAGS
yann@339
  9818
+## Special flags used when compiling crtstuff.c.  See Initialization.
yann@339
  9819
+##
yann@339
  9820
+## CRTSTUFF_T_CFLAGS_S
yann@339
  9821
+## Special flags used when compiling crtstuff.c for shared linking.  Used
yann@339
  9822
+## if you use crtbeginS.o and crtendS.o in EXTRA-PARTS. See Initialization.
yann@339
  9823
+##
yann@339
  9824
+## MULTILIB_OPTIONS
yann@339
  9825
+## For some targets, invoking GCC in different ways produces objects that
yann@339
  9826
+## can not be linked together.  For example, for some targets GCC produces
yann@339
  9827
+## both big and little endian code.  For these targets, you must arrange
yann@339
  9828
+## for multiple versions of libgcc.a to be compiled, one for each set of
yann@339
  9829
+## incompatible options.  When GCC invokes the linker, it arranges to link
yann@339
  9830
+## in the right version of libgcc.a, based on the command line options
yann@339
  9831
+## used.
yann@339
  9832
+## The MULTILIB_OPTIONS macro lists the set of options for which special
yann@339
  9833
+## versions of libgcc.a must be built.  Write options that are mutually
yann@339
  9834
+## incompatible side by side, separated by a slash.  Write options that may
yann@339
  9835
+## be used together separated by a space.  The build procedure will build
yann@339
  9836
+## all combinations of compatible options.
yann@339
  9837
+##
yann@339
  9838
+## For example, if you set MULTILIB_OPTIONS to m68000/m68020 msoft-float,
yann@339
  9839
+## Makefile will build special versions of libgcc.a using the following
yann@339
  9840
+## sets of options: -m68000, -m68020, -msoft-float, -m68000 -msoft-float,
yann@339
  9841
+## and -m68020 -msoft-float.
yann@339
  9842
+
yann@339
  9843
+MULTILIB_OPTIONS = mno-hw-mul mhw-mulx
yann@339
  9844
+
yann@339
  9845
+## MULTILIB_DIRNAMES
yann@339
  9846
+## If MULTILIB_OPTIONS is used, this variable specifies the directory names
yann@339
  9847
+## that should be used to hold the various libraries.  Write one element in
yann@339
  9848
+## MULTILIB_DIRNAMES for each element in MULTILIB_OPTIONS. If
yann@339
  9849
+## MULTILIB_DIRNAMES is not used, the default value will be
yann@339
  9850
+## MULTILIB_OPTIONS, with all slashes treated as spaces.
yann@339
  9851
+## For example, if MULTILIB_OPTIONS is set to m68000/m68020 msoft-float,
yann@339
  9852
+## then the default value of MULTILIB_DIRNAMES is m68000 m68020
yann@339
  9853
+## msoft-float.  You may specify a different value if you desire a
yann@339
  9854
+## different set of directory names.
yann@339
  9855
+
yann@339
  9856
+# MULTILIB_DIRNAMES =
yann@339
  9857
+
yann@339
  9858
+## MULTILIB_MATCHES
yann@339
  9859
+## Sometimes the same option may be written in two different ways.  If an
yann@339
  9860
+## option is listed in MULTILIB_OPTIONS, GCC needs to know about any
yann@339
  9861
+## synonyms.  In that case, set MULTILIB_MATCHES to a list of items of the
yann@339
  9862
+## form option=option to describe all relevant synonyms.  For example,
yann@339
  9863
+## m68000=mc68000 m68020=mc68020.
yann@339
  9864
+##
yann@339
  9865
+## MULTILIB_EXCEPTIONS
yann@339
  9866
+## Sometimes when there are multiple sets of MULTILIB_OPTIONS being
yann@339
  9867
+## specified, there are combinations that should not be built.  In that
yann@339
  9868
+## case, set MULTILIB_EXCEPTIONS to be all of the switch exceptions in
yann@339
  9869
+## shell case syntax that should not be built.
yann@339
  9870
+## For example, in the PowerPC embedded ABI support, it is not desirable to
yann@339
  9871
+## build libraries compiled with the -mcall-aix option and either of the
yann@339
  9872
+## -fleading-underscore or -mlittle options at the same time.  Therefore
yann@339
  9873
+## MULTILIB_EXCEPTIONS is set to
yann@339
  9874
+##
yann@339
  9875
+## *mcall-aix/*fleading-underscore* *mlittle/*mcall-aix*
yann@339
  9876
+##
yann@339
  9877
+
yann@339
  9878
+MULTILIB_EXCEPTIONS = *mno-hw-mul/*mhw-mulx*
yann@339
  9879
+
yann@339
  9880
+##
yann@339
  9881
+## MULTILIB_EXTRA_OPTS Sometimes it is desirable that when building
yann@339
  9882
+## multiple versions of libgcc.a certain options should always be passed on
yann@339
  9883
+## to the compiler.  In that case, set MULTILIB_EXTRA_OPTS to be the list
yann@339
  9884
+## of options to be used for all builds.
yann@339
  9885
+##
yann@339
  9886
+
yann@339
  9887
diff -durN gcc-3.4.6.orig/gcc/config.gcc gcc-3.4.6/gcc/config.gcc
yann@339
  9888
--- gcc-3.4.6.orig/gcc/config.gcc	2007-08-15 23:07:00.000000000 +0200
yann@339
  9889
+++ gcc-3.4.6/gcc/config.gcc	2007-08-15 23:09:36.000000000 +0200
yann@339
  9890
@@ -1342,6 +1342,10 @@
yann@339
  9891
 		thread_file='posix'
yann@339
  9892
 	fi
yann@339
  9893
 	;;
yann@339
  9894
+# JBG
yann@339
  9895
+nios2-*-* | nios2-*-*)
yann@339
  9896
+	tm_file="elfos.h ${tm_file}"
yann@339
  9897
+	;;
yann@339
  9898
 # m68hc11 and m68hc12 share the same machine description.
yann@339
  9899
 m68hc11-*-*|m6811-*-*)
yann@339
  9900
 	tm_file="dbxelf.h elfos.h m68hc11/m68hc11.h"
yann@339
  9901
diff -durN gcc-3.4.6.orig/gcc/cse.c gcc-3.4.6/gcc/cse.c
yann@339
  9902
--- gcc-3.4.6.orig/gcc/cse.c	2005-12-31 01:39:42.000000000 +0100
yann@339
  9903
+++ gcc-3.4.6/gcc/cse.c	2007-08-15 23:09:36.000000000 +0200
yann@339
  9904
@@ -3134,6 +3134,10 @@
yann@339
  9905
 #ifdef FLOAT_STORE_FLAG_VALUE
yann@339
  9906
 	  REAL_VALUE_TYPE fsfv;
yann@339
  9907
 #endif
yann@339
  9908
+#ifdef __nios2__
yann@339
  9909
+	  if (p->is_const)
yann@339
  9910
+	    break;
yann@339
  9911
+#endif
yann@339
  9912
 
yann@339
  9913
 	  /* If the entry isn't valid, skip it.  */
yann@339
  9914
 	  if (! exp_equiv_p (p->exp, p->exp, 1, 0))
yann@339
  9915
diff -durN gcc-3.4.6.orig/gcc/doc/extend.texi gcc-3.4.6/gcc/doc/extend.texi
yann@339
  9916
--- gcc-3.4.6.orig/gcc/doc/extend.texi	2005-02-26 23:17:26.000000000 +0100
yann@339
  9917
+++ gcc-3.4.6/gcc/doc/extend.texi	2007-08-15 23:09:36.000000000 +0200
yann@339
  9918
@@ -5638,12 +5638,118 @@
yann@339
  9919
 instructions, but allow the compiler to schedule those calls.
yann@339
  9920
 
yann@339
  9921
 @menu
yann@339
  9922
+* Altera Nios II Built-in Functions::
yann@339
  9923
 * Alpha Built-in Functions::
yann@339
  9924
 * ARM Built-in Functions::
yann@339
  9925
 * X86 Built-in Functions::
yann@339
  9926
 * PowerPC AltiVec Built-in Functions::
yann@339
  9927
 @end menu
yann@339
  9928
 
yann@339
  9929
+@node Altera Nios II Built-in Functions
yann@339
  9930
+@subsection Altera Nios II Built-in Functions
yann@339
  9931
+
yann@339
  9932
+These built-in functions are available for the Altera Nios II
yann@339
  9933
+family of processors.
yann@339
  9934
+
yann@339
  9935
+The following built-in functions are always available.  They
yann@339
  9936
+all generate the machine instruction that is part of the name.
yann@339
  9937
+
yann@339
  9938
+@example
yann@339
  9939
+int __builtin_ldbio (volatile const void *)
yann@339
  9940
+int __builtin_ldbuio (volatile const void *)
yann@339
  9941
+int __builtin_ldhio (volatile const void *)
yann@339
  9942
+int __builtin_ldhuio (volatile const void *)
yann@339
  9943
+int __builtin_ldwio (volatile const void *)
yann@339
  9944
+void __builtin_stbio (volatile void *, int)
yann@339
  9945
+void __builtin_sthio (volatile void *, int)
yann@339
  9946
+void __builtin_stwio (volatile void *, int)
yann@339
  9947
+void __builtin_sync (void)
yann@339
  9948
+int __builtin_rdctl (int) 
yann@339
  9949
+void __builtin_wrctl (int, int)
yann@339
  9950
+@end example
yann@339
  9951
+
yann@339
  9952
+The following built-in functions are always available.  They
yann@339
  9953
+all generate a Nios II Custom Instruction. The name of the 
yann@339
  9954
+function represents the types that the function takes and 
yann@339
  9955
+returns. The letter before the @code{n} is the return type
yann@339
  9956
+or void if absent. The @code{n} represnts the first parameter
yann@339
  9957
+to all the custom instructions, the custom instruction number.
yann@339
  9958
+The two letters after the @code{n} represent the up to two 
yann@339
  9959
+parameters to the function.
yann@339
  9960
+
yann@339
  9961
+The letters reprsent the following data types:
yann@339
  9962
+@table @code
yann@339
  9963
+@item <no letter>
yann@339
  9964
+@code{void} for return type and no parameter for parameter types.
yann@339
  9965
+
yann@339
  9966
+@item i
yann@339
  9967
+@code{int} for return type and parameter type
yann@339
  9968
+
yann@339
  9969
+@item f
yann@339
  9970
+@code{float} for return type and parameter type
yann@339
  9971
+
yann@339
  9972
+@item p
yann@339
  9973
+@code{void *} for return type and parameter type
yann@339
  9974
+
yann@339
  9975
+@end table
yann@339
  9976
+
yann@339
  9977
+And the function names are:
yann@339
  9978
+@example
yann@339
  9979
+void __builtin_custom_n (void)
yann@339
  9980
+void __builtin_custom_ni (int)
yann@339
  9981
+void __builtin_custom_nf (float)
yann@339
  9982
+void __builtin_custom_np (void *)
yann@339
  9983
+void __builtin_custom_nii (int, int)
yann@339
  9984
+void __builtin_custom_nif (int, float)
yann@339
  9985
+void __builtin_custom_nip (int, void *)
yann@339
  9986
+void __builtin_custom_nfi (float, int)
yann@339
  9987
+void __builtin_custom_nff (float, float)
yann@339
  9988
+void __builtin_custom_nfp (float, void *)
yann@339
  9989
+void __builtin_custom_npi (void *, int)
yann@339
  9990
+void __builtin_custom_npf (void *, float)
yann@339
  9991
+void __builtin_custom_npp (void *, void *)
yann@339
  9992
+int __builtin_custom_in (void)
yann@339
  9993
+int __builtin_custom_ini (int)
yann@339
  9994
+int __builtin_custom_inf (float)
yann@339
  9995
+int __builtin_custom_inp (void *)
yann@339
  9996
+int __builtin_custom_inii (int, int)
yann@339
  9997
+int __builtin_custom_inif (int, float)
yann@339
  9998
+int __builtin_custom_inip (int, void *)
yann@339
  9999
+int __builtin_custom_infi (float, int)
yann@339
 10000
+int __builtin_custom_inff (float, float)
yann@339
 10001
+int __builtin_custom_infp (float, void *)
yann@339
 10002
+int __builtin_custom_inpi (void *, int)
yann@339
 10003
+int __builtin_custom_inpf (void *, float)
yann@339
 10004
+int __builtin_custom_inpp (void *, void *)
yann@339
 10005
+float __builtin_custom_fn (void)
yann@339
 10006
+float __builtin_custom_fni (int)
yann@339
 10007
+float __builtin_custom_fnf (float)
yann@339
 10008
+float __builtin_custom_fnp (void *)
yann@339
 10009
+float __builtin_custom_fnii (int, int)
yann@339
 10010
+float __builtin_custom_fnif (int, float)
yann@339
 10011
+float __builtin_custom_fnip (int, void *)
yann@339
 10012
+float __builtin_custom_fnfi (float, int)
yann@339
 10013
+float __builtin_custom_fnff (float, float)
yann@339
 10014
+float __builtin_custom_fnfp (float, void *)
yann@339
 10015
+float __builtin_custom_fnpi (void *, int)
yann@339
 10016
+float __builtin_custom_fnpf (void *, float)
yann@339
 10017
+float __builtin_custom_fnpp (void *, void *)
yann@339
 10018
+void * __builtin_custom_pn (void)
yann@339
 10019
+void * __builtin_custom_pni (int)
yann@339
 10020
+void * __builtin_custom_pnf (float)
yann@339
 10021
+void * __builtin_custom_pnp (void *)
yann@339
 10022
+void * __builtin_custom_pnii (int, int)
yann@339
 10023
+void * __builtin_custom_pnif (int, float)
yann@339
 10024
+void * __builtin_custom_pnip (int, void *)
yann@339
 10025
+void * __builtin_custom_pnfi (float, int)
yann@339
 10026
+void * __builtin_custom_pnff (float, float)
yann@339
 10027
+void * __builtin_custom_pnfp (float, void *)
yann@339
 10028
+void * __builtin_custom_pnpi (void *, int)
yann@339
 10029
+void * __builtin_custom_pnpf (void *, float)
yann@339
 10030
+void * __builtin_custom_pnpp (void *, void *)
yann@339
 10031
+@end example
yann@339
 10032
+
yann@339
 10033
+
yann@339
 10034
 @node Alpha Built-in Functions
yann@339
 10035
 @subsection Alpha Built-in Functions
yann@339
 10036
 
yann@339
 10037
diff -durN gcc-3.4.6.orig/gcc/doc/invoke.texi gcc-3.4.6/gcc/doc/invoke.texi
yann@339
 10038
--- gcc-3.4.6.orig/gcc/doc/invoke.texi	2005-10-08 02:22:20.000000000 +0200
yann@339
 10039
+++ gcc-3.4.6/gcc/doc/invoke.texi	2007-08-15 23:09:36.000000000 +0200
yann@339
 10040
@@ -337,6 +337,14 @@
yann@339
 10041
 @item Machine Dependent Options
yann@339
 10042
 @xref{Submodel Options,,Hardware Models and Configurations}.
yann@339
 10043
 
yann@339
 10044
+@emph{Altera Nios II Options}
yann@339
 10045
+@gccoptlist{-msmallc -mno-bypass-cache -mbypass-cache @gol
yann@339
 10046
+-mno-cache-volatile -mcache-volatile -mno-inline-memcpy @gol 
yann@339
 10047
+-minline-memcpy -mno-fast-sw-div -mfast-sw-div @gol
yann@339
 10048
+-mhw-mul -mno-hw-mul -mhw-mulx -mno-hw-mulx @gol
yann@339
 10049
+-mno-hw-div -mhw-div @gol
yann@339
 10050
+-msys-crt0= -msys-lib= -msys=nosys }
yann@339
 10051
+
yann@339
 10052
 @emph{M680x0 Options}
yann@339
 10053
 @gccoptlist{-m68000  -m68020  -m68020-40  -m68020-60  -m68030  -m68040 @gol
yann@339
 10054
 -m68060  -mcpu32  -m5200  -m68881  -mbitfield  -mc68000  -mc68020   @gol
yann@339
 10055
@@ -5839,6 +5847,7 @@
yann@339
 10056
 that macro, which enables you to change the defaults.
yann@339
 10057
 
yann@339
 10058
 @menu
yann@339
 10059
+* Altera Nios II Options::
yann@339
 10060
 * M680x0 Options::
yann@339
 10061
 * M68hc1x Options::
yann@339
 10062
 * VAX Options::
yann@339
 10063
@@ -5874,6 +5883,103 @@
yann@339
 10064
 * FRV Options::
yann@339
 10065
 @end menu
yann@339
 10066
 
yann@339
 10067
+
yann@339
 10068
+@node Altera Nios II Options
yann@339
 10069
+@subsection Altera Nios II Options
yann@339
 10070
+@cindex Altera Nios II options
yann@339
 10071
+
yann@339
 10072
+These are the @samp{-m} options defined for the Altera Nios II 
yann@339
 10073
+processor.
yann@339
 10074
+
yann@339
 10075
+@table @gcctabopt
yann@339
 10076
+
yann@339
 10077
+@item -msmallc
yann@339
 10078
+@opindex msmallc
yann@339
 10079
+
yann@339
 10080
+Link with a limited version of the C library, -lsmallc. For more 
yann@339
 10081
+information see the C Library Documentation.
yann@339
 10082
+
yann@339
 10083
+
yann@339
 10084
+@item -mbypass-cache
yann@339
 10085
+@itemx -mno-bypass-cache
yann@339
 10086
+@opindex mno-bypass-cache
yann@339
 10087
+@opindex mbypass-cache
yann@339
 10088
+
yann@339
 10089
+Force all load and store instructions to always bypass cache by 
yann@339
 10090
+using io variants of the instructions. The default is to not
yann@339
 10091
+bypass the cache.
yann@339
 10092
+
yann@339
 10093
+@item -mno-cache-volatile 
yann@339
 10094
+@itemx -mcache-volatile       
yann@339
 10095
+@opindex mcache-volatile 
yann@339
 10096
+@opindex mno-cache-volatile
yann@339
 10097
+
yann@339
 10098
+Volatile memory access bypass the cache using the io variants of 
yann@339
 10099
+the ld and st instructions. The default is to cache volatile 
yann@339
 10100
+accesses. 
yann@339
 10101
+
yann@339
 10102
+-mno-cache-volatile is deprecated and will be deleted in a 
yann@339
 10103
+future GCC release.
yann@339
 10104
+
yann@339
 10105
+
yann@339
 10106
+@item -mno-inline-memcpy
yann@339
 10107
+@itemx -minline-memcpy
yann@339
 10108
+@opindex mno-inline-memcpy 
yann@339
 10109
+@opindex minline-memcpy
yann@339
 10110
+
yann@339
 10111
+Do not inline memcpy. The default is to inline when -O is on.
yann@339
 10112
+
yann@339
 10113
+
yann@339
 10114
+@item -mno-fast-sw-div
yann@339
 10115
+@itemx -mfast-sw-div
yann@339
 10116
+@opindex mno-fast-sw-div
yann@339
 10117
+@opindex mfast-sw-div
yann@339
 10118
+
yann@339
 10119
+Do no use table based fast divide for small numbers. The default 
yann@339
 10120
+is to use the fast divide at -O3 and above.
yann@339
 10121
+
yann@339
 10122
+
yann@339
 10123
+@item -mno-hw-mul
yann@339
 10124
+@itemx -mhw-mul
yann@339
 10125
+@itemx -mno-hw-mulx
yann@339
 10126
+@itemx -mhw-mulx
yann@339
 10127
+@itemx -mno-hw-div
yann@339
 10128
+@itemx -mhw-div
yann@339
 10129
+@opindex mno-hw-mul
yann@339
 10130
+@opindex mhw-mul
yann@339
 10131
+@opindex mno-hw-mulx
yann@339
 10132
+@opindex mhw-mulx
yann@339
 10133
+@opindex mno-hw-div
yann@339
 10134
+@opindex mhw-div
yann@339
 10135
+
yann@339
 10136
+Enable or disable emitting @code{mul}, @code{mulx} and @code{div} family of 
yann@339
 10137
+instructions by the compiler. The default is to emit @code{mul}
yann@339
 10138
+and not emit @code{div} and @code{mulx}.
yann@339
 10139
+
yann@339
 10140
+The different combinations of @code{mul} and @code{mulx} instructions 
yann@339
 10141
+generate a different multilib options. 
yann@339
 10142
+
yann@339
 10143
+
yann@339
 10144
+@item -msys-crt0=@var{startfile}
yann@339
 10145
+@opindex msys-crt0
yann@339
 10146
+
yann@339
 10147
+@var{startfile} is the file name  of the startfile (crt0) to use 
yann@339
 10148
+when linking. The default is crt0.o that comes with libgloss
yann@339
 10149
+and is only suitable for use with the instruction set
yann@339
 10150
+simulator.
yann@339
 10151
+
yann@339
 10152
+@item -msys-lib=@var{systemlib}
yann@339
 10153
+@itemx -msys-lib=nosys
yann@339
 10154
+@opindex msys-lib
yann@339
 10155
+
yann@339
 10156
+@var{systemlib} is the library name of the library which provides
yann@339
 10157
+the system calls required by the C library, e.g. @code{read}, @code{write}
yann@339
 10158
+etc. The default is to use nosys, this library provides
yann@339
 10159
+stub implementations of the calls and is part of libgloss.
yann@339
 10160
+
yann@339
 10161
+@end table
yann@339
 10162
+
yann@339
 10163
+
yann@339
 10164
 @node M680x0 Options
yann@339
 10165
 @subsection M680x0 Options
yann@339
 10166
 @cindex M680x0 options
yann@339
 10167
diff -durN gcc-3.4.6.orig/gcc/doc/md.texi gcc-3.4.6/gcc/doc/md.texi
yann@339
 10168
--- gcc-3.4.6.orig/gcc/doc/md.texi	2004-11-13 23:31:42.000000000 +0100
yann@339
 10169
+++ gcc-3.4.6/gcc/doc/md.texi	2007-08-15 23:09:36.000000000 +0200
yann@339
 10170
@@ -1337,6 +1337,49 @@
yann@339
 10171
 available on some particular machines.
yann@339
 10172
 
yann@339
 10173
 @table @emph
yann@339
 10174
+
yann@339
 10175
+@item Altera Nios II family---@file{nios2.h}
yann@339
 10176
+@table @code
yann@339
 10177
+
yann@339
 10178
+@item I
yann@339
 10179
+Integer that is valid as an immediate operand in an
yann@339
 10180
+instruction taking a signed 16-bit number. Range
yann@339
 10181
+@minus{}32768 to 32767.
yann@339
 10182
+
yann@339
 10183
+@item J
yann@339
 10184
+Integer that is valid as an immediate operand in an
yann@339
 10185
+instruction taking an unsigned 16-bit number. Range
yann@339
 10186
+0 to 65535.
yann@339
 10187
+
yann@339
 10188
+@item K
yann@339
 10189
+Integer that is valid as an immediate operand in an
yann@339
 10190
+instruction taking only the upper 16-bits of a
yann@339
 10191
+32-bit number. Range 32-bit numbers with the lower
yann@339
 10192
+16-bits being 0.
yann@339
 10193
+
yann@339
 10194
+@item L
yann@339
 10195
+Integer that is valid as an immediate operand for a 
yann@339
 10196
+shift instruction. Range 0 to 31.
yann@339
 10197
+
yann@339
 10198
+
yann@339
 10199
+@item M
yann@339
 10200
+Integer that is valid as an immediate operand for
yann@339
 10201
+only the value 0. Can be used in conjunction with
yann@339
 10202
+the format modifier @code{z} to use @code{r0}
yann@339
 10203
+instead of @code{0} in the assembly output.
yann@339
 10204
+
yann@339
 10205
+@item N
yann@339
 10206
+Integer that is valid as an immediate operand for
yann@339
 10207
+a custom instruction opcode. Range 0 to 255.
yann@339
 10208
+
yann@339
 10209
+@item S
yann@339
 10210
+Matches immediates which are addresses in the small
yann@339
 10211
+data section and therefore can be added to @code{gp}
yann@339
 10212
+as a 16-bit immediate to re-create their 32-bit value.
yann@339
 10213
+
yann@339
 10214
+@end table
yann@339
 10215
+
yann@339
 10216
+
yann@339
 10217
 @item ARM family---@file{arm.h}
yann@339
 10218
 @table @code
yann@339
 10219
 @item f
yann@339
 10220
diff -durN gcc-3.4.6.orig/gcc/Makefile.in gcc-3.4.6/gcc/Makefile.in
yann@339
 10221
--- gcc-3.4.6.orig/gcc/Makefile.in	2005-02-24 10:26:59.000000000 +0100
yann@339
 10222
+++ gcc-3.4.6/gcc/Makefile.in	2007-08-15 23:09:36.000000000 +0200
yann@339
 10223
@@ -3094,7 +3094,7 @@
yann@339
 10224
 	  $(INSTALL_DATA) $(srcdir)/README-fixinc \
yann@339
 10225
 	    $(DESTDIR)$(itoolsdatadir)/include/README ; \
yann@339
 10226
 	  $(INSTALL_SCRIPT) fixinc.sh $(DESTDIR)$(itoolsdir)/fixinc.sh ; \
yann@339
 10227
-	  $(INSTALL_PROGRAM) fixinc/fixincl $(DESTDIR)$(itoolsdir)/fixincl ; \
yann@339
 10228
+	  $(INSTALL_PROGRAM) fixinc/fixincl$(build_exeext) $(DESTDIR)$(itoolsdir)/fixincl$(build_exeext) ; \
yann@339
 10229
 	  $(INSTALL_DATA) $(srcdir)/gsyslimits.h \
yann@339
 10230
 	    $(DESTDIR)$(itoolsdatadir)/gsyslimits.h ; \
yann@339
 10231
 	else :; fi