patches/gcc/3.4.6/250-nios2.patch
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Tue Jan 12 19:24:03 2010 +0100 (2010-01-12)
changeset 1761 88020b2c3246
parent 339 bd5e0a849352
permissions -rw-r--r--
scripts/functions: change handling of nochdir

- 'nochdir' must be the first option
- have systematic pushd/popd, even if nochdir
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