Configure tsocks with a simple heuristic.
Consider the proxy has to be in a 'local' network. It means it is directly
reachable by the local machine, even if the local machine has to hop through
one or more gates to reach the proxy (often the case in enterprise networks
where class A 10.0.0.0/8 is in fact sub-divided into smaller networks, each
one of them in a different location, eg. 10.1.0.0/16 in a place, while
10.2.0.0/16 would be on the other side of the world). Not being in the same
subnet does not mean the proxy is not available.
So we will build a mask with at most high bits set, which defines a network
that has both the local machine and the proxy. Because a machine may have
more than one interface, build a mask for each of them, removing 127.0.0.1
which is added automagically by tsocks, and removing duplicate masks.
If all of this does not work, then it means the local machine can NOT in fact
reach the proxy, which in turn means the user mis-configured something (most
probably a typo...).
/trunk/scripts/crosstool.sh | 61 52 9 0 +++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 52 insertions(+), 9 deletions(-)
1 diff -durN gcc-3.4.6.orig/gcc/combine.c gcc-3.4.6/gcc/combine.c
2 --- gcc-3.4.6.orig/gcc/combine.c 2005-08-08 20:41:04.000000000 +0200
3 +++ gcc-3.4.6/gcc/combine.c 2007-08-15 23:09:36.000000000 +0200
9 +/* This screws up Nios II in this test case:
16 else if (STORE_FLAG_VALUE == 1
17 && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT
20 gen_lowpart_for_combine (mode, op0),
25 else if (STORE_FLAG_VALUE == 1
26 && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT
27 diff -durN gcc-3.4.6.orig/gcc/config/nios2/crti.asm gcc-3.4.6/gcc/config/nios2/crti.asm
28 --- gcc-3.4.6.orig/gcc/config/nios2/crti.asm 1970-01-01 01:00:00.000000000 +0100
29 +++ gcc-3.4.6/gcc/config/nios2/crti.asm 2007-08-15 23:09:36.000000000 +0200
33 + by Jonah Graham (jgraham@altera.com)
35 +This file is free software; you can redistribute it and/or modify it
36 +under the terms of the GNU General Public License as published by the
37 +Free Software Foundation; either version 2, or (at your option) any
40 +In addition to the permissions in the GNU General Public License, the
41 +Free Software Foundation gives you unlimited permission to link the
42 +compiled version of this file with other programs, and to distribute
43 +those programs without any restriction coming from the use of this
44 +file. (The General Public License restrictions do apply in other
45 +respects; for example, they cover modification of the file, and
46 +distribution when not linked into another program.)
48 +This file is distributed in the hope that it will be useful, but
49 +WITHOUT ANY WARRANTY; without even the implied warranty of
50 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
51 +General Public License for more details.
53 +You should have received a copy of the GNU General Public License
54 +along with this program; see the file COPYING. If not, write to
55 +the Free Software Foundation, 59 Temple Place - Suite 330,
56 +Boston, MA 02111-1307, USA.
58 + As a special exception, if you link this library with files
59 + compiled with GCC to produce an executable, this does not cause
60 + the resulting executable to be covered by the GNU General Public License.
61 + This exception does not however invalidate any other reasons why
62 + the executable file might be covered by the GNU General Public License.
65 +This file just make a stack frame for the contents of the .fini and
66 +.init sections. Users may put any desired instructions in those
70 +While technically any code can be put in the init and fini sections
71 +most stuff will not work other than stuff which obeys the call frame
72 +and ABI. All the call-preserved registers are saved, the call clobbered
73 +registers should have been saved by the code calling init and fini.
75 +See crtstuff.c for an example of code that inserts itself in the
76 +init and fini sections.
78 +See crt0.s for the code that calls init and fini.
119 diff -durN gcc-3.4.6.orig/gcc/config/nios2/crtn.asm gcc-3.4.6/gcc/config/nios2/crtn.asm
120 --- gcc-3.4.6.orig/gcc/config/nios2/crtn.asm 1970-01-01 01:00:00.000000000 +0100
121 +++ gcc-3.4.6/gcc/config/nios2/crtn.asm 2007-08-15 23:09:36.000000000 +0200
125 + by Jonah Graham (jgraham@altera.com)
127 +This file is free software; you can redistribute it and/or modify it
128 +under the terms of the GNU General Public License as published by the
129 +Free Software Foundation; either version 2, or (at your option) any
132 +In addition to the permissions in the GNU General Public License, the
133 +Free Software Foundation gives you unlimited permission to link the
134 +compiled version of this file with other programs, and to distribute
135 +those programs without any restriction coming from the use of this
136 +file. (The General Public License restrictions do apply in other
137 +respects; for example, they cover modification of the file, and
138 +distribution when not linked into another program.)
140 +This file is distributed in the hope that it will be useful, but
141 +WITHOUT ANY WARRANTY; without even the implied warranty of
142 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
143 +General Public License for more details.
145 +You should have received a copy of the GNU General Public License
146 +along with this program; see the file COPYING. If not, write to
147 +the Free Software Foundation, 59 Temple Place - Suite 330,
148 +Boston, MA 02111-1307, USA.
150 + As a special exception, if you link this library with files
151 + compiled with GCC to produce an executable, this does not cause
152 + the resulting executable to be covered by the GNU General Public License.
153 + This exception does not however invalidate any other reasons why
154 + the executable file might be covered by the GNU General Public License.
157 +This file just makes sure that the .fini and .init sections do in
158 +fact return. Users may put any desired instructions in those sections.
159 +This file is the last thing linked into any executable.
193 diff -durN gcc-3.4.6.orig/gcc/config/nios2/lib2-divmod.c gcc-3.4.6/gcc/config/nios2/lib2-divmod.c
194 --- gcc-3.4.6.orig/gcc/config/nios2/lib2-divmod.c 1970-01-01 01:00:00.000000000 +0100
195 +++ gcc-3.4.6/gcc/config/nios2/lib2-divmod.c 2007-08-15 23:09:36.000000000 +0200
198 +/* We include auto-host.h here to get HAVE_GAS_HIDDEN. This is
199 + supposedly valid even though this is a "target" file. */
200 +#include "auto-host.h"
203 +#include "tconfig.h"
204 +#include "tsystem.h"
205 +#include "coretypes.h"
209 +/* Don't use `fancy_abort' here even if config.h says to use it. */
215 +#ifdef HAVE_GAS_HIDDEN
216 +#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
218 +#define ATTRIBUTE_HIDDEN
221 +#include "libgcc2.h"
223 +extern SItype __modsi3 (SItype, SItype);
224 +extern SItype __divsi3 (SItype, SItype);
225 +extern SItype __umodsi3 (SItype, SItype);
226 +extern SItype __udivsi3 (SItype, SItype);
228 +static USItype udivmodsi4(USItype, USItype, word_type);
230 +/* 16-bit SI divide and modulo as used in NIOS */
234 +udivmodsi4(USItype num, USItype den, word_type modwanted)
239 + while (den < num && bit && !(den & (1L<<31)))
254 + if (modwanted) return num;
260 +__divsi3 (SItype a, SItype b)
277 + res = udivmodsi4 (a, b, 0);
287 +__modsi3 (SItype a, SItype b)
301 + res = udivmodsi4 (a, b, 1);
311 +__udivsi3 (SItype a, SItype b)
313 + return udivmodsi4 (a, b, 0);
318 +__umodsi3 (SItype a, SItype b)
320 + return udivmodsi4 (a, b, 1);
323 diff -durN gcc-3.4.6.orig/gcc/config/nios2/lib2-divmod-hi.c gcc-3.4.6/gcc/config/nios2/lib2-divmod-hi.c
324 --- gcc-3.4.6.orig/gcc/config/nios2/lib2-divmod-hi.c 1970-01-01 01:00:00.000000000 +0100
325 +++ gcc-3.4.6/gcc/config/nios2/lib2-divmod-hi.c 2007-08-15 23:09:36.000000000 +0200
328 +/* We include auto-host.h here to get HAVE_GAS_HIDDEN. This is
329 + supposedly valid even though this is a "target" file. */
330 +#include "auto-host.h"
333 +#include "tconfig.h"
334 +#include "tsystem.h"
335 +#include "coretypes.h"
339 +/* Don't use `fancy_abort' here even if config.h says to use it. */
345 +#ifdef HAVE_GAS_HIDDEN
346 +#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
348 +#define ATTRIBUTE_HIDDEN
351 +#include "libgcc2.h"
353 +extern HItype __modhi3 (HItype, HItype);
354 +extern HItype __divhi3 (HItype, HItype);
355 +extern HItype __umodhi3 (HItype, HItype);
356 +extern HItype __udivhi3 (HItype, HItype);
358 +static UHItype udivmodhi4(UHItype, UHItype, word_type);
361 +udivmodhi4(UHItype num, UHItype den, word_type modwanted)
366 + while (den < num && bit && !(den & (1L<<15)))
381 + if (modwanted) return num;
387 +__divhi3 (HItype a, HItype b)
404 + res = udivmodhi4 (a, b, 0);
414 +__modhi3 (HItype a, HItype b)
428 + res = udivmodhi4 (a, b, 1);
438 +__udivhi3 (HItype a, HItype b)
440 + return udivmodhi4 (a, b, 0);
445 +__umodhi3 (HItype a, HItype b)
447 + return udivmodhi4 (a, b, 1);
450 diff -durN gcc-3.4.6.orig/gcc/config/nios2/lib2-divtable.c gcc-3.4.6/gcc/config/nios2/lib2-divtable.c
451 --- gcc-3.4.6.orig/gcc/config/nios2/lib2-divtable.c 1970-01-01 01:00:00.000000000 +0100
452 +++ gcc-3.4.6/gcc/config/nios2/lib2-divtable.c 2007-08-15 23:09:36.000000000 +0200
455 +/* We include auto-host.h here to get HAVE_GAS_HIDDEN. This is
456 + supposedly valid even though this is a "target" file. */
457 +#include "auto-host.h"
460 +#include "tconfig.h"
461 +#include "tsystem.h"
462 +#include "coretypes.h"
466 +/* Don't use `fancy_abort' here even if config.h says to use it. */
472 +#ifdef HAVE_GAS_HIDDEN
473 +#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
475 +#define ATTRIBUTE_HIDDEN
478 +#include "libgcc2.h"
480 +UQItype __divsi3_table[] =
482 + 0, 0/1, 0/2, 0/3, 0/4, 0/5, 0/6, 0/7, 0/8, 0/9, 0/10, 0/11, 0/12, 0/13, 0/14, 0/15,
483 + 0, 1/1, 1/2, 1/3, 1/4, 1/5, 1/6, 1/7, 1/8, 1/9, 1/10, 1/11, 1/12, 1/13, 1/14, 1/15,
484 + 0, 2/1, 2/2, 2/3, 2/4, 2/5, 2/6, 2/7, 2/8, 2/9, 2/10, 2/11, 2/12, 2/13, 2/14, 2/15,
485 + 0, 3/1, 3/2, 3/3, 3/4, 3/5, 3/6, 3/7, 3/8, 3/9, 3/10, 3/11, 3/12, 3/13, 3/14, 3/15,
486 + 0, 4/1, 4/2, 4/3, 4/4, 4/5, 4/6, 4/7, 4/8, 4/9, 4/10, 4/11, 4/12, 4/13, 4/14, 4/15,
487 + 0, 5/1, 5/2, 5/3, 5/4, 5/5, 5/6, 5/7, 5/8, 5/9, 5/10, 5/11, 5/12, 5/13, 5/14, 5/15,
488 + 0, 6/1, 6/2, 6/3, 6/4, 6/5, 6/6, 6/7, 6/8, 6/9, 6/10, 6/11, 6/12, 6/13, 6/14, 6/15,
489 + 0, 7/1, 7/2, 7/3, 7/4, 7/5, 7/6, 7/7, 7/8, 7/9, 7/10, 7/11, 7/12, 7/13, 7/14, 7/15,
490 + 0, 8/1, 8/2, 8/3, 8/4, 8/5, 8/6, 8/7, 8/8, 8/9, 8/10, 8/11, 8/12, 8/13, 8/14, 8/15,
491 + 0, 9/1, 9/2, 9/3, 9/4, 9/5, 9/6, 9/7, 9/8, 9/9, 9/10, 9/11, 9/12, 9/13, 9/14, 9/15,
492 + 0, 10/1, 10/2, 10/3, 10/4, 10/5, 10/6, 10/7, 10/8, 10/9, 10/10, 10/11, 10/12, 10/13, 10/14, 10/15,
493 + 0, 11/1, 11/2, 11/3, 11/4, 11/5, 11/6, 11/7, 11/8, 11/9, 11/10, 11/11, 11/12, 11/13, 11/14, 11/15,
494 + 0, 12/1, 12/2, 12/3, 12/4, 12/5, 12/6, 12/7, 12/8, 12/9, 12/10, 12/11, 12/12, 12/13, 12/14, 12/15,
495 + 0, 13/1, 13/2, 13/3, 13/4, 13/5, 13/6, 13/7, 13/8, 13/9, 13/10, 13/11, 13/12, 13/13, 13/14, 13/15,
496 + 0, 14/1, 14/2, 14/3, 14/4, 14/5, 14/6, 14/7, 14/8, 14/9, 14/10, 14/11, 14/12, 14/13, 14/14, 14/15,
497 + 0, 15/1, 15/2, 15/3, 15/4, 15/5, 15/6, 15/7, 15/8, 15/9, 15/10, 15/11, 15/12, 15/13, 15/14, 15/15,
500 diff -durN gcc-3.4.6.orig/gcc/config/nios2/lib2-mul.c gcc-3.4.6/gcc/config/nios2/lib2-mul.c
501 --- gcc-3.4.6.orig/gcc/config/nios2/lib2-mul.c 1970-01-01 01:00:00.000000000 +0100
502 +++ gcc-3.4.6/gcc/config/nios2/lib2-mul.c 2007-08-15 23:09:36.000000000 +0200
504 +/* while we are debugging (ie compile outside of gcc build)
505 + disable gcc specific headers */
506 +#ifndef DEBUG_MULSI3
509 +/* We include auto-host.h here to get HAVE_GAS_HIDDEN. This is
510 + supposedly valid even though this is a "target" file. */
511 +#include "auto-host.h"
514 +#include "tconfig.h"
515 +#include "tsystem.h"
516 +#include "coretypes.h"
520 +/* Don't use `fancy_abort' here even if config.h says to use it. */
526 +#ifdef HAVE_GAS_HIDDEN
527 +#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
529 +#define ATTRIBUTE_HIDDEN
532 +#include "libgcc2.h"
536 +#define USItype unsigned int
540 +extern SItype __mulsi3 (SItype, SItype);
543 +__mulsi3 (SItype a, SItype b)
561 +TODO: Choose best alternative implementation.
564 +__divsi3 (SItype a, SItype b)
571 + if (a & (1L << cnt))
592 + for (i = -1000; i < 1000; i++)
593 + for (j = -1000; j < 1000; j++)
595 + int expect = i * j;
596 + int actual = A__divsi3 (i, j);
597 + if (expect != actual)
599 + printf ("error: %d * %d = %d not %d\n", i, j, expect, actual);
607 diff -durN gcc-3.4.6.orig/gcc/config/nios2/nios2.c gcc-3.4.6/gcc/config/nios2/nios2.c
608 --- gcc-3.4.6.orig/gcc/config/nios2/nios2.c 1970-01-01 01:00:00.000000000 +0100
609 +++ gcc-3.4.6/gcc/config/nios2/nios2.c 2007-08-15 23:09:36.000000000 +0200
611 +/* Subroutines for assembler code output for Altera NIOS 2G NIOS2 version.
612 + Copyright (C) 2003 Altera
613 + Contributed by Jonah Graham (jgraham@altera.com).
615 +This file is part of GNU CC.
617 +GNU CC is free software; you can redistribute it and/or modify
618 +it under the terms of the GNU General Public License as published by
619 +the Free Software Foundation; either version 2, or (at your option)
622 +GNU CC is distributed in the hope that it will be useful,
623 +but WITHOUT ANY WARRANTY; without even the implied warranty of
624 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
625 +GNU General Public License for more details.
627 +You should have received a copy of the GNU General Public License
628 +along with GNU CC; see the file COPYING. If not, write to
629 +the Free Software Foundation, 59 Temple Place - Suite 330,
630 +Boston, MA 02111-1307, USA. */
636 +#include "coretypes.h"
642 +#include "hard-reg-set.h"
644 +#include "insn-config.h"
645 +#include "conditions.h"
647 +#include "insn-attr.h"
652 +#include "basic-block.h"
653 +#include "function.h"
659 +#include "target-def.h"
661 +/* local prototypes */
662 +static bool nios2_rtx_costs (rtx, int, int, int *);
664 +static void nios2_asm_function_prologue (FILE *, HOST_WIDE_INT);
665 +static int nios2_use_dfa_pipeline_interface (void);
666 +static int nios2_issue_rate (void);
667 +static struct machine_function *nios2_init_machine_status (void);
668 +static bool nios2_in_small_data_p (tree);
669 +static rtx save_reg (int, HOST_WIDE_INT, rtx);
670 +static rtx restore_reg (int, HOST_WIDE_INT);
671 +static unsigned int nios2_section_type_flags (tree, const char *, int);
672 +static void nios2_init_builtins (void);
673 +static rtx nios2_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
674 +static bool nios2_function_ok_for_sibcall (tree, tree);
675 +static void nios2_encode_section_info (tree, rtx, int);
677 +/* Initialize the GCC target structure. */
678 +#undef TARGET_ASM_FUNCTION_PROLOGUE
679 +#define TARGET_ASM_FUNCTION_PROLOGUE nios2_asm_function_prologue
681 +#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
682 +#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE \
683 + nios2_use_dfa_pipeline_interface
684 +#undef TARGET_SCHED_ISSUE_RATE
685 +#define TARGET_SCHED_ISSUE_RATE nios2_issue_rate
686 +#undef TARGET_IN_SMALL_DATA_P
687 +#define TARGET_IN_SMALL_DATA_P nios2_in_small_data_p
688 +#undef TARGET_ENCODE_SECTION_INFO
689 +#define TARGET_ENCODE_SECTION_INFO nios2_encode_section_info
690 +#undef TARGET_SECTION_TYPE_FLAGS
691 +#define TARGET_SECTION_TYPE_FLAGS nios2_section_type_flags
693 +#undef TARGET_INIT_BUILTINS
694 +#define TARGET_INIT_BUILTINS nios2_init_builtins
695 +#undef TARGET_EXPAND_BUILTIN
696 +#define TARGET_EXPAND_BUILTIN nios2_expand_builtin
698 +#undef TARGET_FUNCTION_OK_FOR_SIBCALL
699 +#define TARGET_FUNCTION_OK_FOR_SIBCALL nios2_function_ok_for_sibcall
701 +#undef TARGET_RTX_COSTS
702 +#define TARGET_RTX_COSTS nios2_rtx_costs
705 +struct gcc_target targetm = TARGET_INITIALIZER;
709 +/* Threshold for data being put into the small data/bss area, instead
710 + of the normal data area (references to the small data/bss area take
711 + 1 instruction, and use the global pointer, references to the normal
712 + data area takes 2 instructions). */
713 +unsigned HOST_WIDE_INT nios2_section_threshold = NIOS2_DEFAULT_GVALUE;
716 +/* Structure to be filled in by compute_frame_size with register
717 + save masks, and offsets for the current function. */
719 +struct nios2_frame_info
722 + long total_size; /* # bytes that the entire frame takes up */
723 + long var_size; /* # bytes that variables take up */
724 + long args_size; /* # bytes that outgoing arguments take up */
725 + int save_reg_size; /* # bytes needed to store gp regs */
726 + int save_reg_rounded; /* # bytes needed to store gp regs */
727 + long save_regs_offset; /* offset from new sp to store gp registers */
728 + int initialized; /* != 0 if frame size already calculated */
729 + int num_regs; /* number of gp registers saved */
732 +struct machine_function
736 + /* Current frame information, calculated by compute_frame_size. */
737 + struct nios2_frame_info frame;
741 +/***************************************
742 + * Section encodings
743 + ***************************************/
749 +/***************************************
750 + * Stack Layout and Calling Conventions
751 + ***************************************/
754 +#define TOO_BIG_OFFSET(X) ((X) > ((1 << 15) - 1))
755 +#define TEMP_REG_NUM 8
758 +nios2_asm_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
760 + if (flag_verbose_asm || flag_debug_asm)
762 + compute_frame_size ();
763 + dump_frame_size (file);
768 +save_reg (int regno, HOST_WIDE_INT offset, rtx cfa_store_reg)
770 + rtx insn, stack_slot;
772 + stack_slot = gen_rtx_PLUS (SImode,
776 + insn = emit_insn (gen_rtx_SET (SImode,
777 + gen_rtx_MEM (SImode, stack_slot),
778 + gen_rtx_REG (SImode, regno)));
780 + RTX_FRAME_RELATED_P (insn) = 1;
786 +restore_reg (int regno, HOST_WIDE_INT offset)
788 + rtx insn, stack_slot;
790 + if (TOO_BIG_OFFSET (offset))
792 + stack_slot = gen_rtx_REG (SImode, TEMP_REG_NUM);
793 + insn = emit_insn (gen_rtx_SET (SImode,
795 + GEN_INT (offset)));
797 + insn = emit_insn (gen_rtx_SET (SImode,
799 + gen_rtx_PLUS (SImode,
801 + stack_pointer_rtx)));
805 + stack_slot = gen_rtx_PLUS (SImode,
810 + stack_slot = gen_rtx_MEM (SImode, stack_slot);
812 + insn = emit_move_insn (gen_rtx_REG (SImode, regno), stack_slot);
818 +/* There are two possible paths for prologue expansion,
819 +- the first is if the total frame size is < 2^15-1. In that
820 +case all the immediates will fit into the 16-bit immediate
822 +- the second is when the frame size is too big, in that
823 +case an additional temporary register is used, first
824 +as a cfa_temp to offset the sp, second as the cfa_store
827 +See the comment above dwarf2out_frame_debug_expr in
828 +dwarf2out.c for more explanation of the "rules."
832 +Rule # Example Insn Effect
833 +2 addi sp, sp, -total_frame_size cfa.reg=sp, cfa.offset=total_frame_size
834 + cfa_store.reg=sp, cfa_store.offset=total_frame_size
835 +12 stw ra, offset(sp)
836 +12 stw r16, offset(sp)
840 +Rule # Example Insn Effect
841 +6 movi r8, total_frame_size cfa_temp.reg=r8, cfa_temp.offset=total_frame_size
842 +2 sub sp, sp, r8 cfa.reg=sp, cfa.offset=total_frame_size
843 + cfa_store.reg=sp, cfa_store.offset=total_frame_size
844 +5 add r8, r8, sp cfa_store.reg=r8, cfa_store.offset=0
845 +12 stw ra, offset(r8)
846 +12 stw r16, offset(r8)
855 + HOST_WIDE_INT total_frame_size;
856 + int cfa_store_offset;
858 + rtx cfa_store_reg = 0;
860 + total_frame_size = compute_frame_size ();
862 + if (total_frame_size)
865 + if (TOO_BIG_OFFSET (total_frame_size))
867 + /* cfa_temp and cfa_store_reg are the same register,
868 + cfa_store_reg overwrites cfa_temp */
869 + cfa_store_reg = gen_rtx_REG (SImode, TEMP_REG_NUM);
870 + insn = emit_insn (gen_rtx_SET (SImode,
872 + GEN_INT (total_frame_size)));
874 + RTX_FRAME_RELATED_P (insn) = 1;
877 + insn = gen_rtx_SET (SImode,
879 + gen_rtx_MINUS (SImode,
883 + insn = emit_insn (insn);
884 + RTX_FRAME_RELATED_P (insn) = 1;
887 + /* if there are no registers to save, I don't need to
888 + create a cfa_store */
889 + if (cfun->machine->frame.save_reg_size)
891 + insn = gen_rtx_SET (SImode,
893 + gen_rtx_PLUS (SImode,
895 + stack_pointer_rtx));
897 + insn = emit_insn (insn);
898 + RTX_FRAME_RELATED_P (insn) = 1;
903 + - (cfun->machine->frame.save_regs_offset
904 + + cfun->machine->frame.save_reg_rounded);
908 + insn = gen_rtx_SET (SImode,
910 + gen_rtx_PLUS (SImode,
912 + GEN_INT (-total_frame_size)));
913 + insn = emit_insn (insn);
914 + RTX_FRAME_RELATED_P (insn) = 1;
916 + cfa_store_reg = stack_pointer_rtx;
918 + = cfun->machine->frame.save_regs_offset
919 + + cfun->machine->frame.save_reg_rounded;
923 + if (MUST_SAVE_REGISTER (RA_REGNO))
925 + cfa_store_offset -= 4;
926 + save_reg (RA_REGNO, cfa_store_offset, cfa_store_reg);
928 + if (MUST_SAVE_REGISTER (FP_REGNO))
930 + cfa_store_offset -= 4;
931 + save_reg (FP_REGNO, cfa_store_offset, cfa_store_reg);
934 + for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
936 + if (MUST_SAVE_REGISTER (i) && i != FP_REGNO && i != RA_REGNO)
938 + cfa_store_offset -= 4;
939 + save_reg (i, cfa_store_offset, cfa_store_reg);
943 + if (frame_pointer_needed)
945 + insn = emit_insn (gen_rtx_SET (SImode,
946 + gen_rtx_REG (SImode, FP_REGNO),
947 + gen_rtx_REG (SImode, SP_REGNO)));
949 + RTX_FRAME_RELATED_P (insn) = 1;
952 + /* If we are profiling, make sure no instructions are scheduled before
953 + the call to mcount. */
954 + if (current_function_profile)
955 + emit_insn (gen_blockage ());
959 +expand_epilogue (bool sibcall_p)
963 + HOST_WIDE_INT total_frame_size;
964 + int register_store_offset;
966 + total_frame_size = compute_frame_size ();
968 + if (!sibcall_p && nios2_can_use_return_insn ())
970 + insn = emit_jump_insn (gen_return ());
974 + emit_insn (gen_blockage ());
976 + register_store_offset =
977 + cfun->machine->frame.save_regs_offset +
978 + cfun->machine->frame.save_reg_rounded;
980 + if (MUST_SAVE_REGISTER (RA_REGNO))
982 + register_store_offset -= 4;
983 + restore_reg (RA_REGNO, register_store_offset);
986 + if (MUST_SAVE_REGISTER (FP_REGNO))
988 + register_store_offset -= 4;
989 + restore_reg (FP_REGNO, register_store_offset);
992 + for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
994 + if (MUST_SAVE_REGISTER (i) && i != FP_REGNO && i != RA_REGNO)
996 + register_store_offset -= 4;
997 + restore_reg (i, register_store_offset);
1001 + if (total_frame_size)
1005 + if (TOO_BIG_OFFSET (total_frame_size))
1007 + sp_adjust = gen_rtx_REG (SImode, TEMP_REG_NUM);
1008 + insn = emit_insn (gen_rtx_SET (SImode,
1010 + GEN_INT (total_frame_size)));
1015 + sp_adjust = GEN_INT (total_frame_size);
1018 + insn = gen_rtx_SET (SImode,
1019 + stack_pointer_rtx,
1020 + gen_rtx_PLUS (SImode,
1021 + stack_pointer_rtx,
1023 + insn = emit_insn (insn);
1029 + insn = emit_jump_insn (gen_return_from_epilogue (gen_rtx (REG, Pmode,
1036 +nios2_function_ok_for_sibcall (tree a ATTRIBUTE_UNUSED, tree b ATTRIBUTE_UNUSED)
1045 +/* ----------------------- *
1047 + * ----------------------- */
1050 +function_profiler (FILE *file, int labelno)
1052 + fprintf (file, "\t%s mcount begin, label: .LP%d\n",
1053 + ASM_COMMENT_START, labelno);
1054 + fprintf (file, "\tnextpc\tr8\n");
1055 + fprintf (file, "\tmov\tr9, ra\n");
1056 + fprintf (file, "\tmovhi\tr10, %%hiadj(.LP%d)\n", labelno);
1057 + fprintf (file, "\taddi\tr10, r10, %%lo(.LP%d)\n", labelno);
1058 + fprintf (file, "\tcall\tmcount\n");
1059 + fprintf (file, "\tmov\tra, r9\n");
1060 + fprintf (file, "\t%s mcount end\n", ASM_COMMENT_START);
1064 +/***************************************
1066 + ***************************************/
1070 +dump_frame_size (FILE *file)
1072 + fprintf (file, "\t%s Current Frame Info\n", ASM_COMMENT_START);
1074 + fprintf (file, "\t%s total_size = %ld\n", ASM_COMMENT_START,
1075 + cfun->machine->frame.total_size);
1076 + fprintf (file, "\t%s var_size = %ld\n", ASM_COMMENT_START,
1077 + cfun->machine->frame.var_size);
1078 + fprintf (file, "\t%s args_size = %ld\n", ASM_COMMENT_START,
1079 + cfun->machine->frame.args_size);
1080 + fprintf (file, "\t%s save_reg_size = %d\n", ASM_COMMENT_START,
1081 + cfun->machine->frame.save_reg_size);
1082 + fprintf (file, "\t%s save_reg_rounded = %d\n", ASM_COMMENT_START,
1083 + cfun->machine->frame.save_reg_rounded);
1084 + fprintf (file, "\t%s initialized = %d\n", ASM_COMMENT_START,
1085 + cfun->machine->frame.initialized);
1086 + fprintf (file, "\t%s num_regs = %d\n", ASM_COMMENT_START,
1087 + cfun->machine->frame.num_regs);
1088 + fprintf (file, "\t%s save_regs_offset = %ld\n", ASM_COMMENT_START,
1089 + cfun->machine->frame.save_regs_offset);
1090 + fprintf (file, "\t%s current_function_is_leaf = %d\n", ASM_COMMENT_START,
1091 + current_function_is_leaf);
1092 + fprintf (file, "\t%s frame_pointer_needed = %d\n", ASM_COMMENT_START,
1093 + frame_pointer_needed);
1094 + fprintf (file, "\t%s pretend_args_size = %d\n", ASM_COMMENT_START,
1095 + current_function_pretend_args_size);
1100 +/* Return the bytes needed to compute the frame pointer from the current
1105 +compute_frame_size ()
1107 + unsigned int regno;
1108 + HOST_WIDE_INT var_size; /* # of var. bytes allocated */
1109 + HOST_WIDE_INT total_size; /* # bytes that the entire frame takes up */
1110 + HOST_WIDE_INT save_reg_size; /* # bytes needed to store callee save regs */
1111 + HOST_WIDE_INT save_reg_rounded;
1112 + /* # bytes needed to store callee save regs (rounded) */
1113 + HOST_WIDE_INT out_args_size; /* # bytes needed for outgoing args */
1115 + save_reg_size = 0;
1116 + var_size = STACK_ALIGN (get_frame_size ());
1117 + out_args_size = STACK_ALIGN (current_function_outgoing_args_size);
1119 + total_size = var_size + out_args_size;
1121 + /* Calculate space needed for gp registers. */
1122 + for (regno = 0; regno <= FIRST_PSEUDO_REGISTER; regno++)
1124 + if (MUST_SAVE_REGISTER (regno))
1126 + save_reg_size += 4;
1130 + save_reg_rounded = STACK_ALIGN (save_reg_size);
1131 + total_size += save_reg_rounded;
1133 + total_size += STACK_ALIGN (current_function_pretend_args_size);
1135 + /* Save other computed information. */
1136 + cfun->machine->frame.total_size = total_size;
1137 + cfun->machine->frame.var_size = var_size;
1138 + cfun->machine->frame.args_size = current_function_outgoing_args_size;
1139 + cfun->machine->frame.save_reg_size = save_reg_size;
1140 + cfun->machine->frame.save_reg_rounded = save_reg_rounded;
1141 + cfun->machine->frame.initialized = reload_completed;
1142 + cfun->machine->frame.num_regs = save_reg_size / UNITS_PER_WORD;
1144 + cfun->machine->frame.save_regs_offset
1145 + = save_reg_rounded ? current_function_outgoing_args_size + var_size : 0;
1147 + return total_size;
1152 +nios2_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED)
1156 + /* Set OFFSET to the offset from the stack pointer. */
1159 + case FRAME_POINTER_REGNUM:
1163 + case ARG_POINTER_REGNUM:
1164 + compute_frame_size ();
1165 + offset = cfun->machine->frame.total_size;
1166 + offset -= current_function_pretend_args_size;
1169 + case RETURN_ADDRESS_POINTER_REGNUM:
1170 + compute_frame_size ();
1171 + /* since the return address is always the first of the
1172 + saved registers, return the offset to the beginning
1173 + of the saved registers block */
1174 + offset = cfun->machine->frame.save_regs_offset;
1184 +/* Return nonzero if this function is known to have a null epilogue.
1185 + This allows the optimizer to omit jumps to jumps if no stack
1188 +nios2_can_use_return_insn ()
1190 + if (!reload_completed)
1193 + if (regs_ever_live[RA_REGNO] || current_function_profile)
1196 + if (cfun->machine->frame.initialized)
1197 + return cfun->machine->frame.total_size == 0;
1199 + return compute_frame_size () == 0;
1206 +/***************************************
1208 + ***************************************/
1210 +const char *nios2_sys_nosys_string; /* for -msys=nosys */
1211 +const char *nios2_sys_lib_string; /* for -msys-lib= */
1212 +const char *nios2_sys_crt0_string; /* for -msys-crt0= */
1215 +override_options ()
1217 + /* Function to allocate machine-dependent function status. */
1218 + init_machine_status = &nios2_init_machine_status;
1220 + nios2_section_threshold
1221 + = g_switch_set ? g_switch_value : NIOS2_DEFAULT_GVALUE;
1223 + if (nios2_sys_nosys_string && *nios2_sys_nosys_string)
1225 + error ("invalid option '-msys=nosys%s'", nios2_sys_nosys_string);
1228 + /* If we don't have mul, we don't have mulx either! */
1229 + if (!TARGET_HAS_MUL && TARGET_HAS_MULX)
1231 + target_flags &= ~HAS_MULX_FLAG;
1237 +optimization_options (int level, int size)
1239 + if (level || size)
1241 + target_flags |= INLINE_MEMCPY_FLAG;
1244 + if (level >= 3 && !size)
1246 + target_flags |= FAST_SW_DIV_FLAG;
1250 +/* Allocate a chunk of memory for per-function machine-dependent data. */
1251 +static struct machine_function *
1252 +nios2_init_machine_status ()
1254 + return ((struct machine_function *)
1255 + ggc_alloc_cleared (sizeof (struct machine_function)));
1261 + * Describing Relative Costs of Operations
1262 + *****************/
1264 +/* Compute a (partial) cost for rtx X. Return true if the complete
1265 + cost has been computed, and false if subexpressions should be
1266 + scanned. In either case, *TOTAL contains the cost result. */
1271 +nios2_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total)
1276 + if (INTVAL (x) == 0)
1278 + *total = COSTS_N_INSNS (0);
1281 + else if (SMALL_INT (INTVAL (x))
1282 + || SMALL_INT_UNSIGNED (INTVAL (x))
1283 + || UPPER16_INT (INTVAL (x)))
1285 + *total = COSTS_N_INSNS (2);
1290 + *total = COSTS_N_INSNS (4);
1296 + /* ??? gp relative stuff will fit in here */
1297 + /* fall through */
1299 + case CONST_DOUBLE:
1301 + *total = COSTS_N_INSNS (4);
1307 + *total = COSTS_N_INSNS (1);
1312 + *total = COSTS_N_INSNS (3);
1317 + *total = COSTS_N_INSNS (1);
1327 +/***************************************
1328 + * INSTRUCTION SUPPORT
1330 + * These functions are used within the Machine Description to
1331 + * handle common or complicated output and expansions from
1333 + ***************************************/
1336 +nios2_emit_move_sequence (rtx *operands, enum machine_mode mode)
1338 + rtx to = operands[0];
1339 + rtx from = operands[1];
1341 + if (!register_operand (to, mode) && !reg_or_0_operand (from, mode))
1343 + if (no_new_pseudos)
1344 + internal_error ("Trying to force_reg no_new_pseudos == 1");
1345 + from = copy_to_mode_reg (mode, from);
1349 + operands[1] = from;
1353 +/* Divide Support */
1356 + If -O3 is used, we want to output a table lookup for
1357 + divides between small numbers (both num and den >= 0
1358 + and < 0x10). The overhead of this method in the worse
1359 + case is 40 bytes in the text section (10 insns) and
1360 + 256 bytes in the data section. Additional divides do
1361 + not incur additional penalties in the data section.
1363 + Code speed is improved for small divides by about 5x
1364 + when using this method in the worse case (~9 cycles
1365 + vs ~45). And in the worse case divides not within the
1366 + table are penalized by about 10% (~5 cycles vs ~45).
1367 + However in the typical case the penalty is not as bad
1368 + because doing the long divide in only 45 cycles is
1371 + ??? It would be nice to have some benchmarks other
1372 + than Dhrystone to back this up.
1374 + This bit of expansion is to create this instruction
1378 + cmpgeui $3, $8, 16
1381 + add $12, $11, divide_table
1387 +# continue here with result in $2
1389 + ??? Ideally I would like the emit libcall block to contain
1390 + all of this code, but I don't know how to do that. What it
1391 + means is that if the divide can be eliminated, it may not
1392 + completely disappear.
1394 + ??? The __divsi3_table label should ideally be moved out
1395 + of this block and into a global. If it is placed into the
1396 + sdata section we can save even more cycles by doing things
1400 +nios2_emit_expensive_div (rtx *operands, enum machine_mode mode)
1402 + rtx or_result, shift_left_result;
1410 + /* it may look a little generic, but only SImode
1411 + is supported for now */
1412 + if (mode != SImode)
1415 + libfunc = sdiv_optab->handlers[(int) SImode].libfunc;
1419 + lab1 = gen_label_rtx ();
1420 + lab3 = gen_label_rtx ();
1422 + or_result = expand_simple_binop (SImode, IOR,
1423 + operands[1], operands[2],
1424 + 0, 0, OPTAB_LIB_WIDEN);
1426 + emit_cmp_and_jump_insns (or_result, GEN_INT (15), GTU, 0,
1427 + GET_MODE (or_result), 0, lab3);
1428 + JUMP_LABEL (get_last_insn ()) = lab3;
1430 + shift_left_result = expand_simple_binop (SImode, ASHIFT,
1431 + operands[1], GEN_INT (4),
1432 + 0, 0, OPTAB_LIB_WIDEN);
1434 + lookup_value = expand_simple_binop (SImode, IOR,
1435 + shift_left_result, operands[2],
1436 + 0, 0, OPTAB_LIB_WIDEN);
1438 + convert_move (operands[0],
1439 + gen_rtx (MEM, QImode,
1440 + gen_rtx (PLUS, SImode,
1442 + gen_rtx_SYMBOL_REF (SImode, "__divsi3_table"))),
1446 + tmp = emit_jump_insn (gen_jump (lab1));
1447 + JUMP_LABEL (tmp) = lab1;
1450 + emit_label (lab3);
1451 + LABEL_NUSES (lab3) = 1;
1453 + start_sequence ();
1454 + final_result = emit_library_call_value (libfunc, NULL_RTX,
1455 + LCT_CONST, SImode, 2,
1456 + operands[1], SImode,
1457 + operands[2], SImode);
1460 + insns = get_insns ();
1462 + emit_libcall_block (insns, operands[0], final_result,
1463 + gen_rtx (DIV, SImode, operands[1], operands[2]));
1465 + emit_label (lab1);
1466 + LABEL_NUSES (lab1) = 1;
1470 +/* Branches/Compares */
1472 +/* the way of handling branches/compares
1473 + in gcc is heavily borrowed from MIPS */
1490 +static enum internal_test map_test_to_internal_test (enum rtx_code);
1492 +/* Cached operands, and operator to compare for use in set/branch/trap
1493 + on condition codes. */
1495 +enum cmp_type branch_type;
1497 +/* Make normal rtx_code into something we can index from an array */
1499 +static enum internal_test
1500 +map_test_to_internal_test (enum rtx_code test_code)
1502 + enum internal_test test = ITEST_MAX;
1504 + switch (test_code)
1543 +/* Generate the code to compare (and possibly branch) two integer values
1544 + TEST_CODE is the comparison code we are trying to emulate
1545 + (or implement directly)
1546 + RESULT is where to store the result of the comparison,
1547 + or null to emit a branch
1548 + CMP0 CMP1 are the two comparison operands
1549 + DESTINATION is the destination of the branch, or null to only compare
1553 +gen_int_relational (enum rtx_code test_code, /* relational test (EQ, etc) */
1554 + rtx result, /* result to store comp. or 0 if branch */
1555 + rtx cmp0, /* first operand to compare */
1556 + rtx cmp1, /* second operand to compare */
1557 + rtx destination) /* destination of the branch, or 0 if compare */
1561 + /* for register (or 0) compares */
1562 + enum rtx_code test_code_reg; /* code to use in instruction (LT vs. LTU) */
1563 + int reverse_regs; /* reverse registers in test */
1565 + /* for immediate compares */
1566 + enum rtx_code test_code_const;
1567 + /* code to use in instruction (LT vs. LTU) */
1568 + int const_low; /* low bound of constant we can accept */
1569 + int const_high; /* high bound of constant we can accept */
1570 + int const_add; /* constant to add */
1572 + /* generic info */
1573 + int unsignedp; /* != 0 for unsigned comparisons. */
1576 + static const struct cmp_info info[(int) ITEST_MAX] = {
1578 + {EQ, 0, EQ, -32768, 32767, 0, 0}, /* EQ */
1579 + {NE, 0, NE, -32768, 32767, 0, 0}, /* NE */
1581 + {LT, 1, GE, -32769, 32766, 1, 0}, /* GT */
1582 + {GE, 0, GE, -32768, 32767, 0, 0}, /* GE */
1583 + {LT, 0, LT, -32768, 32767, 0, 0}, /* LT */
1584 + {GE, 1, LT, -32769, 32766, 1, 0}, /* LE */
1586 + {LTU, 1, GEU, 0, 65534, 1, 0}, /* GTU */
1587 + {GEU, 0, GEU, 0, 65535, 0, 0}, /* GEU */
1588 + {LTU, 0, LTU, 0, 65535, 0, 0}, /* LTU */
1589 + {GEU, 1, LTU, 0, 65534, 1, 0}, /* LEU */
1592 + enum internal_test test;
1593 + enum machine_mode mode;
1594 + const struct cmp_info *p_info;
1600 + test = map_test_to_internal_test (test_code);
1601 + if (test == ITEST_MAX)
1604 + p_info = &info[(int) test];
1606 + mode = GET_MODE (cmp0);
1607 + if (mode == VOIDmode)
1608 + mode = GET_MODE (cmp1);
1610 + branch_p = (destination != 0);
1612 + /* We can't, under any circumstances, have const_ints in cmp0
1613 + ??? Actually we could have const0 */
1614 + if (GET_CODE (cmp0) == CONST_INT)
1615 + cmp0 = force_reg (mode, cmp0);
1617 + /* if the comparison is against an int not in legal range
1618 + move it into a register */
1619 + if (GET_CODE (cmp1) == CONST_INT)
1621 + HOST_WIDE_INT value = INTVAL (cmp1);
1623 + if (value < p_info->const_low || value > p_info->const_high)
1624 + cmp1 = force_reg (mode, cmp1);
1627 + /* Comparison to constants, may involve adding 1 to change a GT into GE.
1628 + Comparison between two registers, may involve switching operands. */
1629 + if (GET_CODE (cmp1) == CONST_INT)
1631 + if (p_info->const_add != 0)
1633 + HOST_WIDE_INT new = INTVAL (cmp1) + p_info->const_add;
1635 + /* If modification of cmp1 caused overflow,
1636 + we would get the wrong answer if we follow the usual path;
1637 + thus, x > 0xffffffffU would turn into x > 0U. */
1638 + if ((p_info->unsignedp
1639 + ? (unsigned HOST_WIDE_INT) new >
1640 + (unsigned HOST_WIDE_INT) INTVAL (cmp1)
1641 + : new > INTVAL (cmp1)) != (p_info->const_add > 0))
1643 + /* ??? This case can never happen with the current numbers,
1644 + but I am paranoid and would rather an abort than
1645 + a bug I will never find */
1649 + cmp1 = GEN_INT (new);
1653 + else if (p_info->reverse_regs)
1664 + if (register_operand (cmp0, mode) && register_operand (cmp1, mode))
1667 + rtx cond = gen_rtx (p_info->test_code_reg, mode, cmp0, cmp1);
1668 + rtx label = gen_rtx_LABEL_REF (VOIDmode, destination);
1670 + insn = gen_rtx_SET (VOIDmode, pc_rtx,
1671 + gen_rtx_IF_THEN_ELSE (VOIDmode,
1672 + cond, label, pc_rtx));
1673 + emit_jump_insn (insn);
1679 + result = gen_reg_rtx (mode);
1681 + emit_move_insn (result,
1682 + gen_rtx (p_info->test_code_const, mode, cmp0,
1685 + cond = gen_rtx (NE, mode, result, const0_rtx);
1686 + label = gen_rtx_LABEL_REF (VOIDmode, destination);
1688 + emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
1689 + gen_rtx_IF_THEN_ELSE (VOIDmode,
1696 + if (register_operand (cmp0, mode) && register_operand (cmp1, mode))
1698 + emit_move_insn (result,
1699 + gen_rtx (p_info->test_code_reg, mode, cmp0, cmp1));
1703 + emit_move_insn (result,
1704 + gen_rtx (p_info->test_code_const, mode, cmp0,
1712 +/* ??? For now conditional moves are only supported
1713 + when the mode of the operands being compared are
1714 + the same as the ones being moved */
1717 +gen_conditional_move (rtx *operands, enum machine_mode mode)
1720 + rtx cmp_reg = gen_reg_rtx (mode);
1721 + enum rtx_code cmp_code = GET_CODE (operands[1]);
1722 + enum rtx_code move_code = EQ;
1724 + /* emit a comparison if it is not "simple".
1725 + Simple comparisons are X eq 0 and X ne 0 */
1726 + if ((cmp_code == EQ || cmp_code == NE) && branch_cmp[1] == const0_rtx)
1728 + cmp_reg = branch_cmp[0];
1729 + move_code = cmp_code;
1731 + else if ((cmp_code == EQ || cmp_code == NE) && branch_cmp[0] == const0_rtx)
1733 + cmp_reg = branch_cmp[1];
1734 + move_code = cmp_code == EQ ? NE : EQ;
1737 + gen_int_relational (cmp_code, cmp_reg, branch_cmp[0], branch_cmp[1],
1740 + cond = gen_rtx (move_code, VOIDmode, cmp_reg, CONST0_RTX (mode));
1741 + insn = gen_rtx_SET (mode, operands[0],
1742 + gen_rtx_IF_THEN_ELSE (mode,
1743 + cond, operands[2], operands[3]));
1747 +/*******************
1748 + * Addressing Modes
1749 + *******************/
1752 +nios2_legitimate_address (rtx operand, enum machine_mode mode ATTRIBUTE_UNUSED,
1757 + switch (GET_CODE (operand))
1761 + if (SYMBOL_REF_IN_NIOS2_SMALL_DATA_P (operand))
1766 + /* else, fall through */
1770 + case CONST_DOUBLE:
1771 + /* ??? In here I need to add gp addressing */
1776 + /* Register indirect. */
1778 + ret_val = REG_OK_FOR_BASE_P2 (operand, strict);
1781 + /* Register indirect with displacement */
1784 + rtx op0 = XEXP (operand, 0);
1785 + rtx op1 = XEXP (operand, 1);
1787 + if (REG_P (op0) && REG_P (op1))
1789 + else if (REG_P (op0) && CONSTANT_P (op1))
1790 + ret_val = REG_OK_FOR_BASE_P2 (op0, strict)
1791 + && SMALL_INT (INTVAL (op1));
1792 + else if (REG_P (op1) && CONSTANT_P (op0))
1793 + ret_val = REG_OK_FOR_BASE_P2 (op1, strict)
1794 + && SMALL_INT (INTVAL (op0));
1808 +/* Return true if EXP should be placed in the small data section. */
1811 +nios2_in_small_data_p (tree exp)
1813 + /* We want to merge strings, so we never consider them small data. */
1814 + if (TREE_CODE (exp) == STRING_CST)
1817 + if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
1819 + const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
1820 + /* ??? these string names need moving into
1821 + an array in some header file */
1822 + if (nios2_section_threshold > 0
1823 + && (strcmp (section, ".sbss") == 0
1824 + || strncmp (section, ".sbss.", 6) == 0
1825 + || strcmp (section, ".sdata") == 0
1826 + || strncmp (section, ".sdata.", 7) == 0))
1829 + else if (TREE_CODE (exp) == VAR_DECL)
1831 + HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
1833 + /* If this is an incomplete type with size 0, then we can't put it
1834 + in sdata because it might be too big when completed. */
1835 + if (size > 0 && size <= nios2_section_threshold)
1843 +nios2_encode_section_info (tree decl, rtx rtl, int first)
1849 + default_encode_section_info (decl, rtl, first);
1851 + /* Careful not to prod global register variables. */
1852 + if (GET_CODE (rtl) != MEM)
1854 + symbol = XEXP (rtl, 0);
1855 + if (GET_CODE (symbol) != SYMBOL_REF)
1858 + flags = SYMBOL_REF_FLAGS (symbol);
1860 + /* We don't want weak variables to be addressed with gp in case they end up with
1861 + value 0 which is not within 2^15 of $gp */
1862 + if (DECL_P (decl) && DECL_WEAK (decl))
1863 + flags |= SYMBOL_FLAG_WEAK_DECL;
1865 + SYMBOL_REF_FLAGS (symbol) = flags;
1869 +static unsigned int
1870 +nios2_section_type_flags (tree decl, const char *name, int reloc)
1872 + unsigned int flags;
1874 + flags = default_section_type_flags (decl, name, reloc);
1876 + /* ??? these string names need moving into an array in some header file */
1877 + if (strcmp (name, ".sbss") == 0
1878 + || strncmp (name, ".sbss.", 6) == 0
1879 + || strcmp (name, ".sdata") == 0
1880 + || strncmp (name, ".sdata.", 7) == 0)
1881 + flags |= SECTION_SMALL;
1889 +/*****************************************
1890 + * Defining the Output Assembler Language
1891 + *****************************************/
1893 +/* -------------- *
1895 + * -------------- */
1898 +/* -------------------------------- *
1899 + * Output of Assembler Instructions
1900 + * -------------------------------- */
1903 +/* print the operand OP to file stream
1904 + FILE modified by LETTER. LETTER
1906 + i: print "i" if OP is an immediate, except 0
1907 + o: print "io" if OP is volatile
1909 + z: for const0_rtx print $0 instead of 0
1912 + U: for upper half of 32 bit value
1916 +nios2_print_operand (FILE *file, rtx op, int letter)
1922 + if (CONSTANT_P (op) && (op != const0_rtx))
1923 + fprintf (file, "i");
1927 + if (GET_CODE (op) == MEM
1928 + && ((MEM_VOLATILE_P (op) && !TARGET_CACHE_VOLATILE)
1929 + || TARGET_BYPASS_CACHE))
1930 + fprintf (file, "io");
1937 + if (comparison_operator (op, VOIDmode))
1941 + fprintf (file, "%s", GET_RTX_NAME (GET_CODE (op)));
1947 + switch (GET_CODE (op))
1950 + if (letter == 0 || letter == 'z')
1952 + fprintf (file, "%s", reg_names[REGNO (op)]);
1957 + if (INTVAL (op) == 0 && letter == 'z')
1959 + fprintf (file, "zero");
1962 + else if (letter == 'U')
1964 + HOST_WIDE_INT val = INTVAL (op);
1966 + val = (val / 65536) & 0xFFFF;
1967 + new_op = GEN_INT (val);
1968 + output_addr_const (file, new_op);
1972 + /* else, fall through */
1976 + case CONST_DOUBLE:
1977 + if (letter == 0 || letter == 'z')
1979 + output_addr_const (file, op);
1982 + else if (letter == 'H')
1984 + fprintf (file, "%%hiadj(");
1985 + output_addr_const (file, op);
1986 + fprintf (file, ")");
1989 + else if (letter == 'L')
1991 + fprintf (file, "%%lo(");
1992 + output_addr_const (file, op);
1993 + fprintf (file, ")");
2002 + output_address (op);
2009 + output_addr_const (file, op);
2017 + fprintf (stderr, "Missing way to print (%c) ", letter);
2022 +static int gprel_constant (rtx);
2025 +gprel_constant (rtx op)
2027 + if (GET_CODE (op) == SYMBOL_REF
2028 + && SYMBOL_REF_IN_NIOS2_SMALL_DATA_P (op))
2032 + else if (GET_CODE (op) == CONST
2033 + && GET_CODE (XEXP (op, 0)) == PLUS)
2035 + return gprel_constant (XEXP (XEXP (op, 0), 0));
2044 +nios2_print_operand_address (FILE *file, rtx op)
2046 + switch (GET_CODE (op))
2051 + case CONST_DOUBLE:
2053 + if (gprel_constant (op))
2055 + fprintf (file, "%%gprel(");
2056 + output_addr_const (file, op);
2057 + fprintf (file, ")(%s)", reg_names[GP_REGNO]);
2065 + rtx op0 = XEXP (op, 0);
2066 + rtx op1 = XEXP (op, 1);
2068 + if (REG_P (op0) && CONSTANT_P (op1))
2070 + output_addr_const (file, op1);
2071 + fprintf (file, "(%s)", reg_names[REGNO (op0)]);
2074 + else if (REG_P (op1) && CONSTANT_P (op0))
2076 + output_addr_const (file, op0);
2077 + fprintf (file, "(%s)", reg_names[REGNO (op1)]);
2084 + fprintf (file, "0(%s)", reg_names[REGNO (op)]);
2089 + rtx base = XEXP (op, 0);
2090 + PRINT_OPERAND_ADDRESS (file, base);
2097 + fprintf (stderr, "Missing way to print address\n");
2106 +/****************************
2108 + ****************************/
2111 +arith_operand (rtx op, enum machine_mode mode)
2113 + if (GET_CODE (op) == CONST_INT && SMALL_INT (INTVAL (op)))
2116 + return register_operand (op, mode);
2120 +uns_arith_operand (rtx op, enum machine_mode mode)
2122 + if (GET_CODE (op) == CONST_INT && SMALL_INT_UNSIGNED (INTVAL (op)))
2125 + return register_operand (op, mode);
2129 +logical_operand (rtx op, enum machine_mode mode)
2131 + if (GET_CODE (op) == CONST_INT
2132 + && (SMALL_INT_UNSIGNED (INTVAL (op)) || UPPER16_INT (INTVAL (op))))
2135 + return register_operand (op, mode);
2139 +shift_operand (rtx op, enum machine_mode mode)
2141 + if (GET_CODE (op) == CONST_INT && SHIFT_INT (INTVAL (op)))
2144 + return register_operand (op, mode);
2148 +rdwrctl_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
2150 + return GET_CODE (op) == CONST_INT && RDWRCTL_INT (INTVAL (op));
2153 +/* Return truth value of whether OP is a register or the constant 0. */
2156 +reg_or_0_operand (rtx op, enum machine_mode mode)
2158 + switch (GET_CODE (op))
2161 + return INTVAL (op) == 0;
2163 + case CONST_DOUBLE:
2164 + return op == CONST0_RTX (mode);
2170 + return register_operand (op, mode);
2175 +equality_op (rtx op, enum machine_mode mode)
2177 + if (mode != GET_MODE (op))
2180 + return GET_CODE (op) == EQ || GET_CODE (op) == NE;
2184 +custom_insn_opcode (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
2186 + return GET_CODE (op) == CONST_INT && CUSTOM_INSN_OPCODE (INTVAL (op));
2195 +/*****************************************************************************
2197 +** instruction scheduler
2199 +*****************************************************************************/
2201 +nios2_use_dfa_pipeline_interface ()
2208 +nios2_issue_rate ()
2210 +#ifdef MAX_DFA_ISSUE_RATE
2211 + return MAX_DFA_ISSUE_RATE;
2219 +asm_output_opcode (FILE *file ATTRIBUTE_UNUSED,
2220 + const char *ptr ATTRIBUTE_UNUSED)
2230 +/*****************************************************************************
2232 +** function arguments
2234 +*****************************************************************************/
2237 +init_cumulative_args (CUMULATIVE_ARGS *cum,
2238 + tree fntype ATTRIBUTE_UNUSED,
2239 + rtx libname ATTRIBUTE_UNUSED,
2240 + tree fndecl ATTRIBUTE_UNUSED,
2241 + int n_named_args ATTRIBUTE_UNUSED)
2243 + cum->regs_used = 0;
2247 +/* Update the data in CUM to advance over an argument
2248 + of mode MODE and data type TYPE.
2249 + (TYPE is null for libcalls where that information may not be available.) */
2252 +function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
2253 + tree type ATTRIBUTE_UNUSED, int named ATTRIBUTE_UNUSED)
2255 + HOST_WIDE_INT param_size;
2257 + if (mode == BLKmode)
2259 + param_size = int_size_in_bytes (type);
2260 + if (param_size < 0)
2262 + ("Do not know how to handle large structs or variable length types");
2266 + param_size = GET_MODE_SIZE (mode);
2269 + /* convert to words (round up) */
2270 + param_size = (3 + param_size) / 4;
2272 + if (cum->regs_used + param_size > NUM_ARG_REGS)
2274 + cum->regs_used = NUM_ARG_REGS;
2278 + cum->regs_used += param_size;
2284 +/* Define where to put the arguments to a function. Value is zero to
2285 + push the argument on the stack, or a hard register in which to
2286 + store the argument.
2288 + MODE is the argument's machine mode.
2289 + TYPE is the data type of the argument (as a tree).
2290 + This is null for libcalls where that information may
2292 + CUM is a variable of type CUMULATIVE_ARGS which gives info about
2293 + the preceding args and about the function being called.
2294 + NAMED is nonzero if this argument is a named parameter
2295 + (otherwise it is an extra parameter matching an ellipsis). */
2297 +function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
2298 + tree type ATTRIBUTE_UNUSED, int named ATTRIBUTE_UNUSED)
2300 + rtx return_rtx = NULL_RTX;
2302 + if (cum->regs_used < NUM_ARG_REGS)
2304 + return_rtx = gen_rtx_REG (mode, FIRST_ARG_REGNO + cum->regs_used);
2307 + return return_rtx;
2311 +function_arg_partial_nregs (const CUMULATIVE_ARGS *cum,
2312 + enum machine_mode mode, tree type,
2313 + int named ATTRIBUTE_UNUSED)
2315 + HOST_WIDE_INT param_size;
2317 + if (mode == BLKmode)
2319 + param_size = int_size_in_bytes (type);
2320 + if (param_size < 0)
2322 + ("Do not know how to handle large structs or variable length types");
2326 + param_size = GET_MODE_SIZE (mode);
2329 + /* convert to words (round up) */
2330 + param_size = (3 + param_size) / 4;
2332 + if (cum->regs_used < NUM_ARG_REGS
2333 + && cum->regs_used + param_size > NUM_ARG_REGS)
2335 + return NUM_ARG_REGS - cum->regs_used;
2345 +nios2_return_in_memory (tree type)
2347 + int res = ((int_size_in_bytes (type) > (2 * UNITS_PER_WORD))
2348 + || (int_size_in_bytes (type) == -1));
2353 +/* ??? It may be possible to eliminate the copyback and implement
2354 + my own va_arg type, but that is more work for now. */
2356 +nios2_setup_incoming_varargs (const CUMULATIVE_ARGS *cum,
2357 + enum machine_mode mode, tree type,
2360 + CUMULATIVE_ARGS local_cum;
2364 + FUNCTION_ARG_ADVANCE (local_cum, mode, type, 1);
2366 + regs_to_push = NUM_ARG_REGS - local_cum.regs_used;
2370 + if (regs_to_push > 0)
2374 + ptr = virtual_incoming_args_rtx;
2375 + mem = gen_rtx_MEM (BLKmode, ptr);
2377 + /* va_arg is an array access in this case, which causes
2378 + it to get MEM_IN_STRUCT_P set. We must set it here
2379 + so that the insn scheduler won't assume that these
2380 + stores can't possibly overlap with the va_arg loads. */
2381 + MEM_SET_IN_STRUCT_P (mem, 1);
2383 + emit_insn (gen_blockage ());
2384 + move_block_from_reg (local_cum.regs_used + FIRST_ARG_REGNO, mem,
2386 + emit_insn (gen_blockage ());
2390 + return regs_to_push * UNITS_PER_WORD;
2396 +/*****************************************************************************
2400 +** This method for handling builtins is from CSP where _many_ more types of
2401 +** expanders have already been written. Check there first before writing
2404 +*****************************************************************************/
2406 +enum nios2_builtins
2408 + NIOS2_BUILTIN_LDBIO,
2409 + NIOS2_BUILTIN_LDBUIO,
2410 + NIOS2_BUILTIN_LDHIO,
2411 + NIOS2_BUILTIN_LDHUIO,
2412 + NIOS2_BUILTIN_LDWIO,
2413 + NIOS2_BUILTIN_STBIO,
2414 + NIOS2_BUILTIN_STHIO,
2415 + NIOS2_BUILTIN_STWIO,
2416 + NIOS2_BUILTIN_SYNC,
2417 + NIOS2_BUILTIN_RDCTL,
2418 + NIOS2_BUILTIN_WRCTL,
2420 + NIOS2_BUILTIN_CUSTOM_N,
2421 + NIOS2_BUILTIN_CUSTOM_NI,
2422 + NIOS2_BUILTIN_CUSTOM_NF,
2423 + NIOS2_BUILTIN_CUSTOM_NP,
2424 + NIOS2_BUILTIN_CUSTOM_NII,
2425 + NIOS2_BUILTIN_CUSTOM_NIF,
2426 + NIOS2_BUILTIN_CUSTOM_NIP,
2427 + NIOS2_BUILTIN_CUSTOM_NFI,
2428 + NIOS2_BUILTIN_CUSTOM_NFF,
2429 + NIOS2_BUILTIN_CUSTOM_NFP,
2430 + NIOS2_BUILTIN_CUSTOM_NPI,
2431 + NIOS2_BUILTIN_CUSTOM_NPF,
2432 + NIOS2_BUILTIN_CUSTOM_NPP,
2433 + NIOS2_BUILTIN_CUSTOM_IN,
2434 + NIOS2_BUILTIN_CUSTOM_INI,
2435 + NIOS2_BUILTIN_CUSTOM_INF,
2436 + NIOS2_BUILTIN_CUSTOM_INP,
2437 + NIOS2_BUILTIN_CUSTOM_INII,
2438 + NIOS2_BUILTIN_CUSTOM_INIF,
2439 + NIOS2_BUILTIN_CUSTOM_INIP,
2440 + NIOS2_BUILTIN_CUSTOM_INFI,
2441 + NIOS2_BUILTIN_CUSTOM_INFF,
2442 + NIOS2_BUILTIN_CUSTOM_INFP,
2443 + NIOS2_BUILTIN_CUSTOM_INPI,
2444 + NIOS2_BUILTIN_CUSTOM_INPF,
2445 + NIOS2_BUILTIN_CUSTOM_INPP,
2446 + NIOS2_BUILTIN_CUSTOM_FN,
2447 + NIOS2_BUILTIN_CUSTOM_FNI,
2448 + NIOS2_BUILTIN_CUSTOM_FNF,
2449 + NIOS2_BUILTIN_CUSTOM_FNP,
2450 + NIOS2_BUILTIN_CUSTOM_FNII,
2451 + NIOS2_BUILTIN_CUSTOM_FNIF,
2452 + NIOS2_BUILTIN_CUSTOM_FNIP,
2453 + NIOS2_BUILTIN_CUSTOM_FNFI,
2454 + NIOS2_BUILTIN_CUSTOM_FNFF,
2455 + NIOS2_BUILTIN_CUSTOM_FNFP,
2456 + NIOS2_BUILTIN_CUSTOM_FNPI,
2457 + NIOS2_BUILTIN_CUSTOM_FNPF,
2458 + NIOS2_BUILTIN_CUSTOM_FNPP,
2459 + NIOS2_BUILTIN_CUSTOM_PN,
2460 + NIOS2_BUILTIN_CUSTOM_PNI,
2461 + NIOS2_BUILTIN_CUSTOM_PNF,
2462 + NIOS2_BUILTIN_CUSTOM_PNP,
2463 + NIOS2_BUILTIN_CUSTOM_PNII,
2464 + NIOS2_BUILTIN_CUSTOM_PNIF,
2465 + NIOS2_BUILTIN_CUSTOM_PNIP,
2466 + NIOS2_BUILTIN_CUSTOM_PNFI,
2467 + NIOS2_BUILTIN_CUSTOM_PNFF,
2468 + NIOS2_BUILTIN_CUSTOM_PNFP,
2469 + NIOS2_BUILTIN_CUSTOM_PNPI,
2470 + NIOS2_BUILTIN_CUSTOM_PNPF,
2471 + NIOS2_BUILTIN_CUSTOM_PNPP,
2474 + LIM_NIOS2_BUILTINS
2477 +struct builtin_description
2479 + const enum insn_code icode;
2480 + const char *const name;
2481 + const enum nios2_builtins code;
2483 + rtx (* expander) PARAMS ((const struct builtin_description *,
2484 + tree, rtx, rtx, enum machine_mode, int));
2487 +static rtx nios2_expand_STXIO (const struct builtin_description *,
2488 + tree, rtx, rtx, enum machine_mode, int);
2489 +static rtx nios2_expand_LDXIO (const struct builtin_description *,
2490 + tree, rtx, rtx, enum machine_mode, int);
2491 +static rtx nios2_expand_sync (const struct builtin_description *,
2492 + tree, rtx, rtx, enum machine_mode, int);
2493 +static rtx nios2_expand_rdctl (const struct builtin_description *,
2494 + tree, rtx, rtx, enum machine_mode, int);
2495 +static rtx nios2_expand_wrctl (const struct builtin_description *,
2496 + tree, rtx, rtx, enum machine_mode, int);
2498 +static rtx nios2_expand_custom_n (const struct builtin_description *,
2499 + tree, rtx, rtx, enum machine_mode, int);
2500 +static rtx nios2_expand_custom_Xn (const struct builtin_description *,
2501 + tree, rtx, rtx, enum machine_mode, int);
2502 +static rtx nios2_expand_custom_nX (const struct builtin_description *,
2503 + tree, rtx, rtx, enum machine_mode, int);
2504 +static rtx nios2_expand_custom_XnX (const struct builtin_description *,
2505 + tree, rtx, rtx, enum machine_mode, int);
2506 +static rtx nios2_expand_custom_nXX (const struct builtin_description *,
2507 + tree, rtx, rtx, enum machine_mode, int);
2508 +static rtx nios2_expand_custom_XnXX (const struct builtin_description *,
2509 + tree, rtx, rtx, enum machine_mode, int);
2511 +static tree endlink;
2513 +/* int fn (volatile const void *)
2515 +static tree int_ftype_volatile_const_void_p;
2519 +static tree int_ftype_int;
2521 +/* void fn (int, int)
2523 +static tree void_ftype_int_int;
2525 +/* void fn (volatile void *, int)
2527 +static tree void_ftype_volatile_void_p_int;
2531 +static tree void_ftype_void;
2533 +static tree custom_n;
2534 +static tree custom_ni;
2535 +static tree custom_nf;
2536 +static tree custom_np;
2537 +static tree custom_nii;
2538 +static tree custom_nif;
2539 +static tree custom_nip;
2540 +static tree custom_nfi;
2541 +static tree custom_nff;
2542 +static tree custom_nfp;
2543 +static tree custom_npi;
2544 +static tree custom_npf;
2545 +static tree custom_npp;
2546 +static tree custom_in;
2547 +static tree custom_ini;
2548 +static tree custom_inf;
2549 +static tree custom_inp;
2550 +static tree custom_inii;
2551 +static tree custom_inif;
2552 +static tree custom_inip;
2553 +static tree custom_infi;
2554 +static tree custom_inff;
2555 +static tree custom_infp;
2556 +static tree custom_inpi;
2557 +static tree custom_inpf;
2558 +static tree custom_inpp;
2559 +static tree custom_fn;
2560 +static tree custom_fni;
2561 +static tree custom_fnf;
2562 +static tree custom_fnp;
2563 +static tree custom_fnii;
2564 +static tree custom_fnif;
2565 +static tree custom_fnip;
2566 +static tree custom_fnfi;
2567 +static tree custom_fnff;
2568 +static tree custom_fnfp;
2569 +static tree custom_fnpi;
2570 +static tree custom_fnpf;
2571 +static tree custom_fnpp;
2572 +static tree custom_pn;
2573 +static tree custom_pni;
2574 +static tree custom_pnf;
2575 +static tree custom_pnp;
2576 +static tree custom_pnii;
2577 +static tree custom_pnif;
2578 +static tree custom_pnip;
2579 +static tree custom_pnfi;
2580 +static tree custom_pnff;
2581 +static tree custom_pnfp;
2582 +static tree custom_pnpi;
2583 +static tree custom_pnpf;
2584 +static tree custom_pnpp;
2587 +static const struct builtin_description bdesc[] = {
2588 + {CODE_FOR_ldbio, "__builtin_ldbio", NIOS2_BUILTIN_LDBIO, &int_ftype_volatile_const_void_p, nios2_expand_LDXIO},
2589 + {CODE_FOR_ldbuio, "__builtin_ldbuio", NIOS2_BUILTIN_LDBUIO, &int_ftype_volatile_const_void_p, nios2_expand_LDXIO},
2590 + {CODE_FOR_ldhio, "__builtin_ldhio", NIOS2_BUILTIN_LDHIO, &int_ftype_volatile_const_void_p, nios2_expand_LDXIO},
2591 + {CODE_FOR_ldhuio, "__builtin_ldhuio", NIOS2_BUILTIN_LDHUIO, &int_ftype_volatile_const_void_p, nios2_expand_LDXIO},
2592 + {CODE_FOR_ldwio, "__builtin_ldwio", NIOS2_BUILTIN_LDWIO, &int_ftype_volatile_const_void_p, nios2_expand_LDXIO},
2594 + {CODE_FOR_stbio, "__builtin_stbio", NIOS2_BUILTIN_STBIO, &void_ftype_volatile_void_p_int, nios2_expand_STXIO},
2595 + {CODE_FOR_sthio, "__builtin_sthio", NIOS2_BUILTIN_STHIO, &void_ftype_volatile_void_p_int, nios2_expand_STXIO},
2596 + {CODE_FOR_stwio, "__builtin_stwio", NIOS2_BUILTIN_STWIO, &void_ftype_volatile_void_p_int, nios2_expand_STXIO},
2598 + {CODE_FOR_sync, "__builtin_sync", NIOS2_BUILTIN_SYNC, &void_ftype_void, nios2_expand_sync},
2599 + {CODE_FOR_rdctl, "__builtin_rdctl", NIOS2_BUILTIN_RDCTL, &int_ftype_int, nios2_expand_rdctl},
2600 + {CODE_FOR_wrctl, "__builtin_wrctl", NIOS2_BUILTIN_WRCTL, &void_ftype_int_int, nios2_expand_wrctl},
2602 + {CODE_FOR_custom_n, "__builtin_custom_n", NIOS2_BUILTIN_CUSTOM_N, &custom_n, nios2_expand_custom_n},
2603 + {CODE_FOR_custom_ni, "__builtin_custom_ni", NIOS2_BUILTIN_CUSTOM_NI, &custom_ni, nios2_expand_custom_nX},
2604 + {CODE_FOR_custom_nf, "__builtin_custom_nf", NIOS2_BUILTIN_CUSTOM_NF, &custom_nf, nios2_expand_custom_nX},
2605 + {CODE_FOR_custom_np, "__builtin_custom_np", NIOS2_BUILTIN_CUSTOM_NP, &custom_np, nios2_expand_custom_nX},
2606 + {CODE_FOR_custom_nii, "__builtin_custom_nii", NIOS2_BUILTIN_CUSTOM_NII, &custom_nii, nios2_expand_custom_nXX},
2607 + {CODE_FOR_custom_nif, "__builtin_custom_nif", NIOS2_BUILTIN_CUSTOM_NIF, &custom_nif, nios2_expand_custom_nXX},
2608 + {CODE_FOR_custom_nip, "__builtin_custom_nip", NIOS2_BUILTIN_CUSTOM_NIP, &custom_nip, nios2_expand_custom_nXX},
2609 + {CODE_FOR_custom_nfi, "__builtin_custom_nfi", NIOS2_BUILTIN_CUSTOM_NFI, &custom_nfi, nios2_expand_custom_nXX},
2610 + {CODE_FOR_custom_nff, "__builtin_custom_nff", NIOS2_BUILTIN_CUSTOM_NFF, &custom_nff, nios2_expand_custom_nXX},
2611 + {CODE_FOR_custom_nfp, "__builtin_custom_nfp", NIOS2_BUILTIN_CUSTOM_NFP, &custom_nfp, nios2_expand_custom_nXX},
2612 + {CODE_FOR_custom_npi, "__builtin_custom_npi", NIOS2_BUILTIN_CUSTOM_NPI, &custom_npi, nios2_expand_custom_nXX},
2613 + {CODE_FOR_custom_npf, "__builtin_custom_npf", NIOS2_BUILTIN_CUSTOM_NPF, &custom_npf, nios2_expand_custom_nXX},
2614 + {CODE_FOR_custom_npp, "__builtin_custom_npp", NIOS2_BUILTIN_CUSTOM_NPP, &custom_npp, nios2_expand_custom_nXX},
2615 + {CODE_FOR_custom_in, "__builtin_custom_in", NIOS2_BUILTIN_CUSTOM_IN, &custom_in, nios2_expand_custom_Xn},
2616 + {CODE_FOR_custom_ini, "__builtin_custom_ini", NIOS2_BUILTIN_CUSTOM_INI, &custom_ini, nios2_expand_custom_XnX},
2617 + {CODE_FOR_custom_inf, "__builtin_custom_inf", NIOS2_BUILTIN_CUSTOM_INF, &custom_inf, nios2_expand_custom_XnX},
2618 + {CODE_FOR_custom_inp, "__builtin_custom_inp", NIOS2_BUILTIN_CUSTOM_INP, &custom_inp, nios2_expand_custom_XnX},
2619 + {CODE_FOR_custom_inii, "__builtin_custom_inii", NIOS2_BUILTIN_CUSTOM_INII, &custom_inii, nios2_expand_custom_XnXX},
2620 + {CODE_FOR_custom_inif, "__builtin_custom_inif", NIOS2_BUILTIN_CUSTOM_INIF, &custom_inif, nios2_expand_custom_XnXX},
2621 + {CODE_FOR_custom_inip, "__builtin_custom_inip", NIOS2_BUILTIN_CUSTOM_INIP, &custom_inip, nios2_expand_custom_XnXX},
2622 + {CODE_FOR_custom_infi, "__builtin_custom_infi", NIOS2_BUILTIN_CUSTOM_INFI, &custom_infi, nios2_expand_custom_XnXX},
2623 + {CODE_FOR_custom_inff, "__builtin_custom_inff", NIOS2_BUILTIN_CUSTOM_INFF, &custom_inff, nios2_expand_custom_XnXX},
2624 + {CODE_FOR_custom_infp, "__builtin_custom_infp", NIOS2_BUILTIN_CUSTOM_INFP, &custom_infp, nios2_expand_custom_XnXX},
2625 + {CODE_FOR_custom_inpi, "__builtin_custom_inpi", NIOS2_BUILTIN_CUSTOM_INPI, &custom_inpi, nios2_expand_custom_XnXX},
2626 + {CODE_FOR_custom_inpf, "__builtin_custom_inpf", NIOS2_BUILTIN_CUSTOM_INPF, &custom_inpf, nios2_expand_custom_XnXX},
2627 + {CODE_FOR_custom_inpp, "__builtin_custom_inpp", NIOS2_BUILTIN_CUSTOM_INPP, &custom_inpp, nios2_expand_custom_XnXX},
2628 + {CODE_FOR_custom_fn, "__builtin_custom_fn", NIOS2_BUILTIN_CUSTOM_FN, &custom_fn, nios2_expand_custom_Xn},
2629 + {CODE_FOR_custom_fni, "__builtin_custom_fni", NIOS2_BUILTIN_CUSTOM_FNI, &custom_fni, nios2_expand_custom_XnX},
2630 + {CODE_FOR_custom_fnf, "__builtin_custom_fnf", NIOS2_BUILTIN_CUSTOM_FNF, &custom_fnf, nios2_expand_custom_XnX},
2631 + {CODE_FOR_custom_fnp, "__builtin_custom_fnp", NIOS2_BUILTIN_CUSTOM_FNP, &custom_fnp, nios2_expand_custom_XnX},
2632 + {CODE_FOR_custom_fnii, "__builtin_custom_fnii", NIOS2_BUILTIN_CUSTOM_FNII, &custom_fnii, nios2_expand_custom_XnXX},
2633 + {CODE_FOR_custom_fnif, "__builtin_custom_fnif", NIOS2_BUILTIN_CUSTOM_FNIF, &custom_fnif, nios2_expand_custom_XnXX},
2634 + {CODE_FOR_custom_fnip, "__builtin_custom_fnip", NIOS2_BUILTIN_CUSTOM_FNIP, &custom_fnip, nios2_expand_custom_XnXX},
2635 + {CODE_FOR_custom_fnfi, "__builtin_custom_fnfi", NIOS2_BUILTIN_CUSTOM_FNFI, &custom_fnfi, nios2_expand_custom_XnXX},
2636 + {CODE_FOR_custom_fnff, "__builtin_custom_fnff", NIOS2_BUILTIN_CUSTOM_FNFF, &custom_fnff, nios2_expand_custom_XnXX},
2637 + {CODE_FOR_custom_fnfp, "__builtin_custom_fnfp", NIOS2_BUILTIN_CUSTOM_FNFP, &custom_fnfp, nios2_expand_custom_XnXX},
2638 + {CODE_FOR_custom_fnpi, "__builtin_custom_fnpi", NIOS2_BUILTIN_CUSTOM_FNPI, &custom_fnpi, nios2_expand_custom_XnXX},
2639 + {CODE_FOR_custom_fnpf, "__builtin_custom_fnpf", NIOS2_BUILTIN_CUSTOM_FNPF, &custom_fnpf, nios2_expand_custom_XnXX},
2640 + {CODE_FOR_custom_fnpp, "__builtin_custom_fnpp", NIOS2_BUILTIN_CUSTOM_FNPP, &custom_fnpp, nios2_expand_custom_XnXX},
2641 + {CODE_FOR_custom_pn, "__builtin_custom_pn", NIOS2_BUILTIN_CUSTOM_PN, &custom_pn, nios2_expand_custom_Xn},
2642 + {CODE_FOR_custom_pni, "__builtin_custom_pni", NIOS2_BUILTIN_CUSTOM_PNI, &custom_pni, nios2_expand_custom_XnX},
2643 + {CODE_FOR_custom_pnf, "__builtin_custom_pnf", NIOS2_BUILTIN_CUSTOM_PNF, &custom_pnf, nios2_expand_custom_XnX},
2644 + {CODE_FOR_custom_pnp, "__builtin_custom_pnp", NIOS2_BUILTIN_CUSTOM_PNP, &custom_pnp, nios2_expand_custom_XnX},
2645 + {CODE_FOR_custom_pnii, "__builtin_custom_pnii", NIOS2_BUILTIN_CUSTOM_PNII, &custom_pnii, nios2_expand_custom_XnXX},
2646 + {CODE_FOR_custom_pnif, "__builtin_custom_pnif", NIOS2_BUILTIN_CUSTOM_PNIF, &custom_pnif, nios2_expand_custom_XnXX},
2647 + {CODE_FOR_custom_pnip, "__builtin_custom_pnip", NIOS2_BUILTIN_CUSTOM_PNIP, &custom_pnip, nios2_expand_custom_XnXX},
2648 + {CODE_FOR_custom_pnfi, "__builtin_custom_pnfi", NIOS2_BUILTIN_CUSTOM_PNFI, &custom_pnfi, nios2_expand_custom_XnXX},
2649 + {CODE_FOR_custom_pnff, "__builtin_custom_pnff", NIOS2_BUILTIN_CUSTOM_PNFF, &custom_pnff, nios2_expand_custom_XnXX},
2650 + {CODE_FOR_custom_pnfp, "__builtin_custom_pnfp", NIOS2_BUILTIN_CUSTOM_PNFP, &custom_pnfp, nios2_expand_custom_XnXX},
2651 + {CODE_FOR_custom_pnpi, "__builtin_custom_pnpi", NIOS2_BUILTIN_CUSTOM_PNPI, &custom_pnpi, nios2_expand_custom_XnXX},
2652 + {CODE_FOR_custom_pnpf, "__builtin_custom_pnpf", NIOS2_BUILTIN_CUSTOM_PNPF, &custom_pnpf, nios2_expand_custom_XnXX},
2653 + {CODE_FOR_custom_pnpp, "__builtin_custom_pnpp", NIOS2_BUILTIN_CUSTOM_PNPP, &custom_pnpp, nios2_expand_custom_XnXX},
2659 +/* This does not have a closing bracket on purpose (see use) */
2660 +#define def_param(TYPE) \
2661 + tree_cons (NULL_TREE, TYPE,
2664 +nios2_init_builtins ()
2666 + const struct builtin_description *d;
2669 + endlink = void_list_node;
2671 + /* Special indenting here because one of the brackets is in def_param */
2672 + /* *INDENT-OFF* */
2674 + /* int fn (volatile const void *)
2676 + int_ftype_volatile_const_void_p
2677 + = build_function_type (integer_type_node,
2678 + def_param (build_qualified_type (ptr_type_node,
2679 + TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE))
2683 + /* void fn (volatile void *, int)
2685 + void_ftype_volatile_void_p_int
2686 + = build_function_type (void_type_node,
2687 + def_param (build_qualified_type (ptr_type_node,
2688 + TYPE_QUAL_VOLATILE))
2689 + def_param (integer_type_node)
2695 + = build_function_type (void_type_node,
2701 + = build_function_type (integer_type_node,
2702 + def_param (integer_type_node)
2705 + /* void fn (int, int)
2707 + void_ftype_int_int
2708 + = build_function_type (void_type_node,
2709 + def_param (integer_type_node)
2710 + def_param (integer_type_node)
2714 +#define CUSTOM_NUM def_param (integer_type_node)
2717 + = build_function_type (void_type_node,
2721 + = build_function_type (void_type_node,
2723 + def_param (integer_type_node)
2726 + = build_function_type (void_type_node,
2728 + def_param (float_type_node)
2731 + = build_function_type (void_type_node,
2733 + def_param (ptr_type_node)
2736 + = build_function_type (void_type_node,
2738 + def_param (integer_type_node)
2739 + def_param (integer_type_node)
2742 + = build_function_type (void_type_node,
2744 + def_param (integer_type_node)
2745 + def_param (float_type_node)
2748 + = build_function_type (void_type_node,
2750 + def_param (integer_type_node)
2751 + def_param (ptr_type_node)
2754 + = build_function_type (void_type_node,
2756 + def_param (float_type_node)
2757 + def_param (integer_type_node)
2760 + = build_function_type (void_type_node,
2762 + def_param (float_type_node)
2763 + def_param (float_type_node)
2766 + = build_function_type (void_type_node,
2768 + def_param (float_type_node)
2769 + def_param (ptr_type_node)
2772 + = build_function_type (void_type_node,
2774 + def_param (ptr_type_node)
2775 + def_param (integer_type_node)
2778 + = build_function_type (void_type_node,
2780 + def_param (ptr_type_node)
2781 + def_param (float_type_node)
2784 + = build_function_type (void_type_node,
2786 + def_param (ptr_type_node)
2787 + def_param (ptr_type_node)
2791 + = build_function_type (integer_type_node,
2795 + = build_function_type (integer_type_node,
2797 + def_param (integer_type_node)
2800 + = build_function_type (integer_type_node,
2802 + def_param (float_type_node)
2805 + = build_function_type (integer_type_node,
2807 + def_param (ptr_type_node)
2810 + = build_function_type (integer_type_node,
2812 + def_param (integer_type_node)
2813 + def_param (integer_type_node)
2816 + = build_function_type (integer_type_node,
2818 + def_param (integer_type_node)
2819 + def_param (float_type_node)
2822 + = build_function_type (integer_type_node,
2824 + def_param (integer_type_node)
2825 + def_param (ptr_type_node)
2828 + = build_function_type (integer_type_node,
2830 + def_param (float_type_node)
2831 + def_param (integer_type_node)
2834 + = build_function_type (integer_type_node,
2836 + def_param (float_type_node)
2837 + def_param (float_type_node)
2840 + = build_function_type (integer_type_node,
2842 + def_param (float_type_node)
2843 + def_param (ptr_type_node)
2846 + = build_function_type (integer_type_node,
2848 + def_param (ptr_type_node)
2849 + def_param (integer_type_node)
2852 + = build_function_type (integer_type_node,
2854 + def_param (ptr_type_node)
2855 + def_param (float_type_node)
2858 + = build_function_type (integer_type_node,
2860 + def_param (ptr_type_node)
2861 + def_param (ptr_type_node)
2865 + = build_function_type (float_type_node,
2869 + = build_function_type (float_type_node,
2871 + def_param (integer_type_node)
2874 + = build_function_type (float_type_node,
2876 + def_param (float_type_node)
2879 + = build_function_type (float_type_node,
2881 + def_param (ptr_type_node)
2884 + = build_function_type (float_type_node,
2886 + def_param (integer_type_node)
2887 + def_param (integer_type_node)
2890 + = build_function_type (float_type_node,
2892 + def_param (integer_type_node)
2893 + def_param (float_type_node)
2896 + = build_function_type (float_type_node,
2898 + def_param (integer_type_node)
2899 + def_param (ptr_type_node)
2902 + = build_function_type (float_type_node,
2904 + def_param (float_type_node)
2905 + def_param (integer_type_node)
2908 + = build_function_type (float_type_node,
2910 + def_param (float_type_node)
2911 + def_param (float_type_node)
2914 + = build_function_type (float_type_node,
2916 + def_param (float_type_node)
2917 + def_param (ptr_type_node)
2920 + = build_function_type (float_type_node,
2922 + def_param (ptr_type_node)
2923 + def_param (integer_type_node)
2926 + = build_function_type (float_type_node,
2928 + def_param (ptr_type_node)
2929 + def_param (float_type_node)
2932 + = build_function_type (float_type_node,
2934 + def_param (ptr_type_node)
2935 + def_param (ptr_type_node)
2940 + = build_function_type (ptr_type_node,
2944 + = build_function_type (ptr_type_node,
2946 + def_param (integer_type_node)
2949 + = build_function_type (ptr_type_node,
2951 + def_param (float_type_node)
2954 + = build_function_type (ptr_type_node,
2956 + def_param (ptr_type_node)
2959 + = build_function_type (ptr_type_node,
2961 + def_param (integer_type_node)
2962 + def_param (integer_type_node)
2965 + = build_function_type (ptr_type_node,
2967 + def_param (integer_type_node)
2968 + def_param (float_type_node)
2971 + = build_function_type (ptr_type_node,
2973 + def_param (integer_type_node)
2974 + def_param (ptr_type_node)
2977 + = build_function_type (ptr_type_node,
2979 + def_param (float_type_node)
2980 + def_param (integer_type_node)
2983 + = build_function_type (ptr_type_node,
2985 + def_param (float_type_node)
2986 + def_param (float_type_node)
2989 + = build_function_type (ptr_type_node,
2991 + def_param (float_type_node)
2992 + def_param (ptr_type_node)
2995 + = build_function_type (ptr_type_node,
2997 + def_param (ptr_type_node)
2998 + def_param (integer_type_node)
3001 + = build_function_type (ptr_type_node,
3003 + def_param (ptr_type_node)
3004 + def_param (float_type_node)
3007 + = build_function_type (ptr_type_node,
3009 + def_param (ptr_type_node)
3010 + def_param (ptr_type_node)
3018 + for (d = bdesc; d->name; d++)
3020 + builtin_function (d->name, *d->type, d->code,
3021 + BUILT_IN_MD, NULL, NULL);
3025 +/* Expand an expression EXP that calls a built-in function,
3026 + with result going to TARGET if that's convenient
3027 + (and in mode MODE if that's convenient).
3028 + SUBTARGET may be used as the target for computing one of EXP's operands.
3029 + IGNORE is nonzero if the value is to be ignored. */
3032 +nios2_expand_builtin (tree exp, rtx target, rtx subtarget,
3033 + enum machine_mode mode, int ignore)
3035 + const struct builtin_description *d;
3036 + tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
3037 + unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
3039 + for (d = bdesc; d->name; d++)
3040 + if (d->code == fcode)
3041 + return (d->expander) (d, exp, target, subtarget, mode, ignore);
3043 + /* we should have seen one of the functins we registered */
3047 +static rtx nios2_create_target (const struct builtin_description *, rtx);
3051 +nios2_create_target (const struct builtin_description *d, rtx target)
3054 + || !(*insn_data[d->icode].operand[0].predicate) (target,
3055 + insn_data[d->icode].operand[0].mode))
3057 + target = gen_reg_rtx (insn_data[d->icode].operand[0].mode);
3064 +static rtx nios2_extract_opcode (const struct builtin_description *, int, tree);
3065 +static rtx nios2_extract_operand (const struct builtin_description *, int, int, tree);
3068 +nios2_extract_opcode (const struct builtin_description *d, int op, tree arglist)
3070 + enum machine_mode mode = insn_data[d->icode].operand[op].mode;
3071 + tree arg = TREE_VALUE (arglist);
3072 + rtx opcode = expand_expr (arg, NULL_RTX, mode, 0);
3073 + opcode = protect_from_queue (opcode, 0);
3075 + if (!(*insn_data[d->icode].operand[op].predicate) (opcode, mode))
3076 + error ("Custom instruction opcode must be compile time constant in the range 0-255 for %s", d->name);
3082 +nios2_extract_operand (const struct builtin_description *d, int op, int argnum, tree arglist)
3084 + enum machine_mode mode = insn_data[d->icode].operand[op].mode;
3085 + tree arg = TREE_VALUE (arglist);
3086 + rtx operand = expand_expr (arg, NULL_RTX, mode, 0);
3087 + operand = protect_from_queue (operand, 0);
3089 + if (!(*insn_data[d->icode].operand[op].predicate) (operand, mode))
3090 + operand = copy_to_mode_reg (mode, operand);
3092 + /* ??? Better errors would be nice */
3093 + if (!(*insn_data[d->icode].operand[op].predicate) (operand, mode))
3094 + error ("Invalid argument %d to %s", argnum, d->name);
3101 +nios2_expand_custom_n (const struct builtin_description *d, tree exp,
3102 + rtx target ATTRIBUTE_UNUSED, rtx subtarget ATTRIBUTE_UNUSED,
3103 + enum machine_mode mode ATTRIBUTE_UNUSED, int ignore ATTRIBUTE_UNUSED)
3105 + tree arglist = TREE_OPERAND (exp, 1);
3109 + /* custom_n should have exactly one operand */
3110 + if (insn_data[d->icode].n_operands != 1)
3113 + opcode = nios2_extract_opcode (d, 0, arglist);
3115 + pat = GEN_FCN (d->icode) (opcode);
3123 +nios2_expand_custom_Xn (const struct builtin_description *d, tree exp,
3124 + rtx target, rtx subtarget ATTRIBUTE_UNUSED,
3125 + enum machine_mode mode ATTRIBUTE_UNUSED,
3126 + int ignore ATTRIBUTE_UNUSED)
3128 + tree arglist = TREE_OPERAND (exp, 1);
3132 + /* custom_Xn should have exactly two operands */
3133 + if (insn_data[d->icode].n_operands != 2)
3136 + target = nios2_create_target (d, target);
3137 + opcode = nios2_extract_opcode (d, 1, arglist);
3139 + pat = GEN_FCN (d->icode) (target, opcode);
3147 +nios2_expand_custom_nX (const struct builtin_description *d, tree exp,
3148 + rtx target ATTRIBUTE_UNUSED, rtx subtarget ATTRIBUTE_UNUSED,
3149 + enum machine_mode mode ATTRIBUTE_UNUSED, int ignore ATTRIBUTE_UNUSED)
3151 + tree arglist = TREE_OPERAND (exp, 1);
3158 + /* custom_nX should have exactly two operands */
3159 + if (insn_data[d->icode].n_operands != 2)
3162 + opcode = nios2_extract_opcode (d, 0, arglist);
3163 + for (i = 0; i < 1; i++)
3165 + arglist = TREE_CHAIN (arglist);
3166 + operands[i] = nios2_extract_operand (d, i + 1, i + 1, arglist);
3169 + pat = GEN_FCN (d->icode) (opcode, operands[0]);
3177 +nios2_expand_custom_XnX (const struct builtin_description *d, tree exp, rtx target,
3178 + rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED,
3179 + int ignore ATTRIBUTE_UNUSED)
3181 + tree arglist = TREE_OPERAND (exp, 1);
3187 + /* custom_Xn should have exactly three operands */
3188 + if (insn_data[d->icode].n_operands != 3)
3191 + target = nios2_create_target (d, target);
3192 + opcode = nios2_extract_opcode (d, 1, arglist);
3194 + for (i = 0; i < 1; i++)
3196 + arglist = TREE_CHAIN (arglist);
3197 + operands[i] = nios2_extract_operand (d, i + 2, i + 1, arglist);
3200 + pat = GEN_FCN (d->icode) (target, opcode, operands[0]);
3209 +nios2_expand_custom_nXX (const struct builtin_description *d, tree exp, rtx target ATTRIBUTE_UNUSED,
3210 + rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED,
3211 + int ignore ATTRIBUTE_UNUSED)
3213 + tree arglist = TREE_OPERAND (exp, 1);
3220 + /* custom_nX should have exactly three operands */
3221 + if (insn_data[d->icode].n_operands != 3)
3224 + opcode = nios2_extract_opcode (d, 0, arglist);
3225 + for (i = 0; i < 2; i++)
3227 + arglist = TREE_CHAIN (arglist);
3228 + operands[i] = nios2_extract_operand (d, i + 1, i + 1, arglist);
3231 + pat = GEN_FCN (d->icode) (opcode, operands[0], operands[1]);
3239 +nios2_expand_custom_XnXX (const struct builtin_description *d, tree exp, rtx target,
3240 + rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED,
3241 + int ignore ATTRIBUTE_UNUSED)
3243 + tree arglist = TREE_OPERAND (exp, 1);
3250 + /* custom_XnX should have exactly four operands */
3251 + if (insn_data[d->icode].n_operands != 4)
3254 + target = nios2_create_target (d, target);
3255 + opcode = nios2_extract_opcode (d, 1, arglist);
3256 + for (i = 0; i < 2; i++)
3258 + arglist = TREE_CHAIN (arglist);
3259 + operands[i] = nios2_extract_operand (d, i + 2, i + 1, arglist);
3262 + pat = GEN_FCN (d->icode) (target, opcode, operands[0], operands[1]);
3273 +nios2_expand_STXIO (const struct builtin_description *d, tree exp, rtx target ATTRIBUTE_UNUSED,
3274 + rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED,
3275 + int ignore ATTRIBUTE_UNUSED)
3277 + tree arglist = TREE_OPERAND (exp, 1);
3279 + rtx store_dest, store_val;
3280 + enum insn_code icode = d->icode;
3282 + /* stores should have exactly two operands */
3283 + if (insn_data[icode].n_operands != 2)
3286 + /* process the destination of the store */
3288 + enum machine_mode mode = insn_data[icode].operand[0].mode;
3289 + tree arg = TREE_VALUE (arglist);
3290 + store_dest = expand_expr (arg, NULL_RTX, VOIDmode, 0);
3291 + store_dest = protect_from_queue (store_dest, 0);
3293 + store_dest = gen_rtx_MEM (mode, copy_to_mode_reg (Pmode, store_dest));
3295 + /* ??? Better errors would be nice */
3296 + if (!(*insn_data[icode].operand[0].predicate) (store_dest, mode))
3297 + error ("Invalid argument 1 to %s", d->name);
3301 + /* process the value to store */
3303 + enum machine_mode mode = insn_data[icode].operand[1].mode;
3304 + tree arg = TREE_VALUE (TREE_CHAIN (arglist));
3305 + store_val = expand_expr (arg, NULL_RTX, mode, 0);
3306 + store_val = protect_from_queue (store_val, 0);
3308 + if (!(*insn_data[icode].operand[1].predicate) (store_val, mode))
3309 + store_val = copy_to_mode_reg (mode, store_val);
3311 + /* ??? Better errors would be nice */
3312 + if (!(*insn_data[icode].operand[1].predicate) (store_val, mode))
3313 + error ("Invalid argument 2 to %s", d->name);
3316 + pat = GEN_FCN (d->icode) (store_dest, store_val);
3325 +nios2_expand_LDXIO (const struct builtin_description * d, tree exp, rtx target,
3326 + rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED,
3327 + int ignore ATTRIBUTE_UNUSED)
3329 + tree arglist = TREE_OPERAND (exp, 1);
3332 + enum insn_code icode = d->icode;
3334 + /* loads should have exactly two operands */
3335 + if (insn_data[icode].n_operands != 2)
3338 + target = nios2_create_target (d, target);
3341 + enum machine_mode mode = insn_data[icode].operand[1].mode;
3342 + tree arg = TREE_VALUE (arglist);
3343 + ld_src = expand_expr (arg, NULL_RTX, VOIDmode, 0);
3344 + ld_src = protect_from_queue (ld_src, 0);
3346 + ld_src = gen_rtx_MEM (mode, copy_to_mode_reg (Pmode, ld_src));
3348 + /* ??? Better errors would be nice */
3349 + if (!(*insn_data[icode].operand[1].predicate) (ld_src, mode))
3351 + error ("Invalid argument 1 to %s", d->name);
3355 + pat = GEN_FCN (d->icode) (target, ld_src);
3364 +nios2_expand_sync (const struct builtin_description * d ATTRIBUTE_UNUSED,
3365 + tree exp ATTRIBUTE_UNUSED, rtx target ATTRIBUTE_UNUSED,
3366 + rtx subtarget ATTRIBUTE_UNUSED,
3367 + enum machine_mode mode ATTRIBUTE_UNUSED,
3368 + int ignore ATTRIBUTE_UNUSED)
3370 + emit_insn (gen_sync ());
3375 +nios2_expand_rdctl (const struct builtin_description * d ATTRIBUTE_UNUSED,
3376 + tree exp ATTRIBUTE_UNUSED, rtx target ATTRIBUTE_UNUSED,
3377 + rtx subtarget ATTRIBUTE_UNUSED,
3378 + enum machine_mode mode ATTRIBUTE_UNUSED,
3379 + int ignore ATTRIBUTE_UNUSED)
3381 + tree arglist = TREE_OPERAND (exp, 1);
3384 + enum insn_code icode = d->icode;
3386 + /* rdctl should have exactly two operands */
3387 + if (insn_data[icode].n_operands != 2)
3390 + target = nios2_create_target (d, target);
3393 + enum machine_mode mode = insn_data[icode].operand[1].mode;
3394 + tree arg = TREE_VALUE (arglist);
3395 + rdctl_reg = expand_expr (arg, NULL_RTX, VOIDmode, 0);
3396 + rdctl_reg = protect_from_queue (rdctl_reg, 0);
3398 + if (!(*insn_data[icode].operand[1].predicate) (rdctl_reg, mode))
3400 + error ("Control register number must be in range 0-31 for %s", d->name);
3404 + pat = GEN_FCN (d->icode) (target, rdctl_reg);
3412 +nios2_expand_wrctl (const struct builtin_description * d ATTRIBUTE_UNUSED,
3413 + tree exp ATTRIBUTE_UNUSED, rtx target ATTRIBUTE_UNUSED,
3414 + rtx subtarget ATTRIBUTE_UNUSED,
3415 + enum machine_mode mode ATTRIBUTE_UNUSED,
3416 + int ignore ATTRIBUTE_UNUSED)
3418 + tree arglist = TREE_OPERAND (exp, 1);
3420 + rtx wrctl_reg, store_val;
3421 + enum insn_code icode = d->icode;
3423 + /* stores should have exactly two operands */
3424 + if (insn_data[icode].n_operands != 2)
3427 + /* process the destination of the store */
3429 + enum machine_mode mode = insn_data[icode].operand[0].mode;
3430 + tree arg = TREE_VALUE (arglist);
3431 + wrctl_reg = expand_expr (arg, NULL_RTX, VOIDmode, 0);
3432 + wrctl_reg = protect_from_queue (wrctl_reg, 0);
3434 + if (!(*insn_data[icode].operand[0].predicate) (wrctl_reg, mode))
3435 + error ("Control register number must be in range 0-31 for %s", d->name);
3439 + /* process the value to store */
3441 + enum machine_mode mode = insn_data[icode].operand[1].mode;
3442 + tree arg = TREE_VALUE (TREE_CHAIN (arglist));
3443 + store_val = expand_expr (arg, NULL_RTX, mode, 0);
3444 + store_val = protect_from_queue (store_val, 0);
3446 + if (!(*insn_data[icode].operand[1].predicate) (store_val, mode))
3447 + store_val = copy_to_mode_reg (mode, store_val);
3449 + /* ??? Better errors would be nice */
3450 + if (!(*insn_data[icode].operand[1].predicate) (store_val, mode))
3451 + error ("Invalid argument 2 to %s", d->name);
3454 + pat = GEN_FCN (d->icode) (wrctl_reg, store_val);
3462 +#include "gt-nios2.h"
3464 diff -durN gcc-3.4.6.orig/gcc/config/nios2/nios2-dp-bit.c gcc-3.4.6/gcc/config/nios2/nios2-dp-bit.c
3465 --- gcc-3.4.6.orig/gcc/config/nios2/nios2-dp-bit.c 1970-01-01 01:00:00.000000000 +0100
3466 +++ gcc-3.4.6/gcc/config/nios2/nios2-dp-bit.c 2007-08-15 23:09:36.000000000 +0200
3469 +/* This is a software floating point library which can be used
3470 + for targets without hardware floating point.
3471 + Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004
3472 + Free Software Foundation, Inc.
3474 +This file is free software; you can redistribute it and/or modify it
3475 +under the terms of the GNU General Public License as published by the
3476 +Free Software Foundation; either version 2, or (at your option) any
3479 +In addition to the permissions in the GNU General Public License, the
3480 +Free Software Foundation gives you unlimited permission to link the
3481 +compiled version of this file with other programs, and to distribute
3482 +those programs without any restriction coming from the use of this
3483 +file. (The General Public License restrictions do apply in other
3484 +respects; for example, they cover modification of the file, and
3485 +distribution when not linked into another program.)
3487 +This file is distributed in the hope that it will be useful, but
3488 +WITHOUT ANY WARRANTY; without even the implied warranty of
3489 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3490 +General Public License for more details.
3492 +You should have received a copy of the GNU General Public License
3493 +along with this program; see the file COPYING. If not, write to
3494 +the Free Software Foundation, 59 Temple Place - Suite 330,
3495 +Boston, MA 02111-1307, USA. */
3497 +/* As a special exception, if you link this library with other files,
3498 + some of which are compiled with GCC, to produce an executable,
3499 + this library does not by itself cause the resulting executable
3500 + to be covered by the GNU General Public License.
3501 + This exception does not however invalidate any other reasons why
3502 + the executable file might be covered by the GNU General Public License. */
3504 +/* This implements IEEE 754 format arithmetic, but does not provide a
3505 + mechanism for setting the rounding mode, or for generating or handling
3508 + The original code by Steve Chamberlain, hacked by Mark Eichin and Jim
3509 + Wilson, all of Cygnus Support. */
3511 +/* The intended way to use this file is to make two copies, add `#define FLOAT'
3512 + to one copy, then compile both copies and add them to libgcc.a. */
3514 +#include "tconfig.h"
3515 +#include "coretypes.h"
3517 +#include "config/fp-bit.h"
3519 +/* The following macros can be defined to change the behavior of this file:
3520 + FLOAT: Implement a `float', aka SFmode, fp library. If this is not
3521 + defined, then this file implements a `double', aka DFmode, fp library.
3522 + FLOAT_ONLY: Used with FLOAT, to implement a `float' only library, i.e.
3523 + don't include float->double conversion which requires the double library.
3524 + This is useful only for machines which can't support doubles, e.g. some
3526 + CMPtype: Specify the type that floating point compares should return.
3527 + This defaults to SItype, aka int.
3528 + US_SOFTWARE_GOFAST: This makes all entry points use the same names as the
3529 + US Software goFast library.
3530 + _DEBUG_BITFLOAT: This makes debugging the code a little easier, by adding
3531 + two integers to the FLO_union_type.
3532 + NO_DENORMALS: Disable handling of denormals.
3533 + NO_NANS: Disable nan and infinity handling
3534 + SMALL_MACHINE: Useful when operations on QIs and HIs are faster
3537 +/* We don't currently support extended floats (long doubles) on machines
3538 + without hardware to deal with them.
3540 + These stubs are just to keep the linker from complaining about unresolved
3541 + references which can be pulled in from libio & libstdc++, even if the
3542 + user isn't using long doubles. However, they may generate an unresolved
3543 + external to abort if abort is not used by the function, and the stubs
3544 + are referenced from within libc, since libgcc goes before and after the
3545 + system library. */
3547 +#ifdef DECLARE_LIBRARY_RENAMES
3548 + DECLARE_LIBRARY_RENAMES
3551 +#ifdef EXTENDED_FLOAT_STUBS
3552 +extern void abort (void);
3553 +void __extendsfxf2 (void) { abort(); }
3554 +void __extenddfxf2 (void) { abort(); }
3555 +void __truncxfdf2 (void) { abort(); }
3556 +void __truncxfsf2 (void) { abort(); }
3557 +void __fixxfsi (void) { abort(); }
3558 +void __floatsixf (void) { abort(); }
3559 +void __addxf3 (void) { abort(); }
3560 +void __subxf3 (void) { abort(); }
3561 +void __mulxf3 (void) { abort(); }
3562 +void __divxf3 (void) { abort(); }
3563 +void __negxf2 (void) { abort(); }
3564 +void __eqxf2 (void) { abort(); }
3565 +void __nexf2 (void) { abort(); }
3566 +void __gtxf2 (void) { abort(); }
3567 +void __gexf2 (void) { abort(); }
3568 +void __lexf2 (void) { abort(); }
3569 +void __ltxf2 (void) { abort(); }
3571 +void __extendsftf2 (void) { abort(); }
3572 +void __extenddftf2 (void) { abort(); }
3573 +void __trunctfdf2 (void) { abort(); }
3574 +void __trunctfsf2 (void) { abort(); }
3575 +void __fixtfsi (void) { abort(); }
3576 +void __floatsitf (void) { abort(); }
3577 +void __addtf3 (void) { abort(); }
3578 +void __subtf3 (void) { abort(); }
3579 +void __multf3 (void) { abort(); }
3580 +void __divtf3 (void) { abort(); }
3581 +void __negtf2 (void) { abort(); }
3582 +void __eqtf2 (void) { abort(); }
3583 +void __netf2 (void) { abort(); }
3584 +void __gttf2 (void) { abort(); }
3585 +void __getf2 (void) { abort(); }
3586 +void __letf2 (void) { abort(); }
3587 +void __lttf2 (void) { abort(); }
3588 +#else /* !EXTENDED_FLOAT_STUBS, rest of file */
3590 +/* IEEE "special" number predicates */
3599 +#if defined L_thenan_sf
3600 +const fp_number_type __thenan_sf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
3601 +#elif defined L_thenan_df
3602 +const fp_number_type __thenan_df = { CLASS_SNAN, 0, 0, {(fractype) 0} };
3603 +#elif defined L_thenan_tf
3604 +const fp_number_type __thenan_tf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
3605 +#elif defined TFLOAT
3606 +extern const fp_number_type __thenan_tf;
3607 +#elif defined FLOAT
3608 +extern const fp_number_type __thenan_sf;
3610 +extern const fp_number_type __thenan_df;
3614 +static fp_number_type *
3617 + /* Discard the const qualifier... */
3619 + return (fp_number_type *) (& __thenan_tf);
3620 +#elif defined FLOAT
3621 + return (fp_number_type *) (& __thenan_sf);
3623 + return (fp_number_type *) (& __thenan_df);
3629 +isnan ( fp_number_type * x)
3631 + return x->class == CLASS_SNAN || x->class == CLASS_QNAN;
3636 +isinf ( fp_number_type * x)
3638 + return x->class == CLASS_INFINITY;
3641 +#endif /* NO_NANS */
3645 +iszero ( fp_number_type * x)
3647 + return x->class == CLASS_ZERO;
3652 +flip_sign ( fp_number_type * x)
3654 + x->sign = !x->sign;
3657 +extern FLO_type pack_d ( fp_number_type * );
3659 +#if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf)
3661 +pack_d ( fp_number_type * src)
3663 + FLO_union_type dst;
3664 + fractype fraction = src->fraction.ll; /* wasn't unsigned before? */
3665 + int sign = src->sign;
3668 + if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && (isnan (src) || isinf (src)))
3670 + /* We can't represent these values accurately. By using the
3671 + largest possible magnitude, we guarantee that the conversion
3672 + of infinity is at least as big as any finite number. */
3674 + fraction = ((fractype) 1 << FRACBITS) - 1;
3676 + else if (isnan (src))
3679 + if (src->class == CLASS_QNAN || 1)
3681 +#ifdef QUIET_NAN_NEGATED
3682 + fraction |= QUIET_NAN - 1;
3684 + fraction |= QUIET_NAN;
3688 + else if (isinf (src))
3693 + else if (iszero (src))
3698 + else if (fraction == 0)
3704 + if (src->normal_exp < NORMAL_EXPMIN)
3706 +#ifdef NO_DENORMALS
3707 + /* Go straight to a zero representation if denormals are not
3708 + supported. The denormal handling would be harmless but
3709 + isn't unnecessary. */
3712 +#else /* NO_DENORMALS */
3713 + /* This number's exponent is too low to fit into the bits
3714 + available in the number, so we'll store 0 in the exponent and
3715 + shift the fraction to the right to make up for it. */
3717 + int shift = NORMAL_EXPMIN - src->normal_exp;
3721 + if (shift > FRAC_NBITS - NGARDS)
3723 + /* No point shifting, since it's more that 64 out. */
3728 + int lowbit = (fraction & (((fractype)1 << shift) - 1)) ? 1 : 0;
3729 + fraction = (fraction >> shift) | lowbit;
3731 + if ((fraction & GARDMASK) == GARDMSB)
3733 + if ((fraction & (1 << NGARDS)))
3734 + fraction += GARDROUND + 1;
3738 + /* Add to the guards to round up. */
3739 + fraction += GARDROUND;
3741 + /* Perhaps the rounding means we now need to change the
3742 + exponent, because the fraction is no longer denormal. */
3743 + if (fraction >= IMPLICIT_1)
3747 + fraction >>= NGARDS;
3748 +#endif /* NO_DENORMALS */
3750 + else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS)
3751 + && src->normal_exp > EXPBIAS)
3758 + exp = src->normal_exp + EXPBIAS;
3759 + if (!ROUND_TOWARDS_ZERO)
3761 + /* IF the gard bits are the all zero, but the first, then we're
3762 + half way between two numbers, choose the one which makes the
3763 + lsb of the answer 0. */
3764 + if ((fraction & GARDMASK) == GARDMSB)
3766 + if (fraction & (1 << NGARDS))
3767 + fraction += GARDROUND + 1;
3771 + /* Add a one to the guards to round up */
3772 + fraction += GARDROUND;
3774 + if (fraction >= IMPLICIT_2)
3780 + fraction >>= NGARDS;
3782 + if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp > EXPMAX)
3784 + /* Saturate on overflow. */
3786 + fraction = ((fractype) 1 << FRACBITS) - 1;
3791 + /* We previously used bitfields to store the number, but this doesn't
3792 + handle little/big endian systems conveniently, so use shifts and
3794 +#ifdef FLOAT_BIT_ORDER_MISMATCH
3795 + dst.bits.fraction = fraction;
3796 + dst.bits.exp = exp;
3797 + dst.bits.sign = sign;
3799 +# if defined TFLOAT && defined HALFFRACBITS
3801 + halffractype high, low, unity;
3802 + int lowsign, lowexp;
3804 + unity = (halffractype) 1 << HALFFRACBITS;
3806 + /* Set HIGH to the high double's significand, masking out the implicit 1.
3807 + Set LOW to the low double's full significand. */
3808 + high = (fraction >> (FRACBITS - HALFFRACBITS)) & (unity - 1);
3809 + low = fraction & (unity * 2 - 1);
3811 + /* Get the initial sign and exponent of the low double. */
3812 + lowexp = exp - HALFFRACBITS - 1;
3815 + /* HIGH should be rounded like a normal double, making |LOW| <=
3816 + 0.5 ULP of HIGH. Assume round-to-nearest. */
3818 + if (low > unity || (low == unity && (high & 1) == 1))
3820 + /* Round HIGH up and adjust LOW to match. */
3822 + if (high == unity)
3824 + /* May make it infinite, but that's OK. */
3828 + low = unity * 2 - low;
3832 + high |= (halffractype) exp << HALFFRACBITS;
3833 + high |= (halffractype) sign << (HALFFRACBITS + EXPBITS);
3835 + if (exp == EXPMAX || exp == 0 || low == 0)
3839 + while (lowexp > 0 && low < unity)
3847 + halffractype roundmsb, round;
3850 + shift = 1 - lowexp;
3851 + roundmsb = (1 << (shift - 1));
3852 + round = low & ((roundmsb << 1) - 1);
3857 + if (round > roundmsb || (round == roundmsb && (low & 1) == 1))
3861 + /* LOW rounds up to the smallest normal number. */
3867 + low |= (halffractype) lowexp << HALFFRACBITS;
3868 + low |= (halffractype) lowsign << (HALFFRACBITS + EXPBITS);
3870 + dst.value_raw = ((fractype) high << HALFSHIFT) | low;
3873 + dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1);
3874 + dst.value_raw |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << FRACBITS;
3875 + dst.value_raw |= ((fractype) (sign & 1)) << (FRACBITS | EXPBITS);
3879 +#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
3882 + qrtrfractype tmp1 = dst.words[0];
3883 + qrtrfractype tmp2 = dst.words[1];
3884 + dst.words[0] = dst.words[3];
3885 + dst.words[1] = dst.words[2];
3886 + dst.words[2] = tmp2;
3887 + dst.words[3] = tmp1;
3891 + halffractype tmp = dst.words[0];
3892 + dst.words[0] = dst.words[1];
3893 + dst.words[1] = tmp;
3902 +#if defined(L_unpack_df) || defined(L_unpack_sf) || defined(L_unpack_tf)
3904 +unpack_d (FLO_union_type * src, fp_number_type * dst)
3906 + /* We previously used bitfields to store the number, but this doesn't
3907 + handle little/big endian systems conveniently, so use shifts and
3909 + fractype fraction;
3913 +#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
3914 + FLO_union_type swapped;
3917 + swapped.words[0] = src->words[3];
3918 + swapped.words[1] = src->words[2];
3919 + swapped.words[2] = src->words[1];
3920 + swapped.words[3] = src->words[0];
3922 + swapped.words[0] = src->words[1];
3923 + swapped.words[1] = src->words[0];
3928 +#ifdef FLOAT_BIT_ORDER_MISMATCH
3929 + fraction = src->bits.fraction;
3930 + exp = src->bits.exp;
3931 + sign = src->bits.sign;
3933 +# if defined TFLOAT && defined HALFFRACBITS
3935 + halffractype high, low;
3937 + high = src->value_raw >> HALFSHIFT;
3938 + low = src->value_raw & (((fractype)1 << HALFSHIFT) - 1);
3940 + fraction = high & ((((fractype)1) << HALFFRACBITS) - 1);
3941 + fraction <<= FRACBITS - HALFFRACBITS;
3942 + exp = ((int)(high >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
3943 + sign = ((int)(high >> (((HALFFRACBITS + EXPBITS))))) & 1;
3945 + if (exp != EXPMAX && exp != 0 && low != 0)
3947 + int lowexp = ((int)(low >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
3948 + int lowsign = ((int)(low >> (((HALFFRACBITS + EXPBITS))))) & 1;
3952 + xlow = low & ((((fractype)1) << HALFFRACBITS) - 1);
3954 + xlow |= (((halffractype)1) << HALFFRACBITS);
3957 + shift = (FRACBITS - HALFFRACBITS) - (exp - lowexp);
3960 + else if (shift < 0)
3962 + if (sign == lowsign)
3964 + else if (fraction >= xlow)
3968 + /* The high part is a power of two but the full number is lower.
3969 + This code will leave the implicit 1 in FRACTION, but we'd
3970 + have added that below anyway. */
3971 + fraction = (((fractype) 1 << FRACBITS) - xlow) << 1;
3977 + fraction = src->value_raw & ((((fractype)1) << FRACBITS) - 1);
3978 + exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1);
3979 + sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1;
3986 + /* Hmm. Looks like 0 */
3988 +#ifdef NO_DENORMALS
3993 + /* tastes like zero */
3994 + dst->class = CLASS_ZERO;
3998 + /* Zero exponent with nonzero fraction - it's denormalized,
3999 + so there isn't a leading implicit one - we'll shift it so
4001 + dst->normal_exp = exp - EXPBIAS + 1;
4002 + fraction <<= NGARDS;
4004 + dst->class = CLASS_NUMBER;
4006 + while (fraction < IMPLICIT_1)
4009 + dst->normal_exp--;
4012 + dst->fraction.ll = fraction;
4015 + else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp == EXPMAX)
4017 + /* Huge exponent*/
4018 + if (fraction == 0)
4020 + /* Attached to a zero fraction - means infinity */
4021 + dst->class = CLASS_INFINITY;
4025 + /* Nonzero fraction, means nan */
4026 +#ifdef QUIET_NAN_NEGATED
4027 + if ((fraction & QUIET_NAN) == 0)
4029 + if (fraction & QUIET_NAN)
4032 + dst->class = CLASS_QNAN;
4036 + dst->class = CLASS_SNAN;
4038 + /* Keep the fraction part as the nan number */
4039 + dst->fraction.ll = fraction;
4044 + /* Nothing strange about this number */
4045 + dst->normal_exp = exp - EXPBIAS;
4046 + dst->class = CLASS_NUMBER;
4047 + dst->fraction.ll = (fraction << NGARDS) | IMPLICIT_1;
4050 +#endif /* L_unpack_df || L_unpack_sf */
4052 +#if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf)
4053 +static fp_number_type *
4054 +_fpadd_parts (fp_number_type * a,
4055 + fp_number_type * b,
4056 + fp_number_type * tmp)
4058 + intfrac tfraction;
4060 + /* Put commonly used fields in local variables. */
4063 + fractype a_fraction;
4064 + fractype b_fraction;
4076 + /* Adding infinities with opposite signs yields a NaN. */
4077 + if (isinf (b) && a->sign != b->sign)
4090 + tmp->sign = a->sign & b->sign;
4100 + /* Got two numbers. shift the smaller and increment the exponent till
4101 + they're the same */
4105 + a_normal_exp = a->normal_exp;
4106 + b_normal_exp = b->normal_exp;
4107 + a_fraction = a->fraction.ll;
4108 + b_fraction = b->fraction.ll;
4110 + diff = a_normal_exp - b_normal_exp;
4114 + if (diff < FRAC_NBITS)
4116 + /* ??? This does shifts one bit at a time. Optimize. */
4117 + while (a_normal_exp > b_normal_exp)
4120 + LSHIFT (b_fraction);
4122 + while (b_normal_exp > a_normal_exp)
4125 + LSHIFT (a_fraction);
4130 + /* Somethings's up.. choose the biggest */
4131 + if (a_normal_exp > b_normal_exp)
4133 + b_normal_exp = a_normal_exp;
4138 + a_normal_exp = b_normal_exp;
4144 + if (a->sign != b->sign)
4148 + tfraction = -a_fraction + b_fraction;
4152 + tfraction = a_fraction - b_fraction;
4154 + if (tfraction >= 0)
4157 + tmp->normal_exp = a_normal_exp;
4158 + tmp->fraction.ll = tfraction;
4163 + tmp->normal_exp = a_normal_exp;
4164 + tmp->fraction.ll = -tfraction;
4166 + /* and renormalize it */
4168 + while (tmp->fraction.ll < IMPLICIT_1 && tmp->fraction.ll)
4170 + tmp->fraction.ll <<= 1;
4171 + tmp->normal_exp--;
4176 + tmp->sign = a->sign;
4177 + tmp->normal_exp = a_normal_exp;
4178 + tmp->fraction.ll = a_fraction + b_fraction;
4180 + tmp->class = CLASS_NUMBER;
4181 + /* Now the fraction is added, we have to shift down to renormalize the
4184 + if (tmp->fraction.ll >= IMPLICIT_2)
4186 + LSHIFT (tmp->fraction.ll);
4187 + tmp->normal_exp++;
4194 +add (FLO_type arg_a, FLO_type arg_b)
4198 + fp_number_type tmp;
4199 + fp_number_type *res;
4200 + FLO_union_type au, bu;
4205 + unpack_d (&au, &a);
4206 + unpack_d (&bu, &b);
4208 + res = _fpadd_parts (&a, &b, &tmp);
4210 + return pack_d (res);
4214 +sub (FLO_type arg_a, FLO_type arg_b)
4218 + fp_number_type tmp;
4219 + fp_number_type *res;
4220 + FLO_union_type au, bu;
4225 + unpack_d (&au, &a);
4226 + unpack_d (&bu, &b);
4230 + res = _fpadd_parts (&a, &b, &tmp);
4232 + return pack_d (res);
4234 +#endif /* L_addsub_sf || L_addsub_df */
4236 +#if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf)
4237 +static inline __attribute__ ((__always_inline__)) fp_number_type *
4238 +_fpmul_parts ( fp_number_type * a,
4239 + fp_number_type * b,
4240 + fp_number_type * tmp)
4243 + fractype high = 0;
4247 + a->sign = a->sign != b->sign;
4252 + b->sign = a->sign != b->sign;
4259 + a->sign = a->sign != b->sign;
4268 + b->sign = a->sign != b->sign;
4273 + a->sign = a->sign != b->sign;
4278 + b->sign = a->sign != b->sign;
4282 + /* Calculate the mantissa by multiplying both numbers to get a
4283 + twice-as-wide number. */
4285 +#if defined(NO_DI_MODE) || defined(TFLOAT)
4287 + fractype x = a->fraction.ll;
4288 + fractype ylow = b->fraction.ll;
4289 + fractype yhigh = 0;
4292 + /* ??? This does multiplies one bit at a time. Optimize. */
4293 + for (bit = 0; bit < FRAC_NBITS; bit++)
4299 + carry = (low += ylow) < ylow;
4300 + high += yhigh + carry;
4303 + if (ylow & FRACHIGH)
4311 +#elif defined(FLOAT)
4312 + /* Multiplying two USIs to get a UDI, we're safe. */
4314 + UDItype answer = (UDItype)a->fraction.ll * (UDItype)b->fraction.ll;
4316 + high = answer >> BITS_PER_SI;
4320 + /* fractype is DImode, but we need the result to be twice as wide.
4321 + Assuming a widening multiply from DImode to TImode is not
4322 + available, build one by hand. */
4324 + USItype nl = a->fraction.ll;
4325 + USItype nh = a->fraction.ll >> BITS_PER_SI;
4326 + USItype ml = b->fraction.ll;
4327 + USItype mh = b->fraction.ll >> BITS_PER_SI;
4328 + UDItype pp_ll = (UDItype) ml * nl;
4329 + UDItype pp_hl = (UDItype) mh * nl;
4330 + UDItype pp_lh = (UDItype) ml * nh;
4331 + UDItype pp_hh = (UDItype) mh * nh;
4334 + UDItype ps_hh__ = pp_hl + pp_lh;
4335 + if (ps_hh__ < pp_hl)
4336 + res2 += (UDItype)1 << BITS_PER_SI;
4337 + pp_hl = (UDItype)(USItype)ps_hh__ << BITS_PER_SI;
4338 + res0 = pp_ll + pp_hl;
4341 + res2 += (ps_hh__ >> BITS_PER_SI) + pp_hh;
4348 + tmp->normal_exp = a->normal_exp + b->normal_exp
4349 + + FRAC_NBITS - (FRACBITS + NGARDS);
4350 + tmp->sign = a->sign != b->sign;
4351 + while (high >= IMPLICIT_2)
4353 + tmp->normal_exp++;
4361 + while (high < IMPLICIT_1)
4363 + tmp->normal_exp--;
4366 + if (low & FRACHIGH)
4370 + /* rounding is tricky. if we only round if it won't make us round later. */
4372 + if (low & FRACHIGH2)
4374 + if (((high & GARDMASK) != GARDMSB)
4375 + && (((high + 1) & GARDMASK) == GARDMSB))
4377 + /* don't round, it gets done again later. */
4385 + if (!ROUND_TOWARDS_ZERO && (high & GARDMASK) == GARDMSB)
4387 + if (high & (1 << NGARDS))
4389 + /* half way, so round to even */
4390 + high += GARDROUND + 1;
4394 + /* but we really weren't half way */
4395 + high += GARDROUND + 1;
4398 + tmp->fraction.ll = high;
4399 + tmp->class = CLASS_NUMBER;
4404 +multiply (FLO_type arg_a, FLO_type arg_b)
4408 + fp_number_type tmp;
4409 + fp_number_type *res;
4410 + FLO_union_type au, bu;
4415 + unpack_d (&au, &a);
4416 + unpack_d (&bu, &b);
4418 + res = _fpmul_parts (&a, &b, &tmp);
4420 + return pack_d (res);
4422 +#endif /* L_mul_sf || L_mul_df */
4424 +#if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf)
4425 +static inline __attribute__ ((__always_inline__)) fp_number_type *
4426 +_fpdiv_parts (fp_number_type * a,
4427 + fp_number_type * b)
4430 + fractype numerator;
4431 + fractype denominator;
4432 + fractype quotient;
4443 + a->sign = a->sign ^ b->sign;
4445 + if (isinf (a) || iszero (a))
4447 + if (a->class == b->class)
4454 + a->fraction.ll = 0;
4455 + a->normal_exp = 0;
4460 + a->class = CLASS_INFINITY;
4464 + /* Calculate the mantissa by multiplying both 64bit numbers to get a
4468 + ( numerator / denominator) * 2^(numerator exponent - denominator exponent)
4471 + a->normal_exp = a->normal_exp - b->normal_exp;
4472 + numerator = a->fraction.ll;
4473 + denominator = b->fraction.ll;
4475 + if (numerator < denominator)
4477 + /* Fraction will be less than 1.0 */
4483 + /* ??? Does divide one bit at a time. Optimize. */
4486 + if (numerator >= denominator)
4489 + numerator -= denominator;
4495 + if (!ROUND_TOWARDS_ZERO && (quotient & GARDMASK) == GARDMSB)
4497 + if (quotient & (1 << NGARDS))
4499 + /* half way, so round to even */
4500 + quotient += GARDROUND + 1;
4502 + else if (numerator)
4504 + /* but we really weren't half way, more bits exist */
4505 + quotient += GARDROUND + 1;
4509 + a->fraction.ll = quotient;
4515 +divide (FLO_type arg_a, FLO_type arg_b)
4519 + fp_number_type *res;
4520 + FLO_union_type au, bu;
4525 + unpack_d (&au, &a);
4526 + unpack_d (&bu, &b);
4528 + res = _fpdiv_parts (&a, &b);
4530 + return pack_d (res);
4532 +#endif /* L_div_sf || L_div_df */
4534 +#if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) \
4535 + || defined(L_fpcmp_parts_tf)
4536 +/* according to the demo, fpcmp returns a comparison with 0... thus
4543 +__fpcmp_parts (fp_number_type * a, fp_number_type * b)
4546 + /* either nan -> unordered. Must be checked outside of this routine. */
4547 + if (isnan (a) && isnan (b))
4549 + return 1; /* still unordered! */
4553 + if (isnan (a) || isnan (b))
4555 + return 1; /* how to indicate unordered compare? */
4557 + if (isinf (a) && isinf (b))
4559 + /* +inf > -inf, but +inf != +inf */
4560 + /* b \a| +inf(0)| -inf(1)
4561 + ______\+--------+--------
4562 + +inf(0)| a==b(0)| a<b(-1)
4563 + -------+--------+--------
4564 + -inf(1)| a>b(1) | a==b(0)
4565 + -------+--------+--------
4566 + So since unordered must be nonzero, just line up the columns...
4568 + return b->sign - a->sign;
4570 + /* but not both... */
4573 + return a->sign ? -1 : 1;
4577 + return b->sign ? 1 : -1;
4579 + if (iszero (a) && iszero (b))
4585 + return b->sign ? 1 : -1;
4589 + return a->sign ? -1 : 1;
4591 + /* now both are "normal". */
4592 + if (a->sign != b->sign)
4594 + /* opposite signs */
4595 + return a->sign ? -1 : 1;
4597 + /* same sign; exponents? */
4598 + if (a->normal_exp > b->normal_exp)
4600 + return a->sign ? -1 : 1;
4602 + if (a->normal_exp < b->normal_exp)
4604 + return a->sign ? 1 : -1;
4606 + /* same exponents; check size. */
4607 + if (a->fraction.ll > b->fraction.ll)
4609 + return a->sign ? -1 : 1;
4611 + if (a->fraction.ll < b->fraction.ll)
4613 + return a->sign ? 1 : -1;
4615 + /* after all that, they're equal. */
4620 +#if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compoare_tf)
4622 +compare (FLO_type arg_a, FLO_type arg_b)
4626 + FLO_union_type au, bu;
4631 + unpack_d (&au, &a);
4632 + unpack_d (&bu, &b);
4634 + return __fpcmp_parts (&a, &b);
4636 +#endif /* L_compare_sf || L_compare_df */
4638 +#ifndef US_SOFTWARE_GOFAST
4640 +/* These should be optimized for their specific tasks someday. */
4642 +#if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf)
4644 +_eq_f2 (FLO_type arg_a, FLO_type arg_b)
4648 + FLO_union_type au, bu;
4653 + unpack_d (&au, &a);
4654 + unpack_d (&bu, &b);
4656 + if (isnan (&a) || isnan (&b))
4657 + return 1; /* false, truth == 0 */
4659 + return __fpcmp_parts (&a, &b) ;
4661 +#endif /* L_eq_sf || L_eq_df */
4663 +#if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf)
4665 +_ne_f2 (FLO_type arg_a, FLO_type arg_b)
4669 + FLO_union_type au, bu;
4674 + unpack_d (&au, &a);
4675 + unpack_d (&bu, &b);
4677 + if (isnan (&a) || isnan (&b))
4678 + return 1; /* true, truth != 0 */
4680 + return __fpcmp_parts (&a, &b) ;
4682 +#endif /* L_ne_sf || L_ne_df */
4684 +#if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf)
4686 +_gt_f2 (FLO_type arg_a, FLO_type arg_b)
4690 + FLO_union_type au, bu;
4695 + unpack_d (&au, &a);
4696 + unpack_d (&bu, &b);
4698 + if (isnan (&a) || isnan (&b))
4699 + return -1; /* false, truth > 0 */
4701 + return __fpcmp_parts (&a, &b);
4703 +#endif /* L_gt_sf || L_gt_df */
4705 +#if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf)
4707 +_ge_f2 (FLO_type arg_a, FLO_type arg_b)
4711 + FLO_union_type au, bu;
4716 + unpack_d (&au, &a);
4717 + unpack_d (&bu, &b);
4719 + if (isnan (&a) || isnan (&b))
4720 + return -1; /* false, truth >= 0 */
4721 + return __fpcmp_parts (&a, &b) ;
4723 +#endif /* L_ge_sf || L_ge_df */
4725 +#if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf)
4727 +_lt_f2 (FLO_type arg_a, FLO_type arg_b)
4731 + FLO_union_type au, bu;
4736 + unpack_d (&au, &a);
4737 + unpack_d (&bu, &b);
4739 + if (isnan (&a) || isnan (&b))
4740 + return 1; /* false, truth < 0 */
4742 + return __fpcmp_parts (&a, &b);
4744 +#endif /* L_lt_sf || L_lt_df */
4746 +#if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf)
4748 +_le_f2 (FLO_type arg_a, FLO_type arg_b)
4752 + FLO_union_type au, bu;
4757 + unpack_d (&au, &a);
4758 + unpack_d (&bu, &b);
4760 + if (isnan (&a) || isnan (&b))
4761 + return 1; /* false, truth <= 0 */
4763 + return __fpcmp_parts (&a, &b) ;
4765 +#endif /* L_le_sf || L_le_df */
4767 +#endif /* ! US_SOFTWARE_GOFAST */
4769 +#if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf)
4771 +_unord_f2 (FLO_type arg_a, FLO_type arg_b)
4775 + FLO_union_type au, bu;
4780 + unpack_d (&au, &a);
4781 + unpack_d (&bu, &b);
4783 + return (isnan (&a) || isnan (&b));
4785 +#endif /* L_unord_sf || L_unord_df */
4787 +#if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf)
4789 +si_to_float (SItype arg_a)
4791 + fp_number_type in;
4793 + in.class = CLASS_NUMBER;
4794 + in.sign = arg_a < 0;
4797 + in.class = CLASS_ZERO;
4801 + in.normal_exp = FRACBITS + NGARDS;
4804 + /* Special case for minint, since there is no +ve integer
4805 + representation for it */
4806 + if (arg_a == (- MAX_SI_INT - 1))
4808 + return (FLO_type)(- MAX_SI_INT - 1);
4810 + in.fraction.ll = (-arg_a);
4813 + in.fraction.ll = arg_a;
4815 + while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS)))
4817 + in.fraction.ll <<= 1;
4818 + in.normal_exp -= 1;
4821 + return pack_d (&in);
4823 +#endif /* L_si_to_sf || L_si_to_df */
4825 +#if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf)
4827 +usi_to_float (USItype arg_a)
4829 + fp_number_type in;
4834 + in.class = CLASS_ZERO;
4838 + in.class = CLASS_NUMBER;
4839 + in.normal_exp = FRACBITS + NGARDS;
4840 + in.fraction.ll = arg_a;
4842 + while (in.fraction.ll > ((fractype)1 << (FRACBITS + NGARDS)))
4844 + in.fraction.ll >>= 1;
4845 + in.normal_exp += 1;
4847 + while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS)))
4849 + in.fraction.ll <<= 1;
4850 + in.normal_exp -= 1;
4853 + return pack_d (&in);
4857 +#if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si)
4859 +float_to_si (FLO_type arg_a)
4863 + FLO_union_type au;
4866 + unpack_d (&au, &a);
4872 + /* get reasonable MAX_SI_INT... */
4874 + return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
4875 + /* it is a number, but a small one */
4876 + if (a.normal_exp < 0)
4878 + if (a.normal_exp > BITS_PER_SI - 2)
4879 + return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
4880 + tmp = a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
4881 + return a.sign ? (-tmp) : (tmp);
4883 +#endif /* L_sf_to_si || L_df_to_si */
4885 +#if defined(L_sf_to_usi) || defined(L_df_to_usi) || defined(L_tf_to_usi)
4886 +#if defined US_SOFTWARE_GOFAST || defined(L_tf_to_usi)
4887 +/* While libgcc2.c defines its own __fixunssfsi and __fixunsdfsi routines,
4888 + we also define them for GOFAST because the ones in libgcc2.c have the
4889 + wrong names and I'd rather define these here and keep GOFAST CYG-LOC's
4890 + out of libgcc2.c. We can't define these here if not GOFAST because then
4891 + there'd be duplicate copies. */
4894 +float_to_usi (FLO_type arg_a)
4897 + FLO_union_type au;
4900 + unpack_d (&au, &a);
4906 + /* it is a negative number */
4909 + /* get reasonable MAX_USI_INT... */
4911 + return MAX_USI_INT;
4912 + /* it is a number, but a small one */
4913 + if (a.normal_exp < 0)
4915 + if (a.normal_exp > BITS_PER_SI - 1)
4916 + return MAX_USI_INT;
4917 + else if (a.normal_exp > (FRACBITS + NGARDS))
4918 + return a.fraction.ll << (a.normal_exp - (FRACBITS + NGARDS));
4920 + return a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
4922 +#endif /* US_SOFTWARE_GOFAST */
4923 +#endif /* L_sf_to_usi || L_df_to_usi */
4925 +#if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf)
4927 +negate (FLO_type arg_a)
4930 + FLO_union_type au;
4933 + unpack_d (&au, &a);
4936 + return pack_d (&a);
4938 +#endif /* L_negate_sf || L_negate_df */
4942 +#if defined(L_make_sf)
4944 +__make_fp(fp_class_type class,
4945 + unsigned int sign,
4949 + fp_number_type in;
4953 + in.normal_exp = exp;
4954 + in.fraction.ll = frac;
4955 + return pack_d (&in);
4957 +#endif /* L_make_sf */
4961 +/* This enables one to build an fp library that supports float but not double.
4962 + Otherwise, we would get an undefined reference to __make_dp.
4963 + This is needed for some 8-bit ports that can't handle well values that
4964 + are 8-bytes in size, so we just don't support double for them at all. */
4966 +#if defined(L_sf_to_df)
4968 +sf_to_df (SFtype arg_a)
4970 + fp_number_type in;
4971 + FLO_union_type au;
4974 + unpack_d (&au, &in);
4976 + return __make_dp (in.class, in.sign, in.normal_exp,
4977 + ((UDItype) in.fraction.ll) << F_D_BITOFF);
4979 +#endif /* L_sf_to_df */
4981 +#if defined(L_sf_to_tf) && defined(TMODES)
4983 +sf_to_tf (SFtype arg_a)
4985 + fp_number_type in;
4986 + FLO_union_type au;
4989 + unpack_d (&au, &in);
4991 + return __make_tp (in.class, in.sign, in.normal_exp,
4992 + ((UTItype) in.fraction.ll) << F_T_BITOFF);
4994 +#endif /* L_sf_to_df */
4996 +#endif /* ! FLOAT_ONLY */
5001 +extern SFtype __make_fp (fp_class_type, unsigned int, int, USItype);
5003 +#if defined(L_make_df)
5005 +__make_dp (fp_class_type class, unsigned int sign, int exp, UDItype frac)
5007 + fp_number_type in;
5011 + in.normal_exp = exp;
5012 + in.fraction.ll = frac;
5013 + return pack_d (&in);
5015 +#endif /* L_make_df */
5017 +#if defined(L_df_to_sf)
5019 +df_to_sf (DFtype arg_a)
5021 + fp_number_type in;
5023 + FLO_union_type au;
5026 + unpack_d (&au, &in);
5028 + sffrac = in.fraction.ll >> F_D_BITOFF;
5030 + /* We set the lowest guard bit in SFFRAC if we discarded any non
5032 + if ((in.fraction.ll & (((USItype) 1 << F_D_BITOFF) - 1)) != 0)
5035 + return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
5037 +#endif /* L_df_to_sf */
5039 +#if defined(L_df_to_tf) && defined(TMODES) \
5040 + && !defined(FLOAT) && !defined(TFLOAT)
5042 +df_to_tf (DFtype arg_a)
5044 + fp_number_type in;
5045 + FLO_union_type au;
5048 + unpack_d (&au, &in);
5050 + return __make_tp (in.class, in.sign, in.normal_exp,
5051 + ((UTItype) in.fraction.ll) << D_T_BITOFF);
5053 +#endif /* L_sf_to_df */
5056 +#if defined(L_make_tf)
5058 +__make_tp(fp_class_type class,
5059 + unsigned int sign,
5063 + fp_number_type in;
5067 + in.normal_exp = exp;
5068 + in.fraction.ll = frac;
5069 + return pack_d (&in);
5071 +#endif /* L_make_tf */
5073 +#if defined(L_tf_to_df)
5075 +tf_to_df (TFtype arg_a)
5077 + fp_number_type in;
5079 + FLO_union_type au;
5082 + unpack_d (&au, &in);
5084 + sffrac = in.fraction.ll >> D_T_BITOFF;
5086 + /* We set the lowest guard bit in SFFRAC if we discarded any non
5088 + if ((in.fraction.ll & (((UTItype) 1 << D_T_BITOFF) - 1)) != 0)
5091 + return __make_dp (in.class, in.sign, in.normal_exp, sffrac);
5093 +#endif /* L_tf_to_df */
5095 +#if defined(L_tf_to_sf)
5097 +tf_to_sf (TFtype arg_a)
5099 + fp_number_type in;
5101 + FLO_union_type au;
5104 + unpack_d (&au, &in);
5106 + sffrac = in.fraction.ll >> F_T_BITOFF;
5108 + /* We set the lowest guard bit in SFFRAC if we discarded any non
5110 + if ((in.fraction.ll & (((UTItype) 1 << F_T_BITOFF) - 1)) != 0)
5113 + return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
5115 +#endif /* L_tf_to_sf */
5116 +#endif /* TFLOAT */
5118 +#endif /* ! FLOAT */
5119 +#endif /* !EXTENDED_FLOAT_STUBS */
5120 diff -durN gcc-3.4.6.orig/gcc/config/nios2/nios2-fp-bit.c gcc-3.4.6/gcc/config/nios2/nios2-fp-bit.c
5121 --- gcc-3.4.6.orig/gcc/config/nios2/nios2-fp-bit.c 1970-01-01 01:00:00.000000000 +0100
5122 +++ gcc-3.4.6/gcc/config/nios2/nios2-fp-bit.c 2007-08-15 23:09:36.000000000 +0200
5125 +/* This is a software floating point library which can be used
5126 + for targets without hardware floating point.
5127 + Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004
5128 + Free Software Foundation, Inc.
5130 +This file is free software; you can redistribute it and/or modify it
5131 +under the terms of the GNU General Public License as published by the
5132 +Free Software Foundation; either version 2, or (at your option) any
5135 +In addition to the permissions in the GNU General Public License, the
5136 +Free Software Foundation gives you unlimited permission to link the
5137 +compiled version of this file with other programs, and to distribute
5138 +those programs without any restriction coming from the use of this
5139 +file. (The General Public License restrictions do apply in other
5140 +respects; for example, they cover modification of the file, and
5141 +distribution when not linked into another program.)
5143 +This file is distributed in the hope that it will be useful, but
5144 +WITHOUT ANY WARRANTY; without even the implied warranty of
5145 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5146 +General Public License for more details.
5148 +You should have received a copy of the GNU General Public License
5149 +along with this program; see the file COPYING. If not, write to
5150 +the Free Software Foundation, 59 Temple Place - Suite 330,
5151 +Boston, MA 02111-1307, USA. */
5153 +/* As a special exception, if you link this library with other files,
5154 + some of which are compiled with GCC, to produce an executable,
5155 + this library does not by itself cause the resulting executable
5156 + to be covered by the GNU General Public License.
5157 + This exception does not however invalidate any other reasons why
5158 + the executable file might be covered by the GNU General Public License. */
5160 +/* This implements IEEE 754 format arithmetic, but does not provide a
5161 + mechanism for setting the rounding mode, or for generating or handling
5164 + The original code by Steve Chamberlain, hacked by Mark Eichin and Jim
5165 + Wilson, all of Cygnus Support. */
5167 +/* The intended way to use this file is to make two copies, add `#define FLOAT'
5168 + to one copy, then compile both copies and add them to libgcc.a. */
5170 +#include "tconfig.h"
5171 +#include "coretypes.h"
5173 +#include "config/fp-bit.h"
5175 +/* The following macros can be defined to change the behavior of this file:
5176 + FLOAT: Implement a `float', aka SFmode, fp library. If this is not
5177 + defined, then this file implements a `double', aka DFmode, fp library.
5178 + FLOAT_ONLY: Used with FLOAT, to implement a `float' only library, i.e.
5179 + don't include float->double conversion which requires the double library.
5180 + This is useful only for machines which can't support doubles, e.g. some
5182 + CMPtype: Specify the type that floating point compares should return.
5183 + This defaults to SItype, aka int.
5184 + US_SOFTWARE_GOFAST: This makes all entry points use the same names as the
5185 + US Software goFast library.
5186 + _DEBUG_BITFLOAT: This makes debugging the code a little easier, by adding
5187 + two integers to the FLO_union_type.
5188 + NO_DENORMALS: Disable handling of denormals.
5189 + NO_NANS: Disable nan and infinity handling
5190 + SMALL_MACHINE: Useful when operations on QIs and HIs are faster
5193 +/* We don't currently support extended floats (long doubles) on machines
5194 + without hardware to deal with them.
5196 + These stubs are just to keep the linker from complaining about unresolved
5197 + references which can be pulled in from libio & libstdc++, even if the
5198 + user isn't using long doubles. However, they may generate an unresolved
5199 + external to abort if abort is not used by the function, and the stubs
5200 + are referenced from within libc, since libgcc goes before and after the
5201 + system library. */
5203 +#ifdef DECLARE_LIBRARY_RENAMES
5204 + DECLARE_LIBRARY_RENAMES
5207 +#ifdef EXTENDED_FLOAT_STUBS
5208 +extern void abort (void);
5209 +void __extendsfxf2 (void) { abort(); }
5210 +void __extenddfxf2 (void) { abort(); }
5211 +void __truncxfdf2 (void) { abort(); }
5212 +void __truncxfsf2 (void) { abort(); }
5213 +void __fixxfsi (void) { abort(); }
5214 +void __floatsixf (void) { abort(); }
5215 +void __addxf3 (void) { abort(); }
5216 +void __subxf3 (void) { abort(); }
5217 +void __mulxf3 (void) { abort(); }
5218 +void __divxf3 (void) { abort(); }
5219 +void __negxf2 (void) { abort(); }
5220 +void __eqxf2 (void) { abort(); }
5221 +void __nexf2 (void) { abort(); }
5222 +void __gtxf2 (void) { abort(); }
5223 +void __gexf2 (void) { abort(); }
5224 +void __lexf2 (void) { abort(); }
5225 +void __ltxf2 (void) { abort(); }
5227 +void __extendsftf2 (void) { abort(); }
5228 +void __extenddftf2 (void) { abort(); }
5229 +void __trunctfdf2 (void) { abort(); }
5230 +void __trunctfsf2 (void) { abort(); }
5231 +void __fixtfsi (void) { abort(); }
5232 +void __floatsitf (void) { abort(); }
5233 +void __addtf3 (void) { abort(); }
5234 +void __subtf3 (void) { abort(); }
5235 +void __multf3 (void) { abort(); }
5236 +void __divtf3 (void) { abort(); }
5237 +void __negtf2 (void) { abort(); }
5238 +void __eqtf2 (void) { abort(); }
5239 +void __netf2 (void) { abort(); }
5240 +void __gttf2 (void) { abort(); }
5241 +void __getf2 (void) { abort(); }
5242 +void __letf2 (void) { abort(); }
5243 +void __lttf2 (void) { abort(); }
5244 +#else /* !EXTENDED_FLOAT_STUBS, rest of file */
5246 +/* IEEE "special" number predicates */
5255 +#if defined L_thenan_sf
5256 +const fp_number_type __thenan_sf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
5257 +#elif defined L_thenan_df
5258 +const fp_number_type __thenan_df = { CLASS_SNAN, 0, 0, {(fractype) 0} };
5259 +#elif defined L_thenan_tf
5260 +const fp_number_type __thenan_tf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
5261 +#elif defined TFLOAT
5262 +extern const fp_number_type __thenan_tf;
5263 +#elif defined FLOAT
5264 +extern const fp_number_type __thenan_sf;
5266 +extern const fp_number_type __thenan_df;
5270 +static fp_number_type *
5273 + /* Discard the const qualifier... */
5275 + return (fp_number_type *) (& __thenan_tf);
5276 +#elif defined FLOAT
5277 + return (fp_number_type *) (& __thenan_sf);
5279 + return (fp_number_type *) (& __thenan_df);
5285 +isnan ( fp_number_type * x)
5287 + return x->class == CLASS_SNAN || x->class == CLASS_QNAN;
5292 +isinf ( fp_number_type * x)
5294 + return x->class == CLASS_INFINITY;
5297 +#endif /* NO_NANS */
5301 +iszero ( fp_number_type * x)
5303 + return x->class == CLASS_ZERO;
5308 +flip_sign ( fp_number_type * x)
5310 + x->sign = !x->sign;
5313 +extern FLO_type pack_d ( fp_number_type * );
5315 +#if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf)
5317 +pack_d ( fp_number_type * src)
5319 + FLO_union_type dst;
5320 + fractype fraction = src->fraction.ll; /* wasn't unsigned before? */
5321 + int sign = src->sign;
5324 + if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && (isnan (src) || isinf (src)))
5326 + /* We can't represent these values accurately. By using the
5327 + largest possible magnitude, we guarantee that the conversion
5328 + of infinity is at least as big as any finite number. */
5330 + fraction = ((fractype) 1 << FRACBITS) - 1;
5332 + else if (isnan (src))
5335 + if (src->class == CLASS_QNAN || 1)
5337 +#ifdef QUIET_NAN_NEGATED
5338 + fraction |= QUIET_NAN - 1;
5340 + fraction |= QUIET_NAN;
5344 + else if (isinf (src))
5349 + else if (iszero (src))
5354 + else if (fraction == 0)
5360 + if (src->normal_exp < NORMAL_EXPMIN)
5362 +#ifdef NO_DENORMALS
5363 + /* Go straight to a zero representation if denormals are not
5364 + supported. The denormal handling would be harmless but
5365 + isn't unnecessary. */
5368 +#else /* NO_DENORMALS */
5369 + /* This number's exponent is too low to fit into the bits
5370 + available in the number, so we'll store 0 in the exponent and
5371 + shift the fraction to the right to make up for it. */
5373 + int shift = NORMAL_EXPMIN - src->normal_exp;
5377 + if (shift > FRAC_NBITS - NGARDS)
5379 + /* No point shifting, since it's more that 64 out. */
5384 + int lowbit = (fraction & (((fractype)1 << shift) - 1)) ? 1 : 0;
5385 + fraction = (fraction >> shift) | lowbit;
5387 + if ((fraction & GARDMASK) == GARDMSB)
5389 + if ((fraction & (1 << NGARDS)))
5390 + fraction += GARDROUND + 1;
5394 + /* Add to the guards to round up. */
5395 + fraction += GARDROUND;
5397 + /* Perhaps the rounding means we now need to change the
5398 + exponent, because the fraction is no longer denormal. */
5399 + if (fraction >= IMPLICIT_1)
5403 + fraction >>= NGARDS;
5404 +#endif /* NO_DENORMALS */
5406 + else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS)
5407 + && src->normal_exp > EXPBIAS)
5414 + exp = src->normal_exp + EXPBIAS;
5415 + if (!ROUND_TOWARDS_ZERO)
5417 + /* IF the gard bits are the all zero, but the first, then we're
5418 + half way between two numbers, choose the one which makes the
5419 + lsb of the answer 0. */
5420 + if ((fraction & GARDMASK) == GARDMSB)
5422 + if (fraction & (1 << NGARDS))
5423 + fraction += GARDROUND + 1;
5427 + /* Add a one to the guards to round up */
5428 + fraction += GARDROUND;
5430 + if (fraction >= IMPLICIT_2)
5436 + fraction >>= NGARDS;
5438 + if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp > EXPMAX)
5440 + /* Saturate on overflow. */
5442 + fraction = ((fractype) 1 << FRACBITS) - 1;
5447 + /* We previously used bitfields to store the number, but this doesn't
5448 + handle little/big endian systems conveniently, so use shifts and
5450 +#ifdef FLOAT_BIT_ORDER_MISMATCH
5451 + dst.bits.fraction = fraction;
5452 + dst.bits.exp = exp;
5453 + dst.bits.sign = sign;
5455 +# if defined TFLOAT && defined HALFFRACBITS
5457 + halffractype high, low, unity;
5458 + int lowsign, lowexp;
5460 + unity = (halffractype) 1 << HALFFRACBITS;
5462 + /* Set HIGH to the high double's significand, masking out the implicit 1.
5463 + Set LOW to the low double's full significand. */
5464 + high = (fraction >> (FRACBITS - HALFFRACBITS)) & (unity - 1);
5465 + low = fraction & (unity * 2 - 1);
5467 + /* Get the initial sign and exponent of the low double. */
5468 + lowexp = exp - HALFFRACBITS - 1;
5471 + /* HIGH should be rounded like a normal double, making |LOW| <=
5472 + 0.5 ULP of HIGH. Assume round-to-nearest. */
5474 + if (low > unity || (low == unity && (high & 1) == 1))
5476 + /* Round HIGH up and adjust LOW to match. */
5478 + if (high == unity)
5480 + /* May make it infinite, but that's OK. */
5484 + low = unity * 2 - low;
5488 + high |= (halffractype) exp << HALFFRACBITS;
5489 + high |= (halffractype) sign << (HALFFRACBITS + EXPBITS);
5491 + if (exp == EXPMAX || exp == 0 || low == 0)
5495 + while (lowexp > 0 && low < unity)
5503 + halffractype roundmsb, round;
5506 + shift = 1 - lowexp;
5507 + roundmsb = (1 << (shift - 1));
5508 + round = low & ((roundmsb << 1) - 1);
5513 + if (round > roundmsb || (round == roundmsb && (low & 1) == 1))
5517 + /* LOW rounds up to the smallest normal number. */
5523 + low |= (halffractype) lowexp << HALFFRACBITS;
5524 + low |= (halffractype) lowsign << (HALFFRACBITS + EXPBITS);
5526 + dst.value_raw = ((fractype) high << HALFSHIFT) | low;
5529 + dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1);
5530 + dst.value_raw |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << FRACBITS;
5531 + dst.value_raw |= ((fractype) (sign & 1)) << (FRACBITS | EXPBITS);
5535 +#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
5538 + qrtrfractype tmp1 = dst.words[0];
5539 + qrtrfractype tmp2 = dst.words[1];
5540 + dst.words[0] = dst.words[3];
5541 + dst.words[1] = dst.words[2];
5542 + dst.words[2] = tmp2;
5543 + dst.words[3] = tmp1;
5547 + halffractype tmp = dst.words[0];
5548 + dst.words[0] = dst.words[1];
5549 + dst.words[1] = tmp;
5558 +#if defined(L_unpack_df) || defined(L_unpack_sf) || defined(L_unpack_tf)
5560 +unpack_d (FLO_union_type * src, fp_number_type * dst)
5562 + /* We previously used bitfields to store the number, but this doesn't
5563 + handle little/big endian systems conveniently, so use shifts and
5565 + fractype fraction;
5569 +#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
5570 + FLO_union_type swapped;
5573 + swapped.words[0] = src->words[3];
5574 + swapped.words[1] = src->words[2];
5575 + swapped.words[2] = src->words[1];
5576 + swapped.words[3] = src->words[0];
5578 + swapped.words[0] = src->words[1];
5579 + swapped.words[1] = src->words[0];
5584 +#ifdef FLOAT_BIT_ORDER_MISMATCH
5585 + fraction = src->bits.fraction;
5586 + exp = src->bits.exp;
5587 + sign = src->bits.sign;
5589 +# if defined TFLOAT && defined HALFFRACBITS
5591 + halffractype high, low;
5593 + high = src->value_raw >> HALFSHIFT;
5594 + low = src->value_raw & (((fractype)1 << HALFSHIFT) - 1);
5596 + fraction = high & ((((fractype)1) << HALFFRACBITS) - 1);
5597 + fraction <<= FRACBITS - HALFFRACBITS;
5598 + exp = ((int)(high >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
5599 + sign = ((int)(high >> (((HALFFRACBITS + EXPBITS))))) & 1;
5601 + if (exp != EXPMAX && exp != 0 && low != 0)
5603 + int lowexp = ((int)(low >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
5604 + int lowsign = ((int)(low >> (((HALFFRACBITS + EXPBITS))))) & 1;
5608 + xlow = low & ((((fractype)1) << HALFFRACBITS) - 1);
5610 + xlow |= (((halffractype)1) << HALFFRACBITS);
5613 + shift = (FRACBITS - HALFFRACBITS) - (exp - lowexp);
5616 + else if (shift < 0)
5618 + if (sign == lowsign)
5620 + else if (fraction >= xlow)
5624 + /* The high part is a power of two but the full number is lower.
5625 + This code will leave the implicit 1 in FRACTION, but we'd
5626 + have added that below anyway. */
5627 + fraction = (((fractype) 1 << FRACBITS) - xlow) << 1;
5633 + fraction = src->value_raw & ((((fractype)1) << FRACBITS) - 1);
5634 + exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1);
5635 + sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1;
5642 + /* Hmm. Looks like 0 */
5644 +#ifdef NO_DENORMALS
5649 + /* tastes like zero */
5650 + dst->class = CLASS_ZERO;
5654 + /* Zero exponent with nonzero fraction - it's denormalized,
5655 + so there isn't a leading implicit one - we'll shift it so
5657 + dst->normal_exp = exp - EXPBIAS + 1;
5658 + fraction <<= NGARDS;
5660 + dst->class = CLASS_NUMBER;
5662 + while (fraction < IMPLICIT_1)
5665 + dst->normal_exp--;
5668 + dst->fraction.ll = fraction;
5671 + else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp == EXPMAX)
5673 + /* Huge exponent*/
5674 + if (fraction == 0)
5676 + /* Attached to a zero fraction - means infinity */
5677 + dst->class = CLASS_INFINITY;
5681 + /* Nonzero fraction, means nan */
5682 +#ifdef QUIET_NAN_NEGATED
5683 + if ((fraction & QUIET_NAN) == 0)
5685 + if (fraction & QUIET_NAN)
5688 + dst->class = CLASS_QNAN;
5692 + dst->class = CLASS_SNAN;
5694 + /* Keep the fraction part as the nan number */
5695 + dst->fraction.ll = fraction;
5700 + /* Nothing strange about this number */
5701 + dst->normal_exp = exp - EXPBIAS;
5702 + dst->class = CLASS_NUMBER;
5703 + dst->fraction.ll = (fraction << NGARDS) | IMPLICIT_1;
5706 +#endif /* L_unpack_df || L_unpack_sf */
5708 +#if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf)
5709 +static fp_number_type *
5710 +_fpadd_parts (fp_number_type * a,
5711 + fp_number_type * b,
5712 + fp_number_type * tmp)
5714 + intfrac tfraction;
5716 + /* Put commonly used fields in local variables. */
5719 + fractype a_fraction;
5720 + fractype b_fraction;
5732 + /* Adding infinities with opposite signs yields a NaN. */
5733 + if (isinf (b) && a->sign != b->sign)
5746 + tmp->sign = a->sign & b->sign;
5756 + /* Got two numbers. shift the smaller and increment the exponent till
5757 + they're the same */
5761 + a_normal_exp = a->normal_exp;
5762 + b_normal_exp = b->normal_exp;
5763 + a_fraction = a->fraction.ll;
5764 + b_fraction = b->fraction.ll;
5766 + diff = a_normal_exp - b_normal_exp;
5770 + if (diff < FRAC_NBITS)
5772 + /* ??? This does shifts one bit at a time. Optimize. */
5773 + while (a_normal_exp > b_normal_exp)
5776 + LSHIFT (b_fraction);
5778 + while (b_normal_exp > a_normal_exp)
5781 + LSHIFT (a_fraction);
5786 + /* Somethings's up.. choose the biggest */
5787 + if (a_normal_exp > b_normal_exp)
5789 + b_normal_exp = a_normal_exp;
5794 + a_normal_exp = b_normal_exp;
5800 + if (a->sign != b->sign)
5804 + tfraction = -a_fraction + b_fraction;
5808 + tfraction = a_fraction - b_fraction;
5810 + if (tfraction >= 0)
5813 + tmp->normal_exp = a_normal_exp;
5814 + tmp->fraction.ll = tfraction;
5819 + tmp->normal_exp = a_normal_exp;
5820 + tmp->fraction.ll = -tfraction;
5822 + /* and renormalize it */
5824 + while (tmp->fraction.ll < IMPLICIT_1 && tmp->fraction.ll)
5826 + tmp->fraction.ll <<= 1;
5827 + tmp->normal_exp--;
5832 + tmp->sign = a->sign;
5833 + tmp->normal_exp = a_normal_exp;
5834 + tmp->fraction.ll = a_fraction + b_fraction;
5836 + tmp->class = CLASS_NUMBER;
5837 + /* Now the fraction is added, we have to shift down to renormalize the
5840 + if (tmp->fraction.ll >= IMPLICIT_2)
5842 + LSHIFT (tmp->fraction.ll);
5843 + tmp->normal_exp++;
5850 +add (FLO_type arg_a, FLO_type arg_b)
5854 + fp_number_type tmp;
5855 + fp_number_type *res;
5856 + FLO_union_type au, bu;
5861 + unpack_d (&au, &a);
5862 + unpack_d (&bu, &b);
5864 + res = _fpadd_parts (&a, &b, &tmp);
5866 + return pack_d (res);
5870 +sub (FLO_type arg_a, FLO_type arg_b)
5874 + fp_number_type tmp;
5875 + fp_number_type *res;
5876 + FLO_union_type au, bu;
5881 + unpack_d (&au, &a);
5882 + unpack_d (&bu, &b);
5886 + res = _fpadd_parts (&a, &b, &tmp);
5888 + return pack_d (res);
5890 +#endif /* L_addsub_sf || L_addsub_df */
5892 +#if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf)
5893 +static inline __attribute__ ((__always_inline__)) fp_number_type *
5894 +_fpmul_parts ( fp_number_type * a,
5895 + fp_number_type * b,
5896 + fp_number_type * tmp)
5899 + fractype high = 0;
5903 + a->sign = a->sign != b->sign;
5908 + b->sign = a->sign != b->sign;
5915 + a->sign = a->sign != b->sign;
5924 + b->sign = a->sign != b->sign;
5929 + a->sign = a->sign != b->sign;
5934 + b->sign = a->sign != b->sign;
5938 + /* Calculate the mantissa by multiplying both numbers to get a
5939 + twice-as-wide number. */
5941 +#if defined(NO_DI_MODE) || defined(TFLOAT)
5943 + fractype x = a->fraction.ll;
5944 + fractype ylow = b->fraction.ll;
5945 + fractype yhigh = 0;
5948 + /* ??? This does multiplies one bit at a time. Optimize. */
5949 + for (bit = 0; bit < FRAC_NBITS; bit++)
5955 + carry = (low += ylow) < ylow;
5956 + high += yhigh + carry;
5959 + if (ylow & FRACHIGH)
5967 +#elif defined(FLOAT)
5968 + /* Multiplying two USIs to get a UDI, we're safe. */
5970 + UDItype answer = (UDItype)a->fraction.ll * (UDItype)b->fraction.ll;
5972 + high = answer >> BITS_PER_SI;
5976 + /* fractype is DImode, but we need the result to be twice as wide.
5977 + Assuming a widening multiply from DImode to TImode is not
5978 + available, build one by hand. */
5980 + USItype nl = a->fraction.ll;
5981 + USItype nh = a->fraction.ll >> BITS_PER_SI;
5982 + USItype ml = b->fraction.ll;
5983 + USItype mh = b->fraction.ll >> BITS_PER_SI;
5984 + UDItype pp_ll = (UDItype) ml * nl;
5985 + UDItype pp_hl = (UDItype) mh * nl;
5986 + UDItype pp_lh = (UDItype) ml * nh;
5987 + UDItype pp_hh = (UDItype) mh * nh;
5990 + UDItype ps_hh__ = pp_hl + pp_lh;
5991 + if (ps_hh__ < pp_hl)
5992 + res2 += (UDItype)1 << BITS_PER_SI;
5993 + pp_hl = (UDItype)(USItype)ps_hh__ << BITS_PER_SI;
5994 + res0 = pp_ll + pp_hl;
5997 + res2 += (ps_hh__ >> BITS_PER_SI) + pp_hh;
6004 + tmp->normal_exp = a->normal_exp + b->normal_exp
6005 + + FRAC_NBITS - (FRACBITS + NGARDS);
6006 + tmp->sign = a->sign != b->sign;
6007 + while (high >= IMPLICIT_2)
6009 + tmp->normal_exp++;
6017 + while (high < IMPLICIT_1)
6019 + tmp->normal_exp--;
6022 + if (low & FRACHIGH)
6026 + /* rounding is tricky. if we only round if it won't make us round later. */
6028 + if (low & FRACHIGH2)
6030 + if (((high & GARDMASK) != GARDMSB)
6031 + && (((high + 1) & GARDMASK) == GARDMSB))
6033 + /* don't round, it gets done again later. */
6041 + if (!ROUND_TOWARDS_ZERO && (high & GARDMASK) == GARDMSB)
6043 + if (high & (1 << NGARDS))
6045 + /* half way, so round to even */
6046 + high += GARDROUND + 1;
6050 + /* but we really weren't half way */
6051 + high += GARDROUND + 1;
6054 + tmp->fraction.ll = high;
6055 + tmp->class = CLASS_NUMBER;
6060 +multiply (FLO_type arg_a, FLO_type arg_b)
6064 + fp_number_type tmp;
6065 + fp_number_type *res;
6066 + FLO_union_type au, bu;
6071 + unpack_d (&au, &a);
6072 + unpack_d (&bu, &b);
6074 + res = _fpmul_parts (&a, &b, &tmp);
6076 + return pack_d (res);
6078 +#endif /* L_mul_sf || L_mul_df */
6080 +#if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf)
6081 +static inline __attribute__ ((__always_inline__)) fp_number_type *
6082 +_fpdiv_parts (fp_number_type * a,
6083 + fp_number_type * b)
6086 + fractype numerator;
6087 + fractype denominator;
6088 + fractype quotient;
6099 + a->sign = a->sign ^ b->sign;
6101 + if (isinf (a) || iszero (a))
6103 + if (a->class == b->class)
6110 + a->fraction.ll = 0;
6111 + a->normal_exp = 0;
6116 + a->class = CLASS_INFINITY;
6120 + /* Calculate the mantissa by multiplying both 64bit numbers to get a
6124 + ( numerator / denominator) * 2^(numerator exponent - denominator exponent)
6127 + a->normal_exp = a->normal_exp - b->normal_exp;
6128 + numerator = a->fraction.ll;
6129 + denominator = b->fraction.ll;
6131 + if (numerator < denominator)
6133 + /* Fraction will be less than 1.0 */
6139 + /* ??? Does divide one bit at a time. Optimize. */
6142 + if (numerator >= denominator)
6145 + numerator -= denominator;
6151 + if (!ROUND_TOWARDS_ZERO && (quotient & GARDMASK) == GARDMSB)
6153 + if (quotient & (1 << NGARDS))
6155 + /* half way, so round to even */
6156 + quotient += GARDROUND + 1;
6158 + else if (numerator)
6160 + /* but we really weren't half way, more bits exist */
6161 + quotient += GARDROUND + 1;
6165 + a->fraction.ll = quotient;
6171 +divide (FLO_type arg_a, FLO_type arg_b)
6175 + fp_number_type *res;
6176 + FLO_union_type au, bu;
6181 + unpack_d (&au, &a);
6182 + unpack_d (&bu, &b);
6184 + res = _fpdiv_parts (&a, &b);
6186 + return pack_d (res);
6188 +#endif /* L_div_sf || L_div_df */
6190 +#if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) \
6191 + || defined(L_fpcmp_parts_tf)
6192 +/* according to the demo, fpcmp returns a comparison with 0... thus
6199 +__fpcmp_parts (fp_number_type * a, fp_number_type * b)
6202 + /* either nan -> unordered. Must be checked outside of this routine. */
6203 + if (isnan (a) && isnan (b))
6205 + return 1; /* still unordered! */
6209 + if (isnan (a) || isnan (b))
6211 + return 1; /* how to indicate unordered compare? */
6213 + if (isinf (a) && isinf (b))
6215 + /* +inf > -inf, but +inf != +inf */
6216 + /* b \a| +inf(0)| -inf(1)
6217 + ______\+--------+--------
6218 + +inf(0)| a==b(0)| a<b(-1)
6219 + -------+--------+--------
6220 + -inf(1)| a>b(1) | a==b(0)
6221 + -------+--------+--------
6222 + So since unordered must be nonzero, just line up the columns...
6224 + return b->sign - a->sign;
6226 + /* but not both... */
6229 + return a->sign ? -1 : 1;
6233 + return b->sign ? 1 : -1;
6235 + if (iszero (a) && iszero (b))
6241 + return b->sign ? 1 : -1;
6245 + return a->sign ? -1 : 1;
6247 + /* now both are "normal". */
6248 + if (a->sign != b->sign)
6250 + /* opposite signs */
6251 + return a->sign ? -1 : 1;
6253 + /* same sign; exponents? */
6254 + if (a->normal_exp > b->normal_exp)
6256 + return a->sign ? -1 : 1;
6258 + if (a->normal_exp < b->normal_exp)
6260 + return a->sign ? 1 : -1;
6262 + /* same exponents; check size. */
6263 + if (a->fraction.ll > b->fraction.ll)
6265 + return a->sign ? -1 : 1;
6267 + if (a->fraction.ll < b->fraction.ll)
6269 + return a->sign ? 1 : -1;
6271 + /* after all that, they're equal. */
6276 +#if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compoare_tf)
6278 +compare (FLO_type arg_a, FLO_type arg_b)
6282 + FLO_union_type au, bu;
6287 + unpack_d (&au, &a);
6288 + unpack_d (&bu, &b);
6290 + return __fpcmp_parts (&a, &b);
6292 +#endif /* L_compare_sf || L_compare_df */
6294 +#ifndef US_SOFTWARE_GOFAST
6296 +/* These should be optimized for their specific tasks someday. */
6298 +#if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf)
6300 +_eq_f2 (FLO_type arg_a, FLO_type arg_b)
6304 + FLO_union_type au, bu;
6309 + unpack_d (&au, &a);
6310 + unpack_d (&bu, &b);
6312 + if (isnan (&a) || isnan (&b))
6313 + return 1; /* false, truth == 0 */
6315 + return __fpcmp_parts (&a, &b) ;
6317 +#endif /* L_eq_sf || L_eq_df */
6319 +#if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf)
6321 +_ne_f2 (FLO_type arg_a, FLO_type arg_b)
6325 + FLO_union_type au, bu;
6330 + unpack_d (&au, &a);
6331 + unpack_d (&bu, &b);
6333 + if (isnan (&a) || isnan (&b))
6334 + return 1; /* true, truth != 0 */
6336 + return __fpcmp_parts (&a, &b) ;
6338 +#endif /* L_ne_sf || L_ne_df */
6340 +#if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf)
6342 +_gt_f2 (FLO_type arg_a, FLO_type arg_b)
6346 + FLO_union_type au, bu;
6351 + unpack_d (&au, &a);
6352 + unpack_d (&bu, &b);
6354 + if (isnan (&a) || isnan (&b))
6355 + return -1; /* false, truth > 0 */
6357 + return __fpcmp_parts (&a, &b);
6359 +#endif /* L_gt_sf || L_gt_df */
6361 +#if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf)
6363 +_ge_f2 (FLO_type arg_a, FLO_type arg_b)
6367 + FLO_union_type au, bu;
6372 + unpack_d (&au, &a);
6373 + unpack_d (&bu, &b);
6375 + if (isnan (&a) || isnan (&b))
6376 + return -1; /* false, truth >= 0 */
6377 + return __fpcmp_parts (&a, &b) ;
6379 +#endif /* L_ge_sf || L_ge_df */
6381 +#if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf)
6383 +_lt_f2 (FLO_type arg_a, FLO_type arg_b)
6387 + FLO_union_type au, bu;
6392 + unpack_d (&au, &a);
6393 + unpack_d (&bu, &b);
6395 + if (isnan (&a) || isnan (&b))
6396 + return 1; /* false, truth < 0 */
6398 + return __fpcmp_parts (&a, &b);
6400 +#endif /* L_lt_sf || L_lt_df */
6402 +#if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf)
6404 +_le_f2 (FLO_type arg_a, FLO_type arg_b)
6408 + FLO_union_type au, bu;
6413 + unpack_d (&au, &a);
6414 + unpack_d (&bu, &b);
6416 + if (isnan (&a) || isnan (&b))
6417 + return 1; /* false, truth <= 0 */
6419 + return __fpcmp_parts (&a, &b) ;
6421 +#endif /* L_le_sf || L_le_df */
6423 +#endif /* ! US_SOFTWARE_GOFAST */
6425 +#if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf)
6427 +_unord_f2 (FLO_type arg_a, FLO_type arg_b)
6431 + FLO_union_type au, bu;
6436 + unpack_d (&au, &a);
6437 + unpack_d (&bu, &b);
6439 + return (isnan (&a) || isnan (&b));
6441 +#endif /* L_unord_sf || L_unord_df */
6443 +#if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf)
6445 +si_to_float (SItype arg_a)
6447 + fp_number_type in;
6449 + in.class = CLASS_NUMBER;
6450 + in.sign = arg_a < 0;
6453 + in.class = CLASS_ZERO;
6457 + in.normal_exp = FRACBITS + NGARDS;
6460 + /* Special case for minint, since there is no +ve integer
6461 + representation for it */
6462 + if (arg_a == (- MAX_SI_INT - 1))
6464 + return (FLO_type)(- MAX_SI_INT - 1);
6466 + in.fraction.ll = (-arg_a);
6469 + in.fraction.ll = arg_a;
6471 + while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS)))
6473 + in.fraction.ll <<= 1;
6474 + in.normal_exp -= 1;
6477 + return pack_d (&in);
6479 +#endif /* L_si_to_sf || L_si_to_df */
6481 +#if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf)
6483 +usi_to_float (USItype arg_a)
6485 + fp_number_type in;
6490 + in.class = CLASS_ZERO;
6494 + in.class = CLASS_NUMBER;
6495 + in.normal_exp = FRACBITS + NGARDS;
6496 + in.fraction.ll = arg_a;
6498 + while (in.fraction.ll > ((fractype)1 << (FRACBITS + NGARDS)))
6500 + in.fraction.ll >>= 1;
6501 + in.normal_exp += 1;
6503 + while (in.fraction.ll < ((fractype)1 << (FRACBITS + NGARDS)))
6505 + in.fraction.ll <<= 1;
6506 + in.normal_exp -= 1;
6509 + return pack_d (&in);
6513 +#if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si)
6515 +float_to_si (FLO_type arg_a)
6519 + FLO_union_type au;
6522 + unpack_d (&au, &a);
6528 + /* get reasonable MAX_SI_INT... */
6530 + return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
6531 + /* it is a number, but a small one */
6532 + if (a.normal_exp < 0)
6534 + if (a.normal_exp > BITS_PER_SI - 2)
6535 + return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
6536 + tmp = a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
6537 + return a.sign ? (-tmp) : (tmp);
6539 +#endif /* L_sf_to_si || L_df_to_si */
6541 +#if defined(L_sf_to_usi) || defined(L_df_to_usi) || defined(L_tf_to_usi)
6542 +#if defined US_SOFTWARE_GOFAST || defined(L_tf_to_usi)
6543 +/* While libgcc2.c defines its own __fixunssfsi and __fixunsdfsi routines,
6544 + we also define them for GOFAST because the ones in libgcc2.c have the
6545 + wrong names and I'd rather define these here and keep GOFAST CYG-LOC's
6546 + out of libgcc2.c. We can't define these here if not GOFAST because then
6547 + there'd be duplicate copies. */
6550 +float_to_usi (FLO_type arg_a)
6553 + FLO_union_type au;
6556 + unpack_d (&au, &a);
6562 + /* it is a negative number */
6565 + /* get reasonable MAX_USI_INT... */
6567 + return MAX_USI_INT;
6568 + /* it is a number, but a small one */
6569 + if (a.normal_exp < 0)
6571 + if (a.normal_exp > BITS_PER_SI - 1)
6572 + return MAX_USI_INT;
6573 + else if (a.normal_exp > (FRACBITS + NGARDS))
6574 + return a.fraction.ll << (a.normal_exp - (FRACBITS + NGARDS));
6576 + return a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
6578 +#endif /* US_SOFTWARE_GOFAST */
6579 +#endif /* L_sf_to_usi || L_df_to_usi */
6581 +#if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf)
6583 +negate (FLO_type arg_a)
6586 + FLO_union_type au;
6589 + unpack_d (&au, &a);
6592 + return pack_d (&a);
6594 +#endif /* L_negate_sf || L_negate_df */
6598 +#if defined(L_make_sf)
6600 +__make_fp(fp_class_type class,
6601 + unsigned int sign,
6605 + fp_number_type in;
6609 + in.normal_exp = exp;
6610 + in.fraction.ll = frac;
6611 + return pack_d (&in);
6613 +#endif /* L_make_sf */
6617 +/* This enables one to build an fp library that supports float but not double.
6618 + Otherwise, we would get an undefined reference to __make_dp.
6619 + This is needed for some 8-bit ports that can't handle well values that
6620 + are 8-bytes in size, so we just don't support double for them at all. */
6622 +#if defined(L_sf_to_df)
6624 +sf_to_df (SFtype arg_a)
6626 + fp_number_type in;
6627 + FLO_union_type au;
6630 + unpack_d (&au, &in);
6632 + return __make_dp (in.class, in.sign, in.normal_exp,
6633 + ((UDItype) in.fraction.ll) << F_D_BITOFF);
6635 +#endif /* L_sf_to_df */
6637 +#if defined(L_sf_to_tf) && defined(TMODES)
6639 +sf_to_tf (SFtype arg_a)
6641 + fp_number_type in;
6642 + FLO_union_type au;
6645 + unpack_d (&au, &in);
6647 + return __make_tp (in.class, in.sign, in.normal_exp,
6648 + ((UTItype) in.fraction.ll) << F_T_BITOFF);
6650 +#endif /* L_sf_to_df */
6652 +#endif /* ! FLOAT_ONLY */
6657 +extern SFtype __make_fp (fp_class_type, unsigned int, int, USItype);
6659 +#if defined(L_make_df)
6661 +__make_dp (fp_class_type class, unsigned int sign, int exp, UDItype frac)
6663 + fp_number_type in;
6667 + in.normal_exp = exp;
6668 + in.fraction.ll = frac;
6669 + return pack_d (&in);
6671 +#endif /* L_make_df */
6673 +#if defined(L_df_to_sf)
6675 +df_to_sf (DFtype arg_a)
6677 + fp_number_type in;
6679 + FLO_union_type au;
6682 + unpack_d (&au, &in);
6684 + sffrac = in.fraction.ll >> F_D_BITOFF;
6686 + /* We set the lowest guard bit in SFFRAC if we discarded any non
6688 + if ((in.fraction.ll & (((USItype) 1 << F_D_BITOFF) - 1)) != 0)
6691 + return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
6693 +#endif /* L_df_to_sf */
6695 +#if defined(L_df_to_tf) && defined(TMODES) \
6696 + && !defined(FLOAT) && !defined(TFLOAT)
6698 +df_to_tf (DFtype arg_a)
6700 + fp_number_type in;
6701 + FLO_union_type au;
6704 + unpack_d (&au, &in);
6706 + return __make_tp (in.class, in.sign, in.normal_exp,
6707 + ((UTItype) in.fraction.ll) << D_T_BITOFF);
6709 +#endif /* L_sf_to_df */
6712 +#if defined(L_make_tf)
6714 +__make_tp(fp_class_type class,
6715 + unsigned int sign,
6719 + fp_number_type in;
6723 + in.normal_exp = exp;
6724 + in.fraction.ll = frac;
6725 + return pack_d (&in);
6727 +#endif /* L_make_tf */
6729 +#if defined(L_tf_to_df)
6731 +tf_to_df (TFtype arg_a)
6733 + fp_number_type in;
6735 + FLO_union_type au;
6738 + unpack_d (&au, &in);
6740 + sffrac = in.fraction.ll >> D_T_BITOFF;
6742 + /* We set the lowest guard bit in SFFRAC if we discarded any non
6744 + if ((in.fraction.ll & (((UTItype) 1 << D_T_BITOFF) - 1)) != 0)
6747 + return __make_dp (in.class, in.sign, in.normal_exp, sffrac);
6749 +#endif /* L_tf_to_df */
6751 +#if defined(L_tf_to_sf)
6753 +tf_to_sf (TFtype arg_a)
6755 + fp_number_type in;
6757 + FLO_union_type au;
6760 + unpack_d (&au, &in);
6762 + sffrac = in.fraction.ll >> F_T_BITOFF;
6764 + /* We set the lowest guard bit in SFFRAC if we discarded any non
6766 + if ((in.fraction.ll & (((UTItype) 1 << F_T_BITOFF) - 1)) != 0)
6769 + return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
6771 +#endif /* L_tf_to_sf */
6772 +#endif /* TFLOAT */
6774 +#endif /* ! FLOAT */
6775 +#endif /* !EXTENDED_FLOAT_STUBS */
6776 diff -durN gcc-3.4.6.orig/gcc/config/nios2/nios2.h gcc-3.4.6/gcc/config/nios2/nios2.h
6777 --- gcc-3.4.6.orig/gcc/config/nios2/nios2.h 1970-01-01 01:00:00.000000000 +0100
6778 +++ gcc-3.4.6/gcc/config/nios2/nios2.h 2007-08-15 23:09:36.000000000 +0200
6780 +/* Definitions of target machine for Altera NIOS 2G NIOS2 version.
6781 + Copyright (C) 2003 Altera
6782 + Contributed by Jonah Graham (jgraham@altera.com).
6784 +This file is part of GNU CC.
6786 +GNU CC is free software; you can redistribute it and/or modify
6787 +it under the terms of the GNU General Public License as published by
6788 +the Free Software Foundation; either version 2, or (at your option)
6791 +GNU CC is distributed in the hope that it will be useful,
6792 +but WITHOUT ANY WARRANTY; without even the implied warranty of
6793 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6794 +GNU General Public License for more details.
6796 +You should have received a copy of the GNU General Public License
6797 +along with GNU CC; see the file COPYING. If not, write to
6798 +the Free Software Foundation, 59 Temple Place - Suite 330,
6799 +Boston, MA 02111-1307, USA. */
6803 +#define TARGET_CPU_CPP_BUILTINS() \
6806 + builtin_define_std ("NIOS2"); \
6807 + builtin_define_std ("nios2"); \
6808 + builtin_define ("_GNU_SOURCE"); \
6811 +#define TARGET_VERSION fprintf (stderr, " (Altera Nios II)")
6817 +/*********************************
6818 + * Run-time Target Specification
6819 + *********************************/
6821 +#define HAS_DIV_FLAG 0x0001
6822 +#define HAS_MUL_FLAG 0x0002
6823 +#define HAS_MULX_FLAG 0x0004
6824 +#define FAST_SW_DIV_FLAG 0x0008
6825 +#define INLINE_MEMCPY_FLAG 0x00010
6826 +#define CACHE_VOLATILE_FLAG 0x0020
6827 +#define BYPASS_CACHE_FLAG 0x0040
6829 +extern int target_flags;
6830 +#define TARGET_HAS_DIV (target_flags & HAS_DIV_FLAG)
6831 +#define TARGET_HAS_MUL (target_flags & HAS_MUL_FLAG)
6832 +#define TARGET_HAS_MULX (target_flags & HAS_MULX_FLAG)
6833 +#define TARGET_FAST_SW_DIV (target_flags & FAST_SW_DIV_FLAG)
6834 +#define TARGET_INLINE_MEMCPY (target_flags & INLINE_MEMCPY_FLAG)
6835 +#define TARGET_CACHE_VOLATILE (target_flags & CACHE_VOLATILE_FLAG)
6836 +#define TARGET_BYPASS_CACHE (target_flags & BYPASS_CACHE_FLAG)
6838 +#define TARGET_SWITCHES \
6840 + { "hw-div", HAS_DIV_FLAG, \
6841 + N_("Enable DIV, DIVU") }, \
6842 + { "no-hw-div", -HAS_DIV_FLAG, \
6843 + N_("Disable DIV, DIVU (default)") }, \
6844 + { "hw-mul", HAS_MUL_FLAG, \
6845 + N_("Enable MUL instructions (default)") }, \
6846 + { "hw-mulx", HAS_MULX_FLAG, \
6847 + N_("Enable MULX instructions, assume fast shifter") }, \
6848 + { "no-hw-mul", -HAS_MUL_FLAG, \
6849 + N_("Disable MUL instructions") }, \
6850 + { "no-hw-mulx", -HAS_MULX_FLAG, \
6851 + N_("Disable MULX instructions, assume slow shifter (default and implied by -mno-hw-mul)") }, \
6852 + { "fast-sw-div", FAST_SW_DIV_FLAG, \
6853 + N_("Use table based fast divide (default at -O3)") }, \
6854 + { "no-fast-sw-div", -FAST_SW_DIV_FLAG, \
6855 + N_("Don't use table based fast divide ever") }, \
6856 + { "inline-memcpy", INLINE_MEMCPY_FLAG, \
6857 + N_("Inline small memcpy (default when optimizing)") }, \
6858 + { "no-inline-memcpy", -INLINE_MEMCPY_FLAG, \
6859 + N_("Don't Inline small memcpy") }, \
6860 + { "cache-volatile", CACHE_VOLATILE_FLAG, \
6861 + N_("Volatile accesses use non-io variants of instructions (default)") }, \
6862 + { "no-cache-volatile", -CACHE_VOLATILE_FLAG, \
6863 + N_("Volatile accesses use io variants of instructions") }, \
6864 + { "bypass-cache", BYPASS_CACHE_FLAG, \
6865 + N_("All ld/st instructins use io variants") }, \
6866 + { "no-bypass-cache", -BYPASS_CACHE_FLAG, \
6867 + N_("All ld/st instructins do not use io variants (default)") }, \
6869 + N_("Link with a limited version of the C library") }, \
6870 + { "ctors-in-init", 0, \
6871 + "" /* undocumented: N_("Link with static constructors and destructors in init") */ }, \
6872 + { "", TARGET_DEFAULT, 0 } \
6876 +extern const char *nios2_sys_nosys_string; /* for -msys=nosys */
6877 +extern const char *nios2_sys_lib_string; /* for -msys-lib= */
6878 +extern const char *nios2_sys_crt0_string; /* for -msys-crt0= */
6880 +#define TARGET_OPTIONS \
6882 + { "sys=nosys", &nios2_sys_nosys_string, \
6883 + N_("Use stub versions of OS library calls (default)"), 0}, \
6884 + { "sys-lib=", &nios2_sys_lib_string, \
6885 + N_("Name of System Library to link against. (Converted to a -l option)"), 0}, \
6886 + { "sys-crt0=", &nios2_sys_crt0_string, \
6887 + N_("Name of the startfile. (default is a crt0 for the ISS only)"), 0}, \
6891 +/* Default target_flags if no switches specified. */
6892 +#ifndef TARGET_DEFAULT
6893 +# define TARGET_DEFAULT (HAS_MUL_FLAG | CACHE_VOLATILE_FLAG)
6896 +/* Switch Recognition by gcc.c. Add -G xx support */
6897 +#undef SWITCH_TAKES_ARG
6898 +#define SWITCH_TAKES_ARG(CHAR) \
6899 + (DEFAULT_SWITCH_TAKES_ARG (CHAR) || (CHAR) == 'G')
6901 +#define OVERRIDE_OPTIONS override_options ()
6902 +#define OPTIMIZATION_OPTIONS(LEVEL, SIZE) optimization_options (LEVEL, SIZE)
6903 +#define CAN_DEBUG_WITHOUT_FP
6905 +#define CC1_SPEC "\
6910 +"--start-group %{msmallc: -lsmallc} %{!msmallc: -lc} -lgcc \
6911 + %{msys-lib=*: -l%*} \
6912 + %{!msys-lib=*: -lc } \
6914 + %{msys-lib=: %eYou need a library name for -msys-lib=} \
6918 +#undef STARTFILE_SPEC
6919 +#define STARTFILE_SPEC \
6920 +"%{msys-crt0=*: %*} %{!msys-crt0=*: crt1%O%s} \
6921 + %{msys-crt0=: %eYou need a C startup file for -msys-crt0=} \
6922 + %{mctors-in-init: crti%O%s crtbegin%O%s} \
6925 +#undef ENDFILE_SPEC
6926 +#define ENDFILE_SPEC \
6927 + "%{mctors-in-init: crtend%O%s crtn%O%s}"
6930 +/***********************
6932 + ***********************/
6934 +#define DEFAULT_SIGNED_CHAR 1
6935 +#define BITS_BIG_ENDIAN 0
6936 +#define BYTES_BIG_ENDIAN 0
6937 +#define WORDS_BIG_ENDIAN 0
6938 +#define BITS_PER_UNIT 8
6939 +#define BITS_PER_WORD 32
6940 +#define UNITS_PER_WORD 4
6941 +#define POINTER_SIZE 32
6942 +#define BIGGEST_ALIGNMENT 32
6943 +#define STRICT_ALIGNMENT 1
6944 +#define FUNCTION_BOUNDARY 32
6945 +#define PARM_BOUNDARY 32
6946 +#define STACK_BOUNDARY 32
6947 +#define PREFERRED_STACK_BOUNDARY 32
6948 +#define MAX_FIXED_MODE_SIZE 64
6950 +#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
6951 + ((TREE_CODE (EXP) == STRING_CST) \
6952 + && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
6955 +/**********************
6956 + * Layout of Source Language Data Types
6957 + **********************/
6959 +#define INT_TYPE_SIZE 32
6960 +#define SHORT_TYPE_SIZE 16
6961 +#define LONG_TYPE_SIZE 32
6962 +#define LONG_LONG_TYPE_SIZE 64
6963 +#define FLOAT_TYPE_SIZE 32
6964 +#define DOUBLE_TYPE_SIZE 64
6965 +#define LONG_DOUBLE_TYPE_SIZE DOUBLE_TYPE_SIZE
6968 +/*************************
6969 + * Condition Code Status
6970 + ************************/
6972 +/* comparison type */
6973 +/* ??? currently only CMP_SI is used */
6975 + CMP_SI, /* compare four byte integers */
6976 + CMP_DI, /* compare eight byte integers */
6977 + CMP_SF, /* compare single precision floats */
6978 + CMP_DF, /* compare double precision floats */
6979 + CMP_MAX /* max comparison type */
6982 +extern GTY(()) rtx branch_cmp[2]; /* operands for compare */
6983 +extern enum cmp_type branch_type; /* what type of branch to use */
6985 +/**********************
6987 + **********************/
6989 +/* ---------------------------------- *
6990 + * Basic Characteristics of Registers
6991 + * ---------------------------------- */
6998 +0 r0 zero always zero
6999 +1 r1 at Assembler Temporary
7000 +2-3 r2-r3 Return Location
7001 +4-7 r4-r7 Register Arguments
7002 +8-15 r8-r15 Caller Saved Registers
7003 +16-22 r16-r22 Callee Saved Registers
7004 +23 r23 sc Static Chain (Callee Saved)
7005 + ??? Does $sc want to be caller or callee
7006 + saved. If caller, 15, else 23.
7007 +24 r24 Exception Temporary
7008 +25 r25 Breakpoint Temporary
7009 +26 r26 gp Global Pointer
7010 +27 r27 sp Stack Pointer
7011 +28 r28 fp Frame Pointer
7012 +29 r29 ea Exception Return Address
7013 +30 r30 ba Breakpoint Return Address
7014 +31 r31 ra Return Address
7017 +33 ctl1 estatus STATUS saved by exception ?
7018 +34 ctl2 bstatus STATUS saved by break ?
7019 +35 ctl3 ipri Interrupt Priority Mask ?
7020 +36 ctl4 ecause Exception Cause ?
7022 +37 pc Not an actual register
7024 +38 rap Return address pointer, this does not
7025 + actually exist and will be eliminated
7027 +39 fake_fp Fake Frame Pointer which will always be eliminated.
7028 +40 fake_ap Fake Argument Pointer which will always be eliminated.
7030 +41 First Pseudo Register
7033 +The definitions for all the hard register numbers
7034 +are located in nios2.md.
7037 +#define FIRST_PSEUDO_REGISTER 41
7038 +#define NUM_ARG_REGS (LAST_ARG_REGNO - FIRST_ARG_REGNO + 1)
7042 +/* also see CONDITIONAL_REGISTER_USAGE */
7043 +#define FIXED_REGISTERS \
7045 +/* +0 1 2 3 4 5 6 7 8 9 */ \
7046 +/* 0 */ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, \
7047 +/* 10 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
7048 +/* 20 */ 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, \
7049 +/* 30 */ 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, \
7053 +/* call used is the same as caller saved
7054 + + fixed regs + args + ret vals */
7055 +#define CALL_USED_REGISTERS \
7057 +/* +0 1 2 3 4 5 6 7 8 9 */ \
7058 +/* 0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
7059 +/* 10 */ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, \
7060 +/* 20 */ 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, \
7061 +/* 30 */ 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, \
7065 +#define HARD_REGNO_NREGS(REGNO, MODE) \
7066 + ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \
7069 +/* --------------------------- *
7070 + * How Values Fit in Registers
7071 + * --------------------------- */
7073 +#define HARD_REGNO_MODE_OK(REGNO, MODE) 1
7075 +#define MODES_TIEABLE_P(MODE1, MODE2) 1
7078 +/*************************
7079 + * Register Classes
7080 + *************************/
7089 +#define N_REG_CLASSES (int) LIM_REG_CLASSES
7091 +#define REG_CLASS_NAMES \
7095 +#define GENERAL_REGS ALL_REGS
7097 +#define REG_CLASS_CONTENTS \
7098 +/* NO_REGS */ {{ 0, 0}, \
7099 +/* ALL_REGS */ {~0,~0}} \
7101 +#define REGNO_REG_CLASS(REGNO) ALL_REGS
7103 +#define BASE_REG_CLASS ALL_REGS
7104 +#define INDEX_REG_CLASS ALL_REGS
7106 +/* only one reg class, 'r', is handled automatically */
7107 +#define REG_CLASS_FROM_LETTER(CHAR) NO_REGS
7109 +#define REGNO_OK_FOR_BASE_P2(REGNO, STRICT) \
7111 + ? (REGNO) < FIRST_PSEUDO_REGISTER \
7112 + : (REGNO) < FIRST_PSEUDO_REGISTER || (reg_renumber && reg_renumber[REGNO] < FIRST_PSEUDO_REGISTER))
7114 +#define REGNO_OK_FOR_INDEX_P2(REGNO, STRICT) \
7115 + (REGNO_OK_FOR_BASE_P2 (REGNO, STRICT))
7117 +#define REGNO_OK_FOR_BASE_P(REGNO) \
7118 + (REGNO_OK_FOR_BASE_P2 (REGNO, 1))
7120 +#define REGNO_OK_FOR_INDEX_P(REGNO) \
7121 + (REGNO_OK_FOR_INDEX_P2 (REGNO, 1))
7123 +#define REG_OK_FOR_BASE_P2(X, STRICT) \
7125 + ? REGNO_OK_FOR_BASE_P2 (REGNO (X), 1) \
7126 + : REGNO_OK_FOR_BASE_P2 (REGNO (X), 1) || REGNO(X) >= FIRST_PSEUDO_REGISTER)
7128 +#define REG_OK_FOR_INDEX_P2(X, STRICT) \
7130 + ? REGNO_OK_FOR_INDEX_P2 (REGNO (X), 1) \
7131 + : REGNO_OK_FOR_INDEX_P2 (REGNO (X), 1) || REGNO(X) >= FIRST_PSEUDO_REGISTER)
7133 +#define CLASS_MAX_NREGS(CLASS, MODE) \
7134 + ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \
7138 +#define SMALL_INT(X) ((unsigned HOST_WIDE_INT) ((X) + 0x8000) < 0x10000)
7139 +#define SMALL_INT_UNSIGNED(X) ((unsigned HOST_WIDE_INT) (X) < 0x10000)
7140 +#define UPPER16_INT(X) (((X) & 0xffff) == 0)
7141 +#define SHIFT_INT(X) ((X) >= 0 && (X) <= 31)
7142 +#define RDWRCTL_INT(X) ((X) >= 0 && (X) <= 31)
7143 +#define CUSTOM_INSN_OPCODE(X) ((X) >= 0 && (X) <= 255)
7145 +#define CONST_OK_FOR_LETTER_P(VALUE, C) \
7147 + (C) == 'I' ? SMALL_INT (VALUE) : \
7148 + (C) == 'J' ? SMALL_INT_UNSIGNED (VALUE) : \
7149 + (C) == 'K' ? UPPER16_INT (VALUE) : \
7150 + (C) == 'L' ? SHIFT_INT (VALUE) : \
7151 + (C) == 'M' ? (VALUE) == 0 : \
7152 + (C) == 'N' ? CUSTOM_INSN_OPCODE (VALUE) : \
7153 + (C) == 'O' ? RDWRCTL_INT (VALUE) : \
7156 +#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) 0
7158 +#define PREFERRED_RELOAD_CLASS(X, CLASS) \
7159 + ((CLASS) == NO_REGS ? GENERAL_REGS : (CLASS))
7161 +/* 'S' matches immediates which are in small data
7162 + and therefore can be added to gp to create a
7164 +#define EXTRA_CONSTRAINT(VALUE, C) \
7166 + && (GET_CODE (VALUE) == SYMBOL_REF) \
7167 + && SYMBOL_REF_IN_NIOS2_SMALL_DATA_P (VALUE))
7172 +/* Say that the epilogue uses the return address register. Note that
7173 + in the case of sibcalls, the values "used by the epilogue" are
7174 + considered live at the start of the called function. */
7175 +#define EPILOGUE_USES(REGNO) ((REGNO) == RA_REGNO)
7178 +#define DEFAULT_MAIN_RETURN c_expand_return (integer_zero_node)
7180 +/**********************************
7181 + * Trampolines for Nested Functions
7182 + ***********************************/
7184 +#define TRAMPOLINE_TEMPLATE(FILE) \
7185 + error ("trampolines not yet implemented")
7186 +#define TRAMPOLINE_SIZE 20
7187 +#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
7188 + error ("trampolines not yet implemented")
7190 +/***************************
7191 + * Stack Layout and Calling Conventions
7192 + ***************************/
7194 +/* ------------------ *
7195 + * Basic Stack Layout
7196 + * ------------------ */
7198 +/* The downward variants are used by the compiler,
7199 + the upward ones serve as documentation */
7200 +#define STACK_GROWS_DOWNWARD
7201 +#define FRAME_GROWS_UPWARD
7202 +#define ARGS_GROW_UPWARD
7204 +#define STARTING_FRAME_OFFSET current_function_outgoing_args_size
7205 +#define FIRST_PARM_OFFSET(FUNDECL) 0
7207 +/* Before the prologue, RA lives in r31. */
7208 +#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (VOIDmode, RA_REGNO)
7210 +/* -------------------------------------- *
7211 + * Registers That Address the Stack Frame
7212 + * -------------------------------------- */
7214 +#define STACK_POINTER_REGNUM SP_REGNO
7215 +#define STATIC_CHAIN_REGNUM SC_REGNO
7216 +#define PC_REGNUM PC_REGNO
7217 +#define DWARF_FRAME_RETURN_COLUMN RA_REGNO
7219 +/* Base register for access to local variables of the function. We
7220 + pretend that the frame pointer is a non-existent hard register, and
7221 + then eliminate it to HARD_FRAME_POINTER_REGNUM. */
7222 +#define FRAME_POINTER_REGNUM FAKE_FP_REGNO
7224 +#define HARD_FRAME_POINTER_REGNUM FP_REGNO
7225 +#define RETURN_ADDRESS_POINTER_REGNUM RAP_REGNO
7226 +/* the argumnet pointer needs to always be eliminated
7227 + so it is set to a fake hard register. */
7228 +#define ARG_POINTER_REGNUM FAKE_AP_REGNO
7230 +/* ----------------------------------------- *
7231 + * Eliminating Frame Pointer and Arg Pointer
7232 + * ----------------------------------------- */
7234 +#define FRAME_POINTER_REQUIRED 0
7236 +#define ELIMINABLE_REGS \
7237 +{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
7238 + { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
7239 + { RETURN_ADDRESS_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
7240 + { RETURN_ADDRESS_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
7241 + { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
7242 + { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
7244 +#define CAN_ELIMINATE(FROM, TO) 1
7246 +#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
7247 + (OFFSET) = nios2_initial_elimination_offset ((FROM), (TO))
7249 +#define MUST_SAVE_REGISTER(regno) \
7250 + ((regs_ever_live[regno] && !call_used_regs[regno]) \
7251 + || (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed) \
7252 + || (regno == RA_REGNO && regs_ever_live[RA_REGNO]))
7254 +/* Treat LOC as a byte offset from the stack pointer and round it up
7255 + to the next fully-aligned offset. */
7256 +#define STACK_ALIGN(LOC) \
7257 + (((LOC) + ((PREFERRED_STACK_BOUNDARY / 8) - 1)) & ~((PREFERRED_STACK_BOUNDARY / 8) - 1))
7260 +/* ------------------------------ *
7261 + * Passing Arguments in Registers
7262 + * ------------------------------ */
7265 +#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
7266 + (function_arg (&CUM, MODE, TYPE, NAMED))
7268 +#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
7269 + (function_arg_partial_nregs (&CUM, MODE, TYPE, NAMED))
7271 +#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) 0
7273 +#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) 0
7275 +typedef struct nios2_args
7280 +/* This is to initialize the above unused CUM data type */
7281 +#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \
7282 + (init_cumulative_args (&CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS))
7284 +#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
7285 + (function_arg_advance (&CUM, MODE, TYPE, NAMED))
7287 +#define FUNCTION_ARG_REGNO_P(REGNO) \
7288 + ((REGNO) >= FIRST_ARG_REGNO && (REGNO) <= LAST_ARG_REGNO)
7290 +#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \
7292 + int pret_size = nios2_setup_incoming_varargs (&(CUM), (MODE), \
7293 + (TYPE), (NO_RTL)); \
7295 + (PRETEND_SIZE) = pret_size; \
7298 +/* ----------------------------- *
7299 + * Generating Code for Profiling
7300 + * ----------------------------- */
7302 +#define PROFILE_BEFORE_PROLOGUE
7304 +#define FUNCTION_PROFILER(FILE, LABELNO) \
7305 + function_profiler ((FILE), (LABELNO))
7307 +/* --------------------------------------- *
7308 + * Passing Function Arguments on the Stack
7309 + * --------------------------------------- */
7311 +#define PROMOTE_PROTOTYPES 1
7313 +#define PUSH_ARGS 0
7314 +#define ACCUMULATE_OUTGOING_ARGS 1
7316 +#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACKSIZE) 0
7318 +/* --------------------------------------- *
7319 + * How Scalar Function Values Are Returned
7320 + * --------------------------------------- */
7322 +#define FUNCTION_VALUE(VALTYPE, FUNC) \
7323 + gen_rtx(REG, TYPE_MODE(VALTYPE), FIRST_RETVAL_REGNO)
7325 +#define LIBCALL_VALUE(MODE) \
7326 + gen_rtx(REG, MODE, FIRST_RETVAL_REGNO)
7328 +#define FUNCTION_VALUE_REGNO_P(REGNO) ((REGNO) == FIRST_RETVAL_REGNO)
7330 +/* ----------------------------- *
7331 + * How Large Values Are Returned
7332 + * ----------------------------- */
7335 +#define RETURN_IN_MEMORY(TYPE) \
7336 + nios2_return_in_memory (TYPE)
7339 +#define STRUCT_VALUE 0
7341 +#define DEFAULT_PCC_STRUCT_RETURN 0
7343 +/*******************
7344 + * Addressing Modes
7345 + *******************/
7348 +#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)
7350 +#define CONSTANT_ADDRESS_P(X) (CONSTANT_P (X))
7352 +#define MAX_REGS_PER_ADDRESS 1
7354 +/* Go to ADDR if X is a valid address. */
7355 +#ifndef REG_OK_STRICT
7356 +#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
7358 + if (nios2_legitimate_address ((X), (MODE), 0)) \
7362 +#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
7364 + if (nios2_legitimate_address ((X), (MODE), 1)) \
7369 +#ifndef REG_OK_STRICT
7370 +#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P2 (REGNO (X), 0)
7371 +#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P2 (REGNO (X), 0)
7373 +#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P2 (REGNO (X), 1)
7374 +#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P2 (REGNO (X), 1)
7377 +#define LEGITIMATE_CONSTANT_P(X) 1
7379 +/* Nios II has no mode dependent addresses. */
7380 +#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)
7382 +/* Set if this has a weak declaration */
7383 +#define SYMBOL_FLAG_WEAK_DECL (1 << SYMBOL_FLAG_MACH_DEP_SHIFT)
7384 +#define SYMBOL_REF_WEAK_DECL_P(RTX) \
7385 + ((SYMBOL_REF_FLAGS (RTX) & SYMBOL_FLAG_WEAK_DECL) != 0)
7388 +/* true if a symbol is both small and not weak. In this case, gp
7389 + relative access can be used */
7390 +#define SYMBOL_REF_IN_NIOS2_SMALL_DATA_P(RTX) \
7391 + (SYMBOL_REF_SMALL_P(RTX) && !SYMBOL_REF_WEAK_DECL_P(RTX))
7394 + * Describing Relative Costs of Operations
7395 + *****************/
7397 +#define SLOW_BYTE_ACCESS 1
7399 +/* It is as good to call a constant function address as to call an address
7400 + kept in a register.
7401 + ??? Not true anymore really. Now that call cannot address full range
7402 + of memory callr may need to be used */
7404 +#define NO_FUNCTION_CSE
7405 +#define NO_RECURSIVE_FUNCTION_CSE
7409 +/*****************************************
7410 + * Defining the Output Assembler Language
7411 + *****************************************/
7413 +/* ------------------------------------------ *
7414 + * The Overall Framework of an Assembler File
7415 + * ------------------------------------------ */
7417 +#define ASM_APP_ON "#APP\n"
7418 +#define ASM_APP_OFF "#NO_APP\n"
7420 +#define ASM_COMMENT_START "# "
7422 +/* ------------------------------- *
7423 + * Output and Generation of Labels
7424 + * ------------------------------- */
7426 +#define GLOBAL_ASM_OP "\t.global\t"
7429 +/* -------------- *
7431 + * -------------- */
7433 +#define DWARF2_UNWIND_INFO 0
7436 +/* -------------------------------- *
7437 + * Assembler Commands for Alignment
7438 + * -------------------------------- */
7440 +#define ASM_OUTPUT_ALIGN(FILE, LOG) \
7442 + fprintf ((FILE), "%s%d\n", ALIGN_ASM_OP, (LOG)); \
7446 +/* -------------------------------- *
7447 + * Output of Assembler Instructions
7448 + * -------------------------------- */
7450 +#define REGISTER_NAMES \
7495 +#define ASM_OUTPUT_OPCODE(STREAM, PTR)\
7496 + (PTR) = asm_output_opcode (STREAM, PTR)
7498 +#define PRINT_OPERAND(STREAM, X, CODE) \
7499 + nios2_print_operand (STREAM, X, CODE)
7501 +#define PRINT_OPERAND_ADDRESS(STREAM, X) \
7502 + nios2_print_operand_address (STREAM, X)
7504 +#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
7505 +do { fputs (integer_asm_op (POINTER_SIZE / BITS_PER_UNIT, TRUE), FILE); \
7506 + fprintf (FILE, ".L%u\n", (unsigned) (VALUE)); \
7515 +/* ---------------------------------------------------- *
7516 + * Dividing the Output into Sections (Texts, Data, ...)
7517 + * ---------------------------------------------------- */
7519 +/* Output before read-only data. */
7520 +#define TEXT_SECTION_ASM_OP ("\t.section\t.text")
7522 +/* Output before writable data. */
7523 +#define DATA_SECTION_ASM_OP ("\t.section\t.data")
7526 +/* Default the definition of "small data" to 8 bytes. */
7527 +/* ??? How come I can't use HOST_WIDE_INT here? */
7528 +extern unsigned long nios2_section_threshold;
7529 +#define NIOS2_DEFAULT_GVALUE 8
7533 +/* This says how to output assembler code to declare an
7534 + uninitialized external linkage data object. Under SVR4,
7535 + the linker seems to want the alignment of data objects
7536 + to depend on their types. We do exactly that here. */
7538 +#undef COMMON_ASM_OP
7539 +#define COMMON_ASM_OP "\t.comm\t"
7541 +#undef ASM_OUTPUT_ALIGNED_COMMON
7542 +#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
7545 + if ((SIZE) <= nios2_section_threshold) \
7547 + named_section (0, ".sbss", 0); \
7548 + (*targetm.asm_out.globalize_label) (FILE, NAME); \
7549 + ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \
7550 + if (!flag_inhibit_size_directive) \
7551 + ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE); \
7552 + ASM_OUTPUT_ALIGN ((FILE), exact_log2((ALIGN) / BITS_PER_UNIT)); \
7553 + ASM_OUTPUT_LABEL(FILE, NAME); \
7554 + ASM_OUTPUT_SKIP((FILE), (SIZE) ? (SIZE) : 1); \
7558 + fprintf ((FILE), "%s", COMMON_ASM_OP); \
7559 + assemble_name ((FILE), (NAME)); \
7560 + fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT); \
7566 +/* This says how to output assembler code to declare an
7567 + uninitialized internal linkage data object. Under SVR4,
7568 + the linker seems to want the alignment of data objects
7569 + to depend on their types. We do exactly that here. */
7571 +#undef ASM_OUTPUT_ALIGNED_LOCAL
7572 +#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
7574 + if ((SIZE) <= nios2_section_threshold) \
7575 + named_section (0, ".sbss", 0); \
7577 + named_section (0, ".bss", 0); \
7578 + ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \
7579 + if (!flag_inhibit_size_directive) \
7580 + ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE); \
7581 + ASM_OUTPUT_ALIGN ((FILE), exact_log2((ALIGN) / BITS_PER_UNIT)); \
7582 + ASM_OUTPUT_LABEL(FILE, NAME); \
7583 + ASM_OUTPUT_SKIP((FILE), (SIZE) ? (SIZE) : 1); \
7588 +/***************************
7589 + * Miscellaneous Parameters
7590 + ***************************/
7594 +#define Pmode SImode
7595 +#define FUNCTION_MODE QImode
7597 +#define CASE_VECTOR_MODE Pmode
7599 +#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
7601 +#define LOAD_EXTEND_OP(MODE) (ZERO_EXTEND)
7603 +#define WORD_REGISTER_OPERATIONS
7604 diff -durN gcc-3.4.6.orig/gcc/config/nios2/nios2.md gcc-3.4.6/gcc/config/nios2/nios2.md
7605 --- gcc-3.4.6.orig/gcc/config/nios2/nios2.md 1970-01-01 01:00:00.000000000 +0100
7606 +++ gcc-3.4.6/gcc/config/nios2/nios2.md 2007-08-15 23:09:36.000000000 +0200
7608 +;; Machine Description for Altera NIOS 2G NIOS2 version.
7609 +;; Copyright (C) 2003 Altera
7610 +;; Contributed by Jonah Graham (jgraham@altera.com).
7612 +;; This file is part of GNU CC.
7614 +;; GNU CC is free software; you can redistribute it and/or modify
7615 +;; it under the terms of the GNU General Public License as published by
7616 +;; the Free Software Foundation; either version 2, or (at your option)
7617 +;; any later version.
7619 +;; GNU CC is distributed in the hope that it will be useful,
7620 +;; but WITHOUT ANY WARRANTY; without even the implied warranty of
7621 +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7622 +;; GNU General Public License for more details.
7624 +;; You should have received a copy of the GNU General Public License
7625 +;; along with GNU CC; see the file COPYING. If not, write to
7626 +;; the Free Software Foundation, 59 Temple Place - Suite 330,
7627 +;; Boston, MA 02111-1307, USA. */
7631 +;*****************************************************************************
7635 +;*****************************************************************************
7636 +(define_constants [
7642 + (FIRST_RETVAL_REGNO 2)
7643 + (LAST_RETVAL_REGNO 3)
7644 + (FIRST_ARG_REGNO 4)
7645 + (LAST_ARG_REGNO 7)
7648 + (FAKE_FP_REGNO 39)
7649 + (FAKE_AP_REGNO 40)
7652 + (UNSPEC_BLOCKAGE 0)
7669 +;*****************************************************************************
7671 +;* instruction scheduler
7673 +;*****************************************************************************
7675 +; No schedule info is currently available, using an assumption that no
7676 +; instruction can use the results of the previous instruction without
7677 +; incuring a stall.
7679 +; length of an instruction (in bytes)
7680 +(define_attr "length" "" (const_int 4))
7681 +(define_attr "type" "unknown,complex,control,alu,cond_alu,st,ld,shift,mul,div,custom" (const_string "complex"))
7683 +(define_asm_attributes
7684 + [(set_attr "length" "4")
7685 + (set_attr "type" "complex")])
7687 +(define_automaton "nios2")
7688 +(automata_option "v")
7689 +;(automata_option "no-minimization")
7690 +(automata_option "ndfa")
7692 +; The nios2 pipeline is fairly straightforward for the fast model.
7693 +; Every alu operation is pipelined so that an instruction can
7694 +; be issued every cycle. However, there are still potential
7695 +; stalls which this description tries to deal with.
7697 +(define_cpu_unit "cpu" "nios2")
7699 +(define_insn_reservation "complex" 1
7700 + (eq_attr "type" "complex")
7703 +(define_insn_reservation "control" 1
7704 + (eq_attr "type" "control")
7707 +(define_insn_reservation "alu" 1
7708 + (eq_attr "type" "alu")
7711 +(define_insn_reservation "cond_alu" 1
7712 + (eq_attr "type" "cond_alu")
7715 +(define_insn_reservation "st" 1
7716 + (eq_attr "type" "st")
7719 +(define_insn_reservation "custom" 1
7720 + (eq_attr "type" "custom")
7723 +; shifts, muls and lds have three cycle latency
7724 +(define_insn_reservation "ld" 3
7725 + (eq_attr "type" "ld")
7728 +(define_insn_reservation "shift" 3
7729 + (eq_attr "type" "shift")
7732 +(define_insn_reservation "mul" 3
7733 + (eq_attr "type" "mul")
7736 +(define_insn_reservation "div" 1
7737 + (eq_attr "type" "div")
7741 +;*****************************************************************************
7743 +;* MOV Instructions
7745 +;*****************************************************************************
7747 +(define_expand "movqi"
7748 + [(set (match_operand:QI 0 "nonimmediate_operand" "")
7749 + (match_operand:QI 1 "general_operand" ""))]
7752 + if (nios2_emit_move_sequence (operands, QImode))
7756 +(define_insn "movqi_internal"
7757 + [(set (match_operand:QI 0 "nonimmediate_operand" "=m, r,r, r")
7758 + (match_operand:QI 1 "general_operand" "rM,m,rM,I"))]
7759 + "(register_operand (operands[0], QImode)
7760 + || register_operand (operands[1], QImode)
7761 + || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
7767 + [(set_attr "type" "st,ld,alu,alu")])
7769 +(define_insn "ldbio"
7770 + [(set (match_operand:SI 0 "register_operand" "=r")
7771 + (unspec_volatile:SI [(const_int 0)] UNSPEC_LDBIO))
7772 + (use (match_operand:SI 1 "memory_operand" "m"))]
7775 + [(set_attr "type" "ld")])
7777 +(define_insn "ldbuio"
7778 + [(set (match_operand:SI 0 "register_operand" "=r")
7779 + (unspec_volatile:SI [(const_int 0)] UNSPEC_LDBUIO))
7780 + (use (match_operand:SI 1 "memory_operand" "m"))]
7783 + [(set_attr "type" "ld")])
7785 +(define_insn "stbio"
7786 + [(set (match_operand:SI 0 "memory_operand" "=m")
7787 + (match_operand:SI 1 "register_operand" "r"))
7788 + (unspec_volatile:SI [(const_int 0)] UNSPEC_STBIO)]
7791 + [(set_attr "type" "st")])
7794 +(define_expand "movhi"
7795 + [(set (match_operand:HI 0 "nonimmediate_operand" "")
7796 + (match_operand:HI 1 "general_operand" ""))]
7799 + if (nios2_emit_move_sequence (operands, HImode))
7803 +(define_insn "movhi_internal"
7804 + [(set (match_operand:HI 0 "nonimmediate_operand" "=m, r,r, r,r")
7805 + (match_operand:HI 1 "general_operand" "rM,m,rM,I,J"))]
7806 + "(register_operand (operands[0], HImode)
7807 + || register_operand (operands[1], HImode)
7808 + || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
7815 + [(set_attr "type" "st,ld,alu,alu,alu")])
7817 +(define_insn "ldhio"
7818 + [(set (match_operand:SI 0 "register_operand" "=r")
7819 + (unspec_volatile:SI [(const_int 0)] UNSPEC_LDHIO))
7820 + (use (match_operand:SI 1 "memory_operand" "m"))]
7823 + [(set_attr "type" "ld")])
7825 +(define_insn "ldhuio"
7826 + [(set (match_operand:SI 0 "register_operand" "=r")
7827 + (unspec_volatile:SI [(const_int 0)] UNSPEC_LDHUIO))
7828 + (use (match_operand:SI 1 "memory_operand" "m"))]
7831 + [(set_attr "type" "ld")])
7833 +(define_insn "sthio"
7834 + [(set (match_operand:SI 0 "memory_operand" "=m")
7835 + (match_operand:SI 1 "register_operand" "r"))
7836 + (unspec_volatile:SI [(const_int 0)] UNSPEC_STHIO)]
7839 + [(set_attr "type" "st")])
7841 +(define_expand "movsi"
7842 + [(set (match_operand:SI 0 "nonimmediate_operand" "")
7843 + (match_operand:SI 1 "general_operand" ""))]
7846 + if (nios2_emit_move_sequence (operands, SImode))
7850 +(define_insn "movsi_internal"
7851 + [(set (match_operand:SI 0 "nonimmediate_operand" "=m, r,r, r,r,r,r")
7852 + (match_operand:SI 1 "general_operand" "rM,m,rM,I,J,S,i"))]
7853 + "(register_operand (operands[0], SImode)
7854 + || register_operand (operands[1], SImode)
7855 + || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
7862 + addi\\t%0, gp, %%gprel(%1)
7863 + movhi\\t%0, %H1\;addi\\t%0, %0, %L1"
7864 + [(set_attr "type" "st,ld,alu,alu,alu,alu,alu")])
7866 +(define_insn "ldwio"
7867 + [(set (match_operand:SI 0 "register_operand" "=r")
7868 + (unspec_volatile:SI [(const_int 0)] UNSPEC_LDWIO))
7869 + (use (match_operand:SI 1 "memory_operand" "m"))]
7872 + [(set_attr "type" "ld")])
7874 +(define_insn "stwio"
7875 + [(set (match_operand:SI 0 "memory_operand" "=m")
7876 + (match_operand:SI 1 "register_operand" "r"))
7877 + (unspec_volatile:SI [(const_int 0)] UNSPEC_STWIO)]
7880 + [(set_attr "type" "st")])
7884 +;*****************************************************************************
7888 +;*****************************************************************************
7891 +(define_insn "zero_extendhisi2"
7892 + [(set (match_operand:SI 0 "register_operand" "=r,r")
7893 + (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
7896 + andi\\t%0, %1, 0xffff
7898 + [(set_attr "type" "alu,ld")])
7900 +(define_insn "zero_extendqihi2"
7901 + [(set (match_operand:HI 0 "register_operand" "=r,r")
7902 + (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
7905 + andi\\t%0, %1, 0xff
7907 + [(set_attr "type" "alu,ld")])
7909 +(define_insn "zero_extendqisi2"
7910 + [(set (match_operand:SI 0 "register_operand" "=r,r")
7911 + (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
7914 + andi\\t%0, %1, 0xff
7916 + [(set_attr "type" "alu,ld")])
7920 +;*****************************************************************************
7924 +;*****************************************************************************
7926 +(define_expand "extendhisi2"
7927 + [(set (match_operand:SI 0 "register_operand" "")
7928 + (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
7931 + if (optimize && GET_CODE (operands[1]) == MEM)
7932 + operands[1] = force_not_mem (operands[1]);
7934 + if (GET_CODE (operands[1]) != MEM)
7936 + rtx op1 = gen_lowpart (SImode, operands[1]);
7937 + rtx temp = gen_reg_rtx (SImode);
7938 + rtx shift = GEN_INT (16);
7940 + emit_insn (gen_ashlsi3 (temp, op1, shift));
7941 + emit_insn (gen_ashrsi3 (operands[0], temp, shift));
7946 +(define_insn "extendhisi2_internal"
7947 + [(set (match_operand:SI 0 "register_operand" "=r")
7948 + (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
7951 + [(set_attr "type" "ld")])
7953 +(define_expand "extendqihi2"
7954 + [(set (match_operand:HI 0 "register_operand" "")
7955 + (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
7958 + if (optimize && GET_CODE (operands[1]) == MEM)
7959 + operands[1] = force_not_mem (operands[1]);
7961 + if (GET_CODE (operands[1]) != MEM)
7963 + rtx op0 = gen_lowpart (SImode, operands[0]);
7964 + rtx op1 = gen_lowpart (SImode, operands[1]);
7965 + rtx temp = gen_reg_rtx (SImode);
7966 + rtx shift = GEN_INT (24);
7968 + emit_insn (gen_ashlsi3 (temp, op1, shift));
7969 + emit_insn (gen_ashrsi3 (op0, temp, shift));
7974 +(define_insn "extendqihi2_internal"
7975 + [(set (match_operand:HI 0 "register_operand" "=r")
7976 + (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
7979 + [(set_attr "type" "ld")])
7982 +(define_expand "extendqisi2"
7983 + [(set (match_operand:SI 0 "register_operand" "")
7984 + (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
7987 + if (optimize && GET_CODE (operands[1]) == MEM)
7988 + operands[1] = force_not_mem (operands[1]);
7990 + if (GET_CODE (operands[1]) != MEM)
7992 + rtx op1 = gen_lowpart (SImode, operands[1]);
7993 + rtx temp = gen_reg_rtx (SImode);
7994 + rtx shift = GEN_INT (24);
7996 + emit_insn (gen_ashlsi3 (temp, op1, shift));
7997 + emit_insn (gen_ashrsi3 (operands[0], temp, shift));
8002 +(define_insn "extendqisi2_insn"
8003 + [(set (match_operand:SI 0 "register_operand" "=r")
8004 + (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
8007 + [(set_attr "type" "ld")])
8011 +;*****************************************************************************
8013 +;* Arithmetic Operations
8015 +;*****************************************************************************
8017 +(define_insn "addsi3"
8018 + [(set (match_operand:SI 0 "register_operand" "=r,r")
8019 + (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
8020 + (match_operand:SI 2 "arith_operand" "r,I")))]
8022 + "add%i2\\t%0, %1, %z2"
8023 + [(set_attr "type" "alu")])
8025 +(define_insn "subsi3"
8026 + [(set (match_operand:SI 0 "register_operand" "=r")
8027 + (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
8028 + (match_operand:SI 2 "register_operand" "r")))]
8030 + "sub\\t%0, %z1, %2"
8031 + [(set_attr "type" "alu")])
8033 +(define_insn "mulsi3"
8034 + [(set (match_operand:SI 0 "register_operand" "=r,r")
8035 + (mult:SI (match_operand:SI 1 "register_operand" "r,r")
8036 + (match_operand:SI 2 "arith_operand" "r,I")))]
8038 + "mul%i2\\t%0, %1, %z2"
8039 + [(set_attr "type" "mul")])
8041 +(define_expand "divsi3"
8042 + [(set (match_operand:SI 0 "register_operand" "=r")
8043 + (div:SI (match_operand:SI 1 "register_operand" "r")
8044 + (match_operand:SI 2 "register_operand" "r")))]
8047 + if (!TARGET_HAS_DIV)
8049 + if (!TARGET_FAST_SW_DIV)
8053 + if (nios2_emit_expensive_div (operands, SImode))
8059 +(define_insn "divsi3_insn"
8060 + [(set (match_operand:SI 0 "register_operand" "=r")
8061 + (div:SI (match_operand:SI 1 "register_operand" "r")
8062 + (match_operand:SI 2 "register_operand" "r")))]
8064 + "div\\t%0, %1, %2"
8065 + [(set_attr "type" "div")])
8067 +(define_insn "udivsi3"
8068 + [(set (match_operand:SI 0 "register_operand" "=r")
8069 + (udiv:SI (match_operand:SI 1 "register_operand" "r")
8070 + (match_operand:SI 2 "register_operand" "r")))]
8072 + "divu\\t%0, %1, %2"
8073 + [(set_attr "type" "div")])
8075 +(define_insn "smulsi3_highpart"
8076 + [(set (match_operand:SI 0 "register_operand" "=r")
8079 + (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
8080 + (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
8081 + (const_int 32))))]
8083 + "mulxss\\t%0, %1, %2"
8084 + [(set_attr "type" "mul")])
8086 +(define_insn "umulsi3_highpart"
8087 + [(set (match_operand:SI 0 "register_operand" "=r")
8090 + (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
8091 + (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
8092 + (const_int 32))))]
8094 + "mulxuu\\t%0, %1, %2"
8095 + [(set_attr "type" "mul")])
8098 +(define_expand "mulsidi3"
8099 + [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 0)
8100 + (mult:SI (match_operand:SI 1 "register_operand" "")
8101 + (match_operand:SI 2 "register_operand" "")))
8102 + (set (subreg:SI (match_dup 0) 4)
8103 + (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
8104 + (sign_extend:DI (match_dup 2)))
8105 + (const_int 32))))]
8109 +(define_expand "umulsidi3"
8110 + [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 0)
8111 + (mult:SI (match_operand:SI 1 "register_operand" "")
8112 + (match_operand:SI 2 "register_operand" "")))
8113 + (set (subreg:SI (match_dup 0) 4)
8114 + (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
8115 + (zero_extend:DI (match_dup 2)))
8116 + (const_int 32))))]
8122 +;*****************************************************************************
8124 +;* Negate and ones complement
8126 +;*****************************************************************************
8128 +(define_insn "negsi2"
8129 + [(set (match_operand:SI 0 "register_operand" "=r")
8130 + (neg:SI (match_operand:SI 1 "register_operand" "r")))]
8133 + operands[2] = const0_rtx;
8134 + return "sub\\t%0, %z2, %1";
8136 + [(set_attr "type" "alu")])
8138 +(define_insn "one_cmplsi2"
8139 + [(set (match_operand:SI 0 "register_operand" "=r")
8140 + (not:SI (match_operand:SI 1 "register_operand" "r")))]
8143 + operands[2] = const0_rtx;
8144 + return "nor\\t%0, %z2, %1";
8146 + [(set_attr "type" "alu")])
8150 +; Logical Operantions
8152 +(define_insn "andsi3"
8153 + [(set (match_operand:SI 0 "register_operand" "=r, r,r")
8154 + (and:SI (match_operand:SI 1 "register_operand" "%r, r,r")
8155 + (match_operand:SI 2 "logical_operand" "rM,J,K")))]
8159 + and%i2\\t%0, %1, %2
8160 + andh%i2\\t%0, %1, %U2"
8161 + [(set_attr "type" "alu")])
8163 +(define_insn "iorsi3"
8164 + [(set (match_operand:SI 0 "register_operand" "=r, r,r")
8165 + (ior:SI (match_operand:SI 1 "register_operand" "%r, r,r")
8166 + (match_operand:SI 2 "logical_operand" "rM,J,K")))]
8170 + or%i2\\t%0, %1, %2
8171 + orh%i2\\t%0, %1, %U2"
8172 + [(set_attr "type" "alu")])
8174 +(define_insn "*norsi3"
8175 + [(set (match_operand:SI 0 "register_operand" "=r")
8176 + (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r"))
8177 + (not:SI (match_operand:SI 2 "reg_or_0_operand" "rM"))))]
8179 + "nor\\t%0, %1, %z2"
8180 + [(set_attr "type" "alu")])
8182 +(define_insn "xorsi3"
8183 + [(set (match_operand:SI 0 "register_operand" "=r, r,r")
8184 + (xor:SI (match_operand:SI 1 "register_operand" "%r, r,r")
8185 + (match_operand:SI 2 "logical_operand" "rM,J,K")))]
8189 + xor%i2\\t%0, %1, %2
8190 + xorh%i2\\t%0, %1, %U2"
8191 + [(set_attr "type" "alu")])
8195 +;*****************************************************************************
8199 +;*****************************************************************************
8201 +(define_insn "ashlsi3"
8202 + [(set (match_operand:SI 0 "register_operand" "=r,r")
8203 + (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
8204 + (match_operand:SI 2 "shift_operand" "r,L")))]
8206 + "sll%i2\\t%0, %1, %z2"
8207 + [(set_attr "type" "shift")])
8209 +(define_insn "ashrsi3"
8210 + [(set (match_operand:SI 0 "register_operand" "=r,r")
8211 + (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
8212 + (match_operand:SI 2 "shift_operand" "r,L")))]
8214 + "sra%i2\\t%0, %1, %z2"
8215 + [(set_attr "type" "shift")])
8217 +(define_insn "lshrsi3"
8218 + [(set (match_operand:SI 0 "register_operand" "=r,r")
8219 + (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
8220 + (match_operand:SI 2 "shift_operand" "r,L")))]
8222 + "srl%i2\\t%0, %1, %z2"
8223 + [(set_attr "type" "shift")])
8225 +(define_insn "rotlsi3"
8226 + [(set (match_operand:SI 0 "register_operand" "=r,r")
8227 + (rotate:SI (match_operand:SI 1 "register_operand" "r,r")
8228 + (match_operand:SI 2 "shift_operand" "r,L")))]
8230 + "rol%i2\\t%0, %1, %z2"
8231 + [(set_attr "type" "shift")])
8233 +(define_insn "rotrsi3"
8234 + [(set (match_operand:SI 0 "register_operand" "=r,r")
8235 + (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
8236 + (match_operand:SI 2 "register_operand" "r,r")))]
8238 + "ror\\t%0, %1, %2"
8239 + [(set_attr "type" "shift")])
8241 +(define_insn "*shift_mul_constants"
8242 + [(set (match_operand:SI 0 "register_operand" "=r")
8243 + (ashift:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
8244 + (match_operand:SI 2 "const_int_operand" "I"))
8245 + (match_operand:SI 3 "const_int_operand" "I")))]
8246 + "TARGET_HAS_MUL && SMALL_INT (INTVAL (operands[2]) << INTVAL (operands[3]))"
8248 + HOST_WIDE_INT mul = INTVAL (operands[2]) << INTVAL (operands[3]);
8251 + ops[0] = operands[0];
8252 + ops[1] = operands[1];
8253 + ops[2] = GEN_INT (mul);
8255 + output_asm_insn ("muli\t%0, %1, %2", ops);
8258 + [(set_attr "type" "mul")])
8263 +;*****************************************************************************
8265 +;* Prologue, Epilogue and Return
8267 +;*****************************************************************************
8269 +(define_expand "prologue"
8273 + expand_prologue ();
8277 +(define_expand "epilogue"
8281 + expand_epilogue (false);
8285 +(define_expand "sibcall_epilogue"
8289 + expand_epilogue (true);
8293 +(define_insn "return"
8295 + "reload_completed && nios2_can_use_return_insn ()"
8299 +(define_insn "return_from_epilogue"
8300 + [(use (match_operand 0 "pmode_register_operand" ""))
8302 + "reload_completed"
8306 +;; Block any insns from being moved before this point, since the
8307 +;; profiling call to mcount can use various registers that aren't
8308 +;; saved or used to pass arguments.
8310 +(define_insn "blockage"
8311 + [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
8314 + [(set_attr "type" "unknown")
8315 + (set_attr "length" "0")])
8319 +;*****************************************************************************
8323 +;*****************************************************************************
8325 +(define_insn "indirect_jump"
8326 + [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
8329 + [(set_attr "type" "control")])
8331 +(define_insn "jump"
8333 + (label_ref (match_operand 0 "" "")))]
8336 + [(set_attr "type" "control")])
8339 +(define_insn "indirect_call"
8340 + [(call (mem:QI (match_operand:SI 0 "register_operand" "r"))
8341 + (match_operand 1 "" ""))
8342 + (clobber (reg:SI RA_REGNO))]
8345 + [(set_attr "type" "control")])
8347 +(define_insn "indirect_call_value"
8348 + [(set (match_operand 0 "" "")
8349 + (call (mem:QI (match_operand:SI 1 "register_operand" "r"))
8350 + (match_operand 2 "" "")))
8351 + (clobber (reg:SI RA_REGNO))]
8356 +(define_expand "call"
8357 + [(parallel [(call (match_operand 0 "" "")
8358 + (match_operand 1 "" ""))
8359 + (clobber (reg:SI RA_REGNO))])]
8363 +(define_expand "call_value"
8364 + [(parallel [(set (match_operand 0 "" "")
8365 + (call (match_operand 1 "" "")
8366 + (match_operand 2 "" "")))
8367 + (clobber (reg:SI RA_REGNO))])]
8371 +(define_insn "*call"
8372 + [(call (mem:QI (match_operand:SI 0 "immediate_operand" "i"))
8373 + (match_operand 1 "" ""))
8374 + (clobber (match_operand:SI 2 "register_operand" "=r"))]
8377 + [(set_attr "type" "control")])
8379 +(define_insn "*call_value"
8380 + [(set (match_operand 0 "" "")
8381 + (call (mem:QI (match_operand:SI 1 "immediate_operand" "i"))
8382 + (match_operand 2 "" "")))
8383 + (clobber (match_operand:SI 3 "register_operand" "=r"))]
8386 + [(set_attr "type" "control")])
8388 +(define_expand "sibcall"
8389 + [(parallel [(call (match_operand 0 "" "")
8390 + (match_operand 1 "" ""))
8392 + (use (match_operand 2 "" ""))])]
8395 + XEXP (operands[0], 0) = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
8397 + if (operands[2] == NULL_RTX)
8398 + operands[2] = const0_rtx;
8402 +(define_expand "sibcall_value"
8403 + [(parallel [(set (match_operand 0 "" "")
8404 + (call (match_operand 1 "" "")
8405 + (match_operand 2 "" "")))
8407 + (use (match_operand 3 "" ""))])]
8410 + XEXP (operands[1], 0) = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
8412 + if (operands[3] == NULL_RTX)
8413 + operands[3] = const0_rtx;
8417 +(define_insn "sibcall_insn"
8418 + [(call (mem:QI (match_operand:SI 0 "register_operand" "r"))
8419 + (match_operand 1 "" ""))
8421 + (use (match_operand 2 "" ""))]
8426 +(define_insn "sibcall_value_insn"
8427 + [(set (match_operand 0 "register_operand" "")
8428 + (call (mem:QI (match_operand:SI 1 "register_operand" "r"))
8429 + (match_operand 2 "" "")))
8431 + (use (match_operand 3 "" ""))]
8439 +(define_expand "tablejump"
8440 + [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
8441 + (use (label_ref (match_operand 1 "" "")))])]
8446 +(define_insn "*tablejump"
8448 + (match_operand:SI 0 "register_operand" "r"))
8449 + (use (label_ref (match_operand 1 "" "")))]
8452 + [(set_attr "type" "control")])
8456 +;*****************************************************************************
8460 +;*****************************************************************************
8461 +;; Flow here is rather complex (based on MIPS):
8463 +;; 1) The cmp{si,di,sf,df} routine is called. It deposits the
8464 +;; arguments into the branch_cmp array, and the type into
8465 +;; branch_type. No RTL is generated.
8467 +;; 2) The appropriate branch define_expand is called, which then
8468 +;; creates the appropriate RTL for the comparison and branch.
8469 +;; Different CC modes are used, based on what type of branch is
8470 +;; done, so that we can constrain things appropriately. There
8471 +;; are assumptions in the rest of GCC that break if we fold the
8472 +;; operands into the branchs for integer operations, and use cc0
8473 +;; for floating point, so we use the fp status register instead.
8474 +;; If needed, an appropriate temporary is created to hold the
8475 +;; of the integer compare.
8477 +(define_expand "cmpsi"
8479 + (compare:CC (match_operand:SI 0 "register_operand" "")
8480 + (match_operand:SI 1 "arith_operand" "")))]
8483 + branch_cmp[0] = operands[0];
8484 + branch_cmp[1] = operands[1];
8485 + branch_type = CMP_SI;
8489 +(define_expand "tstsi"
8491 + (match_operand:SI 0 "register_operand" ""))]
8494 + branch_cmp[0] = operands[0];
8495 + branch_cmp[1] = const0_rtx;
8496 + branch_type = CMP_SI;
8501 +;*****************************************************************************
8503 +;* setting a register from a comparison
8505 +;*****************************************************************************
8507 +(define_expand "seq"
8508 + [(set (match_operand:SI 0 "register_operand" "=r")
8509 + (eq:SI (match_dup 1)
8513 + if (branch_type != CMP_SI)
8516 + /* set up operands from compare. */
8517 + operands[1] = branch_cmp[0];
8518 + operands[2] = branch_cmp[1];
8520 + gen_int_relational (EQ, operands[0], operands[1], operands[2], NULL_RTX);
8525 +(define_insn "*seq"
8526 + [(set (match_operand:SI 0 "register_operand" "=r")
8527 + (eq:SI (match_operand:SI 1 "reg_or_0_operand" "%rM")
8528 + (match_operand:SI 2 "arith_operand" "rI")))]
8530 + "cmpeq%i2\\t%0, %z1, %z2"
8531 + [(set_attr "type" "alu")])
8534 +(define_expand "sne"
8535 + [(set (match_operand:SI 0 "register_operand" "=r")
8536 + (ne:SI (match_dup 1)
8540 + if (branch_type != CMP_SI)
8543 + /* set up operands from compare. */
8544 + operands[1] = branch_cmp[0];
8545 + operands[2] = branch_cmp[1];
8547 + gen_int_relational (NE, operands[0], operands[1], operands[2], NULL_RTX);
8552 +(define_insn "*sne"
8553 + [(set (match_operand:SI 0 "register_operand" "=r")
8554 + (ne:SI (match_operand:SI 1 "reg_or_0_operand" "%rM")
8555 + (match_operand:SI 2 "arith_operand" "rI")))]
8557 + "cmpne%i2\\t%0, %z1, %z2"
8558 + [(set_attr "type" "alu")])
8561 +(define_expand "sgt"
8562 + [(set (match_operand:SI 0 "register_operand" "=r")
8563 + (gt:SI (match_dup 1)
8567 + if (branch_type != CMP_SI)
8570 + /* set up operands from compare. */
8571 + operands[1] = branch_cmp[0];
8572 + operands[2] = branch_cmp[1];
8574 + gen_int_relational (GT, operands[0], operands[1], operands[2], NULL_RTX);
8579 +(define_insn "*sgt"
8580 + [(set (match_operand:SI 0 "register_operand" "=r")
8581 + (gt:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
8582 + (match_operand:SI 2 "reg_or_0_operand" "rM")))]
8584 + "cmplt\\t%0, %z2, %z1"
8585 + [(set_attr "type" "alu")])
8588 +(define_expand "sge"
8589 + [(set (match_operand:SI 0 "register_operand" "=r")
8590 + (ge:SI (match_dup 1)
8594 + if (branch_type != CMP_SI)
8597 + /* set up operands from compare. */
8598 + operands[1] = branch_cmp[0];
8599 + operands[2] = branch_cmp[1];
8601 + gen_int_relational (GE, operands[0], operands[1], operands[2], NULL_RTX);
8606 +(define_insn "*sge"
8607 + [(set (match_operand:SI 0 "register_operand" "=r")
8608 + (ge:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
8609 + (match_operand:SI 2 "arith_operand" "rI")))]
8611 + "cmpge%i2\\t%0, %z1, %z2"
8612 + [(set_attr "type" "alu")])
8614 +(define_expand "sle"
8615 + [(set (match_operand:SI 0 "register_operand" "=r")
8616 + (le:SI (match_dup 1)
8620 + if (branch_type != CMP_SI)
8623 + /* set up operands from compare. */
8624 + operands[1] = branch_cmp[0];
8625 + operands[2] = branch_cmp[1];
8627 + gen_int_relational (LE, operands[0], operands[1], operands[2], NULL_RTX);
8632 +(define_insn "*sle"
8633 + [(set (match_operand:SI 0 "register_operand" "=r")
8634 + (le:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
8635 + (match_operand:SI 2 "reg_or_0_operand" "rM")))]
8637 + "cmpge\\t%0, %z2, %z1"
8638 + [(set_attr "type" "alu")])
8641 +(define_expand "slt"
8642 + [(set (match_operand:SI 0 "register_operand" "=r")
8643 + (lt:SI (match_dup 1)
8647 + if (branch_type != CMP_SI)
8650 + /* set up operands from compare. */
8651 + operands[1] = branch_cmp[0];
8652 + operands[2] = branch_cmp[1];
8654 + gen_int_relational (LT, operands[0], operands[1], operands[2], NULL_RTX);
8659 +(define_insn "*slt"
8660 + [(set (match_operand:SI 0 "register_operand" "=r")
8661 + (lt:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
8662 + (match_operand:SI 2 "arith_operand" "rI")))]
8664 + "cmplt%i2\\t%0, %z1, %z2"
8665 + [(set_attr "type" "alu")])
8668 +(define_expand "sgtu"
8669 + [(set (match_operand:SI 0 "register_operand" "=r")
8670 + (gtu:SI (match_dup 1)
8674 + if (branch_type != CMP_SI)
8677 + /* set up operands from compare. */
8678 + operands[1] = branch_cmp[0];
8679 + operands[2] = branch_cmp[1];
8681 + gen_int_relational (GTU, operands[0], operands[1], operands[2], NULL_RTX);
8686 +(define_insn "*sgtu"
8687 + [(set (match_operand:SI 0 "register_operand" "=r")
8688 + (gtu:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
8689 + (match_operand:SI 2 "reg_or_0_operand" "rM")))]
8691 + "cmpltu\\t%0, %z2, %z1"
8692 + [(set_attr "type" "alu")])
8695 +(define_expand "sgeu"
8696 + [(set (match_operand:SI 0 "register_operand" "=r")
8697 + (geu:SI (match_dup 1)
8701 + if (branch_type != CMP_SI)
8704 + /* set up operands from compare. */
8705 + operands[1] = branch_cmp[0];
8706 + operands[2] = branch_cmp[1];
8708 + gen_int_relational (GEU, operands[0], operands[1], operands[2], NULL_RTX);
8713 +(define_insn "*sgeu"
8714 + [(set (match_operand:SI 0 "register_operand" "=r")
8715 + (geu:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
8716 + (match_operand:SI 2 "uns_arith_operand" "rJ")))]
8718 + "cmpgeu%i2\\t%0, %z1, %z2"
8719 + [(set_attr "type" "alu")])
8721 +(define_expand "sleu"
8722 + [(set (match_operand:SI 0 "register_operand" "=r")
8723 + (leu:SI (match_dup 1)
8727 + if (branch_type != CMP_SI)
8730 + /* set up operands from compare. */
8731 + operands[1] = branch_cmp[0];
8732 + operands[2] = branch_cmp[1];
8734 + gen_int_relational (LEU, operands[0], operands[1], operands[2], NULL_RTX);
8739 +(define_insn "*sleu"
8740 + [(set (match_operand:SI 0 "register_operand" "=r")
8741 + (leu:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
8742 + (match_operand:SI 2 "reg_or_0_operand" "rM")))]
8744 + "cmpgeu\\t%0, %z2, %z1"
8745 + [(set_attr "type" "alu")])
8748 +(define_expand "sltu"
8749 + [(set (match_operand:SI 0 "register_operand" "=r")
8750 + (ltu:SI (match_dup 1)
8754 + if (branch_type != CMP_SI)
8757 + /* set up operands from compare. */
8758 + operands[1] = branch_cmp[0];
8759 + operands[2] = branch_cmp[1];
8761 + gen_int_relational (LTU, operands[0], operands[1], operands[2], NULL_RTX);
8766 +(define_insn "*sltu"
8767 + [(set (match_operand:SI 0 "register_operand" "=r")
8768 + (ltu:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
8769 + (match_operand:SI 2 "uns_arith_operand" "rJ")))]
8771 + "cmpltu%i2\\t%0, %z1, %z2"
8772 + [(set_attr "type" "alu")])
8777 +;*****************************************************************************
8781 +;*****************************************************************************
8783 +(define_insn "*cbranch"
8786 + (match_operator:SI 0 "comparison_operator"
8787 + [(match_operand:SI 2 "reg_or_0_operand" "rM")
8788 + (match_operand:SI 3 "reg_or_0_operand" "rM")])
8789 + (label_ref (match_operand 1 "" ""))
8792 + "b%0\\t%z2, %z3, %l1"
8793 + [(set_attr "type" "control")])
8796 +(define_expand "beq"
8798 + (if_then_else (eq:CC (cc0)
8800 + (label_ref (match_operand 0 "" ""))
8804 + gen_int_relational (EQ, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
8809 +(define_expand "bne"
8811 + (if_then_else (ne:CC (cc0)
8813 + (label_ref (match_operand 0 "" ""))
8817 + gen_int_relational (NE, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
8822 +(define_expand "bgt"
8824 + (if_then_else (gt:CC (cc0)
8826 + (label_ref (match_operand 0 "" ""))
8830 + gen_int_relational (GT, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
8834 +(define_expand "bge"
8836 + (if_then_else (ge:CC (cc0)
8838 + (label_ref (match_operand 0 "" ""))
8842 + gen_int_relational (GE, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
8846 +(define_expand "ble"
8848 + (if_then_else (le:CC (cc0)
8850 + (label_ref (match_operand 0 "" ""))
8854 + gen_int_relational (LE, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
8858 +(define_expand "blt"
8860 + (if_then_else (lt:CC (cc0)
8862 + (label_ref (match_operand 0 "" ""))
8866 + gen_int_relational (LT, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
8871 +(define_expand "bgtu"
8873 + (if_then_else (gtu:CC (cc0)
8875 + (label_ref (match_operand 0 "" ""))
8879 + gen_int_relational (GTU, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
8883 +(define_expand "bgeu"
8885 + (if_then_else (geu:CC (cc0)
8887 + (label_ref (match_operand 0 "" ""))
8891 + gen_int_relational (GEU, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
8895 +(define_expand "bleu"
8897 + (if_then_else (leu:CC (cc0)
8899 + (label_ref (match_operand 0 "" ""))
8903 + gen_int_relational (LEU, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
8907 +(define_expand "bltu"
8909 + (if_then_else (ltu:CC (cc0)
8911 + (label_ref (match_operand 0 "" ""))
8915 + gen_int_relational (LTU, NULL_RTX, branch_cmp[0], branch_cmp[1], operands[0]);
8920 +;*****************************************************************************
8922 +;* String and Block Operations
8924 +;*****************************************************************************
8926 +; ??? This is all really a hack to get Dhrystone to work as fast as possible
8927 +; things to be fixed:
8928 +; * let the compiler core handle all of this, for that to work the extra
8929 +; aliasing needs to be addressed.
8930 +; * we use three temporary registers for loading and storing to ensure no
8931 +; ld use stalls, this is excessive, because after the first ld/st only
8932 +; two are needed. Only two would be needed all the way through if
8933 +; we could schedule with other code. Consider:
8937 +; 4 st $1, 0($dest)
8938 +; 5 ld $1, 12($src)
8941 +; The first store has to wait until 4. If it does not there will be one
8942 +; cycle of stalling. However, if any other instruction could be placed
8943 +; between 1 and 4, $3 would not be needed.
8944 +; * In small we probably don't want to ever do this ourself because there
8945 +; is no ld use stall.
8947 +(define_expand "movstrsi"
8948 + [(parallel [(set (match_operand:BLK 0 "general_operand" "")
8949 + (match_operand:BLK 1 "general_operand" ""))
8950 + (use (match_operand:SI 2 "const_int_operand" ""))
8951 + (use (match_operand:SI 3 "const_int_operand" ""))
8952 + (clobber (match_scratch:SI 4 "=&r"))
8953 + (clobber (match_scratch:SI 5 "=&r"))
8954 + (clobber (match_scratch:SI 6 "=&r"))])]
8955 + "TARGET_INLINE_MEMCPY"
8957 + rtx ld_addr_reg, st_addr_reg;
8959 + /* If the predicate for op2 fails in expr.c:emit_block_move_via_movstr
8960 + it trys to copy to a register, but does not re-try the predicate.
8961 + ??? Intead of fixing expr.c, I fix it here. */
8962 + if (!const_int_operand (operands[2], SImode))
8965 + /* ??? there are some magic numbers which need to be sorted out here.
8966 + the basis for them is not increasing code size hugely or going
8967 + out of range of offset addressing */
8968 + if (INTVAL (operands[3]) < 4)
8971 + || (optimize_size && INTVAL (operands[2]) > 12)
8972 + || (optimize < 3 && INTVAL (operands[2]) > 100)
8973 + || INTVAL (operands[2]) > 200)
8977 + = replace_equiv_address (operands[0],
8978 + copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
8980 + = replace_equiv_address (operands[1],
8981 + copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
8982 + emit_insn (gen_movstrsi_internal (st_addr_reg, ld_addr_reg,
8983 + operands[2], operands[3]));
8989 +(define_insn "movstrsi_internal"
8990 + [(set (match_operand:BLK 0 "memory_operand" "=o")
8991 + (match_operand:BLK 1 "memory_operand" "o"))
8992 + (use (match_operand:SI 2 "const_int_operand" "i"))
8993 + (use (match_operand:SI 3 "const_int_operand" "i"))
8994 + (clobber (match_scratch:SI 4 "=&r"))
8995 + (clobber (match_scratch:SI 5 "=&r"))
8996 + (clobber (match_scratch:SI 6 "=&r"))]
8997 + "TARGET_INLINE_MEMCPY"
8999 + int ld_offset = INTVAL (operands[2]);
9000 + int ld_len = INTVAL (operands[2]);
9002 + rtx ld_addr_reg = XEXP (operands[1], 0);
9003 + int st_offset = INTVAL (operands[2]);
9004 + int st_len = INTVAL (operands[2]);
9006 + rtx st_addr_reg = XEXP (operands[0], 0);
9007 + int delay_count = 0;
9009 + /* ops[0] is the address used by the insn
9010 + ops[1] is the register being loaded or stored */
9013 + if (INTVAL (operands[3]) < 4)
9016 + while (ld_offset >= 4)
9018 + /* if the load use delay has been met, I can start
9020 + if (delay_count >= 3)
9022 + ops[0] = gen_rtx (MEM, SImode,
9023 + plus_constant (st_addr_reg, st_len - st_offset));
9024 + ops[1] = operands[st_reg + 4];
9025 + output_asm_insn ("stw\t%1, %0", ops);
9027 + st_reg = (st_reg + 1) % 3;
9031 + ops[0] = gen_rtx (MEM, SImode,
9032 + plus_constant (ld_addr_reg, ld_len - ld_offset));
9033 + ops[1] = operands[ld_reg + 4];
9034 + output_asm_insn ("ldw\t%1, %0", ops);
9036 + ld_reg = (ld_reg + 1) % 3;
9041 + if (ld_offset >= 2)
9043 + /* if the load use delay has been met, I can start
9045 + if (delay_count >= 3)
9047 + ops[0] = gen_rtx (MEM, SImode,
9048 + plus_constant (st_addr_reg, st_len - st_offset));
9049 + ops[1] = operands[st_reg + 4];
9050 + output_asm_insn ("stw\t%1, %0", ops);
9052 + st_reg = (st_reg + 1) % 3;
9056 + ops[0] = gen_rtx (MEM, HImode,
9057 + plus_constant (ld_addr_reg, ld_len - ld_offset));
9058 + ops[1] = operands[ld_reg + 4];
9059 + output_asm_insn ("ldh\t%1, %0", ops);
9061 + ld_reg = (ld_reg + 1) % 3;
9066 + if (ld_offset >= 1)
9068 + /* if the load use delay has been met, I can start
9070 + if (delay_count >= 3)
9072 + ops[0] = gen_rtx (MEM, SImode,
9073 + plus_constant (st_addr_reg, st_len - st_offset));
9074 + ops[1] = operands[st_reg + 4];
9075 + output_asm_insn ("stw\t%1, %0", ops);
9077 + st_reg = (st_reg + 1) % 3;
9081 + ops[0] = gen_rtx (MEM, QImode,
9082 + plus_constant (ld_addr_reg, ld_len - ld_offset));
9083 + ops[1] = operands[ld_reg + 4];
9084 + output_asm_insn ("ldb\t%1, %0", ops);
9086 + ld_reg = (ld_reg + 1) % 3;
9091 + while (st_offset >= 4)
9093 + ops[0] = gen_rtx (MEM, SImode,
9094 + plus_constant (st_addr_reg, st_len - st_offset));
9095 + ops[1] = operands[st_reg + 4];
9096 + output_asm_insn ("stw\t%1, %0", ops);
9098 + st_reg = (st_reg + 1) % 3;
9102 + while (st_offset >= 2)
9104 + ops[0] = gen_rtx (MEM, HImode,
9105 + plus_constant (st_addr_reg, st_len - st_offset));
9106 + ops[1] = operands[st_reg + 4];
9107 + output_asm_insn ("sth\t%1, %0", ops);
9109 + st_reg = (st_reg + 1) % 3;
9113 + while (st_offset >= 1)
9115 + ops[0] = gen_rtx (MEM, QImode,
9116 + plus_constant (st_addr_reg, st_len - st_offset));
9117 + ops[1] = operands[st_reg + 4];
9118 + output_asm_insn ("stb\t%1, %0", ops);
9120 + st_reg = (st_reg + 1) % 3;
9126 +; ??? lengths are not being used yet, but I will probably forget
9127 +; to update this once I am using lengths, so set it to something
9128 +; definetely big enough to cover it. 400 allows for 200 bytes
9130 + [(set_attr "length" "400")])
9134 +;*****************************************************************************
9136 +;* Custom instructions
9138 +;*****************************************************************************
9140 +(define_constants [
9196 +(define_insn "custom_n"
9197 + [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")] CUSTOM_N)]
9199 + "custom\\t%0, zero, zero, zero"
9200 + [(set_attr "type" "custom")])
9202 +(define_insn "custom_ni"
9203 + [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
9204 + (match_operand:SI 1 "register_operand" "r")] CUSTOM_NI)]
9206 + "custom\\t%0, zero, %1, zero"
9207 + [(set_attr "type" "custom")])
9209 +(define_insn "custom_nf"
9210 + [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
9211 + (match_operand:SF 1 "register_operand" "r")] CUSTOM_NF)]
9213 + "custom\\t%0, zero, %1, zero"
9214 + [(set_attr "type" "custom")])
9216 +(define_insn "custom_np"
9217 + [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
9218 + (match_operand:SI 1 "register_operand" "r")] CUSTOM_NP)]
9220 + "custom\\t%0, zero, %1, zero"
9221 + [(set_attr "type" "custom")])
9223 +(define_insn "custom_nii"
9224 + [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
9225 + (match_operand:SI 1 "register_operand" "r")
9226 + (match_operand:SI 2 "register_operand" "r")] CUSTOM_NII)]
9228 + "custom\\t%0, zero, %1, %2"
9229 + [(set_attr "type" "custom")])
9231 +(define_insn "custom_nif"
9232 + [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
9233 + (match_operand:SI 1 "register_operand" "r")
9234 + (match_operand:SF 2 "register_operand" "r")] CUSTOM_NIF)]
9236 + "custom\\t%0, zero, %1, %2"
9237 + [(set_attr "type" "custom")])
9239 +(define_insn "custom_nip"
9240 + [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
9241 + (match_operand:SI 1 "register_operand" "r")
9242 + (match_operand:SI 2 "register_operand" "r")] CUSTOM_NIP)]
9244 + "custom\\t%0, zero, %1, %2"
9245 + [(set_attr "type" "custom")])
9247 +(define_insn "custom_nfi"
9248 + [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
9249 + (match_operand:SF 1 "register_operand" "r")
9250 + (match_operand:SI 2 "register_operand" "r")] CUSTOM_NFI)]
9252 + "custom\\t%0, zero, %1, %2"
9253 + [(set_attr "type" "custom")])
9255 +(define_insn "custom_nff"
9256 + [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
9257 + (match_operand:SF 1 "register_operand" "r")
9258 + (match_operand:SF 2 "register_operand" "r")] CUSTOM_NFF)]
9260 + "custom\\t%0, zero, %1, %2"
9261 + [(set_attr "type" "custom")])
9263 +(define_insn "custom_nfp"
9264 + [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
9265 + (match_operand:SF 1 "register_operand" "r")
9266 + (match_operand:SI 2 "register_operand" "r")] CUSTOM_NFP)]
9268 + "custom\\t%0, zero, %1, %2"
9269 + [(set_attr "type" "custom")])
9271 +(define_insn "custom_npi"
9272 + [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
9273 + (match_operand:SI 1 "register_operand" "r")
9274 + (match_operand:SI 2 "register_operand" "r")] CUSTOM_NPI)]
9276 + "custom\\t%0, zero, %1, %2"
9277 + [(set_attr "type" "custom")])
9279 +(define_insn "custom_npf"
9280 + [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
9281 + (match_operand:SI 1 "register_operand" "r")
9282 + (match_operand:SF 2 "register_operand" "r")] CUSTOM_NPF)]
9284 + "custom\\t%0, zero, %1, %2"
9285 + [(set_attr "type" "custom")])
9287 +(define_insn "custom_npp"
9288 + [(unspec_volatile [(match_operand:SI 0 "custom_insn_opcode" "N")
9289 + (match_operand:SI 1 "register_operand" "r")
9290 + (match_operand:SI 2 "register_operand" "r")] CUSTOM_NPP)]
9292 + "custom\\t%0, zero, %1, %2"
9293 + [(set_attr "type" "custom")])
9297 +(define_insn "custom_in"
9298 + [(set (match_operand:SI 0 "register_operand" "=r")
9299 + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")] CUSTOM_IN))]
9301 + "custom\\t%1, %0, zero, zero"
9302 + [(set_attr "type" "custom")])
9304 +(define_insn "custom_ini"
9305 + [(set (match_operand:SI 0 "register_operand" "=r")
9306 + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
9307 + (match_operand:SI 2 "register_operand" "r")] CUSTOM_INI))]
9309 + "custom\\t%1, %0, %2, zero"
9310 + [(set_attr "type" "custom")])
9312 +(define_insn "custom_inf"
9313 + [(set (match_operand:SI 0 "register_operand" "=r")
9314 + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
9315 + (match_operand:SF 2 "register_operand" "r")] CUSTOM_INF))]
9317 + "custom\\t%1, %0, %2, zero"
9318 + [(set_attr "type" "custom")])
9320 +(define_insn "custom_inp"
9321 + [(set (match_operand:SI 0 "register_operand" "=r")
9322 + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
9323 + (match_operand:SI 2 "register_operand" "r")] CUSTOM_INP))]
9325 + "custom\\t%1, %0, %2, zero"
9326 + [(set_attr "type" "custom")])
9328 +(define_insn "custom_inii"
9329 + [(set (match_operand:SI 0 "register_operand" "=r")
9330 + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
9331 + (match_operand:SI 2 "register_operand" "r")
9332 + (match_operand:SI 3 "register_operand" "r")] CUSTOM_INII))]
9334 + "custom\\t%1, %0, %2, %3"
9335 + [(set_attr "type" "custom")])
9337 +(define_insn "custom_inif"
9338 + [(set (match_operand:SI 0 "register_operand" "=r")
9339 + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
9340 + (match_operand:SI 2 "register_operand" "r")
9341 + (match_operand:SF 3 "register_operand" "r")] CUSTOM_INIF))]
9343 + "custom\\t%1, %0, %2, %3"
9344 + [(set_attr "type" "custom")])
9346 +(define_insn "custom_inip"
9347 + [(set (match_operand:SI 0 "register_operand" "=r")
9348 + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
9349 + (match_operand:SI 2 "register_operand" "r")
9350 + (match_operand:SI 3 "register_operand" "r")] CUSTOM_INIP))]
9352 + "custom\\t%1, %0, %2, %3"
9353 + [(set_attr "type" "custom")])
9355 +(define_insn "custom_infi"
9356 + [(set (match_operand:SI 0 "register_operand" "=r")
9357 + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
9358 + (match_operand:SF 2 "register_operand" "r")
9359 + (match_operand:SI 3 "register_operand" "r")] CUSTOM_INFI))]
9361 + "custom\\t%1, %0, %2, %3"
9362 + [(set_attr "type" "custom")])
9364 +(define_insn "custom_inff"
9365 + [(set (match_operand:SI 0 "register_operand" "=r")
9366 + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
9367 + (match_operand:SF 2 "register_operand" "r")
9368 + (match_operand:SF 3 "register_operand" "r")] CUSTOM_INFF))]
9370 + "custom\\t%1, %0, %2, %3"
9371 + [(set_attr "type" "custom")])
9373 +(define_insn "custom_infp"
9374 + [(set (match_operand:SI 0 "register_operand" "=r")
9375 + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
9376 + (match_operand:SF 2 "register_operand" "r")
9377 + (match_operand:SI 3 "register_operand" "r")] CUSTOM_INFP))]
9379 + "custom\\t%1, %0, %2, %3"
9380 + [(set_attr "type" "custom")])
9382 +(define_insn "custom_inpi"
9383 + [(set (match_operand:SI 0 "register_operand" "=r")
9384 + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
9385 + (match_operand:SI 2 "register_operand" "r")
9386 + (match_operand:SI 3 "register_operand" "r")] CUSTOM_INPI))]
9388 + "custom\\t%1, %0, %2, %3"
9389 + [(set_attr "type" "custom")])
9391 +(define_insn "custom_inpf"
9392 + [(set (match_operand:SI 0 "register_operand" "=r")
9393 + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
9394 + (match_operand:SI 2 "register_operand" "r")
9395 + (match_operand:SF 3 "register_operand" "r")] CUSTOM_INPF))]
9397 + "custom\\t%1, %0, %2, %3"
9398 + [(set_attr "type" "custom")])
9400 +(define_insn "custom_inpp"
9401 + [(set (match_operand:SI 0 "register_operand" "=r")
9402 + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
9403 + (match_operand:SI 2 "register_operand" "r")
9404 + (match_operand:SI 3 "register_operand" "r")] CUSTOM_INPP))]
9406 + "custom\\t%1, %0, %2, %3"
9407 + [(set_attr "type" "custom")])
9413 +(define_insn "custom_fn"
9414 + [(set (match_operand:SF 0 "register_operand" "=r")
9415 + (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")] CUSTOM_FN))]
9417 + "custom\\t%1, %0, zero, zero"
9418 + [(set_attr "type" "custom")])
9420 +(define_insn "custom_fni"
9421 + [(set (match_operand:SF 0 "register_operand" "=r")
9422 + (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
9423 + (match_operand:SI 2 "register_operand" "r")] CUSTOM_FNI))]
9425 + "custom\\t%1, %0, %2, zero"
9426 + [(set_attr "type" "custom")])
9428 +(define_insn "custom_fnf"
9429 + [(set (match_operand:SF 0 "register_operand" "=r")
9430 + (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
9431 + (match_operand:SF 2 "register_operand" "r")] CUSTOM_FNF))]
9433 + "custom\\t%1, %0, %2, zero"
9434 + [(set_attr "type" "custom")])
9436 +(define_insn "custom_fnp"
9437 + [(set (match_operand:SF 0 "register_operand" "=r")
9438 + (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
9439 + (match_operand:SI 2 "register_operand" "r")] CUSTOM_FNP))]
9441 + "custom\\t%1, %0, %2, zero"
9442 + [(set_attr "type" "custom")])
9444 +(define_insn "custom_fnii"
9445 + [(set (match_operand:SF 0 "register_operand" "=r")
9446 + (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
9447 + (match_operand:SI 2 "register_operand" "r")
9448 + (match_operand:SI 3 "register_operand" "r")] CUSTOM_FNII))]
9450 + "custom\\t%1, %0, %2, %3"
9451 + [(set_attr "type" "custom")])
9453 +(define_insn "custom_fnif"
9454 + [(set (match_operand:SF 0 "register_operand" "=r")
9455 + (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
9456 + (match_operand:SI 2 "register_operand" "r")
9457 + (match_operand:SF 3 "register_operand" "r")] CUSTOM_FNIF))]
9459 + "custom\\t%1, %0, %2, %3"
9460 + [(set_attr "type" "custom")])
9462 +(define_insn "custom_fnip"
9463 + [(set (match_operand:SF 0 "register_operand" "=r")
9464 + (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
9465 + (match_operand:SI 2 "register_operand" "r")
9466 + (match_operand:SI 3 "register_operand" "r")] CUSTOM_FNIP))]
9468 + "custom\\t%1, %0, %2, %3"
9469 + [(set_attr "type" "custom")])
9471 +(define_insn "custom_fnfi"
9472 + [(set (match_operand:SF 0 "register_operand" "=r")
9473 + (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
9474 + (match_operand:SF 2 "register_operand" "r")
9475 + (match_operand:SI 3 "register_operand" "r")] CUSTOM_FNFI))]
9477 + "custom\\t%1, %0, %2, %3"
9478 + [(set_attr "type" "custom")])
9480 +(define_insn "custom_fnff"
9481 + [(set (match_operand:SF 0 "register_operand" "=r")
9482 + (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
9483 + (match_operand:SF 2 "register_operand" "r")
9484 + (match_operand:SF 3 "register_operand" "r")] CUSTOM_FNFF))]
9486 + "custom\\t%1, %0, %2, %3"
9487 + [(set_attr "type" "custom")])
9489 +(define_insn "custom_fnfp"
9490 + [(set (match_operand:SF 0 "register_operand" "=r")
9491 + (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
9492 + (match_operand:SF 2 "register_operand" "r")
9493 + (match_operand:SI 3 "register_operand" "r")] CUSTOM_FNFP))]
9495 + "custom\\t%1, %0, %2, %3"
9496 + [(set_attr "type" "custom")])
9498 +(define_insn "custom_fnpi"
9499 + [(set (match_operand:SF 0 "register_operand" "=r")
9500 + (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
9501 + (match_operand:SI 2 "register_operand" "r")
9502 + (match_operand:SI 3 "register_operand" "r")] CUSTOM_FNPI))]
9504 + "custom\\t%1, %0, %2, %3"
9505 + [(set_attr "type" "custom")])
9507 +(define_insn "custom_fnpf"
9508 + [(set (match_operand:SF 0 "register_operand" "=r")
9509 + (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
9510 + (match_operand:SI 2 "register_operand" "r")
9511 + (match_operand:SF 3 "register_operand" "r")] CUSTOM_FNPF))]
9513 + "custom\\t%1, %0, %2, %3"
9514 + [(set_attr "type" "custom")])
9516 +(define_insn "custom_fnpp"
9517 + [(set (match_operand:SF 0 "register_operand" "=r")
9518 + (unspec_volatile:SF [(match_operand:SI 1 "custom_insn_opcode" "N")
9519 + (match_operand:SI 2 "register_operand" "r")
9520 + (match_operand:SI 3 "register_operand" "r")] CUSTOM_FNPP))]
9522 + "custom\\t%1, %0, %2, %3"
9523 + [(set_attr "type" "custom")])
9527 +(define_insn "custom_pn"
9528 + [(set (match_operand:SI 0 "register_operand" "=r")
9529 + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")] CUSTOM_PN))]
9531 + "custom\\t%1, %0, zero, zero"
9532 + [(set_attr "type" "custom")])
9534 +(define_insn "custom_pni"
9535 + [(set (match_operand:SI 0 "register_operand" "=r")
9536 + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
9537 + (match_operand:SI 2 "register_operand" "r")] CUSTOM_PNI))]
9539 + "custom\\t%1, %0, %2, zero"
9540 + [(set_attr "type" "custom")])
9542 +(define_insn "custom_pnf"
9543 + [(set (match_operand:SI 0 "register_operand" "=r")
9544 + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
9545 + (match_operand:SF 2 "register_operand" "r")] CUSTOM_PNF))]
9547 + "custom\\t%1, %0, %2, zero"
9548 + [(set_attr "type" "custom")])
9550 +(define_insn "custom_pnp"
9551 + [(set (match_operand:SI 0 "register_operand" "=r")
9552 + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
9553 + (match_operand:SI 2 "register_operand" "r")] CUSTOM_PNP))]
9555 + "custom\\t%1, %0, %2, zero"
9556 + [(set_attr "type" "custom")])
9558 +(define_insn "custom_pnii"
9559 + [(set (match_operand:SI 0 "register_operand" "=r")
9560 + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
9561 + (match_operand:SI 2 "register_operand" "r")
9562 + (match_operand:SI 3 "register_operand" "r")] CUSTOM_PNII))]
9564 + "custom\\t%1, %0, %2, %3"
9565 + [(set_attr "type" "custom")])
9567 +(define_insn "custom_pnif"
9568 + [(set (match_operand:SI 0 "register_operand" "=r")
9569 + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
9570 + (match_operand:SI 2 "register_operand" "r")
9571 + (match_operand:SF 3 "register_operand" "r")] CUSTOM_PNIF))]
9573 + "custom\\t%1, %0, %2, %3"
9574 + [(set_attr "type" "custom")])
9576 +(define_insn "custom_pnip"
9577 + [(set (match_operand:SI 0 "register_operand" "=r")
9578 + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
9579 + (match_operand:SI 2 "register_operand" "r")
9580 + (match_operand:SI 3 "register_operand" "r")] CUSTOM_PNIP))]
9582 + "custom\\t%1, %0, %2, %3"
9583 + [(set_attr "type" "custom")])
9585 +(define_insn "custom_pnfi"
9586 + [(set (match_operand:SI 0 "register_operand" "=r")
9587 + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
9588 + (match_operand:SF 2 "register_operand" "r")
9589 + (match_operand:SI 3 "register_operand" "r")] CUSTOM_PNFI))]
9591 + "custom\\t%1, %0, %2, %3"
9592 + [(set_attr "type" "custom")])
9594 +(define_insn "custom_pnff"
9595 + [(set (match_operand:SI 0 "register_operand" "=r")
9596 + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
9597 + (match_operand:SF 2 "register_operand" "r")
9598 + (match_operand:SF 3 "register_operand" "r")] CUSTOM_PNFF))]
9600 + "custom\\t%1, %0, %2, %3"
9601 + [(set_attr "type" "custom")])
9603 +(define_insn "custom_pnfp"
9604 + [(set (match_operand:SI 0 "register_operand" "=r")
9605 + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
9606 + (match_operand:SF 2 "register_operand" "r")
9607 + (match_operand:SI 3 "register_operand" "r")] CUSTOM_PNFP))]
9609 + "custom\\t%1, %0, %2, %3"
9610 + [(set_attr "type" "custom")])
9612 +(define_insn "custom_pnpi"
9613 + [(set (match_operand:SI 0 "register_operand" "=r")
9614 + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
9615 + (match_operand:SI 2 "register_operand" "r")
9616 + (match_operand:SI 3 "register_operand" "r")] CUSTOM_PNPI))]
9618 + "custom\\t%1, %0, %2, %3"
9619 + [(set_attr "type" "custom")])
9621 +(define_insn "custom_pnpf"
9622 + [(set (match_operand:SI 0 "register_operand" "=r")
9623 + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
9624 + (match_operand:SI 2 "register_operand" "r")
9625 + (match_operand:SF 3 "register_operand" "r")] CUSTOM_PNPF))]
9627 + "custom\\t%1, %0, %2, %3"
9628 + [(set_attr "type" "custom")])
9630 +(define_insn "custom_pnpp"
9631 + [(set (match_operand:SI 0 "register_operand" "=r")
9632 + (unspec_volatile:SI [(match_operand:SI 1 "custom_insn_opcode" "N")
9633 + (match_operand:SI 2 "register_operand" "r")
9634 + (match_operand:SI 3 "register_operand" "r")] CUSTOM_PNPP))]
9636 + "custom\\t%1, %0, %2, %3"
9637 + [(set_attr "type" "custom")])
9644 +;*****************************************************************************
9648 +;*****************************************************************************
9654 + [(set_attr "type" "alu")])
9656 +(define_insn "sync"
9657 + [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)]
9660 + [(set_attr "type" "control")])
9663 +(define_insn "rdctl"
9664 + [(set (match_operand:SI 0 "register_operand" "=r")
9665 + (unspec_volatile:SI [(match_operand:SI 1 "rdwrctl_operand" "O")] UNSPEC_RDCTL))]
9667 + "rdctl\\t%0, ctl%1"
9668 + [(set_attr "type" "control")])
9670 +(define_insn "wrctl"
9671 + [(unspec_volatile:SI [(match_operand:SI 0 "rdwrctl_operand" "O")
9672 + (match_operand:SI 1 "register_operand" "r")] UNSPEC_WRCTL)]
9674 + "wrctl\\tctl%0, %1"
9675 + [(set_attr "type" "control")])
9679 +;*****************************************************************************
9683 +;*****************************************************************************
9686 diff -durN gcc-3.4.6.orig/gcc/config/nios2/nios2-protos.h gcc-3.4.6/gcc/config/nios2/nios2-protos.h
9687 --- gcc-3.4.6.orig/gcc/config/nios2/nios2-protos.h 1970-01-01 01:00:00.000000000 +0100
9688 +++ gcc-3.4.6/gcc/config/nios2/nios2-protos.h 2007-08-15 23:09:36.000000000 +0200
9690 +/* Subroutines for assembler code output for Altera NIOS 2G NIOS2 version.
9691 + Copyright (C) 2003 Altera
9692 + Contributed by Jonah Graham (jgraham@altera.com).
9694 +This file is part of GNU CC.
9696 +GNU CC is free software; you can redistribute it and/or modify
9697 +it under the terms of the GNU General Public License as published by
9698 +the Free Software Foundation; either version 2, or (at your option)
9701 +GNU CC is distributed in the hope that it will be useful,
9702 +but WITHOUT ANY WARRANTY; without even the implied warranty of
9703 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9704 +GNU General Public License for more details.
9706 +You should have received a copy of the GNU General Public License
9707 +along with GNU CC; see the file COPYING. If not, write to
9708 +the Free Software Foundation, 59 Temple Place - Suite 330,
9709 +Boston, MA 02111-1307, USA. */
9711 +extern void dump_frame_size (FILE *);
9712 +extern HOST_WIDE_INT compute_frame_size (void);
9713 +extern int nios2_initial_elimination_offset (int, int);
9714 +extern void override_options (void);
9715 +extern void optimization_options (int, int);
9716 +extern int nios2_can_use_return_insn (void);
9717 +extern void expand_prologue (void);
9718 +extern void expand_epilogue (bool);
9719 +extern void function_profiler (FILE *, int);
9723 +extern int nios2_legitimate_address (rtx, enum machine_mode, int);
9724 +extern void nios2_print_operand (FILE *, rtx, int);
9725 +extern void nios2_print_operand_address (FILE *, rtx);
9727 +extern int nios2_emit_move_sequence (rtx *, enum machine_mode);
9728 +extern int nios2_emit_expensive_div (rtx *, enum machine_mode);
9730 +extern void gen_int_relational (enum rtx_code, rtx, rtx, rtx, rtx);
9731 +extern void gen_conditional_move (rtx *, enum machine_mode);
9732 +extern const char *asm_output_opcode (FILE *, const char *);
9735 +extern int arith_operand (rtx, enum machine_mode);
9736 +extern int uns_arith_operand (rtx, enum machine_mode);
9737 +extern int logical_operand (rtx, enum machine_mode);
9738 +extern int shift_operand (rtx, enum machine_mode);
9739 +extern int reg_or_0_operand (rtx, enum machine_mode);
9740 +extern int equality_op (rtx, enum machine_mode);
9741 +extern int custom_insn_opcode (rtx, enum machine_mode);
9742 +extern int rdwrctl_operand (rtx, enum machine_mode);
9744 +# ifdef HAVE_MACHINE_MODES
9745 +# if defined TREE_CODE
9746 +extern void function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
9747 +extern rtx function_arg (const CUMULATIVE_ARGS *, enum machine_mode, tree, int);
9748 +extern int function_arg_partial_nregs (const CUMULATIVE_ARGS *, enum machine_mode, tree, int);
9749 +extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree, int);
9750 +extern int nios2_setup_incoming_varargs (const CUMULATIVE_ARGS *, enum machine_mode, tree, int);
9752 +# endif /* TREE_CODE */
9753 +# endif /* HAVE_MACHINE_MODES */
9757 +extern int nios2_return_in_memory (tree);
9759 +#endif /* TREE_CODE */
9760 diff -durN gcc-3.4.6.orig/gcc/config/nios2/t-nios2 gcc-3.4.6/gcc/config/nios2/t-nios2
9761 --- gcc-3.4.6.orig/gcc/config/nios2/t-nios2 1970-01-01 01:00:00.000000000 +0100
9762 +++ gcc-3.4.6/gcc/config/nios2/t-nios2 2007-08-15 23:09:36.000000000 +0200
9765 +## Compiler flags to use when compiling libgcc2.c.
9768 +## A list of source file names to be compiled or assembled and inserted into libgcc.a.
9770 +LIB2FUNCS_EXTRA=$(srcdir)/config/nios2/lib2-divmod.c \
9771 + $(srcdir)/config/nios2/lib2-divmod-hi.c \
9772 + $(srcdir)/config/nios2/lib2-divtable.c \
9773 + $(srcdir)/config/nios2/lib2-mul.c
9776 +## Floating Point Emulation
9777 +## To have GCC include software floating point libraries in libgcc.a define FPBIT
9778 +## and DPBIT along with a few rules as follows:
9780 +## # We want fine grained libraries, so use the new code
9781 +## # to build the floating point emulation libraries.
9782 +FPBIT=$(srcdir)/config/nios2/nios2-fp-bit.c
9783 +DPBIT=$(srcdir)/config/nios2/nios2-dp-bit.c
9785 +TARGET_LIBGCC2_CFLAGS = -O2
9787 +# FLOAT_ONLY - no doubles
9788 +# SMALL_MACHINE - QI/HI is faster than SI
9789 +# Actually SMALL_MACHINE uses chars and shorts instead of ints
9790 +# since ints (16-bit ones as they are today) are at least as fast
9791 +# as chars and shorts, don't define SMALL_MACHINE
9792 +# CMPtype - type returned by FP compare, i.e. INT (hard coded in fp-bit - see code )
9794 +$(FPBIT): $(srcdir)/config/fp-bit.c Makefile
9795 + echo '#define FLOAT' > ${FPBIT}
9796 + cat $(srcdir)/config/fp-bit.c >> ${FPBIT}
9798 +$(DPBIT): $(srcdir)/config/fp-bit.c Makefile
9799 + echo '' > ${DPBIT}
9800 + cat $(srcdir)/config/fp-bit.c >> ${DPBIT}
9802 +EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crti.o crtn.o
9804 +# Assemble startup files.
9805 +$(T)crti.o: $(srcdir)/config/nios2/crti.asm $(GCC_PASSES)
9806 + $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
9807 + -c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/nios2/crti.asm
9809 +$(T)crtn.o: $(srcdir)/config/nios2/crtn.asm $(GCC_PASSES)
9810 + $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
9811 + -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/nios2/crtn.asm
9814 +## You may need to provide additional #defines at the beginning of
9815 +## fp-bit.c and dp-bit.c to control target endianness and other options
9817 +## CRTSTUFF_T_CFLAGS
9818 +## Special flags used when compiling crtstuff.c. See Initialization.
9820 +## CRTSTUFF_T_CFLAGS_S
9821 +## Special flags used when compiling crtstuff.c for shared linking. Used
9822 +## if you use crtbeginS.o and crtendS.o in EXTRA-PARTS. See Initialization.
9824 +## MULTILIB_OPTIONS
9825 +## For some targets, invoking GCC in different ways produces objects that
9826 +## can not be linked together. For example, for some targets GCC produces
9827 +## both big and little endian code. For these targets, you must arrange
9828 +## for multiple versions of libgcc.a to be compiled, one for each set of
9829 +## incompatible options. When GCC invokes the linker, it arranges to link
9830 +## in the right version of libgcc.a, based on the command line options
9832 +## The MULTILIB_OPTIONS macro lists the set of options for which special
9833 +## versions of libgcc.a must be built. Write options that are mutually
9834 +## incompatible side by side, separated by a slash. Write options that may
9835 +## be used together separated by a space. The build procedure will build
9836 +## all combinations of compatible options.
9838 +## For example, if you set MULTILIB_OPTIONS to m68000/m68020 msoft-float,
9839 +## Makefile will build special versions of libgcc.a using the following
9840 +## sets of options: -m68000, -m68020, -msoft-float, -m68000 -msoft-float,
9841 +## and -m68020 -msoft-float.
9843 +MULTILIB_OPTIONS = mno-hw-mul mhw-mulx
9845 +## MULTILIB_DIRNAMES
9846 +## If MULTILIB_OPTIONS is used, this variable specifies the directory names
9847 +## that should be used to hold the various libraries. Write one element in
9848 +## MULTILIB_DIRNAMES for each element in MULTILIB_OPTIONS. If
9849 +## MULTILIB_DIRNAMES is not used, the default value will be
9850 +## MULTILIB_OPTIONS, with all slashes treated as spaces.
9851 +## For example, if MULTILIB_OPTIONS is set to m68000/m68020 msoft-float,
9852 +## then the default value of MULTILIB_DIRNAMES is m68000 m68020
9853 +## msoft-float. You may specify a different value if you desire a
9854 +## different set of directory names.
9856 +# MULTILIB_DIRNAMES =
9858 +## MULTILIB_MATCHES
9859 +## Sometimes the same option may be written in two different ways. If an
9860 +## option is listed in MULTILIB_OPTIONS, GCC needs to know about any
9861 +## synonyms. In that case, set MULTILIB_MATCHES to a list of items of the
9862 +## form option=option to describe all relevant synonyms. For example,
9863 +## m68000=mc68000 m68020=mc68020.
9865 +## MULTILIB_EXCEPTIONS
9866 +## Sometimes when there are multiple sets of MULTILIB_OPTIONS being
9867 +## specified, there are combinations that should not be built. In that
9868 +## case, set MULTILIB_EXCEPTIONS to be all of the switch exceptions in
9869 +## shell case syntax that should not be built.
9870 +## For example, in the PowerPC embedded ABI support, it is not desirable to
9871 +## build libraries compiled with the -mcall-aix option and either of the
9872 +## -fleading-underscore or -mlittle options at the same time. Therefore
9873 +## MULTILIB_EXCEPTIONS is set to
9875 +## *mcall-aix/*fleading-underscore* *mlittle/*mcall-aix*
9878 +MULTILIB_EXCEPTIONS = *mno-hw-mul/*mhw-mulx*
9881 +## MULTILIB_EXTRA_OPTS Sometimes it is desirable that when building
9882 +## multiple versions of libgcc.a certain options should always be passed on
9883 +## to the compiler. In that case, set MULTILIB_EXTRA_OPTS to be the list
9884 +## of options to be used for all builds.
9887 diff -durN gcc-3.4.6.orig/gcc/config.gcc gcc-3.4.6/gcc/config.gcc
9888 --- gcc-3.4.6.orig/gcc/config.gcc 2007-08-15 23:07:00.000000000 +0200
9889 +++ gcc-3.4.6/gcc/config.gcc 2007-08-15 23:09:36.000000000 +0200
9890 @@ -1342,6 +1342,10 @@
9895 +nios2-*-* | nios2-*-*)
9896 + tm_file="elfos.h ${tm_file}"
9898 # m68hc11 and m68hc12 share the same machine description.
9899 m68hc11-*-*|m6811-*-*)
9900 tm_file="dbxelf.h elfos.h m68hc11/m68hc11.h"
9901 diff -durN gcc-3.4.6.orig/gcc/cse.c gcc-3.4.6/gcc/cse.c
9902 --- gcc-3.4.6.orig/gcc/cse.c 2005-12-31 01:39:42.000000000 +0100
9903 +++ gcc-3.4.6/gcc/cse.c 2007-08-15 23:09:36.000000000 +0200
9904 @@ -3134,6 +3134,10 @@
9905 #ifdef FLOAT_STORE_FLAG_VALUE
9906 REAL_VALUE_TYPE fsfv;
9913 /* If the entry isn't valid, skip it. */
9914 if (! exp_equiv_p (p->exp, p->exp, 1, 0))
9915 diff -durN gcc-3.4.6.orig/gcc/doc/extend.texi gcc-3.4.6/gcc/doc/extend.texi
9916 --- gcc-3.4.6.orig/gcc/doc/extend.texi 2005-02-26 23:17:26.000000000 +0100
9917 +++ gcc-3.4.6/gcc/doc/extend.texi 2007-08-15 23:09:36.000000000 +0200
9918 @@ -5638,12 +5638,118 @@
9919 instructions, but allow the compiler to schedule those calls.
9922 +* Altera Nios II Built-in Functions::
9923 * Alpha Built-in Functions::
9924 * ARM Built-in Functions::
9925 * X86 Built-in Functions::
9926 * PowerPC AltiVec Built-in Functions::
9929 +@node Altera Nios II Built-in Functions
9930 +@subsection Altera Nios II Built-in Functions
9932 +These built-in functions are available for the Altera Nios II
9933 +family of processors.
9935 +The following built-in functions are always available. They
9936 +all generate the machine instruction that is part of the name.
9939 +int __builtin_ldbio (volatile const void *)
9940 +int __builtin_ldbuio (volatile const void *)
9941 +int __builtin_ldhio (volatile const void *)
9942 +int __builtin_ldhuio (volatile const void *)
9943 +int __builtin_ldwio (volatile const void *)
9944 +void __builtin_stbio (volatile void *, int)
9945 +void __builtin_sthio (volatile void *, int)
9946 +void __builtin_stwio (volatile void *, int)
9947 +void __builtin_sync (void)
9948 +int __builtin_rdctl (int)
9949 +void __builtin_wrctl (int, int)
9952 +The following built-in functions are always available. They
9953 +all generate a Nios II Custom Instruction. The name of the
9954 +function represents the types that the function takes and
9955 +returns. The letter before the @code{n} is the return type
9956 +or void if absent. The @code{n} represnts the first parameter
9957 +to all the custom instructions, the custom instruction number.
9958 +The two letters after the @code{n} represent the up to two
9959 +parameters to the function.
9961 +The letters reprsent the following data types:
9964 +@code{void} for return type and no parameter for parameter types.
9967 +@code{int} for return type and parameter type
9970 +@code{float} for return type and parameter type
9973 +@code{void *} for return type and parameter type
9977 +And the function names are:
9979 +void __builtin_custom_n (void)
9980 +void __builtin_custom_ni (int)
9981 +void __builtin_custom_nf (float)
9982 +void __builtin_custom_np (void *)
9983 +void __builtin_custom_nii (int, int)
9984 +void __builtin_custom_nif (int, float)
9985 +void __builtin_custom_nip (int, void *)
9986 +void __builtin_custom_nfi (float, int)
9987 +void __builtin_custom_nff (float, float)
9988 +void __builtin_custom_nfp (float, void *)
9989 +void __builtin_custom_npi (void *, int)
9990 +void __builtin_custom_npf (void *, float)
9991 +void __builtin_custom_npp (void *, void *)
9992 +int __builtin_custom_in (void)
9993 +int __builtin_custom_ini (int)
9994 +int __builtin_custom_inf (float)
9995 +int __builtin_custom_inp (void *)
9996 +int __builtin_custom_inii (int, int)
9997 +int __builtin_custom_inif (int, float)
9998 +int __builtin_custom_inip (int, void *)
9999 +int __builtin_custom_infi (float, int)
10000 +int __builtin_custom_inff (float, float)
10001 +int __builtin_custom_infp (float, void *)
10002 +int __builtin_custom_inpi (void *, int)
10003 +int __builtin_custom_inpf (void *, float)
10004 +int __builtin_custom_inpp (void *, void *)
10005 +float __builtin_custom_fn (void)
10006 +float __builtin_custom_fni (int)
10007 +float __builtin_custom_fnf (float)
10008 +float __builtin_custom_fnp (void *)
10009 +float __builtin_custom_fnii (int, int)
10010 +float __builtin_custom_fnif (int, float)
10011 +float __builtin_custom_fnip (int, void *)
10012 +float __builtin_custom_fnfi (float, int)
10013 +float __builtin_custom_fnff (float, float)
10014 +float __builtin_custom_fnfp (float, void *)
10015 +float __builtin_custom_fnpi (void *, int)
10016 +float __builtin_custom_fnpf (void *, float)
10017 +float __builtin_custom_fnpp (void *, void *)
10018 +void * __builtin_custom_pn (void)
10019 +void * __builtin_custom_pni (int)
10020 +void * __builtin_custom_pnf (float)
10021 +void * __builtin_custom_pnp (void *)
10022 +void * __builtin_custom_pnii (int, int)
10023 +void * __builtin_custom_pnif (int, float)
10024 +void * __builtin_custom_pnip (int, void *)
10025 +void * __builtin_custom_pnfi (float, int)
10026 +void * __builtin_custom_pnff (float, float)
10027 +void * __builtin_custom_pnfp (float, void *)
10028 +void * __builtin_custom_pnpi (void *, int)
10029 +void * __builtin_custom_pnpf (void *, float)
10030 +void * __builtin_custom_pnpp (void *, void *)
10034 @node Alpha Built-in Functions
10035 @subsection Alpha Built-in Functions
10037 diff -durN gcc-3.4.6.orig/gcc/doc/invoke.texi gcc-3.4.6/gcc/doc/invoke.texi
10038 --- gcc-3.4.6.orig/gcc/doc/invoke.texi 2005-10-08 02:22:20.000000000 +0200
10039 +++ gcc-3.4.6/gcc/doc/invoke.texi 2007-08-15 23:09:36.000000000 +0200
10040 @@ -337,6 +337,14 @@
10041 @item Machine Dependent Options
10042 @xref{Submodel Options,,Hardware Models and Configurations}.
10044 +@emph{Altera Nios II Options}
10045 +@gccoptlist{-msmallc -mno-bypass-cache -mbypass-cache @gol
10046 +-mno-cache-volatile -mcache-volatile -mno-inline-memcpy @gol
10047 +-minline-memcpy -mno-fast-sw-div -mfast-sw-div @gol
10048 +-mhw-mul -mno-hw-mul -mhw-mulx -mno-hw-mulx @gol
10049 +-mno-hw-div -mhw-div @gol
10050 +-msys-crt0= -msys-lib= -msys=nosys }
10052 @emph{M680x0 Options}
10053 @gccoptlist{-m68000 -m68020 -m68020-40 -m68020-60 -m68030 -m68040 @gol
10054 -m68060 -mcpu32 -m5200 -m68881 -mbitfield -mc68000 -mc68020 @gol
10055 @@ -5839,6 +5847,7 @@
10056 that macro, which enables you to change the defaults.
10059 +* Altera Nios II Options::
10061 * M68hc1x Options::
10063 @@ -5874,6 +5883,103 @@
10068 +@node Altera Nios II Options
10069 +@subsection Altera Nios II Options
10070 +@cindex Altera Nios II options
10072 +These are the @samp{-m} options defined for the Altera Nios II
10080 +Link with a limited version of the C library, -lsmallc. For more
10081 +information see the C Library Documentation.
10084 +@item -mbypass-cache
10085 +@itemx -mno-bypass-cache
10086 +@opindex mno-bypass-cache
10087 +@opindex mbypass-cache
10089 +Force all load and store instructions to always bypass cache by
10090 +using io variants of the instructions. The default is to not
10093 +@item -mno-cache-volatile
10094 +@itemx -mcache-volatile
10095 +@opindex mcache-volatile
10096 +@opindex mno-cache-volatile
10098 +Volatile memory access bypass the cache using the io variants of
10099 +the ld and st instructions. The default is to cache volatile
10102 +-mno-cache-volatile is deprecated and will be deleted in a
10103 +future GCC release.
10106 +@item -mno-inline-memcpy
10107 +@itemx -minline-memcpy
10108 +@opindex mno-inline-memcpy
10109 +@opindex minline-memcpy
10111 +Do not inline memcpy. The default is to inline when -O is on.
10114 +@item -mno-fast-sw-div
10115 +@itemx -mfast-sw-div
10116 +@opindex mno-fast-sw-div
10117 +@opindex mfast-sw-div
10119 +Do no use table based fast divide for small numbers. The default
10120 +is to use the fast divide at -O3 and above.
10125 +@itemx -mno-hw-mulx
10127 +@itemx -mno-hw-div
10129 +@opindex mno-hw-mul
10131 +@opindex mno-hw-mulx
10133 +@opindex mno-hw-div
10136 +Enable or disable emitting @code{mul}, @code{mulx} and @code{div} family of
10137 +instructions by the compiler. The default is to emit @code{mul}
10138 +and not emit @code{div} and @code{mulx}.
10140 +The different combinations of @code{mul} and @code{mulx} instructions
10141 +generate a different multilib options.
10144 +@item -msys-crt0=@var{startfile}
10145 +@opindex msys-crt0
10147 +@var{startfile} is the file name of the startfile (crt0) to use
10148 +when linking. The default is crt0.o that comes with libgloss
10149 +and is only suitable for use with the instruction set
10152 +@item -msys-lib=@var{systemlib}
10153 +@itemx -msys-lib=nosys
10156 +@var{systemlib} is the library name of the library which provides
10157 +the system calls required by the C library, e.g. @code{read}, @code{write}
10158 +etc. The default is to use nosys, this library provides
10159 +stub implementations of the calls and is part of libgloss.
10164 @node M680x0 Options
10165 @subsection M680x0 Options
10166 @cindex M680x0 options
10167 diff -durN gcc-3.4.6.orig/gcc/doc/md.texi gcc-3.4.6/gcc/doc/md.texi
10168 --- gcc-3.4.6.orig/gcc/doc/md.texi 2004-11-13 23:31:42.000000000 +0100
10169 +++ gcc-3.4.6/gcc/doc/md.texi 2007-08-15 23:09:36.000000000 +0200
10170 @@ -1337,6 +1337,49 @@
10171 available on some particular machines.
10175 +@item Altera Nios II family---@file{nios2.h}
10179 +Integer that is valid as an immediate operand in an
10180 +instruction taking a signed 16-bit number. Range
10181 +@minus{}32768 to 32767.
10184 +Integer that is valid as an immediate operand in an
10185 +instruction taking an unsigned 16-bit number. Range
10189 +Integer that is valid as an immediate operand in an
10190 +instruction taking only the upper 16-bits of a
10191 +32-bit number. Range 32-bit numbers with the lower
10195 +Integer that is valid as an immediate operand for a
10196 +shift instruction. Range 0 to 31.
10200 +Integer that is valid as an immediate operand for
10201 +only the value 0. Can be used in conjunction with
10202 +the format modifier @code{z} to use @code{r0}
10203 +instead of @code{0} in the assembly output.
10206 +Integer that is valid as an immediate operand for
10207 +a custom instruction opcode. Range 0 to 255.
10210 +Matches immediates which are addresses in the small
10211 +data section and therefore can be added to @code{gp}
10212 +as a 16-bit immediate to re-create their 32-bit value.
10217 @item ARM family---@file{arm.h}
10220 diff -durN gcc-3.4.6.orig/gcc/Makefile.in gcc-3.4.6/gcc/Makefile.in
10221 --- gcc-3.4.6.orig/gcc/Makefile.in 2005-02-24 10:26:59.000000000 +0100
10222 +++ gcc-3.4.6/gcc/Makefile.in 2007-08-15 23:09:36.000000000 +0200
10223 @@ -3094,7 +3094,7 @@
10224 $(INSTALL_DATA) $(srcdir)/README-fixinc \
10225 $(DESTDIR)$(itoolsdatadir)/include/README ; \
10226 $(INSTALL_SCRIPT) fixinc.sh $(DESTDIR)$(itoolsdir)/fixinc.sh ; \
10227 - $(INSTALL_PROGRAM) fixinc/fixincl $(DESTDIR)$(itoolsdir)/fixincl ; \
10228 + $(INSTALL_PROGRAM) fixinc/fixincl$(build_exeext) $(DESTDIR)$(itoolsdir)/fixincl$(build_exeext) ; \
10229 $(INSTALL_DATA) $(srcdir)/gsyslimits.h \
10230 $(DESTDIR)$(itoolsdatadir)/gsyslimits.h ; \