It's been a long time that the gcc libraries are all installed in the sys-root.
Thus populate does not need to look above to find the libraries.
/trunk/tools/populate.in | 9 3 6 0 +++------
1 file changed, 3 insertions(+), 6 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 ; \