config.gcc (epiphany-*-*): New architecture.
gcc: * config.gcc (epiphany-*-*): New architecture. (epiphany-*-elf): New configuration. * config/epiphany, common/config/epiphany : New directories. * doc/extend.texi (disinterrupt attribute): Add Epiphany. (interrupt attribute): Add Epiphany. (long_call, short_call attribute): Add Epiphany. * doc/invoke.texi (Options): Add Epiphany options. * doc/md.texi (Machine Constraints): Add Epiphany constraints. * doc/install.texi (Options specification): Add --with-stack-offset=@var{num} description. (host/target specific issues): Add epiphany-*-elf. * doc/contrib.texi (Contributors): Mention Epiphany port. gcc/testsuite: * gcc.c-torture/execute/ieee/mul-subnormal-single-1.x: Disable test on Epiphany. * gcc.c-torture/execute/20101011-1.c: Disable test on Epiphany. * gcc.dg/stack-usage-1.c [__epiphany__] (SIZE): Define. * gcc.dg/pragma-pack-3.c: Disable test on Epiphany. * g++.dg/parse/pragma3.C: Likewise. * stackalign/builtin-apply-2.c (STACK_ARGUMENTS_SIZE): Define. (bar): Use it. * gcc.dg/weak/typeof-2.c [epiphany-*-*]: Add option -mshort-calls. * gcc.dg/tls/thr-cse-1.c: Likewise. * g++.dg/opt/devirt2.C: Likewise. * gcc.dg/20020312-2.c [epiphany-*-*] (PIC_REG): Define. * gcc.dg/builtin-apply2.c [__epiphany__]: (STACK_ARGUMENTS_SIZE): 20. * gcc.target/epiphany: New directory. libgcc: * config.host (epiphany-*-elf*): New configuration. * config/epiphany: New Directory. contrib: * contrib-list.mk: Add Epiphany configurations. From-SVN: r181016
This commit is contained in:
parent
12ca92d4f0
commit
feeeff5cfe
69 changed files with 9550 additions and 10 deletions
|
@ -1,3 +1,7 @@
|
|||
2011-11-05 Joern Rennecke <joern.rennecke@embecosm.com>
|
||||
|
||||
* contrib-list.mk: Add Epiphany configurations.
|
||||
|
||||
2011-09-13 Diego Novillo <dnovillo@google.com>
|
||||
|
||||
* testsuite-management: New.
|
||||
|
|
|
@ -18,7 +18,8 @@ LIST = alpha-linux-gnu alpha-freebsd6 alpha-netbsd alpha-openbsd \
|
|||
arm-linux-androideabi arm-uclinux_eabi arm-ecos-elf arm-eabi \
|
||||
arm-symbianelf arm-rtems arm-elf arm-wince-pe avr-rtems avr-elf \
|
||||
bfin-elf bfin-uclinux bfin-linux-uclibc bfin-rtems bfin-openbsd \
|
||||
c6x-elf c6x-uclinux cris-elf cris-linux crisv32-elf crisv32-linux fido-elf \
|
||||
c6x-elf c6x-uclinux cris-elf cris-linux crisv32-elf crisv32-linux \
|
||||
epiphany-elf epiphany-elfOPT-with-stack-offset=16 fido-elf \
|
||||
fr30-elf frv-elf frv-linux h8300-elf h8300-rtems hppa-linux-gnu \
|
||||
hppa-linux-gnuOPT-enable-sjlj-exceptions=yes hppa64-linux-gnu \
|
||||
hppa2.0-hpux10.1 hppa64-hpux11.3 \
|
||||
|
|
|
@ -1,3 +1,18 @@
|
|||
2011-11-05 Joern Rennecke <joern.rennecke@embecosm.com>
|
||||
|
||||
* config.gcc (epiphany-*-*): New architecture.
|
||||
(epiphany-*-elf): New configuration.
|
||||
* config/epiphany, common/config/epiphany : New directories.
|
||||
* doc/extend.texi (disinterrupt attribute): Add Epiphany.
|
||||
(interrupt attribute): Add Epiphany.
|
||||
(long_call, short_call attribute): Add Epiphany.
|
||||
* doc/invoke.texi (Options): Add Epiphany options.
|
||||
* doc/md.texi (Machine Constraints): Add Epiphany constraints.
|
||||
* doc/install.texi (Options specification):
|
||||
Add --with-stack-offset=@var{num} description.
|
||||
(host/target specific issues): Add epiphany-*-elf.
|
||||
* doc/contrib.texi (Contributors): Mention Epiphany port.
|
||||
|
||||
2011-11-05 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/50693
|
||||
|
|
46
gcc/common/config/epiphany/epiphany-common.c
Normal file
46
gcc/common/config/epiphany/epiphany-common.c
Normal file
|
@ -0,0 +1,46 @@
|
|||
/* Common hooks for Adapteva Epiphany
|
||||
Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
|
||||
2004, 2005, 2006, 2007, 2009, 2011 Free Software Foundation, Inc.
|
||||
Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "common/common-target.h"
|
||||
#include "opts.h"
|
||||
#include "flags.h"
|
||||
|
||||
#define TARGET_OPTION_OPTIMIZATION_TABLE epiphany_option_optimization_table
|
||||
|
||||
#define TARGET_DEFAULT_TARGET_FLAGS \
|
||||
(MASK_CMOVE | MASK_SOFT_CMPSF | MASK_SPLIT_LOHI | MASK_ROUND_NEAREST \
|
||||
| MASK_VECT_DOUBLE | MASK_POST_INC | MASK_POST_MODIFY)
|
||||
|
||||
#define TARGET_HAVE_NAMED_SECTIONS true
|
||||
|
||||
#include "common/common-target-def.h"
|
||||
|
||||
/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
|
||||
static const struct default_options epiphany_option_optimization_table[] =
|
||||
{
|
||||
{ OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
|
||||
{ OPT_LEVELS_NONE, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER;
|
|
@ -967,6 +967,14 @@ crisv32-*-linux* | cris-*-linux*)
|
|||
;;
|
||||
esac
|
||||
;;
|
||||
epiphany-*-elf )
|
||||
tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
|
||||
tmake_file="epiphany/t-epiphany"
|
||||
extra_options="${extra_options} fused-madd.opt"
|
||||
extra_objs="$extra_objs mode-switch-use.o resolve-sw-modes.o"
|
||||
tm_defines="${tm_defines} EPIPHANY_STACK_OFFSET=${with_stack_offset:-8}"
|
||||
extra_headers="epiphany_intrinsics.h"
|
||||
;;
|
||||
fr30-*-elf)
|
||||
tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
|
||||
;;
|
||||
|
|
125
gcc/config/epiphany/constraints.md
Normal file
125
gcc/config/epiphany/constraints.md
Normal file
|
@ -0,0 +1,125 @@
|
|||
;; Constraint definitions for Adaptiva epiphany
|
||||
;; Copyright (C) 2007, 2009, 2011 Free Software Foundation, Inc.
|
||||
;; Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
|
||||
;; This file is part of GCC.
|
||||
|
||||
;; GCC is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GCC is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GCC; see the file COPYING3. If not see
|
||||
;; <http://www.gnu.org/licenses/>.
|
||||
|
||||
;; Integer constraints
|
||||
|
||||
(define_constraint "U16"
|
||||
"An unsigned 16-bit constant."
|
||||
(ior (and (match_code "const_int")
|
||||
(match_test "IMM16 (ival)"))
|
||||
(and (match_code "symbol_ref,label_ref,const")
|
||||
(match_test "epiphany_small16 (op)"))))
|
||||
|
||||
(define_constraint "K"
|
||||
"An unsigned 5-bit constant."
|
||||
(and (match_code "const_int")
|
||||
(match_test "IMM5 (ival)")))
|
||||
|
||||
;; This could also accept symbol_ref, label_ref or const if we introduce
|
||||
;; a small area and/or attribute that satisfies the 11-bit signed range.
|
||||
(define_constraint "L"
|
||||
"A signed 11-bit constant."
|
||||
(and (match_code "const_int")
|
||||
(match_test "SIMM11 (ival)")))
|
||||
|
||||
(define_constraint "Cm1"
|
||||
"A signed 11-bit constant added to -1"
|
||||
(and (match_code "const_int")
|
||||
(match_test "SIMM11 (ival+1)")
|
||||
(match_test "epiphany_m1reg >= 0")))
|
||||
|
||||
(define_constraint "Cl1"
|
||||
"Left-shift of -1"
|
||||
(and (match_code "const_int")
|
||||
(match_test "ival == (ival | ~(ival-1))")
|
||||
(match_test "epiphany_m1reg >= 0")))
|
||||
|
||||
(define_constraint "Cr1"
|
||||
"Right-shift of -1"
|
||||
(and (match_code "const_int")
|
||||
(match_test "ival == (ival & ~(ival+1))")
|
||||
(match_test "epiphany_m1reg >= 0")))
|
||||
|
||||
(define_constraint "Cal"
|
||||
"Constant for arithmetic/logical operations"
|
||||
(match_test "(flag_pic
|
||||
? nonsymbolic_immediate_operand (op, VOIDmode)
|
||||
: immediate_operand (op, VOIDmode))"))
|
||||
|
||||
(define_constraint "Csy"
|
||||
"Symbolic constant for call/jump instruction"
|
||||
(match_test "symbolic_operand (op, VOIDmode)"))
|
||||
|
||||
;; Register constraints
|
||||
;; proper register constraints define a register class and can thus
|
||||
;; drive register allocation and reload. OTOH sometimes we want to
|
||||
;; avoid just that.
|
||||
|
||||
;; The register class usable in short insns.
|
||||
;; Subject to TARGET_PREFER_SHORT_INSN_REGS.
|
||||
(define_register_constraint "Rcs" "SHORT_INSN_REGS"
|
||||
"short insn register class.")
|
||||
|
||||
; The registers that can be used to hold a sibcall call address.
|
||||
; This must not conflict with any callee-saved registers.
|
||||
(define_register_constraint "Rsc" "SIBCALL_REGS"
|
||||
"sibcall register class")
|
||||
|
||||
; The registers that can be used to hold a status value
|
||||
(define_register_constraint "Rct" "CORE_CONTROL_REGS"
|
||||
"Core control register class")
|
||||
|
||||
;; The register group usable in short insns.
|
||||
(define_constraint "Rgs"
|
||||
"short insn register group."
|
||||
(and (match_code "reg")
|
||||
(match_test "REGNO (op) >= FIRST_PSEUDO_REGISTER || REGNO (op) <= 7")))
|
||||
|
||||
;; Constant suitable for the addsi3_r pattern.
|
||||
(define_constraint "Car"
|
||||
"addsi3_r constant."
|
||||
(and (match_code "const_int")
|
||||
(ior (match_test "RTX_OK_FOR_OFFSET_P (SImode, op)")
|
||||
(match_test "RTX_OK_FOR_OFFSET_P (HImode, op)")
|
||||
(match_test "RTX_OK_FOR_OFFSET_P (QImode, op)"))))
|
||||
|
||||
;; The return address if it can be replaced with GPR_LR.
|
||||
(define_constraint "Rra"
|
||||
"return address constraint - register variant"
|
||||
(and (match_code "unspec")
|
||||
(match_test "XINT (op, 1) == UNSPEC_RETURN_ADDR")
|
||||
(match_test "!MACHINE_FUNCTION (cfun)->lr_clobbered")))
|
||||
|
||||
(define_constraint "Rcc"
|
||||
"integer condition code"
|
||||
(and (match_code "reg")
|
||||
(match_test "REGNO (op) == CC_REGNUM")))
|
||||
|
||||
;; The return address, which might be a stack slot. */
|
||||
(define_constraint "Sra"
|
||||
"return address constraint - memory variant"
|
||||
(and (match_code "unspec")
|
||||
(match_test "XINT (op, 1) == UNSPEC_RETURN_ADDR")))
|
||||
|
||||
(define_constraint "Cfm"
|
||||
"control register values to switch fp mode"
|
||||
(and (match_code "const")
|
||||
(match_test "GET_CODE (XEXP (op, 0)) == UNSPEC")
|
||||
(match_test "XINT (XEXP (op, 0), 1) == UNSPEC_FP_MODE")))
|
40
gcc/config/epiphany/epiphany-modes.def
Executable file
40
gcc/config/epiphany/epiphany-modes.def
Executable file
|
@ -0,0 +1,40 @@
|
|||
/* Definitions of target machine for GNU compiler, Adapteva Epiphany cpu.
|
||||
Copyright (C) 2002, 2007, 2009, 2011 Free Software Foundation, Inc.
|
||||
Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
CC_MODE (CC_Z); /* only Z valid - for add, testing result. */
|
||||
CC_MODE (CC_N_NE); /* N for not-equal (for lsl). */
|
||||
CC_MODE (CC_C_LTU); /* C for unsigned-less-than (for add with carry). */
|
||||
CC_MODE (CC_C_GTU); /* C for unsigned-greater-than (for sub with carry). */
|
||||
CC_MODE (CC_FP);
|
||||
CC_MODE (CC_FP_EQ); /* AZ for equal. */
|
||||
CC_MODE (CC_FP_ORD); /* AZ || ~AC for ordered. */
|
||||
CC_MODE (CC_FP_UNEQ); /* AZ || ~AC for unordered / equal. */
|
||||
CC_MODE (CC_FP_GTE); /* ~AC / AZ for greater than / equal. */
|
||||
#if 0 /* This would be needed for simplified NaN testing. */
|
||||
RESET_FLOAT_FORMAT (SF, motorola_single_format);
|
||||
RESET_FLOAT_FORMAT (DF, motorola_double_format);
|
||||
#endif
|
||||
VECTOR_MODES (INT, 4); /* V4QI V2HI */
|
||||
VECTOR_MODES (INT, 8); /* V8QI V4HI V2SI */
|
||||
VECTOR_MODE (FLOAT, SF, 2); /* V2SF */
|
||||
ADJUST_ALIGNMENT (V8QI, epiphany_vect_align);
|
||||
ADJUST_ALIGNMENT (V4HI, epiphany_vect_align);
|
||||
ADJUST_ALIGNMENT (V2SI, epiphany_vect_align);
|
||||
ADJUST_ALIGNMENT (V2SF, epiphany_vect_align);
|
55
gcc/config/epiphany/epiphany-protos.h
Executable file
55
gcc/config/epiphany/epiphany-protos.h
Executable file
|
@ -0,0 +1,55 @@
|
|||
/* Definitions of target machine for GNU compiler, EPIPHANY cpu.
|
||||
Copyright (C) 2000, 2004, 2007, 2009, 2011 Free Software Foundation, Inc.
|
||||
Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifdef RTX_CODE
|
||||
extern enum machine_mode epiphany_select_cc_mode (enum rtx_code, rtx, rtx);
|
||||
|
||||
/* Define the function that build the compare insn for scc and bcc. */
|
||||
extern struct rtx_def *gen_compare_reg (enum machine_mode, enum rtx_code,
|
||||
enum machine_mode, rtx, rtx);
|
||||
#endif
|
||||
|
||||
/* Declarations for various fns used in the .md file. */
|
||||
extern void epiphany_final_prescan_insn (rtx, rtx *, int);
|
||||
extern bool epiphany_is_long_call_p (rtx);
|
||||
extern bool epiphany_small16 (rtx);
|
||||
bool epiphany_uninterruptible_p (tree decl);
|
||||
bool epiphany_call_uninterruptible_p (rtx mem);
|
||||
extern rtx sfunc_symbol (const char *name);
|
||||
|
||||
extern void epiphany_expand_prologue (void);
|
||||
extern void epiphany_expand_epilogue (int);
|
||||
extern int epiphany_initial_elimination_offset (int, int);
|
||||
extern void epiphany_init_expanders (void);
|
||||
extern int hard_regno_mode_ok (int regno, enum machine_mode mode);
|
||||
#ifdef HARD_CONST
|
||||
extern void emit_set_fp_mode (int entity, int mode, HARD_REG_SET regs_live);
|
||||
#endif
|
||||
extern void epiphany_insert_mode_switch_use (rtx insn, int, int);
|
||||
extern void epiphany_expand_set_fp_mode (rtx *operands);
|
||||
extern int epiphany_mode_needed (int entity, rtx insn);
|
||||
extern int epiphany_mode_entry_exit (int entity, bool);
|
||||
extern int epiphany_mode_after (int entity, int last_mode, rtx insn);
|
||||
extern int epiphany_mode_priority_to_mode (int entity, unsigned priority);
|
||||
extern bool epiphany_epilogue_uses (int regno);
|
||||
extern bool epiphany_optimize_mode_switching (int entity);
|
||||
extern bool epiphany_is_interrupt_p (tree);
|
||||
extern unsigned epiphany_special_round_type_align (tree, unsigned, unsigned);
|
||||
extern unsigned epiphany_adjust_field_align (tree, unsigned);
|
135
gcc/config/epiphany/epiphany-sched.md
Normal file
135
gcc/config/epiphany/epiphany-sched.md
Normal file
|
@ -0,0 +1,135 @@
|
|||
;; DFA scheduling description for EPIPHANY
|
||||
;; Copyright (C) 2004, 2006, 2007, 2009 Free Software Foundation, Inc.
|
||||
;; Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
|
||||
;; This file is part of GCC.
|
||||
|
||||
;; GCC is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GCC is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GCC; see the file COPYING3. If not see
|
||||
;; <http://www.gnu.org/licenses/>.
|
||||
|
||||
;; Two automata are defined to reduce number of states
|
||||
;; which a single large automaton will have. (Factoring)
|
||||
|
||||
(define_automaton "inst_pipeline,fpu_pipe")
|
||||
|
||||
;; This unit is basically the decode unit of the processor.
|
||||
;; Since epiphany is a dual issue machine, it is as if there are two
|
||||
;; units so that any insn can be processed by either one
|
||||
;; of the decoding unit.
|
||||
|
||||
(define_cpu_unit "pipe_01,pipe_02" "inst_pipeline")
|
||||
|
||||
;; The fixed point arithmetic unit.
|
||||
|
||||
(define_cpu_unit "int" "inst_pipeline")
|
||||
|
||||
;; The floating point unit.
|
||||
|
||||
(define_cpu_unit "F0" "fpu_pipe")
|
||||
|
||||
;; ----------------------------------------------------
|
||||
;; This reservation is to simplify the dual issue description.
|
||||
|
||||
(define_reservation "issue" "pipe_01|pipe_02")
|
||||
|
||||
;; This is to express instructions that cannot be paired.
|
||||
|
||||
(define_reservation "d_lock" "pipe_01+pipe_02")
|
||||
|
||||
;; We don't model all pipeline stages; we model the issue stage
|
||||
;; inasmuch as we allow only two instructions to issue simultaneously,
|
||||
;; and flow instructions prevent any simultaneous issue of another instruction.
|
||||
;; (This uses pipe_01 and pipe_02).
|
||||
;; Double issue of 'other' insns is prevented by using the int unit in the
|
||||
;; E1 stage.
|
||||
;; Double issue of float instructions is prevented by using F0 in the E1 stage.
|
||||
|
||||
(define_insn_reservation "simple_arith" 2
|
||||
(and (eq_attr "pipe_model" "epiphany")
|
||||
(eq_attr "type" "move,cmove,compare,shift,misc,mul")
|
||||
(eq_attr "length" "4"))
|
||||
"issue,int")
|
||||
|
||||
; anything but fp / fp_int has a bypass
|
||||
(define_bypass 1 "simple_arith" "simple_arith,simple_arith_2,simple_arith_4,load,store,branch,call,flow")
|
||||
|
||||
(define_insn_reservation "simple_arith_2" 2
|
||||
(and (eq_attr "pipe_model" "epiphany")
|
||||
(eq_attr "type" "move,cmove,compare,shift,misc,mul")
|
||||
(eq_attr "length" "8"))
|
||||
"issue,issue+int,int")
|
||||
|
||||
(define_insn_reservation "simple_arith_4" 4
|
||||
(and (eq_attr "pipe_model" "epiphany")
|
||||
(eq_attr "type" "move,compare,shift,misc,mul")
|
||||
(eq_attr "length" "12,16,20,24"))
|
||||
"issue,issue+int,issue+int,issue+int,int")
|
||||
|
||||
;; Loads have a latency of two.
|
||||
;; Note that we fix up the latency of post_modify in epiphany.c:epiphany_adjust_cost
|
||||
|
||||
(define_insn_reservation "load" 3
|
||||
(and (eq_attr "pipe_model" "epiphany")
|
||||
(eq_attr "type" "load"))
|
||||
"issue,int")
|
||||
|
||||
; anything but fp / fp_int has a bypass
|
||||
(define_bypass 2 "load" "simple_arith,simple_arith_2,simple_arith_4,load,store,branch,call,flow")
|
||||
|
||||
(define_insn_reservation "store" 1
|
||||
(and (eq_attr "pipe_model" "epiphany")
|
||||
(eq_attr "type" "store"))
|
||||
"issue,int")
|
||||
|
||||
;; Branch
|
||||
;; Latency when taken: 3
|
||||
;; Issue Rate: 1
|
||||
;; The latency is 1 when the branch is not taken.
|
||||
;; We can't really do much with the latency, even if we could express it,
|
||||
;; but the pairing restrictions are useful to take into account.
|
||||
|
||||
(define_insn_reservation "branch" 1
|
||||
(and (eq_attr "pipe_model" "epiphany")
|
||||
(eq_attr "type" "branch,uncond_branch"))
|
||||
"d_lock")
|
||||
|
||||
;; calls introduce a longisch delay that is likely to flush the pipelines
|
||||
;; of the caller's instructions. Both the call instruction itself and
|
||||
;; the rts at the end of the call / sfunc incurs a three cycle penalty,
|
||||
;; thus also isolating the scheduling of caller and callee.
|
||||
|
||||
(define_insn_reservation "call" 8
|
||||
(and (eq_attr "pipe_model" "epiphany")
|
||||
(eq_attr "type" "call,sfunc,fp_sfunc"))
|
||||
"d_lock*8")
|
||||
|
||||
(define_insn_reservation "flow" 1
|
||||
(and (eq_attr "pipe_model" "epiphany")
|
||||
(eq_attr "type" "flow"))
|
||||
"d_lock")
|
||||
|
||||
(define_insn_reservation "fp_arith_trunc" 3
|
||||
(and (eq_attr "pipe_model" "epiphany")
|
||||
(and (eq_attr "type" "fp,fp_int")
|
||||
(eq_attr "rounding" "trunc")))
|
||||
"issue,F0")
|
||||
|
||||
(define_insn_reservation "fp_arith_nearest" 5
|
||||
(and (eq_attr "pipe_model" "epiphany")
|
||||
(and (eq_attr "type" "fp,fp_int")
|
||||
(eq_attr "rounding" "nearest")))
|
||||
"issue,F0")
|
||||
|
||||
(define_bypass 2 "fp_arith_trunc" "store")
|
||||
(define_bypass 4 "fp_arith_nearest" "store")
|
2751
gcc/config/epiphany/epiphany.c
Executable file
2751
gcc/config/epiphany/epiphany.c
Executable file
File diff suppressed because it is too large
Load diff
881
gcc/config/epiphany/epiphany.h
Executable file
881
gcc/config/epiphany/epiphany.h
Executable file
|
@ -0,0 +1,881 @@
|
|||
/* Definitions of target machine for GNU compiler, Argonaut EPIPHANY cpu.
|
||||
Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005,
|
||||
2007, 2009, 2011 Free Software Foundation, Inc.
|
||||
Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_EPIPHANY_H
|
||||
#define GCC_EPIPHANY_H
|
||||
|
||||
#undef LINK_SPEC
|
||||
#undef STARTFILE_SPEC
|
||||
#undef ENDFILE_SPEC
|
||||
#undef SIZE_TYPE
|
||||
#undef PTRDIFF_TYPE
|
||||
#undef WCHAR_TYPE
|
||||
#undef WCHAR_TYPE_SIZE
|
||||
|
||||
/* Names to predefine in the preprocessor for this target machine. */
|
||||
#define TARGET_CPU_CPP_BUILTINS() \
|
||||
do \
|
||||
{ \
|
||||
builtin_define ("__epiphany__"); \
|
||||
builtin_define ("__little_endian__"); \
|
||||
builtin_define_with_int_value ("__EPIPHANY_STACK_OFFSET__", \
|
||||
epiphany_stack_offset); \
|
||||
builtin_assert ("cpu=epiphany"); \
|
||||
builtin_assert ("machine=epiphany"); \
|
||||
} while (0)
|
||||
|
||||
/* Pick up the libgloss library. One day we may do this by linker script, but
|
||||
for now its static. */
|
||||
#undef LIB_SPEC
|
||||
#define LIB_SPEC "%{!shared:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}} -lepiphany"
|
||||
|
||||
#define LINK_SPEC "%{v}"
|
||||
|
||||
#define STARTFILE_SPEC "%{!shared:crt0.o%s} crti.o%s " \
|
||||
"%{mfp-mode=int:crtint.o%s} %{mfp-mode=truncate:crtrunc.o%s} " \
|
||||
"%{m1reg-r43:crtm1reg-r43.o%s} %{m1reg-r63:crtm1reg-r63.o%s} " \
|
||||
"crtbegin.o%s"
|
||||
|
||||
#define ENDFILE_SPEC "crtend.o%s crtn.o%s"
|
||||
|
||||
#undef USER_LABEL_PREFIX
|
||||
#define USER_LABEL_PREFIX "_"
|
||||
|
||||
#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \
|
||||
asm (SECTION_OP "\n\
|
||||
mov r0,%low(" USER_LABEL_PREFIX #FUNC")\n\
|
||||
movt r0,%high(" USER_LABEL_PREFIX #FUNC")\n\
|
||||
jalr r0\n\
|
||||
.text");
|
||||
|
||||
#if 0 /* We would like to use Posix for profiling, but the simulator
|
||||
interface still lacks mkdir. */
|
||||
#define TARGET_POSIX_IO
|
||||
#endif
|
||||
|
||||
/* Target machine storage layout. */
|
||||
|
||||
/* Define this if most significant bit is lowest numbered
|
||||
in instructions that operate on numbered bit-fields. */
|
||||
#define BITS_BIG_ENDIAN 0
|
||||
|
||||
/* Define this if most significant byte of a word is the lowest numbered. */
|
||||
#define BYTES_BIG_ENDIAN 0
|
||||
|
||||
/* Define this if most significant word of a multiword number is the lowest
|
||||
numbered. */
|
||||
#define WORDS_BIG_ENDIAN 0
|
||||
|
||||
/* Width of a word, in units (bytes). */
|
||||
#define UNITS_PER_WORD 4
|
||||
|
||||
/* Define this macro if it is advisable to hold scalars in registers
|
||||
in a wider mode than that declared by the program. In such cases,
|
||||
the value is constrained to be within the bounds of the declared
|
||||
type, but kept valid in the wider mode. The signedness of the
|
||||
extension may differ from that of the type. */
|
||||
/* It is far faster to zero extend chars than to sign extend them */
|
||||
|
||||
#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \
|
||||
if (GET_MODE_CLASS (MODE) == MODE_INT \
|
||||
&& GET_MODE_SIZE (MODE) < 4) \
|
||||
{ \
|
||||
if (MODE == QImode) \
|
||||
UNSIGNEDP = 1; \
|
||||
else if (MODE == HImode) \
|
||||
UNSIGNEDP = 1; \
|
||||
(MODE) = SImode; \
|
||||
}
|
||||
|
||||
/* Allocation boundary (in *bits*) for storing arguments in argument list. */
|
||||
#define PARM_BOUNDARY 32
|
||||
|
||||
/* Boundary (in *bits*) on which stack pointer should be aligned. */
|
||||
#define STACK_BOUNDARY 64
|
||||
|
||||
/* ALIGN FRAMES on word boundaries */
|
||||
#define EPIPHANY_STACK_ALIGN(LOC) (((LOC)+7) & ~7)
|
||||
|
||||
/* Allocation boundary (in *bits*) for the code of a function. */
|
||||
#define FUNCTION_BOUNDARY 32
|
||||
|
||||
/* Every structure's size must be a multiple of this. */
|
||||
#define STRUCTURE_SIZE_BOUNDARY 8
|
||||
|
||||
/* A bit-field declared as `int' forces `int' alignment for the struct. */
|
||||
#define PCC_BITFIELD_TYPE_MATTERS 1
|
||||
|
||||
/* No data type wants to be aligned rounder than this. */
|
||||
/* This is bigger than currently necessary for the EPIPHANY. If 8 byte floats are
|
||||
ever added it's not clear whether they'll need such alignment or not. For
|
||||
now we assume they will. We can always relax it if necessary but the
|
||||
reverse isn't true. */
|
||||
#define BIGGEST_ALIGNMENT 64
|
||||
|
||||
/* The best alignment to use in cases where we have a choice. */
|
||||
#define FASTEST_ALIGNMENT 64
|
||||
|
||||
#define MALLOC_ABI_ALIGNMENT BIGGEST_ALIGNMENT
|
||||
|
||||
/* Make strings dword-aligned so strcpy from constants will be faster. */
|
||||
#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
|
||||
((TREE_CODE (EXP) == STRING_CST \
|
||||
&& (ALIGN) < FASTEST_ALIGNMENT) \
|
||||
? FASTEST_ALIGNMENT : (ALIGN))
|
||||
|
||||
/* Make arrays of chars dword-aligned for the same reasons.
|
||||
Also, align arrays of SImode items. */
|
||||
#define DATA_ALIGNMENT(TYPE, ALIGN) \
|
||||
(TREE_CODE (TYPE) == ARRAY_TYPE \
|
||||
&& TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
|
||||
&& (ALIGN) < FASTEST_ALIGNMENT \
|
||||
? FASTEST_ALIGNMENT \
|
||||
: (TREE_CODE (TYPE) == ARRAY_TYPE \
|
||||
&& TYPE_MODE (TREE_TYPE (TYPE)) == SImode \
|
||||
&& (ALIGN) < FASTEST_ALIGNMENT) \
|
||||
? FASTEST_ALIGNMENT \
|
||||
: (ALIGN))
|
||||
|
||||
/* Set this nonzero if move instructions will actually fail to work
|
||||
when given unaligned data. */
|
||||
/* On the EPIPHANY the lower address bits are masked to 0 as necessary. The chip
|
||||
won't croak when given an unaligned address, but the insn will still fail
|
||||
to produce the correct result. */
|
||||
#define STRICT_ALIGNMENT 1
|
||||
|
||||
/* layout_type overrides our ADJUST_ALIGNMENT settings from epiphany-modes.def
|
||||
for vector modes, so we have to override it back. */
|
||||
#define ROUND_TYPE_ALIGN(TYPE, MANGLED_ALIGN, SPECIFIED_ALIGN) \
|
||||
(TREE_CODE (TYPE) == VECTOR_TYPE && !TYPE_USER_ALIGN (TYPE) \
|
||||
&& SPECIFIED_ALIGN <= GET_MODE_ALIGNMENT (TYPE_MODE (TYPE)) \
|
||||
? GET_MODE_ALIGNMENT (TYPE_MODE (TYPE)) \
|
||||
: ((TREE_CODE (TYPE) == RECORD_TYPE \
|
||||
|| TREE_CODE (TYPE) == UNION_TYPE \
|
||||
|| TREE_CODE (TYPE) == QUAL_UNION_TYPE) \
|
||||
&& !TYPE_PACKED (TYPE)) \
|
||||
? epiphany_special_round_type_align ((TYPE), (MANGLED_ALIGN), \
|
||||
(SPECIFIED_ALIGN)) \
|
||||
: MAX ((MANGLED_ALIGN), (SPECIFIED_ALIGN)))
|
||||
|
||||
#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
|
||||
epiphany_adjust_field_align((FIELD), (COMPUTED))
|
||||
|
||||
/* Layout of source language data types. */
|
||||
|
||||
#define SHORT_TYPE_SIZE 16
|
||||
#define INT_TYPE_SIZE 32
|
||||
#define LONG_TYPE_SIZE 32
|
||||
#define LONG_LONG_TYPE_SIZE 64
|
||||
#define FLOAT_TYPE_SIZE 32
|
||||
#define DOUBLE_TYPE_SIZE 64
|
||||
#define LONG_DOUBLE_TYPE_SIZE 64
|
||||
|
||||
/* Define this as 1 if `char' should by default be signed; else as 0. */
|
||||
#define DEFAULT_SIGNED_CHAR 0
|
||||
|
||||
#define SIZE_TYPE "long unsigned int"
|
||||
#define PTRDIFF_TYPE "long int"
|
||||
#define WCHAR_TYPE "unsigned int"
|
||||
#define WCHAR_TYPE_SIZE BITS_PER_WORD
|
||||
|
||||
/* Standard register usage. */
|
||||
|
||||
/* Number of actual hardware registers.
|
||||
The hardware registers are assigned numbers for the compiler
|
||||
from 0 to just below FIRST_PSEUDO_REGISTER.
|
||||
All registers that the compiler knows about must be given numbers,
|
||||
even those that are not normally considered general registers. */
|
||||
|
||||
#define FIRST_PSEUDO_REGISTER 78
|
||||
|
||||
|
||||
/* General purpose registers. */
|
||||
#define GPR_FIRST 0 /* First gpr */
|
||||
|
||||
#define PIC_REGNO (GPR_FIRST + 28) /* PIC register. */
|
||||
#define GPR_LAST (GPR_FIRST + 63) /* Last gpr */
|
||||
#define CORE_CONTROL_FIRST CONFIG_REGNUM
|
||||
#define CORE_CONTROL_LAST IRET_REGNUM
|
||||
|
||||
#define GPR_P(R) IN_RANGE (R, GPR_FIRST, GPR_LAST)
|
||||
#define GPR_OR_AP_P(R) (GPR_P (R) || (R) == ARG_POINTER_REGNUM)
|
||||
|
||||
#define GPR_OR_PSEUDO_P(R) (GPR_P (R) || (R) >= FIRST_PSEUDO_REGISTER)
|
||||
#define GPR_AP_OR_PSEUDO_P(R) (GPR_OR_AP_P (R) || (R) >= FIRST_PSEUDO_REGISTER)
|
||||
|
||||
#define FIXED_REGISTERS \
|
||||
{ /* Integer Registers */ \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, /* 000-007, gr0 - gr7 */ \
|
||||
0, 0, 0, 0, 0, 1, 0, 0, /* 008-015, gr8 - gr15 */ \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, /* 016-023, gr16 - gr23 */ \
|
||||
0, 0, 0, 0, 1, 1, 1, 1, /* 024-031, gr24 - gr31 */ \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, /* 032-039, gr32 - gr39 */ \
|
||||
1, 1, 1, 1, 0, 0, 0, 0, /* 040-047, gr40 - gr47 */ \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, /* 048-055, gr48 - gr55 */ \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, /* 056-063, gr56 - gr63 */ \
|
||||
/* Other registers */ \
|
||||
1, /* 64 AP - fake arg ptr */ \
|
||||
1, /* soft frame pointer */ \
|
||||
1, /* CC_REGNUM - integer conditions */\
|
||||
1, /* CCFP_REGNUM - fp conditions */\
|
||||
1, 1, 1, 1, 1, 1, /* Core Control Registers. */ \
|
||||
1, 1, 1, /* FP_{NEAREST,...}_REGNUM */\
|
||||
1, /* UNKNOWN_REGNUM - placeholder. */\
|
||||
}
|
||||
|
||||
/* Like `FIXED_REGISTERS' but has 1 for each register that is clobbered (in
|
||||
general) by function calls as well as for fixed registers. This macro
|
||||
therefore identifies the registers that are not available for general
|
||||
allocation of values that must live across function calls.
|
||||
|
||||
If a register has 0 in `CALL_USED_REGISTERS', the compiler automatically
|
||||
saves it on function entry and restores it on function exit, if the register
|
||||
is used within the function. */
|
||||
|
||||
#define CALL_USED_REGISTERS \
|
||||
{ /* Integer Registers */ \
|
||||
1, 1, 1, 1, 0, 0, 0, 0, /* 000-007, gr0 - gr7 */ \
|
||||
0, 0, 0, 0, 1, 1, 1, 0, /* 008-015, gr8 - gr15 */ \
|
||||
1, 1, 1, 1, 1, 1, 1, 1, /* 016-023, gr16 - gr23 */ \
|
||||
1, 1, 1, 1, 1, 1, 1, 1, /* 024-031, gr24 - gr31 */ \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, /* 032-039, gr32 - gr38 */ \
|
||||
1, 1, 1, 1, 1, 1, 1, 1, /* 040-047, gr40 - gr47 */ \
|
||||
1, 1, 1, 1, 1, 1, 1, 1, /* 048-055, gr48 - gr55 */ \
|
||||
1, 1, 1, 1, 1, 1, 1, 1, /* 056-063, gr56 - gr63 */ \
|
||||
1, /* 64 AP - fake arg ptr */ \
|
||||
1, /* soft frame pointer */ \
|
||||
1, /* 66 CC_REGNUM */ \
|
||||
1, /* 67 CCFP_REGNUM */ \
|
||||
1, 1, 1, 1, 1, 1, /* Core Control Registers. */ \
|
||||
1, 1, 1, /* FP_{NEAREST,...}_REGNUM */\
|
||||
1, /* UNKNOWN_REGNUM - placeholder. */\
|
||||
}
|
||||
|
||||
#define REG_ALLOC_ORDER \
|
||||
{ \
|
||||
0, 1, 2, 3, /* Caller-saved 'small' registers. */ \
|
||||
12, /* Caller-saved unpaired register. */ \
|
||||
/* Caller-saved registers. */ \
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, \
|
||||
44, 45, 46, 47, \
|
||||
48, 49, 50, 51, 52, 53, 54, 55, \
|
||||
56, 57, 58, 59, 60, 61, 62, 63, \
|
||||
4, 5, 6, 7, /* Calle-saved 'small' registers. */ \
|
||||
15, /* Calle-saved unpaired register. */ \
|
||||
8, 9, 10, 11, /* Calle-saved registers. */ \
|
||||
32, 33, 34, 35, 36, 37, 38, 39, \
|
||||
14, 13, /* Link register, stack pointer. */ \
|
||||
40, 41, 42, 43, /* Usually constant, but might be made callee-saved. */ \
|
||||
/* Can't allocate, but must name these... */ \
|
||||
28, 29, 30, 31, \
|
||||
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77 \
|
||||
}
|
||||
|
||||
/* Return number of consecutive hard regs needed starting at reg REGNO
|
||||
to hold something of mode MODE.
|
||||
This is ordinarily the length in words of a value of mode MODE
|
||||
but can be less for certain modes in special long registers. */
|
||||
#define HARD_REGNO_NREGS(REGNO, MODE) \
|
||||
((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
|
||||
|
||||
/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. */
|
||||
extern const unsigned int epiphany_hard_regno_mode_ok[];
|
||||
extern unsigned int epiphany_mode_class[];
|
||||
#define HARD_REGNO_MODE_OK(REGNO, MODE) hard_regno_mode_ok((REGNO), (MODE))
|
||||
|
||||
/* A C expression that is nonzero if it is desirable to choose
|
||||
register allocation so as to avoid move instructions between a
|
||||
value of mode MODE1 and a value of mode MODE2.
|
||||
|
||||
If `HARD_REGNO_MODE_OK (R, MODE1)' and `HARD_REGNO_MODE_OK (R,
|
||||
MODE2)' are ever different for any R, then `MODES_TIEABLE_P (MODE1,
|
||||
MODE2)' must be zero. */
|
||||
|
||||
#define MODES_TIEABLE_P(MODE1, MODE2) 1
|
||||
|
||||
/* Register classes and constants. */
|
||||
|
||||
/* Define the classes of registers for register constraints in the
|
||||
machine description. Also define ranges of constants.
|
||||
|
||||
One of the classes must always be named ALL_REGS and include all hard regs.
|
||||
If there is more than one class, another class must be named NO_REGS
|
||||
and contain no registers.
|
||||
|
||||
The name GENERAL_REGS must be the name of a class (or an alias for
|
||||
another name such as ALL_REGS). This is the class of registers
|
||||
that is allowed by "g" or "r" in a register constraint.
|
||||
Also, registers outside this class are allocated only when
|
||||
instructions express preferences for them.
|
||||
|
||||
The classes must be numbered in nondecreasing order; that is,
|
||||
a larger-numbered class must never be contained completely
|
||||
in a smaller-numbered class.
|
||||
|
||||
For any two classes, it is very desirable that there be another
|
||||
class that represents their union.
|
||||
|
||||
It is important that any condition codes have class NO_REGS.
|
||||
See `register_operand'. */
|
||||
|
||||
enum reg_class {
|
||||
NO_REGS,
|
||||
LR_REGS,
|
||||
SHORT_INSN_REGS,
|
||||
SIBCALL_REGS,
|
||||
GENERAL_REGS,
|
||||
CORE_CONTROL_REGS,
|
||||
ALL_REGS,
|
||||
LIM_REG_CLASSES
|
||||
};
|
||||
|
||||
#define N_REG_CLASSES ((int) LIM_REG_CLASSES)
|
||||
|
||||
/* Give names of register classes as strings for dump file. */
|
||||
#define REG_CLASS_NAMES \
|
||||
{ \
|
||||
"NO_REGS", \
|
||||
"LR_REGS", \
|
||||
"SHORT_INSN_REGS", \
|
||||
"SIBCALL_REGS", \
|
||||
"GENERAL_REGS", \
|
||||
"CORE_CONTROL_REGS", \
|
||||
"ALL_REGS" \
|
||||
}
|
||||
|
||||
/* Define which registers fit in which classes.
|
||||
This is an initializer for a vector of HARD_REG_SET
|
||||
of length N_REG_CLASSES. */
|
||||
|
||||
#define REG_CLASS_CONTENTS \
|
||||
{ /* r0-r31 r32-r63 ap/sfp/cc1/cc2/iret/status */ \
|
||||
{ 0x00000000,0x00000000,0x0}, /* NO_REGS */ \
|
||||
{ 0x00004000,0x00000000,0x0}, /* LR_REGS */ \
|
||||
{ 0x000000ff,0x00000000,0x0}, /* SHORT_INSN_REGS */ \
|
||||
{ 0xffff100f,0xffffff00,0x0}, /* SIBCALL_REGS */ \
|
||||
{ 0xffffffff,0xffffffff,0x0003}, /* GENERAL_REGS */ \
|
||||
{ 0x00000000,0x00000000,0x03f0}, /* CORE_CONTROL_REGS */ \
|
||||
{ 0xffffffff,0xffffffff,0x3fff}, /* ALL_REGS */ \
|
||||
}
|
||||
|
||||
|
||||
/* The same information, inverted:
|
||||
Return the class number of the smallest class containing
|
||||
reg number REGNO. This could be a conditional expression
|
||||
or could index an array. */
|
||||
extern enum reg_class epiphany_regno_reg_class[FIRST_PSEUDO_REGISTER];
|
||||
#define REGNO_REG_CLASS(REGNO) \
|
||||
(epiphany_regno_reg_class[REGNO])
|
||||
|
||||
/* The class value for index registers, and the one for base regs. */
|
||||
#define BASE_REG_CLASS GENERAL_REGS
|
||||
#define INDEX_REG_CLASS GENERAL_REGS
|
||||
|
||||
/* These assume that REGNO is a hard or pseudo reg number.
|
||||
They give nonzero only if REGNO is a hard reg of the suitable class
|
||||
or a pseudo reg currently allocated to a suitable hard reg.
|
||||
Since they use reg_renumber, they are safe only once reg_renumber
|
||||
has been allocated, which happens in local-alloc.c. */
|
||||
#define REGNO_OK_FOR_BASE_P(REGNO) \
|
||||
((REGNO) < FIRST_PSEUDO_REGISTER || (unsigned) reg_renumber[REGNO] < FIRST_PSEUDO_REGISTER)
|
||||
#define REGNO_OK_FOR_INDEX_P(REGNO) \
|
||||
((REGNO) < FIRST_PSEUDO_REGISTER || (unsigned) reg_renumber[REGNO] < FIRST_PSEUDO_REGISTER)
|
||||
|
||||
|
||||
|
||||
/* Given an rtx X being reloaded into a reg required to be
|
||||
in class CLASS, return the class of reg to actually use.
|
||||
In general this is just CLASS; but on some machines
|
||||
in some cases it is preferable to use a more restrictive class. */
|
||||
#define PREFERRED_RELOAD_CLASS(X,CLASS) \
|
||||
(CLASS)
|
||||
|
||||
/* Return the maximum number of consecutive registers
|
||||
needed to represent mode MODE in a register of class CLASS. */
|
||||
#define CLASS_MAX_NREGS(CLASS, MODE) \
|
||||
((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
|
||||
|
||||
/* The letters I, J, K, L, M, N, O, P in a register constraint string
|
||||
can be used to stand for particular ranges of immediate operands.
|
||||
This macro defines what the ranges are.
|
||||
C is the letter, and VALUE is a constant value.
|
||||
Return 1 if VALUE is in the range specified by C. */
|
||||
|
||||
/* 'I' is used for 16 bit unsigned.
|
||||
'Cal' is used for long immediates (32 bits)
|
||||
'K' is used for any constant up to 5 bits.
|
||||
'L' is used for any 11 bit signed.
|
||||
*/
|
||||
|
||||
#define IMM16(X) (IN_RANGE ((X), 0, 0xFFFF))
|
||||
#define SIMM16(X) (IN_RANGE ((X), -65536, 65535))
|
||||
#define SIMM11(X) (IN_RANGE ((X), -1024, 1023))
|
||||
#define IMM5(X) (IN_RANGE ((X), 0, 0x1F))
|
||||
|
||||
typedef struct GTY (()) machine_function
|
||||
{
|
||||
unsigned args_parsed : 1;
|
||||
unsigned pretend_args_odd : 1;
|
||||
unsigned lr_clobbered : 1;
|
||||
unsigned control_use_inserted : 1;
|
||||
unsigned sw_entities_processed : 6;
|
||||
long lr_slot_offset;
|
||||
rtx and_mask;
|
||||
rtx or_mask;
|
||||
unsigned unknown_mode_uses;
|
||||
unsigned unknown_mode_sets;
|
||||
} machine_function_t;
|
||||
|
||||
#define MACHINE_FUNCTION(fun) (fun)->machine
|
||||
|
||||
#define INIT_EXPANDERS epiphany_init_expanders ()
|
||||
|
||||
/* Stack layout and stack pointer usage. */
|
||||
|
||||
/* Define this macro if pushing a word onto the stack moves the stack
|
||||
pointer to a smaller address. */
|
||||
#define STACK_GROWS_DOWNWARD
|
||||
|
||||
/* Define this to nonzero if the nominal address of the stack frame
|
||||
is at the high-address end of the local variables;
|
||||
that is, each additional local variable allocated
|
||||
goes at a more negative offset in the frame. */
|
||||
#define FRAME_GROWS_DOWNWARD 1
|
||||
|
||||
/* Offset within stack frame to start allocating local variables at.
|
||||
If FRAME_GROWS_DOWNWARD, this is the offset to the END of the
|
||||
first local allocated. Otherwise, it is the offset to the BEGINNING
|
||||
of the first local allocated. */
|
||||
#define STARTING_FRAME_OFFSET epiphany_stack_offset
|
||||
|
||||
/* Offset from the stack pointer register to the first location at which
|
||||
outgoing arguments are placed. */
|
||||
#define STACK_POINTER_OFFSET epiphany_stack_offset
|
||||
|
||||
/* Offset of first parameter from the argument pointer register value. */
|
||||
/* 4 bytes for each of previous fp, return address, and previous gp.
|
||||
4 byte reserved area for future considerations. */
|
||||
#define FIRST_PARM_OFFSET(FNDECL) \
|
||||
(epiphany_stack_offset \
|
||||
+ (MACHINE_FUNCTION (DECL_STRUCT_FUNCTION (FNDECL))->pretend_args_odd \
|
||||
? 4 : 0))
|
||||
|
||||
#define INCOMING_FRAME_SP_OFFSET epiphany_stack_offset
|
||||
|
||||
/* Register to use for pushing function arguments. */
|
||||
#define STACK_POINTER_REGNUM GPR_SP
|
||||
|
||||
/* Base register for access to local variables of the function. */
|
||||
#define HARD_FRAME_POINTER_REGNUM GPR_FP
|
||||
|
||||
/* Register in which static-chain is passed to a function. This must
|
||||
not be a register used by the prologue. */
|
||||
#define STATIC_CHAIN_REGNUM GPR_IP
|
||||
|
||||
/* Define the offset between two registers, one to be eliminated, and the other
|
||||
its replacement, at the start of a routine. */
|
||||
|
||||
#define ELIMINABLE_REGS \
|
||||
{{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
|
||||
{ FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
|
||||
{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
|
||||
{ ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
|
||||
}
|
||||
|
||||
/* Define the offset between two registers, one to be eliminated, and the other
|
||||
its replacement, at the start of a routine. */
|
||||
|
||||
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
|
||||
((OFFSET) = epiphany_initial_elimination_offset ((FROM), (TO)))
|
||||
|
||||
/* Function argument passing. */
|
||||
|
||||
/* If defined, the maximum amount of space required for outgoing
|
||||
arguments will be computed and placed into the variable
|
||||
`current_function_outgoing_args_size'. No space will be pushed
|
||||
onto the stack for each call; instead, the function prologue should
|
||||
increase the stack frame size by this amount. */
|
||||
#define ACCUMULATE_OUTGOING_ARGS 1
|
||||
|
||||
/* Define a data type for recording info about an argument list
|
||||
during the scan of that argument list. This data type should
|
||||
hold all necessary information about the function itself
|
||||
and about the args processed so far, enough to enable macros
|
||||
such as FUNCTION_ARG to determine where the next arg should go. */
|
||||
#define CUMULATIVE_ARGS int
|
||||
|
||||
/* Initialize a variable CUM of type CUMULATIVE_ARGS
|
||||
for a call to a function whose data type is FNTYPE.
|
||||
For a library call, FNTYPE is 0. */
|
||||
#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
|
||||
((CUM) = 0)
|
||||
|
||||
/* The number of registers used for parameter passing. Local to this file. */
|
||||
#define MAX_EPIPHANY_PARM_REGS 4
|
||||
|
||||
/* 1 if N is a possible register number for function argument passing. */
|
||||
#define FUNCTION_ARG_REGNO_P(N) \
|
||||
((unsigned) (N) < MAX_EPIPHANY_PARM_REGS)
|
||||
|
||||
/* Return boolean indicating arg of type TYPE and mode MODE will be passed in
|
||||
a reg. This includes arguments that have to be passed by reference as the
|
||||
pointer to them is passed in a reg if one is available (and that is what
|
||||
we're given).
|
||||
This macro is only used in this file. */
|
||||
/* We must use partial argument passing because of the chosen mode
|
||||
of varargs handling. */
|
||||
#define PASS_IN_REG_P(CUM, MODE, TYPE) \
|
||||
(ROUND_ADVANCE_CUM ((CUM), (MODE), (TYPE)) < MAX_EPIPHANY_PARM_REGS)
|
||||
|
||||
/* Tell GCC to use TARGET_RETURN_IN_MEMORY. */
|
||||
#define DEFAULT_PCC_STRUCT_RETURN 0
|
||||
|
||||
/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
|
||||
the stack pointer does not matter. The value is tested only in
|
||||
functions that have frame pointers.
|
||||
No definition is equivalent to always zero. */
|
||||
#define EXIT_IGNORE_STACK 1
|
||||
|
||||
#define EPILOGUE_USES(REGNO) epiphany_epilogue_uses (REGNO)
|
||||
|
||||
/* Output assembler code to FILE to increment profiler label # LABELNO
|
||||
for profiling a function entry. */
|
||||
#define FUNCTION_PROFILER(FILE, LABELNO)
|
||||
|
||||
/* Given an rtx for the frame pointer,
|
||||
return an rtx for the address of the frame. */
|
||||
#define FRAME_ADDR_RTX(frame) \
|
||||
((frame) == hard_frame_pointer_rtx ? arg_pointer_rtx : NULL)
|
||||
|
||||
/* This is not only for dwarf unwind info, but also for the benefit of
|
||||
df-scan.c to tell it that LR is live at the function start. */
|
||||
#define INCOMING_RETURN_ADDR_RTX \
|
||||
gen_rtx_REG (Pmode, \
|
||||
(current_function_decl != NULL \
|
||||
&& epiphany_is_interrupt_p (current_function_decl) \
|
||||
? IRET_REGNUM : GPR_LR))
|
||||
|
||||
/* However, we haven't implemented the rest needed for dwarf2 unwind info. */
|
||||
#define DWARF2_UNWIND_INFO 0
|
||||
|
||||
#define RETURN_ADDR_RTX(count, frame) \
|
||||
(count ? NULL_RTX \
|
||||
: gen_rtx_UNSPEC (SImode, gen_rtvec (1, const0_rtx), UNSPEC_RETURN_ADDR))
|
||||
|
||||
/* Trampolines.
|
||||
An epiphany trampoline looks like this:
|
||||
mov r16,%low(fnaddr)
|
||||
movt r16,%high(fnaddr)
|
||||
mov ip,%low(cxt)
|
||||
movt ip,%high(cxt)
|
||||
jr r16 */
|
||||
|
||||
/* Length in units of the trampoline for entering a nested function. */
|
||||
#define TRAMPOLINE_SIZE 20
|
||||
|
||||
/* Addressing modes, and classification of registers for them. */
|
||||
|
||||
/* Maximum number of registers that can appear in a valid memory address. */
|
||||
#define MAX_REGS_PER_ADDRESS 2
|
||||
|
||||
/* We have post_modify (load/store with update). */
|
||||
#define HAVE_POST_INCREMENT TARGET_POST_INC
|
||||
#define HAVE_POST_DECREMENT TARGET_POST_INC
|
||||
#define HAVE_POST_MODIFY_DISP TARGET_POST_MODIFY
|
||||
#define HAVE_POST_MODIFY_REG TARGET_POST_MODIFY
|
||||
|
||||
/* Recognize any constant value that is a valid address. */
|
||||
#define CONSTANT_ADDRESS_P(X) \
|
||||
(GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
|
||||
|| GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST)
|
||||
|
||||
#define RTX_OK_FOR_OFFSET_P(MODE, X) \
|
||||
RTX_OK_FOR_OFFSET_1 (GET_MODE_CLASS (MODE) == MODE_VECTOR_INT \
|
||||
&& epiphany_vect_align == 4 ? SImode : (MODE), X)
|
||||
#define RTX_OK_FOR_OFFSET_1(MODE, X) \
|
||||
(GET_CODE (X) == CONST_INT \
|
||||
&& !(INTVAL (X) & (GET_MODE_SIZE (MODE) - 1)) \
|
||||
&& INTVAL (X) >= -2047 * (int) GET_MODE_SIZE (MODE) \
|
||||
&& INTVAL (X) <= 2047 * (int) GET_MODE_SIZE (MODE))
|
||||
|
||||
/* Frame offsets cannot be evaluated till the frame pointer is eliminated. */
|
||||
#define RTX_FRAME_OFFSET_P(X) \
|
||||
((X) == frame_pointer_rtx \
|
||||
|| (GET_CODE (X) == PLUS && XEXP ((X), 0) == frame_pointer_rtx \
|
||||
&& CONST_INT_P (XEXP ((X), 1))))
|
||||
|
||||
/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
|
||||
return the mode to be used for the comparison. */
|
||||
#define SELECT_CC_MODE(OP, X, Y) \
|
||||
epiphany_select_cc_mode (OP, X, Y)
|
||||
|
||||
/* Return nonzero if SELECT_CC_MODE will never return MODE for a
|
||||
floating point inequality comparison. */
|
||||
|
||||
#define REVERSE_CONDITION(CODE, MODE) \
|
||||
((MODE) == CC_FPmode || (MODE) == CC_FP_EQmode || (MODE) == CC_FP_GTEmode \
|
||||
|| (MODE) == CC_FP_ORDmode || (MODE) == CC_FP_UNEQmode \
|
||||
? reverse_condition_maybe_unordered (CODE) \
|
||||
: (MODE) == CCmode ? reverse_condition (CODE) \
|
||||
: UNKNOWN)
|
||||
|
||||
/* We can reverse all CCmodes with REVERSE_CONDITION. */
|
||||
#define REVERSIBLE_CC_MODE(MODE) \
|
||||
((MODE) == CCmode || (MODE) == CC_FPmode || (MODE) == CC_FP_EQmode \
|
||||
|| (MODE) == CC_FP_GTEmode || (MODE) == CC_FP_ORDmode \
|
||||
|| (MODE) == CC_FP_UNEQmode)
|
||||
|
||||
/* Costs. */
|
||||
|
||||
/* The cost of a branch insn. */
|
||||
/* ??? What's the right value here? Branches are certainly more
|
||||
expensive than reg->reg moves. */
|
||||
#define BRANCH_COST(speed_p, predictable_p) \
|
||||
(speed_p ? epiphany_branch_cost : 1)
|
||||
|
||||
/* Nonzero if access to memory by bytes is slow and undesirable.
|
||||
For RISC chips, it means that access to memory by bytes is no
|
||||
better than access by words when possible, so grab a whole word
|
||||
and maybe make use of that. */
|
||||
#define SLOW_BYTE_ACCESS 1
|
||||
|
||||
/* Define this macro if it is as good or better to call a constant
|
||||
function address than to call an address kept in a register. */
|
||||
/* On the EPIPHANY, calling through registers is slow. */
|
||||
#define NO_FUNCTION_CSE
|
||||
|
||||
/* Section selection. */
|
||||
/* WARNING: These section names also appear in dwarf2out.c. */
|
||||
|
||||
#define TEXT_SECTION_ASM_OP "\t.section .text"
|
||||
#define DATA_SECTION_ASM_OP "\t.section .data"
|
||||
|
||||
#undef READONLY_DATA_SECTION_ASM_OP
|
||||
#define READONLY_DATA_SECTION_ASM_OP "\t.section .rodata"
|
||||
|
||||
#define BSS_SECTION_ASM_OP "\t.section .bss"
|
||||
|
||||
/* Define this macro if jump tables (for tablejump insns) should be
|
||||
output in the text section, along with the assembler instructions.
|
||||
Otherwise, the readonly data section is used.
|
||||
This macro is irrelevant if there is no separate readonly data section. */
|
||||
#define JUMP_TABLES_IN_TEXT_SECTION (flag_pic)
|
||||
|
||||
/* PIC */
|
||||
|
||||
/* The register number of the register used to address a table of static
|
||||
data addresses in memory. In some cases this register is defined by a
|
||||
processor's ``application binary interface'' (ABI). When this macro
|
||||
is defined, RTL is generated for this register once, as with the stack
|
||||
pointer and frame pointer registers. If this macro is not defined, it
|
||||
is up to the machine-dependent files to allocate such a register (if
|
||||
necessary). */
|
||||
#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? PIC_REGNO : INVALID_REGNUM)
|
||||
|
||||
/* Control the assembler format that we output. */
|
||||
|
||||
/* A C string constant describing how to begin a comment in the target
|
||||
assembler language. The compiler assumes that the comment will
|
||||
end at the end of the line. */
|
||||
#define ASM_COMMENT_START ";"
|
||||
|
||||
/* Output to assembler file text saying following lines
|
||||
may contain character constants, extra white space, comments, etc. */
|
||||
#define ASM_APP_ON ""
|
||||
|
||||
/* Output to assembler file text saying following lines
|
||||
no longer contain unusual constructs. */
|
||||
#define ASM_APP_OFF ""
|
||||
|
||||
/* Globalizing directive for a label. */
|
||||
#define GLOBAL_ASM_OP "\t.global\t"
|
||||
|
||||
/* How to refer to registers in assembler output.
|
||||
This sequence is indexed by compiler's hard-register-number (see above). */
|
||||
|
||||
#define REGISTER_NAMES \
|
||||
{ \
|
||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
|
||||
"r8", "r9", "r10", "fp", "ip", "sp", "lr", "r15", \
|
||||
"r16", "r17","r18", "r19", "r20", "r21", "r22", "r23", \
|
||||
"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", \
|
||||
"r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39", \
|
||||
"r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47", \
|
||||
"r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55", \
|
||||
"r56", "r57", "r58", "r59", "r60", "r61", "r62", "r63", \
|
||||
"ap", "sfp", "cc1", "cc2", \
|
||||
"config", "status", "lc", "ls", "le", "iret", \
|
||||
"fp_near", "fp_trunc", "fp_anyfp", "unknown" \
|
||||
}
|
||||
|
||||
#define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \
|
||||
epiphany_final_prescan_insn (INSN, OPVEC, NOPERANDS)
|
||||
|
||||
#define LOCAL_LABEL_PREFIX "."
|
||||
|
||||
/* A C expression which evaluates to true if CODE is a valid
|
||||
punctuation character for use in the `PRINT_OPERAND' macro. */
|
||||
extern char epiphany_punct_chars[256];
|
||||
#define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \
|
||||
epiphany_punct_chars[(unsigned char) (CHAR)]
|
||||
|
||||
/* This is how to output an element of a case-vector that is absolute. */
|
||||
#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
|
||||
do { \
|
||||
if (CASE_VECTOR_MODE == Pmode) \
|
||||
asm_fprintf ((FILE), "\t.word %LL%d\n", (VALUE)); \
|
||||
else \
|
||||
asm_fprintf ((FILE), "\t.short %LL%d\n", (VALUE)); \
|
||||
} while (0)
|
||||
|
||||
/* This is how to output an element of a case-vector that is relative. */
|
||||
#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
|
||||
do { \
|
||||
if (CASE_VECTOR_MODE == Pmode) \
|
||||
asm_fprintf ((FILE), "\t.word"); \
|
||||
else \
|
||||
asm_fprintf ((FILE), "\t.short"); \
|
||||
asm_fprintf ((FILE), " %LL%d-%LL%d\n", (VALUE), (REL)); \
|
||||
} while (0)
|
||||
|
||||
/* This is how to output an assembler line
|
||||
that says to advance the location counter
|
||||
to a multiple of 2**LOG bytes. */
|
||||
#define ASM_OUTPUT_ALIGN(FILE,LOG) \
|
||||
do { if ((LOG) != 0) fprintf (FILE, "\t.balign %d\n", 1 << (LOG)); } while (0)
|
||||
|
||||
/* Debugging information. */
|
||||
|
||||
/* Generate DBX and DWARF debugging information. */
|
||||
#define DBX_DEBUGGING_INFO 1
|
||||
|
||||
#undef PREFERRED_DEBUGGING_TYPE
|
||||
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
|
||||
|
||||
/* Turn off splitting of long stabs. */
|
||||
#define DBX_CONTIN_LENGTH 0
|
||||
|
||||
/* Miscellaneous. */
|
||||
|
||||
/* Specify the machine mode that this machine uses
|
||||
for the index in the tablejump instruction. */
|
||||
#define CASE_VECTOR_MODE (TARGET_SMALL16 && optimize_size ? HImode : Pmode)
|
||||
|
||||
/* Define if operations between registers always perform the operation
|
||||
on the full register even if a narrower mode is specified. */
|
||||
#define WORD_REGISTER_OPERATIONS
|
||||
|
||||
/* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD
|
||||
will either zero-extend or sign-extend. The value of this macro should
|
||||
be the code that says which one of the two operations is implicitly
|
||||
done, UNKNOWN if none. */
|
||||
#define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
|
||||
|
||||
/* Max number of bytes we can move from memory to memory
|
||||
in one reasonably fast instruction. */
|
||||
#define MOVE_MAX 8
|
||||
|
||||
/* Define this to be nonzero if shift instructions ignore all but the low-order
|
||||
few bits. */
|
||||
#define SHIFT_COUNT_TRUNCATED 1
|
||||
|
||||
/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
|
||||
is done just by pretending it is already truncated. */
|
||||
#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
|
||||
|
||||
/* Specify the machine mode that pointers have.
|
||||
After generation of rtl, the compiler makes no further distinction
|
||||
between pointers and any other objects of this machine mode. */
|
||||
|
||||
#define Pmode SImode
|
||||
|
||||
/* A function address in a call instruction. */
|
||||
#define FUNCTION_MODE SImode
|
||||
|
||||
/* EPIPHANY function types. */
|
||||
enum epiphany_function_type
|
||||
{
|
||||
EPIPHANY_FUNCTION_UNKNOWN, EPIPHANY_FUNCTION_NORMAL,
|
||||
/* These are interrupt handlers. The name corresponds to the register
|
||||
name that contains the return address. */
|
||||
EPIPHANY_FUNCTION_ILINK1, EPIPHANY_FUNCTION_ILINK2,
|
||||
/* These are interrupt handlers. The name corresponds to which type
|
||||
of interrupt handler we're dealing with. */
|
||||
EPIPHANY_FUNCTION_RESET, EPIPHANY_FUNCTION_SOFTWARE_EXCEPTION,
|
||||
EPIPHANY_FUNCTION_TIMER, EPIPHANY_FUNCTION_DMA0,
|
||||
EPIPHANY_FUNCTION_DMA1, EPIPHANY_FUNCTION_STATIC_FLAG,
|
||||
EPIPHANY_FUNCTION_SWI
|
||||
};
|
||||
|
||||
#define EPIPHANY_INTERRUPT_P(TYPE) \
|
||||
((TYPE) >= EPIPHANY_FUNCTION_RESET && (TYPE) <= EPIPHANY_FUNCTION_SWI)
|
||||
|
||||
/* Compute the type of a function from its DECL. */
|
||||
|
||||
#define IMMEDIATE_PREFIX "#"
|
||||
|
||||
#define OPTIMIZE_MODE_SWITCHING(ENTITY) \
|
||||
(epiphany_optimize_mode_switching (ENTITY))
|
||||
|
||||
/* We have two fake entities for lazy code motion of the mask constants,
|
||||
one entity each for round-to-nearest / truncating
|
||||
with a different idea what FP_MODE_ROUND_UNKNOWN will be, and
|
||||
finally an entity that runs in a second mode switching pass to
|
||||
resolve FP_MODE_ROUND_UNKNOWN. */
|
||||
#define NUM_MODES_FOR_MODE_SWITCHING \
|
||||
{ 2, 2, FP_MODE_NONE, FP_MODE_NONE, FP_MODE_NONE, FP_MODE_NONE, FP_MODE_NONE }
|
||||
|
||||
#define MODE_NEEDED(ENTITY, INSN) epiphany_mode_needed((ENTITY), (INSN))
|
||||
|
||||
#define MODE_PRIORITY_TO_MODE(ENTITY, N) \
|
||||
(epiphany_mode_priority_to_mode ((ENTITY), (N)))
|
||||
|
||||
#define EMIT_MODE_SET(ENTITY, MODE, HARD_REGS_LIVE) \
|
||||
emit_set_fp_mode ((ENTITY), (MODE), (HARD_REGS_LIVE))
|
||||
|
||||
#define MODE_ENTRY(ENTITY) (epiphany_mode_entry_exit ((ENTITY), false))
|
||||
#define MODE_EXIT(ENTITY) (epiphany_mode_entry_exit ((ENTITY), true))
|
||||
#define MODE_AFTER(LAST_MODE, INSN) \
|
||||
(epiphany_mode_after (e, (LAST_MODE), (INSN)))
|
||||
|
||||
#define TARGET_INSERT_MODE_SWITCH_USE epiphany_insert_mode_switch_use
|
||||
|
||||
/* Mode switching entities. */
|
||||
enum
|
||||
{
|
||||
EPIPHANY_MSW_ENTITY_AND,
|
||||
EPIPHANY_MSW_ENTITY_OR,
|
||||
EPIPHANY_MSW_ENTITY_NEAREST,
|
||||
EPIPHANY_MSW_ENTITY_TRUNC,
|
||||
EPIPHANY_MSW_ENTITY_ROUND_UNKNOWN,
|
||||
EPIPHANY_MSW_ENTITY_ROUND_KNOWN,
|
||||
EPIPHANY_MSW_ENTITY_FPU_OMNIBUS
|
||||
};
|
||||
|
||||
extern int epiphany_normal_fp_rounding;
|
||||
extern struct rtl_opt_pass pass_mode_switch_use;
|
||||
extern struct rtl_opt_pass pass_resolve_sw_modes;
|
||||
|
||||
/* This will need to be adjusted when FP_CONTRACT_ON is properly
|
||||
implemented. */
|
||||
#define TARGET_FUSED_MADD (flag_fp_contract_mode == FP_CONTRACT_FAST)
|
||||
|
||||
#endif /* !GCC_EPIPHANY_H */
|
2447
gcc/config/epiphany/epiphany.md
Executable file
2447
gcc/config/epiphany/epiphany.md
Executable file
File diff suppressed because it is too large
Load diff
140
gcc/config/epiphany/epiphany.opt
Executable file
140
gcc/config/epiphany/epiphany.opt
Executable file
|
@ -0,0 +1,140 @@
|
|||
; Options for the Adapteva EPIPHANY port of the compiler
|
||||
;
|
||||
; Copyright (C) 2005, 2007, 2009, 2011 Free Software Foundation, Inc.
|
||||
; Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
;
|
||||
; This file is part of GCC.
|
||||
;
|
||||
; GCC is free software; you can redistribute it and/or modify it under
|
||||
; the terms of the GNU General Public License as published by the Free
|
||||
; Software Foundation; either version 3, or (at your option) any later
|
||||
; version.
|
||||
;
|
||||
; GCC is distributed in the hope that it will be useful, but WITHOUT
|
||||
; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
; License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with GCC; see the file COPYING3. If not see
|
||||
; <http://www.gnu.org/licenses/>.
|
||||
|
||||
mhalf-reg-file
|
||||
Target Mask(HALF_REG_FILE)
|
||||
Don't use any of r32..r63.
|
||||
|
||||
mprefer-short-insn-regs
|
||||
Target Mask(PREFER_SHORT_INSN_REGS)
|
||||
preferentially allocate registers that allow short instruction generation.
|
||||
|
||||
mbranch-cost=
|
||||
Target RejectNegative Joined UInteger Var(epiphany_branch_cost) Init(3)
|
||||
Set branch cost
|
||||
|
||||
mcmove
|
||||
Target Mask(CMOVE)
|
||||
enable conditional move instruction usage.
|
||||
|
||||
mnops=
|
||||
Target RejectNegative Joined UInteger Var(epiphany_n_nops) Init(0)
|
||||
set number of nops to emit before each insn pattern
|
||||
|
||||
; Problems with using the flags from fsub for comparison are:
|
||||
; - Because of underflow (lack of subnormal numbers), different small numbers
|
||||
; can compare as equal.
|
||||
; - the set of comparisons is limited, and reversing comparisons doesn't work
|
||||
; in the presence of NaNs.
|
||||
; The latter problem might be tolerated with -ffinite-math-only , but nothing
|
||||
; in -funsafe-math-optimizations says different small numbers may be considered
|
||||
; equal.
|
||||
msoft-cmpsf
|
||||
Target Mask(SOFT_CMPSF)
|
||||
Use software floating point comparisons
|
||||
|
||||
msplit-lohi
|
||||
Target Mask(SPLIT_LOHI)
|
||||
Enable split of 32 bit immediate loads into low / high part
|
||||
|
||||
mpost-inc
|
||||
Target Mask(POST_INC)
|
||||
Enable use of POST_INC / POST_DEC
|
||||
|
||||
mpost-modify
|
||||
Target Mask(POST_MODIFY)
|
||||
Enable use of POST_MODIFY
|
||||
|
||||
mstack-offset=
|
||||
Target RejectNegative Joined UInteger Var(epiphany_stack_offset) Init(EPIPHANY_STACK_OFFSET)
|
||||
Set number of bytes on the stack preallocated for use by the callee.
|
||||
|
||||
mround-nearest
|
||||
target Mask(ROUND_NEAREST)
|
||||
Assume round to nearest is selected for purposes of scheduling.
|
||||
|
||||
mlong-calls
|
||||
Target Mask(LONG_CALLS)
|
||||
Generate call insns as indirect calls
|
||||
|
||||
mshort-calls
|
||||
Target Mask(SHORT_CALLS)
|
||||
Generate call insns as direct calls
|
||||
|
||||
msmall16
|
||||
Target Mask(SMALL16)
|
||||
Assume labels and symbols can be addressed using 16 bit absolute addresses.
|
||||
|
||||
mfp-mode=
|
||||
Target RejectNegative Joined Var(epiphany_normal_fp_mode) Enum(attr_fp_mode) Init(FP_MODE_CALLER)
|
||||
|
||||
; The values are from enum attr_fp_mode, but using that enum would bring
|
||||
; problems with enum forward declarations.
|
||||
Enum
|
||||
Name(attr_fp_mode) Type(int)
|
||||
|
||||
EnumValue
|
||||
Enum(attr_fp_mode) String(caller) Value(FP_MODE_CALLER)
|
||||
|
||||
EnumValue
|
||||
Enum(attr_fp_mode) String(round-nearest) Value(FP_MODE_ROUND_NEAREST)
|
||||
|
||||
EnumValue
|
||||
Enum(attr_fp_mode) String(truncate) Value(FP_MODE_ROUND_TRUNC)
|
||||
|
||||
EnumValue
|
||||
Enum(attr_fp_mode) String(int) Value(FP_MODE_INT)
|
||||
|
||||
mvect-double
|
||||
Target Mask(VECT_DOUBLE)
|
||||
Vectorize for double-word operations.
|
||||
|
||||
max-vect-align=
|
||||
Target RejectNegative Joined Var(epiphany_vect_align) Enum(vect_align) Init(8)
|
||||
|
||||
Enum
|
||||
Name(vect_align) Type(int)
|
||||
|
||||
EnumValue
|
||||
Enum(vect_align) String(4) Value(4)
|
||||
|
||||
EnumValue
|
||||
Enum(vect_align) String(8) Value(8)
|
||||
|
||||
msplit-vecmove-early
|
||||
Target Mask(SPLIT_VECMOVE_EARLY)
|
||||
Split unaligned 8 byte vector moves before post-modify address generation.
|
||||
|
||||
m1reg-
|
||||
Target RejectNegative Joined Var(epiphany_m1reg) Enum(m1reg) Init(-1)
|
||||
Set register to hold -1.
|
||||
|
||||
Enum
|
||||
Name(m1reg) Type(int)
|
||||
|
||||
EnumValue
|
||||
Enum(m1reg) String(none) Value(-1)
|
||||
|
||||
EnumValue
|
||||
Enum(m1reg) String(r43) Value(43)
|
||||
|
||||
EnumValue
|
||||
Enum(m1reg) String(r63) Value(63)
|
27
gcc/config/epiphany/epiphany_intrinsics.h
Normal file
27
gcc/config/epiphany/epiphany_intrinsics.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
/* Epiphany intrinsic functions
|
||||
Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
This file is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 3, or (at your option) any
|
||||
later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define __builtin_epiphany_fmadd(a, b, c) __builtin_fmaf (b, c, a)
|
||||
#define __builtin_epiphany_fmsub(a, b, c) __builtin_fmaf (-(b), c, a)
|
91
gcc/config/epiphany/mode-switch-use.c
Normal file
91
gcc/config/epiphany/mode-switch-use.c
Normal file
|
@ -0,0 +1,91 @@
|
|||
/* Insert USEs in instructions that require mode switching.
|
||||
This should probably be merged into mode-switching.c .
|
||||
Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "rtl.h"
|
||||
#include "function.h"
|
||||
#include "emit-rtl.h"
|
||||
#include "tree-pass.h"
|
||||
#include "insn-attr.h"
|
||||
#include "insn-config.h"
|
||||
#include "recog.h"
|
||||
#include "tm_p.h"
|
||||
#include "df.h"
|
||||
|
||||
#ifndef TARGET_INSERT_MODE_SWITCH_USE
|
||||
#define TARGET_INSERT_MODE_SWITCH_USE NULL
|
||||
#endif
|
||||
|
||||
static unsigned int
|
||||
insert_uses (void)
|
||||
{
|
||||
static const int num_modes[] = NUM_MODES_FOR_MODE_SWITCHING;
|
||||
#define N_ENTITIES ARRAY_SIZE (num_modes)
|
||||
int e;
|
||||
void (*target_insert_mode_switch_use) (rtx insn, int, int)
|
||||
= TARGET_INSERT_MODE_SWITCH_USE;
|
||||
|
||||
for (e = N_ENTITIES - 1; e >= 0; e--)
|
||||
{
|
||||
int no_mode = num_modes[e];
|
||||
rtx insn;
|
||||
int mode;
|
||||
|
||||
if (!OPTIMIZE_MODE_SWITCHING (e))
|
||||
continue;
|
||||
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
|
||||
{
|
||||
if (!INSN_P (insn))
|
||||
continue;
|
||||
mode = MODE_NEEDED (e, insn);
|
||||
if (mode == no_mode)
|
||||
continue;
|
||||
if (target_insert_mode_switch_use)
|
||||
{
|
||||
target_insert_mode_switch_use (insn, e, mode);
|
||||
df_insn_rescan (insn);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct rtl_opt_pass pass_mode_switch_use =
|
||||
{
|
||||
{
|
||||
RTL_PASS,
|
||||
"mode_switch_use", /* name */
|
||||
NULL, /* gate */
|
||||
insert_uses, /* execute */
|
||||
NULL, /* sub */
|
||||
NULL, /* next */
|
||||
0, /* static_pass_number */
|
||||
TV_NONE, /* tv_id */
|
||||
0, /* properties_required */
|
||||
0, /* properties_provided */
|
||||
0, /* properties_destroyed */
|
||||
0, /* todo_flags_start */
|
||||
0, /* todo_flags_finish */
|
||||
}
|
||||
};
|
352
gcc/config/epiphany/predicates.md
Executable file
352
gcc/config/epiphany/predicates.md
Executable file
|
@ -0,0 +1,352 @@
|
|||
;; Predicate definitions for code generation on the EPIPHANY cpu.
|
||||
;; Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
|
||||
;; 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
|
||||
;; Free Software Foundation, Inc.
|
||||
;; Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
;;
|
||||
;; This file is part of GCC.
|
||||
|
||||
;; GCC is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GCC is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GCC; see the file COPYING3. If not see
|
||||
;; <http://www.gnu.org/licenses/>.
|
||||
|
||||
;; Returns true iff OP is a symbol reference that is a valid operand
|
||||
;; in a jump or call instruction.
|
||||
|
||||
(define_predicate "symbolic_operand"
|
||||
(match_code "symbol_ref,label_ref,const")
|
||||
{
|
||||
if (GET_CODE (op) == SYMBOL_REF)
|
||||
return (!epiphany_is_long_call_p (op)
|
||||
&& (!flag_pic || SYMBOL_REF_LOCAL_P (op)));
|
||||
if (GET_CODE (op) == LABEL_REF)
|
||||
return true;
|
||||
if (GET_CODE (op) == CONST)
|
||||
{
|
||||
op = XEXP (op, 0);
|
||||
if (GET_CODE (op) != PLUS || !symbolic_operand (XEXP (op, 0), mode))
|
||||
return false;
|
||||
/* The idea here is that a 'small' constant offset should be OK.
|
||||
What exactly is considered 'small' is a bit arbitrary. */
|
||||
return satisfies_constraint_L (XEXP (op, 1));
|
||||
}
|
||||
gcc_unreachable ();
|
||||
})
|
||||
|
||||
;; Acceptable arguments to the call insn.
|
||||
|
||||
(define_predicate "call_address_operand"
|
||||
(ior (match_code "reg")
|
||||
(match_operand 0 "symbolic_operand")))
|
||||
|
||||
(define_predicate "call_operand"
|
||||
(match_code "mem")
|
||||
{
|
||||
op = XEXP (op, 0);
|
||||
return call_address_operand (op, mode);
|
||||
})
|
||||
|
||||
;; general purpose register.
|
||||
(define_predicate "gpr_operand"
|
||||
(match_code "reg,subreg")
|
||||
{
|
||||
int regno;
|
||||
|
||||
if (!register_operand (op, mode))
|
||||
return 0;
|
||||
if (GET_CODE (op) == SUBREG)
|
||||
op = XEXP (op, 0);
|
||||
regno = REGNO (op);
|
||||
return regno >= FIRST_PSEUDO_REGISTER || regno <= 63;
|
||||
})
|
||||
|
||||
(define_special_predicate "any_gpr_operand"
|
||||
(match_code "subreg,reg")
|
||||
{
|
||||
return gpr_operand (op, mode);
|
||||
})
|
||||
|
||||
;; register suitable for integer add / sub operations; besides general purpose
|
||||
;; registers we allow fake hard registers that are eliminated to a real
|
||||
;; hard register via an offset.
|
||||
(define_predicate "add_reg_operand"
|
||||
(match_code "reg,subreg")
|
||||
{
|
||||
int regno;
|
||||
|
||||
if (!register_operand (op, mode))
|
||||
return 0;
|
||||
if (GET_CODE (op) == SUBREG)
|
||||
op = XEXP (op, 0);
|
||||
regno = REGNO (op);
|
||||
return (regno >= FIRST_PSEUDO_REGISTER || regno <= 63
|
||||
|| regno == FRAME_POINTER_REGNUM
|
||||
|| regno == ARG_POINTER_REGNUM);
|
||||
})
|
||||
|
||||
;; Also allows suitable constants
|
||||
(define_predicate "add_operand"
|
||||
(match_code "reg,subreg,const_int,symbol_ref,label_ref,const")
|
||||
{
|
||||
if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
|
||||
return add_reg_operand (op, mode);
|
||||
return satisfies_constraint_L (op);
|
||||
})
|
||||
|
||||
;; Ordinary 3rd operand for arithmetic operations
|
||||
(define_predicate "arith_operand"
|
||||
(match_code "reg,subreg,const_int,symbol_ref,label_ref,const")
|
||||
{
|
||||
if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
|
||||
return register_operand (op, mode);
|
||||
return satisfies_constraint_L (op);
|
||||
})
|
||||
|
||||
;; Constant integer 3rd operand for arithmetic operations
|
||||
(define_predicate "arith_int_operand"
|
||||
(match_code "const_int,symbol_ref,label_ref,const")
|
||||
{
|
||||
return satisfies_constraint_L (op);
|
||||
})
|
||||
|
||||
;; Return true if OP is an acceptable argument for a single word move source.
|
||||
|
||||
(define_predicate "move_src_operand"
|
||||
(match_code
|
||||
"symbol_ref,label_ref,const,const_int,const_double,reg,subreg,mem,unspec")
|
||||
{
|
||||
switch (GET_CODE (op))
|
||||
{
|
||||
case SYMBOL_REF :
|
||||
case LABEL_REF :
|
||||
case CONST :
|
||||
return 1;
|
||||
case CONST_INT :
|
||||
return immediate_operand (op, mode);
|
||||
case CONST_DOUBLE :
|
||||
/* SImode constants should always fit into a CONST_INT. Large
|
||||
unsigned 32-bit constants are represented as negative CONST_INTs. */
|
||||
gcc_assert (GET_MODE (op) != SImode);
|
||||
/* We can handle 32-bit floating point constants. */
|
||||
if (mode == SFmode)
|
||||
return GET_MODE (op) == SFmode;
|
||||
return 0;
|
||||
case REG :
|
||||
return op != frame_pointer_rtx && register_operand (op, mode);
|
||||
case SUBREG :
|
||||
/* (subreg (mem ...) ...) can occur here if the inner part was once a
|
||||
pseudo-reg and is now a stack slot. */
|
||||
if (GET_CODE (SUBREG_REG (op)) == MEM)
|
||||
return address_operand (XEXP (SUBREG_REG (op), 0), mode);
|
||||
else
|
||||
return register_operand (op, mode);
|
||||
case MEM :
|
||||
return address_operand (XEXP (op, 0), mode);
|
||||
case UNSPEC:
|
||||
return satisfies_constraint_Sra (op);
|
||||
default :
|
||||
return 0;
|
||||
}
|
||||
})
|
||||
|
||||
;; Return true if OP is an acceptable argument for a double word move source.
|
||||
|
||||
(define_predicate "move_double_src_operand"
|
||||
(match_code "reg,subreg,mem,const_int,const_double,const_vector")
|
||||
{
|
||||
return general_operand (op, mode);
|
||||
})
|
||||
|
||||
;; Return true if OP is an acceptable argument for a move destination.
|
||||
|
||||
(define_predicate "move_dest_operand"
|
||||
(match_code "reg,subreg,mem")
|
||||
{
|
||||
switch (GET_CODE (op))
|
||||
{
|
||||
case REG :
|
||||
return register_operand (op, mode);
|
||||
case SUBREG :
|
||||
/* (subreg (mem ...) ...) can occur here if the inner part was once a
|
||||
pseudo-reg and is now a stack slot. */
|
||||
if (GET_CODE (SUBREG_REG (op)) == MEM)
|
||||
{
|
||||
return address_operand (XEXP (SUBREG_REG (op), 0), mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
return register_operand (op, mode);
|
||||
}
|
||||
case MEM :
|
||||
return address_operand (XEXP (op, 0), mode);
|
||||
default :
|
||||
return 0;
|
||||
}
|
||||
})
|
||||
|
||||
(define_special_predicate "stacktop_operand"
|
||||
(match_code "mem")
|
||||
{
|
||||
if (mode != VOIDmode && GET_MODE (op) != mode)
|
||||
return false;
|
||||
return rtx_equal_p (XEXP (op, 0), stack_pointer_rtx);
|
||||
})
|
||||
|
||||
;; Return 1 if OP is a comparison operator valid for the mode of CC.
|
||||
;; This allows the use of MATCH_OPERATOR to recognize all the branch insns.
|
||||
;;
|
||||
;; Some insns only set a few bits in the condition code. So only allow those
|
||||
;; comparisons that use the bits that are valid.
|
||||
|
||||
(define_predicate "proper_comparison_operator"
|
||||
(match_code "eq, ne, le, lt, ge, gt, leu, ltu, geu, gtu, unordered, ordered, uneq, unge, ungt, unle, unlt, ltgt")
|
||||
{
|
||||
enum rtx_code code = GET_CODE (op);
|
||||
rtx cc = XEXP (op, 0);
|
||||
|
||||
/* combine can try strange things. */
|
||||
if (!REG_P (cc))
|
||||
return 0;
|
||||
switch (GET_MODE (cc))
|
||||
{
|
||||
case CC_Zmode:
|
||||
case CC_N_NEmode:
|
||||
case CC_FP_EQmode:
|
||||
return REGNO (cc) == CC_REGNUM && (code == EQ || code == NE);
|
||||
case CC_C_LTUmode:
|
||||
return REGNO (cc) == CC_REGNUM && (code == LTU || code == GEU);
|
||||
case CC_C_GTUmode:
|
||||
return REGNO (cc) == CC_REGNUM && (code == GTU || code == LEU);
|
||||
case CC_FPmode:
|
||||
return (REGNO (cc) == CCFP_REGNUM
|
||||
&& (code == EQ || code == NE || code == LT || code == LE));
|
||||
case CC_FP_GTEmode:
|
||||
return (REGNO (cc) == CC_REGNUM
|
||||
&& (code == EQ || code == NE || code == GT || code == GE
|
||||
|| code == UNLE || code == UNLT));
|
||||
case CC_FP_ORDmode:
|
||||
return REGNO (cc) == CC_REGNUM && (code == ORDERED || code == UNORDERED);
|
||||
case CC_FP_UNEQmode:
|
||||
return REGNO (cc) == CC_REGNUM && (code == UNEQ || code == LTGT);
|
||||
case CCmode:
|
||||
return REGNO (cc) == CC_REGNUM;
|
||||
/* From combiner. */
|
||||
case QImode: case SImode: case SFmode: case HImode:
|
||||
/* From cse.c:dead_libcall_p. */
|
||||
case DFmode:
|
||||
return 0;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
})
|
||||
|
||||
(define_predicate "cc_operand"
|
||||
(and (match_code "reg")
|
||||
(match_test "REGNO (op) == CC_REGNUM || REGNO (op) == CCFP_REGNUM")))
|
||||
|
||||
(define_predicate "const0_operand"
|
||||
(match_code "const_int, const_double")
|
||||
{
|
||||
if (mode == VOIDmode)
|
||||
mode = GET_MODE (op);
|
||||
return op == CONST0_RTX (mode);
|
||||
})
|
||||
|
||||
(define_predicate "const_float_1_operand"
|
||||
(match_code "const_double")
|
||||
{
|
||||
return op == CONST1_RTX (mode);
|
||||
})
|
||||
|
||||
(define_predicate "cc_move_operand"
|
||||
(and (match_code "reg")
|
||||
(ior (match_test "REGNO (op) == CC_REGNUM")
|
||||
(match_test "gpr_operand (op, mode)"))))
|
||||
|
||||
(define_predicate "float_operation"
|
||||
(match_code "parallel")
|
||||
{
|
||||
/* Most patterns start out with one SET and one CLOBBER, and gain a USE
|
||||
or two of FP_NEAREST_REGNUM / FP_TRUNCATE_REGNUM / FP_ANYFP_REGNUM
|
||||
after mode switching. The longer patterns are
|
||||
all beyond length 4, and before mode switching, end with a
|
||||
CLOBBER of CCFP_REGNUM. */
|
||||
int count = XVECLEN (op, 0);
|
||||
bool inserted = MACHINE_FUNCTION (cfun)->control_use_inserted;
|
||||
int i;
|
||||
|
||||
if (count == 2)
|
||||
return !inserted;
|
||||
|
||||
/* combine / recog will pass any old garbage here before checking the
|
||||
rest of the insn. */
|
||||
if (count <= 3)
|
||||
return false;
|
||||
|
||||
i = 1;
|
||||
if (count > 4)
|
||||
for (i = 4; i < count; i++)
|
||||
{
|
||||
rtx x = XVECEXP (op, 0, i);
|
||||
|
||||
if (GET_CODE (x) == CLOBBER)
|
||||
{
|
||||
if (!REG_P (XEXP (x, 0)))
|
||||
return false;
|
||||
if (REGNO (XEXP (x, 0)) == CCFP_REGNUM)
|
||||
{
|
||||
if (count == i + 1)
|
||||
return !inserted;
|
||||
break;
|
||||
}
|
||||
/* Just an ordinary clobber, keep looking. */
|
||||
}
|
||||
else if (GET_CODE (x) == USE
|
||||
|| (GET_CODE (x) == SET && i == 2))
|
||||
continue;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
if (count != i + 3 || !inserted)
|
||||
return false;
|
||||
for (i = i+1; i < count; i++)
|
||||
{
|
||||
rtx x = XVECEXP (op, 0, i);
|
||||
|
||||
if (GET_CODE (x) != USE && GET_CODE (x) != CLOBBER)
|
||||
return false;
|
||||
x = XEXP (x, 0);
|
||||
if (!REG_P (x)
|
||||
|| (REGNO (x) != FP_NEAREST_REGNUM
|
||||
&& REGNO (x) != FP_TRUNCATE_REGNUM
|
||||
&& REGNO (x) != FP_ANYFP_REGNUM))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
|
||||
(define_predicate "set_fp_mode_operand"
|
||||
(ior (match_test "gpr_operand (op, mode)")
|
||||
(and (match_code "const")
|
||||
(match_test "satisfies_constraint_Cfm (op)"))))
|
||||
|
||||
(define_predicate "post_modify_address"
|
||||
(match_code "post_modify,post_inc,post_dec"))
|
||||
|
||||
(define_predicate "post_modify_operand"
|
||||
(and (match_code "mem")
|
||||
(match_test "post_modify_address (XEXP (op, 0), Pmode)")))
|
||||
|
||||
(define_predicate "nonsymbolic_immediate_operand"
|
||||
(ior (match_test "immediate_operand (op, mode)")
|
||||
(match_code "const_vector"))) /* Is this specific enough? */
|
182
gcc/config/epiphany/resolve-sw-modes.c
Normal file
182
gcc/config/epiphany/resolve-sw-modes.c
Normal file
|
@ -0,0 +1,182 @@
|
|||
/* Mode switching cleanup pass for the EPIPHANY cpu.
|
||||
Copyright (C) 2000, 2011 Free Software Foundation, Inc.
|
||||
Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "machmode.h"
|
||||
#include "tm.h"
|
||||
#include "hard-reg-set.h"
|
||||
#include "tm_p.h"
|
||||
#include "vec.h"
|
||||
#include "sbitmap.h"
|
||||
#include "basic-block.h"
|
||||
#include "df.h"
|
||||
#include "rtl.h"
|
||||
#include "insn-config.h"
|
||||
#include "insn-codes.h"
|
||||
#include "emit-rtl.h"
|
||||
#include "recog.h"
|
||||
#include "function.h"
|
||||
#include "insn-attr-common.h"
|
||||
#include "tree-pass.h"
|
||||
|
||||
/* Clean-up after mode switching:
|
||||
Check for mode setting insns that have FP_MODE_ROUND_UNKNOWN.
|
||||
If only one rounding mode is required, select that one.
|
||||
Else we have to choose one to use in this mode setting insn and
|
||||
insert new mode setting insns on the edges where the other mode
|
||||
becomes unambigous. */
|
||||
|
||||
static bool
|
||||
gate_resolve_sw_modes (void)
|
||||
{
|
||||
return optimize;
|
||||
}
|
||||
|
||||
static unsigned
|
||||
resolve_sw_modes (void)
|
||||
{
|
||||
basic_block bb;
|
||||
rtx insn, src;
|
||||
VEC (basic_block, heap) *todo;
|
||||
sbitmap pushed;
|
||||
bool need_commit = false;
|
||||
bool finalize_fp_sets = (MACHINE_FUNCTION (cfun)->unknown_mode_sets == 0);
|
||||
|
||||
todo = VEC_alloc (basic_block, heap, last_basic_block);
|
||||
pushed = sbitmap_alloc (last_basic_block);
|
||||
sbitmap_zero (pushed);
|
||||
if (!finalize_fp_sets)
|
||||
{
|
||||
df_note_add_problem ();
|
||||
df_analyze ();
|
||||
}
|
||||
FOR_EACH_BB (bb)
|
||||
FOR_BB_INSNS (bb, insn)
|
||||
{
|
||||
enum attr_fp_mode selected_mode;
|
||||
|
||||
if (!NONJUMP_INSN_P (insn)
|
||||
|| recog_memoized (insn) != CODE_FOR_set_fp_mode)
|
||||
continue;
|
||||
src = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
|
||||
if (finalize_fp_sets)
|
||||
{
|
||||
SET_SRC (XVECEXP (PATTERN (insn), 0, 2)) = copy_rtx (src);
|
||||
if (REG_P (src))
|
||||
df_insn_rescan (insn);
|
||||
continue;
|
||||
}
|
||||
if (REG_P (src)
|
||||
|| XINT (XVECEXP (XEXP (src, 0), 0, 0), 0) != FP_MODE_ROUND_UNKNOWN)
|
||||
continue;
|
||||
if (find_regno_note (insn, REG_UNUSED, FP_TRUNCATE_REGNUM))
|
||||
selected_mode = FP_MODE_ROUND_NEAREST;
|
||||
else if (find_regno_note (insn, REG_UNUSED, FP_NEAREST_REGNUM))
|
||||
selected_mode = FP_MODE_ROUND_TRUNC;
|
||||
else
|
||||
{
|
||||
/* We could get more fancy in the selection of the mode by
|
||||
checking the total frequency of the affected edges. */
|
||||
selected_mode = (enum attr_fp_mode) epiphany_normal_fp_rounding;
|
||||
|
||||
VEC_quick_push (basic_block, todo, bb);
|
||||
SET_BIT (pushed, bb->index);
|
||||
}
|
||||
XVECEXP (XEXP (src, 0), 0, 0) = GEN_INT (selected_mode);
|
||||
SET_SRC (XVECEXP (PATTERN (insn), 0, 1)) = copy_rtx (src);
|
||||
SET_SRC (XVECEXP (PATTERN (insn), 0, 2)) = copy_rtx (src);
|
||||
df_insn_rescan (insn);
|
||||
}
|
||||
while (VEC_length (basic_block, todo))
|
||||
{
|
||||
basic_block bb = VEC_pop (basic_block, todo);
|
||||
int selected_reg, jilted_reg;
|
||||
enum attr_fp_mode jilted_mode;
|
||||
edge e;
|
||||
edge_iterator ei;
|
||||
|
||||
SET_BIT (pushed, bb->index);
|
||||
SET_BIT (pushed, bb->index);
|
||||
|
||||
if (epiphany_normal_fp_rounding == FP_MODE_ROUND_NEAREST)
|
||||
{
|
||||
selected_reg = FP_NEAREST_REGNUM;
|
||||
jilted_reg = FP_TRUNCATE_REGNUM;
|
||||
jilted_mode = FP_MODE_ROUND_TRUNC;
|
||||
}
|
||||
else
|
||||
{
|
||||
selected_reg = FP_TRUNCATE_REGNUM;
|
||||
jilted_reg = FP_NEAREST_REGNUM;
|
||||
jilted_mode = FP_MODE_ROUND_NEAREST;
|
||||
}
|
||||
|
||||
FOR_EACH_EDGE (e, ei, bb->succs)
|
||||
{
|
||||
basic_block succ = e->dest;
|
||||
rtx seq;
|
||||
|
||||
if (!REGNO_REG_SET_P (DF_LIVE_IN (succ), jilted_reg))
|
||||
continue;
|
||||
if (REGNO_REG_SET_P (DF_LIVE_IN (succ), selected_reg))
|
||||
{
|
||||
if (TEST_BIT (pushed, succ->index))
|
||||
continue;
|
||||
VEC_quick_push (basic_block, todo, succ);
|
||||
SET_BIT (pushed, bb->index);
|
||||
continue;
|
||||
}
|
||||
start_sequence ();
|
||||
emit_set_fp_mode (EPIPHANY_MSW_ENTITY_ROUND_UNKNOWN,
|
||||
jilted_mode, NULL);
|
||||
seq = get_insns ();
|
||||
end_sequence ();
|
||||
need_commit = true;
|
||||
insert_insn_on_edge (seq, e);
|
||||
}
|
||||
}
|
||||
VEC_free (basic_block, heap, todo);
|
||||
sbitmap_free (pushed);
|
||||
if (need_commit)
|
||||
commit_edge_insertions ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct rtl_opt_pass pass_resolve_sw_modes =
|
||||
{
|
||||
{
|
||||
RTL_PASS,
|
||||
"resolve_sw_modes", /* name */
|
||||
gate_resolve_sw_modes, /* gate */
|
||||
resolve_sw_modes, /* execute */
|
||||
NULL, /* sub */
|
||||
NULL, /* next */
|
||||
0, /* static_pass_number */
|
||||
TV_MODE_SWITCH, /* tv_id */
|
||||
0, /* properties_required */
|
||||
0, /* properties_provided */
|
||||
0, /* properties_destroyed */
|
||||
0, /* todo_flags_start */
|
||||
TODO_df_finish | TODO_verify_rtl_sharing |
|
||||
0 /* todo_flags_finish */
|
||||
}
|
||||
};
|
32
gcc/config/epiphany/t-epiphany
Executable file
32
gcc/config/epiphany/t-epiphany
Executable file
|
@ -0,0 +1,32 @@
|
|||
# Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003,
|
||||
# 2004, 2009, 2010, 2011 Free Software Foundation, Inc.
|
||||
# Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
#
|
||||
# This file is part of GCC.
|
||||
#
|
||||
# GCC is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GCC is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GCC; see the file COPYING3. If not see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
mode-switch-use.o : $(srcdir)/config/epiphany/mode-switch-use.c \
|
||||
$(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TM_P_H) $(RTL_H) \
|
||||
$(TREE_PASS_H) $(INSN_ATTR_H) $(EMIT_RTL_H) $(FUNCTION_H) $(RECOG_H) \
|
||||
insn-config.h $(DF_H)
|
||||
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $<
|
||||
|
||||
resolve-sw-modes.o : $(srcdir)/config/epiphany/resolve-sw-modes.c \
|
||||
$(CONFIG_H) $(SYSTEM_H) coretypes.h $(MACHMODE_H) $(TM_H) hard-reg-set.h \
|
||||
$(TM_P_H) $(VEC_H) sbitmap.h $(BASIC_BLOCK_H) $(DF_H) $(RTL_H) \
|
||||
insn-config.h insn-codes.h $(EMIT_RTL_H) $(RECOG_H) $(FUNCTION_H) \
|
||||
insn-attr-common.h $(TREE_PASS_H)
|
||||
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $<
|
|
@ -746,7 +746,7 @@ Volker Reichelt for keeping up with the problem reports.
|
|||
|
||||
@item
|
||||
Joern Rennecke for maintaining the sh port, loop, regmove & reload
|
||||
hacking.
|
||||
hacking and developing and maintaining the Epiphany port.
|
||||
|
||||
@item
|
||||
Loren J. Rittle for improvements to libstdc++-v3 including the FreeBSD
|
||||
|
|
|
@ -2192,7 +2192,7 @@ types (@pxref{Variable Attributes}, @pxref{Type Attributes}.)
|
|||
|
||||
@item disinterrupt
|
||||
@cindex @code{disinterrupt} attribute
|
||||
On MeP targets, this attribute causes the compiler to emit
|
||||
On Epiphany and MeP targets, this attribute causes the compiler to emit
|
||||
instructions to disable interrupts for the duration of the given
|
||||
function.
|
||||
|
||||
|
@ -2551,7 +2551,7 @@ This attribute is ignored for R8C target.
|
|||
|
||||
@item interrupt
|
||||
@cindex interrupt handler functions
|
||||
Use this attribute on the ARM, AVR, M32C, M32R/D, m68k, MeP, MIPS,
|
||||
Use this attribute on the ARM, AVR, Epiphany, M32C, M32R/D, m68k, MeP, MIPS,
|
||||
RX and Xstormy16 ports to indicate that the specified function is an
|
||||
interrupt handler. The compiler will generate function entry and exit
|
||||
sequences suitable for use in an interrupt handler when this attribute
|
||||
|
@ -2723,7 +2723,8 @@ attribute is not allowed on types to annotate indirect calls.
|
|||
@item long_call/short_call
|
||||
@cindex indirect calls on ARM
|
||||
This attribute specifies how a particular function is called on
|
||||
ARM@. Both attributes override the @option{-mlong-calls} (@pxref{ARM Options})
|
||||
ARM and Epiphany. Both attributes override the
|
||||
@option{-mlong-calls} (@pxref{ARM Options})
|
||||
command-line switch and @code{#pragma long_calls} settings. The
|
||||
@code{long_call} attribute indicates that the function might be far
|
||||
away from the call site and require a different (more expensive)
|
||||
|
|
|
@ -1208,6 +1208,11 @@ of the arguments depend on the target.
|
|||
Specify if the compiler should default to @option{-marm} or @option{-mthumb}.
|
||||
This option is only supported on ARM targets.
|
||||
|
||||
@item --with-stack-offset=@var{num}
|
||||
This option sets the default for the -mstack-offset=@var{num} option,
|
||||
and will thus generally also control the setting of this option for
|
||||
libraries. This option is only supported on Epiphany targets.
|
||||
|
||||
@item --with-fpmath=@var{isa}
|
||||
This options sets @option{-mfpmath=sse} by default and specifies the default
|
||||
ISA for floating-point arithmetics. You can select either @samp{sse} which
|
||||
|
@ -3312,6 +3317,13 @@ any MSDOS compiler except itself. You need to get the complete
|
|||
compilation package DJGPP, which includes binaries as well as sources,
|
||||
and includes all the necessary compilation tools and libraries.
|
||||
|
||||
@html
|
||||
<hr />
|
||||
@end html
|
||||
@heading @anchor{epiphany-x-elf}epiphany-*-elf
|
||||
Adapteva Epiphany.
|
||||
This configuration is intended for embedded systems.
|
||||
|
||||
@html
|
||||
<hr />
|
||||
@end html
|
||||
|
|
|
@ -458,6 +458,14 @@ Objective-C and Objective-C++ Dialects}.
|
|||
@c Try and put the significant identifier (CPU or system) first,
|
||||
@c so users have a clue at guessing where the ones they want will be.
|
||||
|
||||
@emph{Adapteva Epiphany Options}
|
||||
@gccoptlist{-mhalf-reg-file -mprefer-short-insn-regs @gol
|
||||
-mbranch-cost=@var{num} -mcmove -mnops=@var{num} -msoft-cmpsf @gol
|
||||
-msplit-lohi -mpost-inc -mpost-modify -mstack-offset=@var{num} @gol
|
||||
-mround-nearest -mlong-calls -mshort-calls -msmall16 @gol
|
||||
-mfp-mode=@var{mode} -mvect-double -max-vect-align=@var{num} @gol
|
||||
-msplit-vecmove-early -m1reg-@var{reg}}
|
||||
|
||||
@emph{ARM Options}
|
||||
@gccoptlist{-mapcs-frame -mno-apcs-frame @gol
|
||||
-mabi=@var{name} @gol
|
||||
|
@ -10226,6 +10234,7 @@ platform.
|
|||
@c in Machine Dependent Options
|
||||
|
||||
@menu
|
||||
* Adapteva Epiphany Options::
|
||||
* ARM Options::
|
||||
* AVR Options::
|
||||
* Blackfin Options::
|
||||
|
@ -10274,6 +10283,161 @@ platform.
|
|||
* zSeries Options::
|
||||
@end menu
|
||||
|
||||
@node Adapteva Epiphany Options
|
||||
@subsection Adapteva Epiphany Options
|
||||
|
||||
These @samp{-m} options are defined for Adapteva Epiphany:
|
||||
|
||||
@table @gcctabopt
|
||||
@item -mhalf-reg-file
|
||||
@opindex mhalf-reg-file
|
||||
Don't allocate any register in the range @code{r32}@dots{}@code{r63}.
|
||||
That allows code to run on hardware variants that lack these registers.
|
||||
|
||||
@item -mprefer-short-insn-regs
|
||||
@opindex mprefer-short-insn-regs
|
||||
Preferrentially allocate registers that allow short instruction generation.
|
||||
This can result in increasesd instruction count, so if this reduces or
|
||||
increases code size might vary from case to case.
|
||||
|
||||
@item -mbranch-cost=@var{num}
|
||||
@opindex mbranch-cost
|
||||
Set the cost of branches to roughly @var{num} ``simple'' instructions.
|
||||
This cost is only a heuristic and is not guaranteed to produce
|
||||
consistent results across releases.
|
||||
|
||||
@item -mcmove
|
||||
@opindex mcmove
|
||||
Enable the generation of conditional moves.
|
||||
|
||||
@item -mnops=@var{num}
|
||||
@opindex mnops
|
||||
Emit @var{num} nops before every other generated instruction.
|
||||
|
||||
@item -mno-soft-cmpsf
|
||||
@opindex mno-soft-cmpsf
|
||||
For single-precision floating point comparisons, emit an fsub instruction
|
||||
and test the flags. This is faster than a software comparison, but can
|
||||
get incorrect results in the presence of NaNs, or when two different small
|
||||
numbers are compared such that their difference is calculated as zero.
|
||||
The default is @option{-msoft-cmpsf}, which uses slower, but IEEE-compliant,
|
||||
software comparisons.
|
||||
|
||||
@item -mstack-offset=@var{num}
|
||||
@opindex mstack-offset
|
||||
Set the offset between the top of the stack and the stack pointer.
|
||||
E.g., a value of 8 means that the eight bytes in the range sp+0@dots{}sp+7
|
||||
can be used by leaf functions without stack allocation.
|
||||
Values other than @samp{8} or @samp{16} are untested and unlikely to work.
|
||||
Note also that this option changes the ABI, compiling a program with a
|
||||
different stack offset than the libraries have been compiled with
|
||||
will generally not work.
|
||||
This option can be useful if you want to evaluate if a different stack
|
||||
offset would give you better code, but to actually use a different stack
|
||||
offset to build working programs, it is recommended to configure the
|
||||
toolchain with the appropriate @samp{--with-stack-offset=@var{num}} option.
|
||||
|
||||
@item -mno-round-nearest
|
||||
@opindex mno-round-nearest
|
||||
Make the scheduler assume that the rounding mode has been set to
|
||||
truncating. The default is @option{-mround-nearest}.
|
||||
|
||||
@item -mlong-calls
|
||||
@opindex mlong-calls
|
||||
If not otherwise specified by an attribute, assume all calls might be beyond
|
||||
the offset range of the b / bl instructions, and therefore load the
|
||||
function address into a register before performing a (otherwise direct) call.
|
||||
This is the default.
|
||||
|
||||
@item -mshort-calls
|
||||
@opindex short-calls
|
||||
If not otherwise specified by an attribute, assume all direct calls are
|
||||
in the range of the b / bl instructions, so use these instructions
|
||||
for direct calls. The default is @option{-mlong-calls}.
|
||||
|
||||
@item -msmall16
|
||||
@opindex msmall16
|
||||
Assume addresses can be loaded as 16 bit unsigned values. This does not
|
||||
apply to function addresses for which @option{-mlong-calls} semantics
|
||||
are in effect.
|
||||
|
||||
@item -mfp-mode=@var{mode}
|
||||
@opindex mfp-mode
|
||||
Set the prevailing mode of the floating point unit.
|
||||
This determines the floating point mode that is provided and expected
|
||||
at function call and return time. Making this mode match the mode you
|
||||
predominantly need at function start can make your programs smaller and
|
||||
faster by avoiding unnecessary mode switches.
|
||||
|
||||
@var{mode} can be set to one the following values:
|
||||
|
||||
@table @samp
|
||||
@item caller
|
||||
Any mode at function entry is valid, and retained or restored when
|
||||
the function returns, and when it calls other functions.
|
||||
This mode is useful for compiling libraries or other compilation units
|
||||
you might want to incorporate into different programs with different
|
||||
prevailing FPU modes, and the convenience of being able to use a single
|
||||
object file outweighs the size and speed overhead for any extra
|
||||
mode switching that might be needed, compared with what would be needed
|
||||
with a more specific choice of prevailing FPU mode.
|
||||
|
||||
@item truncate
|
||||
This is the mode used for floating point calculations with
|
||||
truncating (i.e.@: round towards zero) rounding mode. That includes
|
||||
conversion from floating point to integer.
|
||||
|
||||
@item round-nearest
|
||||
This is the mode used for floating point calculations with
|
||||
round-to-nearest-or-even rounding mode.
|
||||
|
||||
@item int
|
||||
This is the mode used to perform integer calculations in the FPU, e.g.@:
|
||||
integer multiply, or integer multiply-and-accumulate.
|
||||
@end table
|
||||
|
||||
The default is @option{-mfp-mode=caller}
|
||||
|
||||
@item -mnosplit-lohi
|
||||
@opindex mnosplit-lohi
|
||||
@item -mno-postinc
|
||||
@opindex mno-postinc
|
||||
@item -mno-postmodify
|
||||
@opindex mno-postmodify
|
||||
Code generation tweaks that disable, respectively, splitting of 32
|
||||
bit loads, generation of post-increment addresses, and generation of
|
||||
post-modify addresses. The defaults are @option{msplit-lohi},
|
||||
@option{-mpost-inc}, and @option{-mpost-modify}.
|
||||
|
||||
@item -mnovect-double
|
||||
@opindex mno-vect-double
|
||||
Change the preferred SIMD mode to SImode. The default is
|
||||
@option{-mvect-double}, which uses DImode as preferred SIMD mode.
|
||||
|
||||
@item -max-vect-align=@var{num}
|
||||
@opindex max-vect-align
|
||||
The maximum alignment for SIMD vector mode types.
|
||||
@var{num} may be 4 or 8. The default is 8.
|
||||
Note that this is an ABI change, even though many library function
|
||||
interfaces will be unaffected, if they don't use SIMD vector modes
|
||||
in places where they affect size and/or alignment of relevant types.
|
||||
|
||||
@item -msplit-vecmove-early
|
||||
@opindex msplit-vecmove-early
|
||||
Split vector moves into single word moves before reload. In theory this
|
||||
could give better register allocation, but so far the reverse seems to be
|
||||
generally the case.
|
||||
|
||||
@item -m1reg-@var{reg}
|
||||
@opindex m1reg-
|
||||
Specify a register to hold the constant @minus{}1, which makes loading small negative
|
||||
constants and certain bitmasks faster.
|
||||
Allowable values for reg are r43 and r63, which specify to use that register
|
||||
as a fixed register, and none, which means that no register is used for this
|
||||
purpose. The default is @option{-m1reg-none}.
|
||||
|
||||
@end table
|
||||
|
||||
@node ARM Options
|
||||
@subsection ARM Options
|
||||
@cindex ARM options
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
@c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1996, 1998, 1999, 2000, 2001,
|
||||
@c 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
|
||||
@c 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
|
||||
@c Free Software Foundation, Inc.
|
||||
@c This is part of the GCC manual.
|
||||
@c For copying conditions, see the file gcc.texi.
|
||||
|
@ -1778,6 +1778,77 @@ A memory address based on Y or Z pointer with displacement.
|
|||
Constant integer 4
|
||||
@end table
|
||||
|
||||
@item Epiphany---@file{config/epiphany/constraints.md}
|
||||
@table @code
|
||||
@item U16
|
||||
An unsigned 16-bit constant.
|
||||
|
||||
@item K
|
||||
An unsigned 5-bit constant.
|
||||
|
||||
@item L
|
||||
A signed 11-bit constant.
|
||||
|
||||
@item Cm1
|
||||
A signed 11-bit constant added to @minus{}1.
|
||||
Can only match when the @option{-m1reg-@var{reg}} option is active.
|
||||
|
||||
@item Cl1
|
||||
Left-shift of @minus{}1, i.e., a bit mask with a block of leading ones, the rest
|
||||
being a block of trailing zeroes.
|
||||
Can only match when the @option{-m1reg-@var{reg}} option is active.
|
||||
|
||||
@item Cr1
|
||||
Right-shift of @minus{}1, i.e., a bit mask with a trailing block of ones, the
|
||||
rest being zeroes. Or to put it another way, one less than a power of two.
|
||||
Can only match when the @option{-m1reg-@var{reg}} option is active.
|
||||
|
||||
@item Cal
|
||||
Constant for arithmetic/logical operations.
|
||||
This is like @code{i}, except that for position independent code,
|
||||
no symbols / expressions needing relocations are allowed.
|
||||
|
||||
@item Csy
|
||||
Symbolic constant for call/jump instruction.
|
||||
|
||||
@item Rcs
|
||||
The register class usable in short insns. This is a register class
|
||||
constraint, and can thus drive register allocation.
|
||||
This constraint won't match unless @option{-mprefer-short-insn-regs} is
|
||||
in effect.
|
||||
|
||||
@item Rsc
|
||||
The the register class of registers that can be used to hold a
|
||||
sibcall call address. I.e., a caller-saved register.
|
||||
|
||||
@item Rct
|
||||
Core control register class.
|
||||
|
||||
@item Rgs
|
||||
The register group usable in short insns.
|
||||
This constraint does not use a register class, so that it only
|
||||
passively matches suitable registers, and doesn't drive register allocation.
|
||||
|
||||
@ifset INTERNALS
|
||||
@item Car
|
||||
Constant suitable for the addsi3_r pattern. This is a valid offset
|
||||
For byte, halfword, or word addressing.
|
||||
@end ifset
|
||||
|
||||
@item Rra
|
||||
Matches the return address if it can be replaced with the link register.
|
||||
|
||||
@item Rcc
|
||||
Matches the integer condition code register.
|
||||
|
||||
@item Sra
|
||||
Matches the return address if it is in a stack slot.
|
||||
|
||||
@item Cfm
|
||||
Matches control register values to switch fp mode, which are encapsulated in
|
||||
@code{UNSPEC_FP_MODE}.
|
||||
@end table
|
||||
|
||||
@item Hewlett-Packard PA-RISC---@file{config/pa/pa.h}
|
||||
@table @code
|
||||
@item a
|
||||
|
|
|
@ -1,3 +1,20 @@
|
|||
2011-11-05 Joern Rennecke <joern.rennecke@embecosm.com>
|
||||
|
||||
* gcc.c-torture/execute/ieee/mul-subnormal-single-1.x:
|
||||
Disable test on Epiphany.
|
||||
* gcc.c-torture/execute/20101011-1.c: Disable test on Epiphany.
|
||||
* gcc.dg/stack-usage-1.c [__epiphany__] (SIZE): Define.
|
||||
* gcc.dg/pragma-pack-3.c: Disable test on Epiphany.
|
||||
* g++.dg/parse/pragma3.C: Likewise.
|
||||
* stackalign/builtin-apply-2.c (STACK_ARGUMENTS_SIZE): Define.
|
||||
(bar): Use it.
|
||||
* gcc.dg/weak/typeof-2.c [epiphany-*-*]: Add option -mshort-calls.
|
||||
* gcc.dg/tls/thr-cse-1.c: Likewise.
|
||||
* g++.dg/opt/devirt2.C: Likewise.
|
||||
* gcc.dg/20020312-2.c [epiphany-*-*] (PIC_REG): Define.
|
||||
* gcc.dg/builtin-apply2.c [__epiphany__]: (STACK_ARGUMENTS_SIZE): 20.
|
||||
* gcc.target/epiphany: New directory.
|
||||
|
||||
2011-11-05 Tobias Burnus <burnus@net-b.de>
|
||||
|
||||
* gfortran.dg/quad_2.f90: New.
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
// { dg-do compile }
|
||||
// { dg-options "-O2" }
|
||||
/* Using -mshort-calls avoids loading the function addresses in
|
||||
registers and thus getting the counts wrong. */
|
||||
// { dg-additional-options "-mshort-calls" {target epiphany-*-*} }
|
||||
// { dg-final { scan-assembler-times "xyzzy" 2 { target { ! { alpha*-*-* hppa*-*-* ia64*-*-hpux* sparc*-*-* } } } } }
|
||||
// The IA64 and HPPA compilers generate external declarations in addition
|
||||
// to the call so those scans need to be more specific.
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// PR c++/25294
|
||||
// { dg-do run }
|
||||
// Epiphany makes struct S 8-byte aligned.
|
||||
// { dg-do run { target { ! epiphany-*-* } } }
|
||||
|
||||
extern "C" void abort (void);
|
||||
|
||||
|
|
|
@ -28,6 +28,10 @@
|
|||
/* Not all Linux kernels deal correctly the breakpoints generated by
|
||||
MIPS16 divisions by zero. They show up as a SIGTRAP instead. */
|
||||
# define DO_TEST 0
|
||||
#elif defined (__epiphany__)
|
||||
/* Epiphany does not have hardware division, and the software implementation
|
||||
has truly undefined behaviour for division by 0. */
|
||||
# define DO_TEST 0
|
||||
#else
|
||||
# define DO_TEST 1
|
||||
#endif
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
if [istarget "epiphany-*-*"] {
|
||||
# The Epiphany single-precision floating point format does not
|
||||
# support subnormals.
|
||||
return 1
|
||||
}
|
||||
if [istarget "mips-sgi-irix6*"] {
|
||||
# IRIX 6 sets the MIPS IV flush to zero bit by default, so this test
|
||||
# isn't expected to work for n32 and n64 on MIPS IV targets.
|
||||
|
|
|
@ -20,6 +20,8 @@ extern void abort (void);
|
|||
/* No pic register. */
|
||||
#elif defined(__cris__)
|
||||
# define PIC_REG "0"
|
||||
#elif defined(__epiphany__)
|
||||
#define PIC_REG "r28"
|
||||
#elif defined(__fr30__)
|
||||
/* No pic register. */
|
||||
#elif defined(__H8300__) || defined(__H8300H__) || defined(__H8300S__)
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
#define INTEGER_ARG 5
|
||||
|
||||
#ifdef __ARM_PCS
|
||||
#if defined(__ARM_PCS) || defined(__epiphany__)
|
||||
/* For Base AAPCS, NAME is passed in r0. D is passed in r2 and r3.
|
||||
E, F and G are passed on stack. So the size of the stack argument
|
||||
data is 20. */
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* PR c++/25294 */
|
||||
/* { dg-options "-std=gnu99" } */
|
||||
/* { dg-do run } */
|
||||
/* Epiphany makes struct S 8-byte aligned. */
|
||||
/* { dg-do run { target { ! epiphany-*-* } } } */
|
||||
|
||||
extern void abort (void);
|
||||
|
||||
|
|
|
@ -52,6 +52,8 @@
|
|||
# define SIZE 160 /* 256 - 96 bytes for register save area */
|
||||
#elif defined (__SPU__)
|
||||
# define SIZE 224
|
||||
#elif defined (__epiphany__)
|
||||
# define SIZE (256 - __EPIPHANY_STACK_OFFSET__)
|
||||
#else
|
||||
# define SIZE 256
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O1" } */
|
||||
/* Using -mshort-calls avoids loading the function addresses in
|
||||
registers and thus getting the counts wrong. */
|
||||
/* { dg-additional-options "-mshort-calls" { target epiphany-*-* } } */
|
||||
/* { dg-require-effective-target tls_emulated } */
|
||||
|
||||
/* Test that we only get one call to emutls_get_address when CSE is
|
||||
|
|
|
@ -9,6 +9,15 @@
|
|||
|
||||
#define INTEGER_ARG 5
|
||||
|
||||
#if defined(__ARM_PCS) || defined(__epiphany__)
|
||||
/* For Base AAPCS, NAME is passed in r0. D is passed in r2 and r3.
|
||||
E, F and G are passed on stack. So the size of the stack argument
|
||||
data is 20. */
|
||||
#define STACK_ARGUMENTS_SIZE 20
|
||||
#else
|
||||
#define STACK_ARGUMENTS_SIZE 64
|
||||
#endif
|
||||
|
||||
extern void abort(void);
|
||||
|
||||
void foo(char *name, double d, double e, double f, int g)
|
||||
|
@ -19,7 +28,7 @@ void foo(char *name, double d, double e, double f, int g)
|
|||
|
||||
void bar(char *name, ...)
|
||||
{
|
||||
__builtin_apply(foo, __builtin_apply_args(), 64);
|
||||
__builtin_apply(foo, __builtin_apply_args(), STACK_ARGUMENTS_SIZE);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
/* { dg-require-weak "" } */
|
||||
/* { dg-require-alias "" } */
|
||||
/* { dg-options "-O2" } */
|
||||
/* Using -mshort-calls avoids loading the function addresses in
|
||||
registers and thus getting the counts wrong. */
|
||||
/* { dg-additional-options "-mshort-calls" { target epiphany-*-* } } */
|
||||
|
||||
extern int foo1 (int x) __asm ("baz1");
|
||||
int bar1 (int x) { return x; }
|
||||
|
|
41
gcc/testsuite/gcc.target/epiphany/epiphany.exp
Normal file
41
gcc/testsuite/gcc.target/epiphany/epiphany.exp
Normal file
|
@ -0,0 +1,41 @@
|
|||
# Copyright (C) 2007, 2011 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GCC; see the file COPYING3. If not see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
# GCC testsuite that uses the `dg.exp' driver.
|
||||
|
||||
# Exit immediately if this isn't an epiphany target.
|
||||
if ![istarget epiphany*-*-*] then {
|
||||
return
|
||||
}
|
||||
|
||||
# Load support procs.
|
||||
load_lib gcc-dg.exp
|
||||
|
||||
# If a testcase doesn't have special options, use these.
|
||||
global DEFAULT_CFLAGS
|
||||
if ![info exists DEFAULT_CFLAGS] then {
|
||||
set DEFAULT_CFLAGS " -ansi -pedantic-errors"
|
||||
}
|
||||
|
||||
# Initialize `dg'.
|
||||
dg-init
|
||||
|
||||
# Main loop.
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \
|
||||
"" $DEFAULT_CFLAGS
|
||||
|
||||
# All done.
|
||||
dg-finish
|
17
gcc/testsuite/gcc.target/epiphany/fmadd-1.c
Normal file
17
gcc/testsuite/gcc.target/epiphany/fmadd-1.c
Normal file
|
@ -0,0 +1,17 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2" } */
|
||||
/* { dg-final { scan-assembler-times "fmadd\[ \ta-zA-Z0-9\]*," 2 } } */
|
||||
|
||||
#include <epiphany_intrinsics.h>
|
||||
|
||||
float
|
||||
f1 (float a, float b, float c)
|
||||
{
|
||||
return __builtin_epiphany_fmadd (a, b, c);
|
||||
}
|
||||
|
||||
float
|
||||
f2 (float a, float b, float c)
|
||||
{
|
||||
return a + b * c;
|
||||
}
|
17
gcc/testsuite/gcc.target/epiphany/fmsub-1.c
Normal file
17
gcc/testsuite/gcc.target/epiphany/fmsub-1.c
Normal file
|
@ -0,0 +1,17 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2" } */
|
||||
/* { dg-final { scan-assembler-times "fmsub\[ \ta-zA-Z0-9\]*," 2 } } */
|
||||
|
||||
#include <epiphany_intrinsics.h>
|
||||
|
||||
float
|
||||
f1 (float a, float b, float c)
|
||||
{
|
||||
return __builtin_epiphany_fmsub (a, b, c);
|
||||
}
|
||||
|
||||
float
|
||||
f2 (float a, float b, float c)
|
||||
{
|
||||
return a - b * c;
|
||||
}
|
14
gcc/testsuite/gcc.target/epiphany/interrupt.c
Normal file
14
gcc/testsuite/gcc.target/epiphany/interrupt.c
Normal file
|
@ -0,0 +1,14 @@
|
|||
void __attribute__((interrupt("dma0")))
|
||||
f (void)
|
||||
{
|
||||
}
|
||||
|
||||
void __attribute__((interrupt("Vss")))
|
||||
g (void)
|
||||
{ /* { dg-warning "is not \"reset\"" } */
|
||||
}
|
||||
|
||||
void __attribute__((interrupt(42)))
|
||||
h (void)
|
||||
{ /* { dg-warning "is not a string constant" } */
|
||||
}
|
|
@ -1,3 +1,8 @@
|
|||
2011-11-05 Joern Rennecke <joern.rennecke@embecosm.com>
|
||||
|
||||
* config.host (epiphany-*-elf*): New configuration.
|
||||
* config/epiphany: New Directory.
|
||||
|
||||
2011-11-05 Ralf Corsépius <ralf.corsepius@rtems.org>
|
||||
|
||||
* config.host (avr-*-rtems*): Add config/avr/t-rtems.
|
||||
|
|
|
@ -433,6 +433,10 @@ cris-*-elf)
|
|||
cris-*-linux* | crisv32-*-linux*)
|
||||
tmake_file="$tmake_file cris/t-cris t-fdpbit cris/t-linux"
|
||||
;;
|
||||
epiphany-*-elf*)
|
||||
tmake_file="epiphany/t-epiphany t-fdpbit epiphany/t-custom-eqsf"
|
||||
extra_parts="$extra_parts crti.o crtint.o crtrunc.o crtm1reg-r43.o crtm1reg-r63.o crtn.o"
|
||||
;;
|
||||
fr30-*-elf)
|
||||
tmake_file="$tmake_file fr30/t-fr30 t-fdpbit"
|
||||
extra_parts="$extra_parts crti.o crtn.o"
|
||||
|
|
34
libgcc/config/epiphany/crti.S
Normal file
34
libgcc/config/epiphany/crti.S
Normal file
|
@ -0,0 +1,34 @@
|
|||
# Start .init and .fini sections.
|
||||
# Copyright (C) 2010, 2011 Free Software Foundation, Inc.
|
||||
# Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
#
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
# Under Section 7 of GPL version 3, you are granted additional
|
||||
# permissions described in the GCC Runtime Library Exception, version
|
||||
# 3.1, as published by the Free Software Foundation.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License and
|
||||
# a copy of the GCC Runtime Library Exception along with this program;
|
||||
# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
.section .init
|
||||
.global init
|
||||
.balign 2
|
||||
init:
|
||||
str lr,[sp],-4
|
||||
|
||||
.section .fini
|
||||
.global fini
|
||||
.balign 2
|
||||
fini:
|
||||
str lr,[sp],-4
|
27
libgcc/config/epiphany/crtint.S
Normal file
27
libgcc/config/epiphany/crtint.S
Normal file
|
@ -0,0 +1,27 @@
|
|||
# initialize config for -mfp-mode=int
|
||||
# Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
# Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
#
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
# Under Section 7 of GPL version 3, you are granted additional
|
||||
# permissions described in the GCC Runtime Library Exception, version
|
||||
# 3.1, as published by the Free Software Foundation.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License and
|
||||
# a copy of the GCC Runtime Library Exception along with this program;
|
||||
# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
.section .init
|
||||
mov r0, %low(#524288)
|
||||
movt r0, %high(#524288)
|
||||
movts config,r0
|
26
libgcc/config/epiphany/crtm1reg-r43.S
Normal file
26
libgcc/config/epiphany/crtm1reg-r43.S
Normal file
|
@ -0,0 +1,26 @@
|
|||
# initialize config for -m1reg-r43
|
||||
# Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
# Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
#
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
# Under Section 7 of GPL version 3, you are granted additional
|
||||
# permissions described in the GCC Runtime Library Exception, version
|
||||
# 3.1, as published by the Free Software Foundation.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License and
|
||||
# a copy of the GCC Runtime Library Exception along with this program;
|
||||
# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
.section .init
|
||||
mov r0, 0
|
||||
sub r43,r0,1
|
26
libgcc/config/epiphany/crtm1reg-r63.S
Normal file
26
libgcc/config/epiphany/crtm1reg-r63.S
Normal file
|
@ -0,0 +1,26 @@
|
|||
# initialize config for -m1reg-r63
|
||||
# Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
# Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
#
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
# Under Section 7 of GPL version 3, you are granted additional
|
||||
# permissions described in the GCC Runtime Library Exception, version
|
||||
# 3.1, as published by the Free Software Foundation.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License and
|
||||
# a copy of the GCC Runtime Library Exception along with this program;
|
||||
# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
.section .init
|
||||
mov r0, 0
|
||||
sub r63,r0,1
|
32
libgcc/config/epiphany/crtn.S
Normal file
32
libgcc/config/epiphany/crtn.S
Normal file
|
@ -0,0 +1,32 @@
|
|||
# End .init and .fini sections.
|
||||
# Copyright (C) 2010, 2011 Free Software Foundation, Inc.
|
||||
# Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
#
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
# Under Section 7 of GPL version 3, you are granted additional
|
||||
# permissions described in the GCC Runtime Library Exception, version
|
||||
# 3.1, as published by the Free Software Foundation.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License and
|
||||
# a copy of the GCC Runtime Library Exception along with this program;
|
||||
# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
.section .init
|
||||
ldr lr,[sp,4]
|
||||
add sp,sp,16
|
||||
jr lr
|
||||
|
||||
.section .fini
|
||||
ldr lr,[sp,4]
|
||||
add sp,sp,16
|
||||
jr lr
|
26
libgcc/config/epiphany/crtrunc.S
Normal file
26
libgcc/config/epiphany/crtrunc.S
Normal file
|
@ -0,0 +1,26 @@
|
|||
# initialize config for -mfp-mode=truncate
|
||||
# Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
# Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
#
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
# Under Section 7 of GPL version 3, you are granted additional
|
||||
# permissions described in the GCC Runtime Library Exception, version
|
||||
# 3.1, as published by the Free Software Foundation.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License and
|
||||
# a copy of the GCC Runtime Library Exception along with this program;
|
||||
# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
.section .init
|
||||
mov r0, 1
|
||||
movts config,r0
|
77
libgcc/config/epiphany/divsi3-float.S
Normal file
77
libgcc/config/epiphany/divsi3-float.S
Normal file
|
@ -0,0 +1,77 @@
|
|||
/* Signed 32 bit division optimized for Epiphany.
|
||||
Copyright (C) 2009, 2011 Free Software Foundation, Inc.
|
||||
Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
This file is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 3, or (at your option) any
|
||||
later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "epiphany-asm.h"
|
||||
|
||||
FSTAB (__divsi3,T_UINT)
|
||||
.global SYM(__divsi3)
|
||||
.balign 4
|
||||
HIDDEN_FUNC(__divsi3)
|
||||
SYM(__divsi3):
|
||||
float TMP2,r0
|
||||
mov TMP4,0
|
||||
float TMP1,r1
|
||||
sub TMP0,TMP4,r0
|
||||
beq .Lret_r0
|
||||
movgt r0,TMP0
|
||||
sub TMP0,TMP4,r1
|
||||
movgt r1,TMP0
|
||||
mov TMP0,1
|
||||
sub TMP2,TMP2,TMP1
|
||||
asr TMP3,TMP2,31 ; save sign
|
||||
lsl TMP2,TMP2,1
|
||||
blt .Lret0
|
||||
sub TMP1,TMP2,1 ; rounding compensation, avoid overflow
|
||||
movgte TMP2,TMP1
|
||||
lsr TMP2,TMP2,24
|
||||
lsl r1,r1,TMP2
|
||||
lsl TMP0,TMP0,TMP2
|
||||
sub TMP1,r0,r1
|
||||
movgteu r0,TMP1
|
||||
movgteu TMP4,TMP0
|
||||
lsl TMP5,TMP0,1
|
||||
sub TMP1,r0,r1
|
||||
movgteu r0,TMP1
|
||||
movgteu TMP4,TMP5
|
||||
sub TMP1,r1,1
|
||||
mov r1,%low(.L0step)
|
||||
movt r1,%high(.L0step)
|
||||
lsl TMP2,TMP2,3
|
||||
sub r1,r1,TMP2
|
||||
jr r1
|
||||
.rep 30
|
||||
lsl r0,r0,1
|
||||
sub.l r1,r0,TMP1
|
||||
movgteu r0,r1
|
||||
.endr
|
||||
.L0step:sub r1,TMP0,1 ; mask result bits from steps ...
|
||||
and r0,r0,r1
|
||||
orr r0,r0,TMP4 ; ... and combine with first bit.
|
||||
eor r0,r0,TMP3 ; restore sign
|
||||
sub r0,r0,TMP3
|
||||
.Lret_r0:rts
|
||||
.Lret0: mov r0,0
|
||||
rts
|
||||
ENDFUNC(__divsi3)
|
92
libgcc/config/epiphany/divsi3.S
Normal file
92
libgcc/config/epiphany/divsi3.S
Normal file
|
@ -0,0 +1,92 @@
|
|||
/* Signed 32 bit division optimized for Epiphany.
|
||||
Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
This file is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 3, or (at your option) any
|
||||
later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "epiphany-asm.h"
|
||||
|
||||
FSTAB (__divsi3,T_INT)
|
||||
.global SYM(__divsi3)
|
||||
.balign 4
|
||||
HIDDEN_FUNC(__divsi3)
|
||||
SYM(__divsi3):
|
||||
mov r12,0
|
||||
sub r2,r12,r0
|
||||
movlt r2,r0
|
||||
sub r3,r12,r1
|
||||
movlt r3,r1
|
||||
sub r19,r2,r3
|
||||
bltu .Lret0
|
||||
movt r12,0x4000
|
||||
orr r16,r2,r12
|
||||
orr r18,r3,r12
|
||||
fsub r16,r16,r12
|
||||
fsub r18,r18,r12
|
||||
movt r12,0x4b80
|
||||
lsr r19,r3,23
|
||||
lsr r17,r2,23
|
||||
movt r17,0x4b80
|
||||
fsub r17,r17,r12
|
||||
movt r19,0x4b80
|
||||
fsub r19,r19,r12
|
||||
mov r12,%low(.L0step)
|
||||
movt r12,%high(.L0step)
|
||||
mov r20,0
|
||||
mov r21,1
|
||||
movne r16,r17
|
||||
lsr r17,r3,23
|
||||
movne r18,r19
|
||||
eor r1,r1,r0 ; save sign
|
||||
asr r19,r1,31
|
||||
lsr r1,r16,23
|
||||
lsr r0,r18,23
|
||||
sub r1,r1,r0 ; calculate bit number difference.
|
||||
lsl r3,r3,r1
|
||||
lsr r16,r3,1
|
||||
lsl r0,r21,r1
|
||||
lsl r1,r1,3
|
||||
sub r12,r12,r1
|
||||
sub r3,r2,r3
|
||||
movgteu r2,r3
|
||||
movgteu r20,r0
|
||||
lsr r0,r0,1
|
||||
add r17,r0,r20
|
||||
sub r3,r2,r16
|
||||
movgteu r2,r3
|
||||
movgteu r20,r17
|
||||
sub r16,r16,1
|
||||
jr r12
|
||||
.rep 30
|
||||
lsl r2,r2,1
|
||||
sub r3,r2,r16
|
||||
movgteu r2,r3
|
||||
.endr
|
||||
sub r0,r0,1 ; mask result bits from steps ...
|
||||
and r0,r0,r2
|
||||
orr r20,r0,r20 ; ... and combine with first bit.
|
||||
.L0step:eor r0,r20,r19 ; restore sign
|
||||
sub r0,r0,r19
|
||||
rts
|
||||
.Lret0: mov r0,0
|
||||
rts
|
||||
ENDFUNC(__divsi3)
|
120
libgcc/config/epiphany/divsi3.c
Normal file
120
libgcc/config/epiphany/divsi3.c
Normal file
|
@ -0,0 +1,120 @@
|
|||
/* Generic signed 32 bit division implementation.
|
||||
Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
This file is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 3, or (at your option) any
|
||||
later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
typedef union { unsigned int i; float f; } fu;
|
||||
|
||||
/* Although the semantics of the function ask for signed / unsigned inputs,
|
||||
for the actual implementation we use unsigned numbers. */
|
||||
unsigned int __divsi3 (unsigned int a, unsigned int b);
|
||||
|
||||
unsigned int
|
||||
__divsi3 (unsigned int a, unsigned int b)
|
||||
{
|
||||
unsigned int sign = (int) (a ^ b) >> 31;
|
||||
unsigned int d, t, s0, s1, s2, r0, r1;
|
||||
fu u0, u1, u2, u1b, u2b;
|
||||
|
||||
a = abs (a);
|
||||
b = abs (b);
|
||||
|
||||
if (b > a)
|
||||
return 0;
|
||||
|
||||
/* Compute difference in number of bits in S0. */
|
||||
u0.i = 0x40000000;
|
||||
u1b.i = u2b.i = u0.i;
|
||||
u1.i = a;
|
||||
u2.i = b;
|
||||
u1.i = a | u0.i;
|
||||
t = 0x4b800000 | ((a >> 23) & 0xffff);
|
||||
if (a >> 23)
|
||||
{
|
||||
u1.i = t;
|
||||
u1b.i = 0x4b800000;
|
||||
}
|
||||
u2.i = b | u0.i;
|
||||
t = 0x4b800000 | ((b >> 23) & 0xffff);
|
||||
if (b >> 23)
|
||||
{
|
||||
u2.i = t;
|
||||
u2b.i = 0x4b800000;
|
||||
}
|
||||
u1.f = u1.f - u1b.f;
|
||||
u2.f = u2.f - u2b.f;
|
||||
s1 = u1.i >> 23;
|
||||
s2 = u2.i >> 23;
|
||||
s0 = s1 - s2;
|
||||
|
||||
b <<= s0;
|
||||
d = b - 1;
|
||||
|
||||
r0 = 1 << s0;
|
||||
r1 = 0;
|
||||
t = a - b;
|
||||
if (t <= a)
|
||||
{
|
||||
a = t;
|
||||
r1 = r0;
|
||||
}
|
||||
|
||||
#define STEP(n) case n: a += a; t = a - d; if (t <= a) a = t;
|
||||
switch (s0)
|
||||
{
|
||||
STEP (31)
|
||||
STEP (30)
|
||||
STEP (29)
|
||||
STEP (28)
|
||||
STEP (27)
|
||||
STEP (26)
|
||||
STEP (25)
|
||||
STEP (24)
|
||||
STEP (23)
|
||||
STEP (22)
|
||||
STEP (21)
|
||||
STEP (20)
|
||||
STEP (19)
|
||||
STEP (18)
|
||||
STEP (17)
|
||||
STEP (16)
|
||||
STEP (15)
|
||||
STEP (14)
|
||||
STEP (13)
|
||||
STEP (12)
|
||||
STEP (11)
|
||||
STEP (10)
|
||||
STEP (9)
|
||||
STEP (8)
|
||||
STEP (7)
|
||||
STEP (6)
|
||||
STEP (5)
|
||||
STEP (4)
|
||||
STEP (3)
|
||||
STEP (2)
|
||||
STEP (1)
|
||||
case 0: ;
|
||||
}
|
||||
r0 = r1 | (r0-1 & a);
|
||||
return (r0 ^ sign) - sign;
|
||||
}
|
53
libgcc/config/epiphany/epiphany-asm.h
Normal file
53
libgcc/config/epiphany/epiphany-asm.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/* Copyright (C) 1995, 1997, 2007, 2008, 2009, 2011
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* ANSI concatenation macros. */
|
||||
|
||||
#define CONCAT1(a, b) CONCAT2(a, b)
|
||||
#define CONCAT2(a, b) a ## b
|
||||
#define STRINGIFY2(a, b) STRINGIFY(a##b)
|
||||
#define STRINGIFY(a) #a
|
||||
|
||||
/* Use the right prefix for global labels. */
|
||||
|
||||
#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
|
||||
|
||||
#define FSTAB(X,T) .stabs STRINGIFY2(X##:F,T),36,0,__LINE__,SYM(X)
|
||||
#define FUNC(X) .type SYM(X),@function
|
||||
#define HIDDEN_FUNC(X) FUNC(X)` .hidden SYM(X)
|
||||
#define ENDFUNC0(X) CONCAT1(.Lfe_,X): .size X,CONCAT1(.Lfe_,X)-X
|
||||
#define ENDFUNC(X) ENDFUNC0(SYM(X))
|
||||
|
||||
#define TMP0 r12
|
||||
#define TMP1 r16
|
||||
#define TMP2 r17
|
||||
#define TMP3 r18
|
||||
#define TMP4 r19
|
||||
#define TMP5 r20
|
||||
|
||||
#define T_INT (0,1)
|
||||
.stabs "int:t(0,1)=r(0,1);-2147483648;2147483647;",128,0,1,0
|
||||
#define T_UINT (0,2)
|
||||
.stabs "unsigned int:t(0,2)=r(0,2);0;037777777777;",128,0,1,0
|
50
libgcc/config/epiphany/ieee-754/eqsf2.S
Normal file
50
libgcc/config/epiphany/ieee-754/eqsf2.S
Normal file
|
@ -0,0 +1,50 @@
|
|||
/* Copyright (C) 2008, 2009 Free Software Foundation, Inc.
|
||||
Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "../epiphany-asm.h"
|
||||
|
||||
/* Assumption: NaNs have all bits 10..30 and one of bit 0..9 set. */
|
||||
|
||||
FSTAB (__eqsf2,T_INT)
|
||||
.global SYM(__eqsf2)
|
||||
.balign 4
|
||||
HIDDEN_FUNC(__eqsf2)
|
||||
SYM(__eqsf2):
|
||||
sub TMP0,r0,r1
|
||||
beq .Lno_bdiff
|
||||
orr TMP0,r0,r1
|
||||
add TMP0,TMP0,TMP0
|
||||
rts
|
||||
.Lno_bdiff:
|
||||
#ifndef FLOAT_FORMAT_MOTOROLA
|
||||
mov TMP0,0xffff
|
||||
movt TMP0,0x7f
|
||||
add TMP0,TMP0,r0
|
||||
#else
|
||||
add TMP0,r0,0x3ff
|
||||
#endif
|
||||
eor TMP0,TMP0,r0
|
||||
lsr TMP0,TMP0,31
|
||||
rts
|
||||
ENDFUNC(__eqsf2)
|
124
libgcc/config/epiphany/ieee-754/fast_div.S
Normal file
124
libgcc/config/epiphany/ieee-754/fast_div.S
Normal file
|
@ -0,0 +1,124 @@
|
|||
/* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "../epiphany-asm.h"
|
||||
|
||||
.section _fast_div_text,"a",@progbits;
|
||||
.balign 8;
|
||||
_fast_div_table:
|
||||
.word 0x007fffff// mantissa mask
|
||||
.word 0x40257ebb// hold constant a = 2.58586
|
||||
|
||||
.word 0x3f000000// hold constant 126 shifted to bits [30:23]
|
||||
.word 0xc0ba2e88// hold constant b = -5.81818
|
||||
|
||||
.word 0x4087c1e8// hold constant c = 4.24242
|
||||
.word 0x40000000// to hold constant 2 for Newton-Raphson iterations
|
||||
|
||||
.global SYM(__fast_recipsf2)
|
||||
FUNC(__fast_recipsf2)
|
||||
SYM(__fast_recipsf2):
|
||||
|
||||
//###################
|
||||
//# input operands:
|
||||
//###################
|
||||
// Divisor
|
||||
//R0
|
||||
// Function address (used with negative offsets to read _fast_div_table)
|
||||
//R1
|
||||
/* Scratch registers: two single (TMP0/TMP5) and two pairs. */
|
||||
#define P0L TMP1
|
||||
#define P0H TMP2
|
||||
#define P1L TMP3
|
||||
#define P1H TMP4
|
||||
|
||||
//#########################################
|
||||
//# Constants to be used in the algorithm
|
||||
//#########################################
|
||||
ldrd P0L , [ R1 , -3 ]
|
||||
|
||||
ldrd P1L , [ R1 , -2 ]
|
||||
|
||||
|
||||
|
||||
//#############################################################################
|
||||
//# The Algorithm
|
||||
//#
|
||||
//# Operation: C=A/B
|
||||
//# stage 1 - find the reciprocal 1/B according to the following scheme:
|
||||
//# B = (2^E)*m (1<m<2, E=e-127)
|
||||
//# 1/B = 1/((2^E)*m) = 1/((2^(E+1))*m1) (0.5<m1<1)
|
||||
//# = (2^-(E+1))*(1/m1) = (2^E1)*(1/m1)
|
||||
//#
|
||||
//# Now we can find the new exponent:
|
||||
//# e1 = E1+127 = -E-1+127 = -e+127-1+127 = 253-e **
|
||||
//# 1/m1 alreadt has the exponent 127, so we have to add 126-e.
|
||||
//# the exponent might underflow, which we can detect as a sign change.
|
||||
//# Since the architeture uses flush-to-zero for subnormals, we can
|
||||
//# give the result 0. then.
|
||||
//#
|
||||
//# The 1/m1 term with 0.5<m1<1 is approximated with the Chebyshev polynomial
|
||||
//# 1/m1 = 2.58586*(m1^2) - 5.81818*m1 + 4.24242
|
||||
//#
|
||||
//# Next step is to use two iterations of Newton-Raphson algorithm to complete
|
||||
//# the reciprocal calculation.
|
||||
//#
|
||||
//# Final result is achieved by multiplying A with 1/B
|
||||
//#############################################################################
|
||||
|
||||
|
||||
|
||||
// R0 exponent and sign "replacement" into TMP0
|
||||
AND TMP0,R0,P0L ;
|
||||
ORR TMP0,TMP0,P1L
|
||||
SUB TMP5,R0,TMP0 // R0 sign/exponent extraction into TMP5
|
||||
// Calculate new mantissa
|
||||
FMADD P1H,TMP0,P0H ;
|
||||
// Calculate new exponent offset 126 - "old exponent"
|
||||
SUB P1L,P1L,TMP5
|
||||
ldrd P0L , [ R1 , -1 ]
|
||||
FMADD P0L,TMP0,P1H ;
|
||||
eor P1H,r0,P1L // check for overflow (N-BIT).
|
||||
blt .Lret_0
|
||||
// P0L exponent and sign "replacement"
|
||||
sub P0L,P0L,TMP5
|
||||
|
||||
// Newton-Raphson iteration #1
|
||||
MOV TMP0,P0H ;
|
||||
FMSUB P0H,R0,P0L ;
|
||||
FMUL P0L,P0H,P0L ;
|
||||
// Newton-Raphson iteration #2
|
||||
FMSUB TMP0,R0,P0L ;
|
||||
FMUL R0,TMP0,P0L ;
|
||||
jr lr
|
||||
.Lret_0:ldrd P0L , [ R1 , -3 ]
|
||||
lsr TMP0,r0,31 ; extract sign
|
||||
lsl TMP0,TMP0,31
|
||||
add P0L,P0L,r0 ; check for NaN input
|
||||
eor P0L,P0L,r0
|
||||
movgte r0,TMP0
|
||||
jr lr
|
||||
// Quotient calculation is expected by the caller: FMUL quotient,divident,R0
|
||||
;
|
||||
ENDFUNC(__fast_recipsf2)
|
66
libgcc/config/epiphany/ieee-754/gtesf2.S
Normal file
66
libgcc/config/epiphany/ieee-754/gtesf2.S
Normal file
|
@ -0,0 +1,66 @@
|
|||
/* Copyright (C) 2008, 2009 Free Software Foundation, Inc.
|
||||
Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "../epiphany-asm.h"
|
||||
|
||||
/* Assumptions: NaNs have all bits 10..30 and one of bit 0..9 set.
|
||||
after sub: AC = ~Borrow.
|
||||
clobber: TMP0
|
||||
output: gt / gte indicates greater / greater or equal. */
|
||||
|
||||
FSTAB (__gtesf2,T_INT)
|
||||
.global SYM(__gtesf2)
|
||||
.balign 4
|
||||
HIDDEN_FUNC(__gtesf2)
|
||||
SYM(__gtesf2):
|
||||
#ifndef FLOAT_FORMAT_MOTOROLA
|
||||
mov TMP0,0xffff
|
||||
movt TMP0,0x7f
|
||||
add TMP0,TMP0,r0
|
||||
eor TMP0,TMP0,r0
|
||||
blt .Lret
|
||||
mov TMP0,0xffff
|
||||
movt TMP0,0x7f
|
||||
add TMP0,TMP0,r1
|
||||
#else
|
||||
add TMP0,r0,0x3ff; check for r0 NaN
|
||||
eor TMP0,TMP0,r0
|
||||
blt .Lret
|
||||
add TMP0,r1,0x3ff; check for r1 NaN
|
||||
#endif
|
||||
eor TMP0,TMP0,r1
|
||||
blt .Lret
|
||||
and TMP0,r0,r1
|
||||
blt .Lneg
|
||||
orr TMP0,r0,r1
|
||||
lsl TMP0,TMP0,1
|
||||
beq .Lret
|
||||
sub TMP0,r0,r1
|
||||
.Lret:
|
||||
rts
|
||||
.balign 4
|
||||
.Lneg:
|
||||
sub TMP0,r1,r0
|
||||
rts
|
||||
ENDFUNC(__gtesf2)
|
50
libgcc/config/epiphany/ieee-754/ordsf2.S
Normal file
50
libgcc/config/epiphany/ieee-754/ordsf2.S
Normal file
|
@ -0,0 +1,50 @@
|
|||
/* Copyright (C) 2008, 2009, 2011 Free Software Foundation, Inc.
|
||||
Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "../epiphany-asm.h"
|
||||
|
||||
FSTAB (__ordsf2,T_INT)
|
||||
.global SYM(__ordsf2)
|
||||
.balign 8,,2
|
||||
HIDDEN_FUNC(__ordsf2)
|
||||
SYM(__ordsf2):
|
||||
#ifndef FLOAT_FORMAT_MOTOROLA
|
||||
mov TMP0,0
|
||||
movt TMP0,0xff00
|
||||
lsl TMP1,r0,1
|
||||
sub TMP1,TMP1,TMP0
|
||||
bgtu .Lret
|
||||
lsl TMP1,r1,1
|
||||
sub TMP1,TMP1,TMP0
|
||||
.Lret: rts /* ordered: lteu */
|
||||
#else
|
||||
/* Assumption: NaNs have all bits 9..30 and one of bit 0..8 set. */
|
||||
lsl TMP0,r0,1
|
||||
add TMP0,TMP0,0x3fe
|
||||
bgteu .Lret
|
||||
lsl TMP0,r1,1
|
||||
add TMP0,TMP0,0x3fe
|
||||
.Lret: rts /* ordered: ltu */
|
||||
#endif
|
||||
ENDFUNC(__ordsf2)
|
45
libgcc/config/epiphany/ieee-754/uneqsf2.S
Normal file
45
libgcc/config/epiphany/ieee-754/uneqsf2.S
Normal file
|
@ -0,0 +1,45 @@
|
|||
/* Copyright (C) 2008, 2009, 2011 Free Software Foundation, Inc.
|
||||
Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "../epiphany-asm.h"
|
||||
|
||||
FSTAB (__uneqsf2,T_INT)
|
||||
.global SYM(__uneqsf2)
|
||||
.balign 8,,2
|
||||
HIDDEN_FUNC(__uneqsf2)
|
||||
SYM(__uneqsf2):
|
||||
sub TMP0,r0,r1
|
||||
beq .Lret
|
||||
orr TMP0,r0,r1
|
||||
add TMP0,TMP0,TMP0
|
||||
beq .Lret
|
||||
mov TMP0,1
|
||||
movt TMP0,0xff00
|
||||
lsl TMP1,r0,1
|
||||
sub TMP1,TMP0,TMP1
|
||||
blteu .Lret
|
||||
lsl TMP1,r1,1
|
||||
sub TMP1,TMP0,TMP1
|
||||
.Lret: rts /* uneq: lteu */
|
||||
ENDFUNC(__uneqsf2)
|
65
libgcc/config/epiphany/modsi3-float.S
Normal file
65
libgcc/config/epiphany/modsi3-float.S
Normal file
|
@ -0,0 +1,65 @@
|
|||
/* Unsigned 32 bit division optimized for Epiphany.
|
||||
Copyright (C) 2009, 2011 Free Software Foundation, Inc.
|
||||
Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
This file is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 3, or (at your option) any
|
||||
later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "epiphany-asm.h"
|
||||
|
||||
FSTAB (__modsi3,T_UINT)
|
||||
.global SYM(__modsi3)
|
||||
.balign 4
|
||||
HIDDEN_FUNC(__modsi3)
|
||||
SYM(__modsi3):
|
||||
asr TMP3,r0,31 ; save sign
|
||||
float TMP0,r0
|
||||
float TMP1,r1
|
||||
mov r2,0
|
||||
sub TMP4,r2,r0
|
||||
beq .Lret_r0
|
||||
movgt r0,TMP4
|
||||
sub TMP2,r2,r1
|
||||
movlte TMP2,r1
|
||||
sub r2,TMP0,TMP1
|
||||
lsl r2,r2,1
|
||||
blte .L0step
|
||||
asr TMP4,r2,24
|
||||
lsl r2,TMP4,3
|
||||
mov TMP4,%low(.L0step)
|
||||
movt TMP4,%high(.L0step)
|
||||
sub r2,TMP4,r2
|
||||
jr r2
|
||||
#define STEP(n) lsl.l r2,TMP2,n` sub r2,r0,r2` movgteu r0,r2
|
||||
.balign 8,,2
|
||||
STEP(31)` STEP(30)` STEP(29)` STEP(28)`
|
||||
STEP(27)` STEP(26)` STEP(25)` STEP(24)`
|
||||
STEP(23)` STEP(22)` STEP(21)` STEP(20)`
|
||||
STEP(19)` STEP(18)` STEP(17)` STEP(16)`
|
||||
STEP(15)` STEP(14)` STEP(13)` STEP(12)`
|
||||
STEP(11)` STEP(10)` STEP(9)` STEP(8)`
|
||||
STEP(7)` STEP(6)` STEP(5)` STEP(4)` STEP(3)` STEP(2)` STEP(1)
|
||||
.L0step:STEP(0)
|
||||
eor r0,r0,TMP3 ; restore sign
|
||||
sub r0,r0,TMP3
|
||||
.Lret_r0:
|
||||
rts
|
||||
ENDFUNC(__modsi3)
|
77
libgcc/config/epiphany/modsi3.S
Normal file
77
libgcc/config/epiphany/modsi3.S
Normal file
|
@ -0,0 +1,77 @@
|
|||
/* Signed 32 bit modulo optimized for Epiphany.
|
||||
Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
This file is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 3, or (at your option) any
|
||||
later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "epiphany-asm.h"
|
||||
|
||||
FSTAB (__modsi3,T_INT)
|
||||
.global SYM(__modsi3)
|
||||
.balign 4
|
||||
HIDDEN_FUNC(__modsi3)
|
||||
SYM(__modsi3):
|
||||
asr r17,r0,31 ; save sign
|
||||
mov r2,0
|
||||
sub r3,r2,r0
|
||||
movgt r0,r3
|
||||
sub r3,r2,r1
|
||||
movgt r1,r3
|
||||
movt r2,0xa000 ; 0xa0000000
|
||||
orr r3,r2,r0
|
||||
lsr r15,r0,16
|
||||
movt r15,0xa800
|
||||
movne r3,r15
|
||||
lsr r16,r2,2 ; 0x28000000
|
||||
and r15,r3,r16
|
||||
fadd r12,r3,r15
|
||||
orr r3,r2,r1
|
||||
lsr r2,r1,16
|
||||
movt r2,0xa800
|
||||
movne r3,r2
|
||||
and r2,r16,r3
|
||||
fadd r3,r3,r2
|
||||
sub r2,r0,r1
|
||||
bltu .Lret_a
|
||||
lsr r12,r12,23
|
||||
mov r2,%low(.L0step)
|
||||
movt r2,%high(.L0step)
|
||||
lsr r3,r3,23
|
||||
sub r3,r12,r3 ; calculate bit number difference.
|
||||
lsl r3,r3,3
|
||||
sub r2,r2,r3
|
||||
jr r2
|
||||
/* lsl_l r2,r1,n` sub r2,r0,r2` movgteu r0,r2 */
|
||||
#define STEP(n) .long 0x0006441f | (n) << 5` sub r2,r0,r2` movgteu r0,r2
|
||||
.balign 8,,2
|
||||
STEP(31)` STEP(30)` STEP(29)` STEP(28)`
|
||||
STEP(27)` STEP(26)` STEP(25)` STEP(24)`
|
||||
STEP(23)` STEP(22)` STEP(21)` STEP(20)`
|
||||
STEP(19)` STEP(18)` STEP(17)` STEP(16)`
|
||||
STEP(15)` STEP(14)` STEP(13)` STEP(12)`
|
||||
STEP(11)` STEP(10)` STEP(9)` STEP(8)`
|
||||
STEP(7)` STEP(6)` STEP(5)` STEP(4)` STEP(3)` STEP(2)` STEP(1)
|
||||
.L0step:STEP(0)
|
||||
.Lret_a:eor r0,r0,r17 ; restore sign
|
||||
sub r0,r0,r17
|
||||
rts
|
||||
ENDFUNC(__modsi3)
|
106
libgcc/config/epiphany/modsi3.c
Normal file
106
libgcc/config/epiphany/modsi3.c
Normal file
|
@ -0,0 +1,106 @@
|
|||
/* Generic signed 32 bit modulo implementation.
|
||||
Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
This file is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 3, or (at your option) any
|
||||
later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
typedef union { unsigned int i; float f; } fu;
|
||||
|
||||
unsigned int __modsi3 (unsigned int a, unsigned int b);
|
||||
|
||||
unsigned int
|
||||
__modsi3 (unsigned int a, unsigned int b)
|
||||
{
|
||||
unsigned int sign = (int) a >> 31;
|
||||
unsigned int d, t, s0, s1, s2, r0, r1;
|
||||
fu u0, u1, u2, u1b, u2b;
|
||||
|
||||
a = abs (a);
|
||||
b = abs (b);
|
||||
|
||||
if (b > a)
|
||||
goto ret_a;
|
||||
|
||||
/* Compute difference in number of bits in S0. */
|
||||
u0.i = 0x40000000;
|
||||
u1b.i = u2b.i = u0.i;
|
||||
u1.i = a;
|
||||
u2.i = b;
|
||||
u1.i = a | u0.i;
|
||||
t = 0x4b800000 | ((a >> 23) & 0xffff);
|
||||
if (a >> 23)
|
||||
{
|
||||
u1.i = t;
|
||||
u1b.i = 0x4b800000;
|
||||
}
|
||||
u2.i = b | u0.i;
|
||||
t = 0x4b800000 | ((b >> 23) & 0xffff);
|
||||
if (b >> 23)
|
||||
{
|
||||
u2.i = t;
|
||||
u2b.i = 0x4b800000;
|
||||
}
|
||||
u1.f = u1.f - u1b.f;
|
||||
u2.f = u2.f - u2b.f;
|
||||
s1 = u1.i >> 23;
|
||||
s2 = u2.i >> 23;
|
||||
s0 = s1 - s2;
|
||||
|
||||
#define STEP(n) case n: d = b << n; t = a - d; if (t <= a) a = t;
|
||||
switch (s0)
|
||||
{
|
||||
STEP (31)
|
||||
STEP (30)
|
||||
STEP (29)
|
||||
STEP (28)
|
||||
STEP (27)
|
||||
STEP (26)
|
||||
STEP (25)
|
||||
STEP (24)
|
||||
STEP (23)
|
||||
STEP (22)
|
||||
STEP (21)
|
||||
STEP (20)
|
||||
STEP (19)
|
||||
STEP (18)
|
||||
STEP (17)
|
||||
STEP (16)
|
||||
STEP (15)
|
||||
STEP (14)
|
||||
STEP (13)
|
||||
STEP (12)
|
||||
STEP (11)
|
||||
STEP (10)
|
||||
STEP (9)
|
||||
STEP (8)
|
||||
STEP (7)
|
||||
STEP (6)
|
||||
STEP (5)
|
||||
STEP (4)
|
||||
STEP (3)
|
||||
STEP (2)
|
||||
STEP (1)
|
||||
STEP (0)
|
||||
}
|
||||
ret_a:
|
||||
return (a ^ sign) - sign;
|
||||
}
|
39
libgcc/config/epiphany/mulsi3.c
Normal file
39
libgcc/config/epiphany/mulsi3.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
/* Generic 32 bit multiply.
|
||||
Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
This file is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 3, or (at your option) any
|
||||
later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
unsigned int
|
||||
__mulsi3 (unsigned int a, unsigned int b)
|
||||
{
|
||||
unsigned int r = 0;
|
||||
|
||||
while (a)
|
||||
{
|
||||
if (a & 1)
|
||||
r += b;
|
||||
a >>= 1;
|
||||
b <<= 1;
|
||||
}
|
||||
return r;
|
||||
}
|
1
libgcc/config/epiphany/t-custom-eqsf
Normal file
1
libgcc/config/epiphany/t-custom-eqsf
Normal file
|
@ -0,0 +1 @@
|
|||
FPBIT_FUNCS := $(filter-out _eq_sf,$(FPBIT_FUNCS))
|
35
libgcc/config/epiphany/t-epiphany
Normal file
35
libgcc/config/epiphany/t-epiphany
Normal file
|
@ -0,0 +1,35 @@
|
|||
# Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003,
|
||||
# 2004, 2009, 2010, 2011 Free Software Foundation, Inc.
|
||||
# Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
#
|
||||
# This file is part of GCC.
|
||||
#
|
||||
# GCC is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GCC is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GCC; see the file COPYING3. If not see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
LIB2ADD_ST = $(srcdir)/config/epiphany/modsi3-float.S \
|
||||
$(srcdir)/config/epiphany/divsi3-float.S \
|
||||
$(srcdir)/config/epiphany/udivsi3-float.S \
|
||||
$(srcdir)/config/epiphany/umodsi3-float.S \
|
||||
$(srcdir)/config/epiphany/ieee-754/eqsf2.S \
|
||||
$(srcdir)/config/epiphany/ieee-754/gtesf2.S \
|
||||
$(srcdir)/config/epiphany/ieee-754/ordsf2.S \
|
||||
$(srcdir)/config/epiphany/ieee-754/uneqsf2.S \
|
||||
$(srcdir)/config/epiphany/ieee-754/fast_div.S
|
||||
|
||||
# .init/.fini section routines
|
||||
|
||||
crtint.o crtrunc.o crtm1reg-r43.o crtm1reg-r63.o : \
|
||||
%.o: $(srcdir)/config/epiphany/%.S $(GCC_PASSES) $(CONFIG_H)
|
||||
$(crt_compile) -c -x assembler-with-cpp $<
|
83
libgcc/config/epiphany/udivsi3-float.S
Normal file
83
libgcc/config/epiphany/udivsi3-float.S
Normal file
|
@ -0,0 +1,83 @@
|
|||
/* Unsigned 32 bit division optimized for Epiphany.
|
||||
Copyright (C) 2009, 2011 Free Software Foundation, Inc.
|
||||
Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
This file is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 3, or (at your option) any
|
||||
later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "epiphany-asm.h"
|
||||
|
||||
FSTAB (__udivsi3,T_UINT)
|
||||
.global SYM(__udivsi3)
|
||||
.balign 4
|
||||
HIDDEN_FUNC(__udivsi3)
|
||||
SYM(__udivsi3):
|
||||
sub TMP0,r0,r1
|
||||
bltu .Lret0
|
||||
float TMP2,r0
|
||||
mov TMP1,%low(0xb0800000) ; ??? this would be faster with small data
|
||||
float TMP3,r1
|
||||
movt TMP1,%high(0xb0800000)
|
||||
asr TMP0,r0,8
|
||||
sub TMP0,TMP0,TMP1
|
||||
movt TMP1,%high(0x00810000)
|
||||
movgteu TMP2,TMP0
|
||||
bblt .Lret1
|
||||
sub TMP2,TMP2,TMP1
|
||||
sub TMP2,TMP2,TMP3
|
||||
mov TMP3,0
|
||||
movltu TMP2,TMP3
|
||||
lsr TMP2,TMP2,23
|
||||
lsl r1,r1,TMP2
|
||||
mov TMP0,1
|
||||
lsl TMP0,TMP0,TMP2
|
||||
sub r0,r0,r1
|
||||
bltu .Ladd_back
|
||||
add TMP3,TMP3,TMP0
|
||||
sub r0,r0,r1
|
||||
bltu .Ladd_back
|
||||
.Lsub_loop:; More than two iterations are rare, so it makes sense to leave
|
||||
; this label here to reduce average branch penalties.
|
||||
add TMP3,TMP3,TMP0
|
||||
sub r0,r0,r1
|
||||
bgteu .Lsub_loop
|
||||
.Ladd_back:
|
||||
add r0,r0,r1
|
||||
sub TMP1,r1,1
|
||||
mov r1,%low(.L0step)
|
||||
movt r1,%high(.L0step)
|
||||
lsl TMP2,TMP2,3
|
||||
sub r1,r1,TMP2
|
||||
jr r1
|
||||
.rep 30
|
||||
lsl r0,r0,1
|
||||
sub.l r1,r0,TMP1
|
||||
movgteu r0,r1
|
||||
.endr
|
||||
.L0step:sub r1,TMP0,1 ; mask result bits from steps ...
|
||||
and r0,r0,r1
|
||||
orr r0,r0,TMP3 ; ... and combine with first bits.
|
||||
rts
|
||||
.Lret0: mov r0,0
|
||||
rts
|
||||
.Lret1: mov r0,1
|
||||
rts
|
||||
ENDFUNC(__udivsi3)
|
125
libgcc/config/epiphany/udivsi3-float.c
Normal file
125
libgcc/config/epiphany/udivsi3-float.c
Normal file
|
@ -0,0 +1,125 @@
|
|||
/* Generic unsigned 32 bit division implementation.
|
||||
Copyright (C) 2009, 2011 Free Software Foundation, Inc.
|
||||
Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
This file is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 3, or (at your option) any
|
||||
later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
typedef union { unsigned int i; float f; } fu;
|
||||
|
||||
unsigned int __udivsi3 (unsigned int a, unsigned int b);
|
||||
|
||||
unsigned int
|
||||
__udivsi3 (unsigned int a, unsigned int b)
|
||||
{
|
||||
unsigned int d, t, s0, s1, s2, r0, r1;
|
||||
fu u0, u1, u2, u1b, u2b;
|
||||
|
||||
if (b > a)
|
||||
return 0;
|
||||
if ((int) b < 0)
|
||||
return 1;
|
||||
|
||||
/* Assuming B is nonzero, compute S0 such that 0 <= S0,
|
||||
(B << S0+1) does not overflow,
|
||||
A < 4.01 * (B << S0), with S0 choosen as small as possible
|
||||
without taking to much time calculating. */
|
||||
#ifdef CONVERT_UNSIGNED
|
||||
u0.f = a;
|
||||
u1.f = b;
|
||||
#else /* !CONVERT_UNSIGNED */
|
||||
u0.f = (int) a;
|
||||
u1.f = (int) b;
|
||||
#ifdef CONCISE
|
||||
if (a < 0)
|
||||
u0.i = (a >> 8) - 0x00800000 + 0x3f800000 + (31 << 23);
|
||||
#else /* To use flag seting / cmove, this can be written as: */
|
||||
{
|
||||
unsigned c = 0xff800000 - 0x4f000000;
|
||||
t = (int)a >> 8;
|
||||
if (t >= c)
|
||||
u0.i = (t - c);
|
||||
}
|
||||
#endif
|
||||
#endif /* !CONVERT_UNSIGNED */
|
||||
s0 = u0.i + 1 /* Compensate for rounding errors. */
|
||||
- 0x00800000 /* adjust by one */ ;
|
||||
s0 = s0 - u1.i;
|
||||
s0 = (int)s0 >= 0 ? s0 : 0;
|
||||
s0 >>= 23;
|
||||
|
||||
b <<= s0;
|
||||
r1 = 0;
|
||||
|
||||
r0 = 1 << s0;
|
||||
a = ((t=a) - b);
|
||||
if (a <= t)
|
||||
{
|
||||
r1 += r0;
|
||||
a = ((t=a) - b);
|
||||
if (a <= t)
|
||||
do {
|
||||
r1 += r0;
|
||||
a = ((t=a) - b);
|
||||
} while (a <= t);
|
||||
}
|
||||
a += b;
|
||||
d = b - 1;
|
||||
|
||||
#define STEP(n) case n: a += a; t = a - d; if (t <= a) a = t;
|
||||
switch (s0)
|
||||
{
|
||||
STEP (31)
|
||||
STEP (30)
|
||||
STEP (29)
|
||||
STEP (28)
|
||||
STEP (27)
|
||||
STEP (26)
|
||||
STEP (25)
|
||||
STEP (24)
|
||||
STEP (23)
|
||||
STEP (22)
|
||||
STEP (21)
|
||||
STEP (20)
|
||||
STEP (19)
|
||||
STEP (18)
|
||||
STEP (17)
|
||||
STEP (16)
|
||||
STEP (15)
|
||||
STEP (14)
|
||||
STEP (13)
|
||||
STEP (12)
|
||||
STEP (11)
|
||||
STEP (10)
|
||||
STEP (9)
|
||||
STEP (8)
|
||||
STEP (7)
|
||||
STEP (6)
|
||||
STEP (5)
|
||||
STEP (4)
|
||||
STEP (3)
|
||||
STEP (2)
|
||||
STEP (1)
|
||||
case 0: ;
|
||||
}
|
||||
r0 = r1 | (r0-1 & a);
|
||||
return r0;
|
||||
}
|
85
libgcc/config/epiphany/udivsi3.S
Normal file
85
libgcc/config/epiphany/udivsi3.S
Normal file
|
@ -0,0 +1,85 @@
|
|||
/* Unsigned 32 bit division optimized for Epiphany.
|
||||
Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
This file is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 3, or (at your option) any
|
||||
later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "epiphany-asm.h"
|
||||
|
||||
FSTAB (__udivsi3,T_UINT)
|
||||
.global SYM(__udivsi3)
|
||||
.balign 4
|
||||
HIDDEN_FUNC(__udivsi3)
|
||||
SYM(__udivsi3):
|
||||
sub r3,r0,r1
|
||||
bltu .Lret0
|
||||
mov r3,0x95
|
||||
lsl r12,r3,23 ; 0x4a800000
|
||||
lsl r3,r3,30 ; 0x40000000
|
||||
orr r16,r0,r3
|
||||
orr r2,r1,r3
|
||||
fsub r16,r16,r3
|
||||
fsub r2,r2,r3
|
||||
lsr r3,r1,21
|
||||
lsr r17,r0,21
|
||||
movt r17,0x4a80
|
||||
fsub r17,r17,r12
|
||||
movt r3,0x4a80
|
||||
fsub r3,r3,r12
|
||||
mov r12,%low(.L0step)
|
||||
movt r12,%high(.L0step)
|
||||
mov r21,1
|
||||
movne r16,r17
|
||||
lsr r17,r1,21
|
||||
movne r2,r3
|
||||
lsr r3,r16,23 ; must mask lower bits of r2 in case op0 was ..
|
||||
lsr r2,r2,23 ; .. shifted and op1 was not.
|
||||
sub r3,r3,r2 ; calculate bit number difference.
|
||||
lsl r1,r1,r3
|
||||
lsr r16,r1,1
|
||||
lsl r2,r21,r3
|
||||
lsl r3,r3,3
|
||||
sub r12,r12,r3
|
||||
sub r3,r0,r1
|
||||
movltu r3,r0
|
||||
mov r0,0
|
||||
movgteu r0,r2
|
||||
lsr r2,r2,1
|
||||
add r17,r2,r0
|
||||
sub r1,r3,r16
|
||||
movgteu r3,r1
|
||||
movgteu r0,r17
|
||||
sub r16,r16,1
|
||||
jr r12
|
||||
.rep 30
|
||||
lsl r3,r3,1
|
||||
sub r1,r3,r16
|
||||
movgteu r3,r1
|
||||
.endr
|
||||
sub r2,r2,1 ; mask result bits from steps ...
|
||||
and r3,r3,r2
|
||||
orr r0,r0,r3 ; ... and combine with first bits.
|
||||
nop
|
||||
.L0step:rts
|
||||
.Lret0: mov r0,0
|
||||
rts
|
||||
ENDFUNC(__udivsi3)
|
114
libgcc/config/epiphany/udivsi3.c
Normal file
114
libgcc/config/epiphany/udivsi3.c
Normal file
|
@ -0,0 +1,114 @@
|
|||
/* Generic unsigned 32 bit division implementation.
|
||||
Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
This file is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 3, or (at your option) any
|
||||
later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
typedef union { unsigned int i; float f; } fu;
|
||||
|
||||
unsigned int __udivsi3 (unsigned int a, unsigned int b);
|
||||
|
||||
unsigned int
|
||||
__udivsi3 (unsigned int a, unsigned int b)
|
||||
{
|
||||
unsigned int d, t, s0, s1, s2, r0, r1;
|
||||
fu u0, u1, u2, u1b, u2b;
|
||||
|
||||
if (b > a)
|
||||
return 0;
|
||||
|
||||
/* Compute difference in number of bits in S0. */
|
||||
u0.i = 0x40000000;
|
||||
u1b.i = u2b.i = u0.i;
|
||||
u1.i = a;
|
||||
u2.i = b;
|
||||
u1.i = a | u0.i;
|
||||
t = 0x4b800000 | ((a >> 23) & 0xffff);
|
||||
if (a >> 23)
|
||||
{
|
||||
u1.i = t;
|
||||
u1b.i = 0x4b800000;
|
||||
}
|
||||
u2.i = b | u0.i;
|
||||
t = 0x4b800000 | ((b >> 23) & 0xffff);
|
||||
if (b >> 23)
|
||||
{
|
||||
u2.i = t;
|
||||
u2b.i = 0x4b800000;
|
||||
}
|
||||
u1.f = u1.f - u1b.f;
|
||||
u2.f = u2.f - u2b.f;
|
||||
s1 = u1.i >> 23;
|
||||
s2 = u2.i >> 23;
|
||||
s0 = s1 - s2;
|
||||
|
||||
b <<= s0;
|
||||
d = b - 1;
|
||||
|
||||
r0 = 1 << s0;
|
||||
r1 = 0;
|
||||
t = a - b;
|
||||
if (t <= a)
|
||||
{
|
||||
a = t;
|
||||
r1 = r0;
|
||||
}
|
||||
|
||||
#define STEP(n) case n: a += a; t = a - d; if (t <= a) a = t;
|
||||
switch (s0)
|
||||
{
|
||||
STEP (31)
|
||||
STEP (30)
|
||||
STEP (29)
|
||||
STEP (28)
|
||||
STEP (27)
|
||||
STEP (26)
|
||||
STEP (25)
|
||||
STEP (24)
|
||||
STEP (23)
|
||||
STEP (22)
|
||||
STEP (21)
|
||||
STEP (20)
|
||||
STEP (19)
|
||||
STEP (18)
|
||||
STEP (17)
|
||||
STEP (16)
|
||||
STEP (15)
|
||||
STEP (14)
|
||||
STEP (13)
|
||||
STEP (12)
|
||||
STEP (11)
|
||||
STEP (10)
|
||||
STEP (9)
|
||||
STEP (8)
|
||||
STEP (7)
|
||||
STEP (6)
|
||||
STEP (5)
|
||||
STEP (4)
|
||||
STEP (3)
|
||||
STEP (2)
|
||||
STEP (1)
|
||||
case 0: ;
|
||||
}
|
||||
r0 = r1 | (r0-1 & a);
|
||||
return r0;
|
||||
}
|
63
libgcc/config/epiphany/umodsi3-float.S
Normal file
63
libgcc/config/epiphany/umodsi3-float.S
Normal file
|
@ -0,0 +1,63 @@
|
|||
/* Unsigned 32 bit division optimized for Epiphany.
|
||||
Copyright (C) 2009, 2011 Free Software Foundation, Inc.
|
||||
Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
This file is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 3, or (at your option) any
|
||||
later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "epiphany-asm.h"
|
||||
|
||||
/* Because we handle a divident with bit 31 set with truncating integer
|
||||
arithmetic, there is no rounding-related overflow. */
|
||||
FSTAB (__umodsi3,T_UINT)
|
||||
.global SYM(__umodsi3)
|
||||
.balign 4
|
||||
HIDDEN_FUNC(__umodsi3)
|
||||
SYM(__umodsi3):
|
||||
float r2,r0
|
||||
mov TMP1,%low(0xb0800000) ; ??? this would be faster with small data
|
||||
float TMP2,r1
|
||||
movt TMP1,%high(0xb0800000)
|
||||
asr TMP0,r0,8
|
||||
sub TMP0,TMP0,TMP1
|
||||
mov TMP1,%low(.L0step)
|
||||
movgteu r2,TMP0
|
||||
sub r2,r2,TMP2
|
||||
blteu .L0step
|
||||
asr r2,r2,23
|
||||
movt TMP1,%high(.L0step)
|
||||
lsl TMP2,r2,3
|
||||
lsl r2,r1,r2` sub r2,r0,r2` movgteu r0,r2 ; STEP(r2)
|
||||
sub r2,TMP1,TMP2
|
||||
jr r2
|
||||
#define STEP(n) lsl.l r2,r1,n` sub r2,r0,r2` movgteu r0,r2
|
||||
.balign 8,,2
|
||||
STEP(31)` STEP(30)` STEP(29)` STEP(28)`
|
||||
STEP(27)` STEP(26)` STEP(25)` STEP(24)`
|
||||
STEP(23)` STEP(22)` STEP(21)` STEP(20)`
|
||||
STEP(19)` STEP(18)` STEP(17)` STEP(16)`
|
||||
STEP(15)` STEP(14)` STEP(13)` STEP(12)`
|
||||
STEP(11)` STEP(10)` STEP(9)` STEP(8)`
|
||||
STEP(7)` STEP(6)` STEP(5)` STEP(4)` STEP(3)` STEP(2)` STEP(1)
|
||||
.L0step:STEP(0)
|
||||
.Lret_r0:
|
||||
rts
|
||||
ENDFUNC(__umodsi3)
|
70
libgcc/config/epiphany/umodsi3.S
Normal file
70
libgcc/config/epiphany/umodsi3.S
Normal file
|
@ -0,0 +1,70 @@
|
|||
/* Unsigned 32 bit modulo optimized for Epiphany.
|
||||
Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
This file is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 3, or (at your option) any
|
||||
later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "epiphany-asm.h"
|
||||
|
||||
FSTAB (__umodsi3,T_UINT)
|
||||
.global SYM(__umodsi3)
|
||||
.balign 4
|
||||
HIDDEN_FUNC(__umodsi3)
|
||||
SYM(__umodsi3):
|
||||
mov r2,5
|
||||
lsl r2,r2,29 ; 0xa0000000
|
||||
orr r3,r2,r0
|
||||
lsr r15,r0,16
|
||||
movt r15,0xa800
|
||||
movne r3,r15
|
||||
lsr r16,r2,2 ; 0x28000000
|
||||
and r15,r3,r16
|
||||
fadd r12,r3,r15
|
||||
orr r3,r2,r1
|
||||
lsr r2,r1,16
|
||||
movt r2,0xa800
|
||||
movne r3,r2
|
||||
and r2,r16,r3
|
||||
fadd r3,r3,r2
|
||||
sub r2,r0,r1
|
||||
bltu .Lret_a
|
||||
lsr r12,r12,23
|
||||
mov r2,%low(.L0step)
|
||||
movt r2,%high(.L0step)
|
||||
lsr r3,r3,23
|
||||
sub r3,r12,r3 ; calculate bit number difference.
|
||||
lsl r3,r3,3
|
||||
sub r2,r2,r3
|
||||
jr r2
|
||||
/* lsl_l r2,r1,n` sub r2,r0,r2` movgteu r0,r2 */
|
||||
#define STEP(n) .long 0x0006441f | (n) << 5` sub r2,r0,r2` movgteu r0,r2
|
||||
.balign 8,,2
|
||||
STEP(31)` STEP(30)` STEP(29)` STEP(28)`
|
||||
STEP(27)` STEP(26)` STEP(25)` STEP(24)`
|
||||
STEP(23)` STEP(22)` STEP(21)` STEP(20)`
|
||||
STEP(19)` STEP(18)` STEP(17)` STEP(16)`
|
||||
STEP(15)` STEP(14)` STEP(13)` STEP(12)`
|
||||
STEP(11)` STEP(10)` STEP(9)` STEP(8)`
|
||||
STEP(7)` STEP(6)` STEP(5)` STEP(4)` STEP(3)` STEP(2)` STEP(1)
|
||||
.L0step:STEP(0)
|
||||
.Lret_a:rts
|
||||
ENDFUNC(__umodsi3)
|
101
libgcc/config/epiphany/umodsi3.c
Normal file
101
libgcc/config/epiphany/umodsi3.c
Normal file
|
@ -0,0 +1,101 @@
|
|||
/* Generic unsigned 32 bit modulo implementation.
|
||||
Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
Contributed by Embecosm on behalf of Adapteva, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
This file is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 3, or (at your option) any
|
||||
later version.
|
||||
|
||||
This file is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
typedef union { unsigned int i; float f; } fu;
|
||||
|
||||
unsigned int __umodsi3 (unsigned int a, unsigned int b);
|
||||
|
||||
unsigned int
|
||||
__umodsi3 (unsigned int a, unsigned int b)
|
||||
{
|
||||
unsigned int d, t, s0, s1, s2, r0, r1;
|
||||
fu u0, u1, u2, u1b, u2b;
|
||||
|
||||
if (b > a)
|
||||
return a;
|
||||
|
||||
/* Compute difference in number of bits in S0. */
|
||||
u0.i = 0x40000000;
|
||||
u1b.i = u2b.i = u0.i;
|
||||
u1.i = a;
|
||||
u2.i = b;
|
||||
u1.i = a | u0.i;
|
||||
t = 0x4b800000 | ((a >> 23) & 0xffff);
|
||||
if (a >> 23)
|
||||
{
|
||||
u1.i = t;
|
||||
u1b.i = 0x4b800000;
|
||||
}
|
||||
u2.i = b | u0.i;
|
||||
t = 0x4b800000 | ((b >> 23) & 0xffff);
|
||||
if (b >> 23)
|
||||
{
|
||||
u2.i = t;
|
||||
u2b.i = 0x4b800000;
|
||||
}
|
||||
u1.f = u1.f - u1b.f;
|
||||
u2.f = u2.f - u2b.f;
|
||||
s1 = u1.i >> 23;
|
||||
s2 = u2.i >> 23;
|
||||
s0 = s1 - s2;
|
||||
|
||||
#define STEP(n) case n: d = b << n; t = a - d; if (t <= a) a = t;
|
||||
switch (s0)
|
||||
{
|
||||
STEP (31)
|
||||
STEP (30)
|
||||
STEP (29)
|
||||
STEP (28)
|
||||
STEP (27)
|
||||
STEP (26)
|
||||
STEP (25)
|
||||
STEP (24)
|
||||
STEP (23)
|
||||
STEP (22)
|
||||
STEP (21)
|
||||
STEP (20)
|
||||
STEP (19)
|
||||
STEP (18)
|
||||
STEP (17)
|
||||
STEP (16)
|
||||
STEP (15)
|
||||
STEP (14)
|
||||
STEP (13)
|
||||
STEP (12)
|
||||
STEP (11)
|
||||
STEP (10)
|
||||
STEP (9)
|
||||
STEP (8)
|
||||
STEP (7)
|
||||
STEP (6)
|
||||
STEP (5)
|
||||
STEP (4)
|
||||
STEP (3)
|
||||
STEP (2)
|
||||
STEP (1)
|
||||
STEP (0)
|
||||
}
|
||||
return a;
|
||||
}
|
Loading…
Add table
Reference in a new issue