diff options
Diffstat (limited to 'gcc/config')
57 files changed, 2137 insertions, 682 deletions
diff --git a/gcc/config/alpha/linux.h b/gcc/config/alpha/linux.h index 86b6594f45b..a1881c8168b 100644 --- a/gcc/config/alpha/linux.h +++ b/gcc/config/alpha/linux.h @@ -61,7 +61,11 @@ along with GCC; see the file COPYING3. If not see #undef WCHAR_TYPE #define WCHAR_TYPE "int" +#ifdef SINGLE_LIBC +#define OPTION_GLIBC (DEFAULT_LIBC == LIBC_GLIBC) +#else #define OPTION_GLIBC (linux_libc == LIBC_GLIBC) +#endif /* Determine whether the entire c99 runtime is present in the runtime library. */ diff --git a/gcc/config/arm/arm-cores.def b/gcc/config/arm/arm-cores.def index 645f2817b93..e06bf65bc51 100644 --- a/gcc/config/arm/arm-cores.def +++ b/gcc/config/arm/arm-cores.def @@ -74,6 +74,8 @@ ARM_CORE("strongarm", strongarm, 4, FL_MODE26 | FL_LDSCHED | FL ARM_CORE("strongarm110", strongarm110, 4, FL_MODE26 | FL_LDSCHED | FL_STRONG, fastmul) ARM_CORE("strongarm1100", strongarm1100, 4, FL_MODE26 | FL_LDSCHED | FL_STRONG, fastmul) ARM_CORE("strongarm1110", strongarm1110, 4, FL_MODE26 | FL_LDSCHED | FL_STRONG, fastmul) +ARM_CORE("fa526", fa526, 4, FL_LDSCHED, fastmul) +ARM_CORE("fa626", fa626, 4, FL_LDSCHED, fastmul) /* V4T Architecture Processors */ ARM_CORE("arm7tdmi", arm7tdmi, 4T, FL_CO_PROC , fastmul) @@ -104,6 +106,10 @@ ARM_CORE("arm1022e", arm1022e, 5TE, FL_LDSCHED, fastmul) ARM_CORE("xscale", xscale, 5TE, FL_LDSCHED | FL_STRONG | FL_XSCALE, xscale) ARM_CORE("iwmmxt", iwmmxt, 5TE, FL_LDSCHED | FL_STRONG | FL_XSCALE | FL_IWMMXT, xscale) ARM_CORE("iwmmxt2", iwmmxt2, 5TE, FL_LDSCHED | FL_STRONG | FL_XSCALE | FL_IWMMXT, xscale) +ARM_CORE("fa606te", fa606te, 5TE, FL_LDSCHED, 9e) +ARM_CORE("fa626te", fa626te, 5TE, FL_LDSCHED, 9e) +ARM_CORE("fmp626", fmp626, 5TE, FL_LDSCHED, 9e) +ARM_CORE("fa726te", fa726te, 5TE, FL_LDSCHED, fa726te) /* V5TEJ Architecture Processors */ ARM_CORE("arm926ej-s", arm926ejs, 5TEJ, FL_LDSCHED, 9e) diff --git a/gcc/config/arm/arm-tune.md b/gcc/config/arm/arm-tune.md index eb1dde5c145..9b664e7e66b 100644 --- a/gcc/config/arm/arm-tune.md +++ b/gcc/config/arm/arm-tune.md @@ -1,5 +1,5 @@ ;; -*- buffer-read-only: t -*- ;; Generated automatically by gentune.sh from arm-cores.def (define_attr "tune" - "arm2,arm250,arm3,arm6,arm60,arm600,arm610,arm620,arm7,arm7d,arm7di,arm70,arm700,arm700i,arm710,arm720,arm710c,arm7100,arm7500,arm7500fe,arm7m,arm7dm,arm7dmi,arm8,arm810,strongarm,strongarm110,strongarm1100,strongarm1110,arm7tdmi,arm7tdmis,arm710t,arm720t,arm740t,arm9,arm9tdmi,arm920,arm920t,arm922t,arm940t,ep9312,arm10tdmi,arm1020t,arm9e,arm946es,arm966es,arm968es,arm10e,arm1020e,arm1022e,xscale,iwmmxt,iwmmxt2,arm926ejs,arm1026ejs,arm1136js,arm1136jfs,arm1176jzs,arm1176jzfs,mpcorenovfp,mpcore,arm1156t2s,arm1156t2fs,cortexa5,cortexa8,cortexa9,cortexa15,cortexr4,cortexr4f,cortexm4,cortexm3,cortexm1,cortexm0" + "arm2,arm250,arm3,arm6,arm60,arm600,arm610,arm620,arm7,arm7d,arm7di,arm70,arm700,arm700i,arm710,arm720,arm710c,arm7100,arm7500,arm7500fe,arm7m,arm7dm,arm7dmi,arm8,arm810,strongarm,strongarm110,strongarm1100,strongarm1110,fa526,fa626,arm7tdmi,arm7tdmis,arm710t,arm720t,arm740t,arm9,arm9tdmi,arm920,arm920t,arm922t,arm940t,ep9312,arm10tdmi,arm1020t,arm9e,arm946es,arm966es,arm968es,arm10e,arm1020e,arm1022e,xscale,iwmmxt,iwmmxt2,fa606te,fa626te,fmp626,fa726te,arm926ejs,arm1026ejs,arm1136js,arm1136jfs,arm1176jzs,arm1176jzfs,mpcorenovfp,mpcore,arm1156t2s,arm1156t2fs,cortexa5,cortexa8,cortexa9,cortexa15,cortexr4,cortexr4f,cortexm4,cortexm3,cortexm1,cortexm0" (const (symbol_ref "((enum attr_tune) arm_tune)"))) diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 21fc2565968..be7bb060bed 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -240,6 +240,7 @@ static rtx arm_trampoline_adjust_address (rtx); static rtx arm_pic_static_addr (rtx orig, rtx reg); static bool cortex_a9_sched_adjust_cost (rtx, rtx, rtx, int *); static bool xscale_sched_adjust_cost (rtx, rtx, rtx, int *); +static bool fa726te_sched_adjust_cost (rtx, rtx, rtx, int *); static enum machine_mode arm_preferred_simd_mode (enum machine_mode); static bool arm_class_likely_spilled_p (reg_class_t); static bool arm_vector_alignment_reachable (const_tree type, bool is_packed); @@ -886,6 +887,14 @@ const struct tune_params arm_cortex_a9_tune = ARM_PREFETCH_BENEFICIAL(4,32,32) }; +const struct tune_params arm_fa726te_tune = +{ + arm_9e_rtx_costs, + fa726te_sched_adjust_cost, + 1, + ARM_PREFETCH_NOT_BENEFICIAL +}; + /* Not all of these give usefully different compilation alternatives, but there is no simple way of generalizing them. */ @@ -5647,8 +5656,8 @@ arm_legitimate_index_p (enum machine_mode mode, rtx index, RTX_CODE outer, /* Standard coprocessor addressing modes. */ if (TARGET_HARD_FLOAT - && (TARGET_FPA || TARGET_MAVERICK) - && (GET_MODE_CLASS (mode) == MODE_FLOAT + && (TARGET_VFP || TARGET_FPA || TARGET_MAVERICK) + && (mode == SFmode || mode == DFmode || (TARGET_MAVERICK && mode == DImode))) return (code == CONST_INT && INTVAL (index) < 1024 && INTVAL (index) > -1024 @@ -5768,8 +5777,8 @@ thumb2_legitimate_index_p (enum machine_mode mode, rtx index, int strict_p) /* ??? Combine arm and thumb2 coprocessor addressing modes. */ /* Standard coprocessor addressing modes. */ if (TARGET_HARD_FLOAT - && (TARGET_FPA || TARGET_MAVERICK) - && (GET_MODE_CLASS (mode) == MODE_FLOAT + && (TARGET_VFP || TARGET_FPA || TARGET_MAVERICK) + && (mode == SFmode || mode == DFmode || (TARGET_MAVERICK && mode == DImode))) return (code == CONST_INT && INTVAL (index) < 1024 && INTVAL (index) > -1024 @@ -7996,6 +8005,36 @@ cortex_a9_sched_adjust_cost (rtx insn, rtx link, rtx dep, int * cost) return true; } +/* Adjust cost hook for FA726TE. */ +static bool +fa726te_sched_adjust_cost (rtx insn, rtx link, rtx dep, int * cost) +{ + /* For FA726TE, true dependency on CPSR (i.e. set cond followed by predicated) + have penalty of 3. */ + if (REG_NOTE_KIND (link) == REG_DEP_TRUE + && recog_memoized (insn) >= 0 + && recog_memoized (dep) >= 0 + && get_attr_conds (dep) == CONDS_SET) + { + /* Use of carry (e.g. 64-bit arithmetic) in ALU: 3-cycle latency. */ + if (get_attr_conds (insn) == CONDS_USE + && get_attr_type (insn) != TYPE_BRANCH) + { + *cost = 3; + return false; + } + + if (GET_CODE (PATTERN (insn)) == COND_EXEC + || get_attr_conds (insn) == CONDS_USE) + { + *cost = 0; + return false; + } + } + + return true; +} + /* This function implements the target macro TARGET_SCHED_ADJUST_COST. It corrects the value of COST based on the relationship between INSN and DEP through the dependence LINK. It returns the new @@ -10602,12 +10641,14 @@ arm_select_cc_mode (enum rtx_code op, rtx x, rtx y) /* Alternate canonicalizations of the above. These are somewhat cleaner. */ if (GET_CODE (x) == AND + && (op == EQ || op == NE) && COMPARISON_P (XEXP (x, 0)) && COMPARISON_P (XEXP (x, 1))) return arm_select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1), DOM_CC_X_AND_Y); if (GET_CODE (x) == IOR + && (op == EQ || op == NE) && COMPARISON_P (XEXP (x, 0)) && COMPARISON_P (XEXP (x, 1))) return arm_select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1), @@ -22838,6 +22879,7 @@ arm_issue_rate (void) case cortexa5: case cortexa8: case cortexa9: + case fa726te: return 2; default: diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 889b86ff764..5a9a914da4d 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -498,7 +498,7 @@ (define_attr "generic_sched" "yes,no" (const (if_then_else - (ior (eq_attr "tune" "arm926ejs,arm1020e,arm1026ejs,arm1136js,arm1136jfs,cortexa5,cortexa8,cortexa9,cortexm4") + (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,arm926ejs,arm1020e,arm1026ejs,arm1136js,arm1136jfs,cortexa5,cortexa8,cortexa9,cortexm4") (eq_attr "tune_cortexr4" "yes")) (const_string "no") (const_string "yes")))) @@ -516,6 +516,11 @@ (include "arm1020e.md") (include "arm1026ejs.md") (include "arm1136jfs.md") +(include "fa526.md") +(include "fa606te.md") +(include "fa626te.md") +(include "fmp626.md") +(include "fa726te.md") (include "cortex-a5.md") (include "cortex-a8.md") (include "cortex-a9.md") @@ -1793,11 +1798,11 @@ (define_insn "maddhisi4" [(set (match_operand:SI 0 "s_register_operand" "=r") - (plus:SI (match_operand:SI 3 "s_register_operand" "r") - (mult:SI (sign_extend:SI - (match_operand:HI 1 "s_register_operand" "%r")) + (plus:SI (mult:SI (sign_extend:SI + (match_operand:HI 1 "s_register_operand" "r")) (sign_extend:SI - (match_operand:HI 2 "s_register_operand" "r")))))] + (match_operand:HI 2 "s_register_operand" "r"))) + (match_operand:SI 3 "s_register_operand" "r")))] "TARGET_DSP_MULTIPLY" "smlabb%?\\t%0, %1, %2, %3" [(set_attr "insn" "smlaxy") @@ -1807,11 +1812,11 @@ (define_insn "*maddhidi4" [(set (match_operand:DI 0 "s_register_operand" "=r") (plus:DI - (match_operand:DI 3 "s_register_operand" "0") (mult:DI (sign_extend:DI - (match_operand:HI 1 "s_register_operand" "%r")) + (match_operand:HI 1 "s_register_operand" "r")) (sign_extend:DI - (match_operand:HI 2 "s_register_operand" "r")))))] + (match_operand:HI 2 "s_register_operand" "r"))) + (match_operand:DI 3 "s_register_operand" "0")))] "TARGET_DSP_MULTIPLY" "smlalbb%?\\t%Q0, %R0, %1, %2" [(set_attr "insn" "smlalxy") @@ -4137,8 +4142,8 @@ }) (define_split - [(set (match_operand:SI 0 "register_operand" "") - (zero_extend:SI (match_operand:HI 1 "register_operand" "")))] + [(set (match_operand:SI 0 "s_register_operand" "") + (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))] "!TARGET_THUMB2 && !arm_arch6" [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16))) (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))] @@ -4244,8 +4249,8 @@ }) (define_split - [(set (match_operand:SI 0 "register_operand" "") - (zero_extend:SI (match_operand:QI 1 "register_operand" "")))] + [(set (match_operand:SI 0 "s_register_operand" "") + (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))] "!arm_arch6" [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24))) (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))] diff --git a/gcc/config/arm/bpabi.h b/gcc/config/arm/bpabi.h index d4b65deeed2..7b5ee623107 100644 --- a/gcc/config/arm/bpabi.h +++ b/gcc/config/arm/bpabi.h @@ -52,13 +52,16 @@ /* The BPABI integer comparison routines return { -1, 0, 1 }. */ #define TARGET_LIB_INT_CMP_BIASED !TARGET_BPABI -#define TARGET_FIX_V4BX_SPEC " %{mcpu=arm8|mcpu=arm810|mcpu=strongarm*|march=armv4:--fix-v4bx}" +#define TARGET_FIX_V4BX_SPEC " %{mcpu=arm8|mcpu=arm810|mcpu=strongarm*"\ + "|march=armv4|mcpu=fa526|mcpu=fa626:--fix-v4bx}" -#define BE8_LINK_SPEC " %{mbig-endian:%{march=armv7-a|mcpu=cortex-a5|mcpu=cortex-a8|mcpu=cortex-a9|mcpu=cortex-a15:%{!r:--be8}}}" +#define BE8_LINK_SPEC " %{mbig-endian:%{march=armv7-a|mcpu=cortex-a5"\ + "|mcpu=cortex-a8|mcpu=cortex-a9|mcpu=cortex-a15:%{!r:--be8}}}" /* Tell the assembler to build BPABI binaries. */ #undef SUBTARGET_EXTRA_ASM_SPEC -#define SUBTARGET_EXTRA_ASM_SPEC "%{mabi=apcs-gnu|mabi=atpcs:-meabi=gnu;:-meabi=5}" TARGET_FIX_V4BX_SPEC +#define SUBTARGET_EXTRA_ASM_SPEC \ + "%{mabi=apcs-gnu|mabi=atpcs:-meabi=gnu;:-meabi=5}" TARGET_FIX_V4BX_SPEC #ifndef SUBTARGET_EXTRA_LINK_SPEC #define SUBTARGET_EXTRA_LINK_SPEC "" diff --git a/gcc/config/arm/fa526.md b/gcc/config/arm/fa526.md new file mode 100644 index 00000000000..42eb9b272fb --- /dev/null +++ b/gcc/config/arm/fa526.md @@ -0,0 +1,161 @@ +;; Faraday FA526 Pipeline Description +;; Copyright (C) 2010 Free Software Foundation, Inc. +;; Written by I-Jui Sung, based on ARM926EJ-S Pipeline Description. + +;; 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/>. */ + +;; These descriptions are based on the information contained in the +;; FA526 Core Design Note, Copyright (c) 2010 Faraday Technology Corp. +;; +;; Modeled pipeline characteristics: +;; LD -> any use: latency = 3 (2 cycle penalty). +;; ALU -> any use: latency = 2 (1 cycle penalty). + +;; This automaton provides a pipeline description for the Faraday +;; FA526 core. +;; +;; The model given here assumes that the condition for all conditional +;; instructions is "true", i.e., that all of the instructions are +;; actually executed. + +(define_automaton "fa526") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Pipelines +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; There is a single pipeline +;; +;; The ALU pipeline has fetch, decode, execute, memory, and +;; write stages. We only need to model the execute, memory and write +;; stages. + +;; S E M W + +(define_cpu_unit "fa526_core" "fa526") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ALU Instructions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; ALU instructions require two cycles to execute, and use the ALU +;; pipeline in each of the three stages. The results are available +;; after the execute stage stage has finished. +;; +;; If the destination register is the PC, the pipelines are stalled +;; for several cycles. That case is not modeled here. + +;; ALU operations +(define_insn_reservation "526_alu_op" 1 + (and (eq_attr "tune" "fa526") + (eq_attr "type" "alu")) + "fa526_core") + +(define_insn_reservation "526_alu_shift_op" 2 + (and (eq_attr "tune" "fa526") + (eq_attr "type" "alu_shift,alu_shift_reg")) + "fa526_core") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Multiplication Instructions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(define_insn_reservation "526_mult1" 2 + (and (eq_attr "tune" "fa526") + (eq_attr "insn" "smlalxy,smulxy,smlaxy,smlalxy")) + "fa526_core") + +(define_insn_reservation "526_mult2" 5 + (and (eq_attr "tune" "fa526") + (eq_attr "insn" "mul,mla,muls,mlas,umull,umlal,smull,smlal,umulls,\ + umlals,smulls,smlals,smlawx")) + "fa526_core*4") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Load/Store Instructions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; The models for load/store instructions do not accurately describe +;; the difference between operations with a base register writeback +;; (such as "ldm!"). These models assume that all memory references +;; hit in dcache. + +(define_insn_reservation "526_load1_op" 3 + (and (eq_attr "tune" "fa526") + (eq_attr "type" "load1,load_byte")) + "fa526_core") + +(define_insn_reservation "526_load2_op" 4 + (and (eq_attr "tune" "fa526") + (eq_attr "type" "load2")) + "fa526_core*2") + +(define_insn_reservation "526_load3_op" 5 + (and (eq_attr "tune" "fa526") + (eq_attr "type" "load3")) + "fa526_core*3") + +(define_insn_reservation "526_load4_op" 6 + (and (eq_attr "tune" "fa526") + (eq_attr "type" "load4")) + "fa526_core*4") + +(define_insn_reservation "526_store1_op" 0 + (and (eq_attr "tune" "fa526") + (eq_attr "type" "store1")) + "fa526_core") + +(define_insn_reservation "526_store2_op" 1 + (and (eq_attr "tune" "fa526") + (eq_attr "type" "store2")) + "fa526_core*2") + +(define_insn_reservation "526_store3_op" 2 + (and (eq_attr "tune" "fa526") + (eq_attr "type" "store3")) + "fa526_core*3") + +(define_insn_reservation "526_store4_op" 3 + (and (eq_attr "tune" "fa526") + (eq_attr "type" "store4")) + "fa526_core*4") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Branch and Call Instructions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; Branch instructions are difficult to model accurately. The FA526 +;; core can predict most branches. If the branch is predicted +;; correctly, and predicted early enough, the branch can be completely +;; eliminated from the instruction stream. Some branches can +;; therefore appear to require zero cycle to execute. We assume that +;; all branches are predicted correctly, and that the latency is +;; therefore the minimum value. + +(define_insn_reservation "526_branch_op" 0 + (and (eq_attr "tune" "fa526") + (eq_attr "type" "branch")) + "fa526_core") + +;; The latency for a call is actually the latency when the result is available. +;; i.e. R0 ready for int return value. For most cases, the return value is set +;; by a mov instruction, which has 1 cycle latency. +(define_insn_reservation "526_call_op" 1 + (and (eq_attr "tune" "fa526") + (eq_attr "type" "call")) + "fa526_core") + diff --git a/gcc/config/arm/fa606te.md b/gcc/config/arm/fa606te.md new file mode 100644 index 00000000000..06e63d696bd --- /dev/null +++ b/gcc/config/arm/fa606te.md @@ -0,0 +1,171 @@ +;; Faraday FA606TE Pipeline Description +;; Copyright (C) 2010 Free Software Foundation, Inc. +;; Written by Mingfeng Wu, based on ARM926EJ-S Pipeline Description. +;; +;; 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/>. */ + +;; These descriptions are based on the information contained in the +;; FA606TE Core Design Note, Copyright (c) 2010 Faraday Technology Corp. + +;; Modeled pipeline characteristics: +;; LD -> any use: latency = 2 (1 cycle penalty). +;; ALU -> any use: latency = 1 (0 cycle penalty). + +;; This automaton provides a pipeline description for the Faraday +;; FA606TE core. +;; +;; The model given here assumes that the condition for all conditional +;; instructions is "true", i.e., that all of the instructions are +;; actually executed. + +(define_automaton "fa606te") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Pipelines +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; There is a single pipeline +;; +;; The ALU pipeline has fetch, decode, execute, memory, and +;; write stages. We only need to model the execute, memory and write +;; stages. + +;; E M W + +(define_cpu_unit "fa606te_core" "fa606te") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ALU Instructions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; ALU instructions require two cycles to execute, and use the ALU +;; pipeline in each of the three stages. The results are available +;; after the execute stage stage has finished. +;; +;; If the destination register is the PC, the pipelines are stalled +;; for several cycles. That case is not modeled here. + +;; ALU operations +(define_insn_reservation "606te_alu_op" 1 + (and (eq_attr "tune" "fa606te") + (eq_attr "type" "alu,alu_shift,alu_shift_reg")) + "fa606te_core") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Multiplication Instructions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(define_insn_reservation "606te_mult1" 2 + (and (eq_attr "tune" "fa606te") + (eq_attr "insn" "smlalxy")) + "fa606te_core") + +(define_insn_reservation "606te_mult2" 3 + (and (eq_attr "tune" "fa606te") + (eq_attr "insn" "smlaxy,smulxy,smulwy,smlawy")) + "fa606te_core*2") + +(define_insn_reservation "606te_mult3" 4 + (and (eq_attr "tune" "fa606te") + (eq_attr "insn" "mul,mla,muls,mlas")) + "fa606te_core*3") + +(define_insn_reservation "606te_mult4" 5 + (and (eq_attr "tune" "fa606te") + (eq_attr "insn" "umull,umlal,smull,smlal,umulls,umlals,smulls,smlals")) + "fa606te_core*4") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Load/Store Instructions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; The models for load/store instructions do not accurately describe +;; the difference between operations with a base register writeback +;; (such as "ldm!"). These models assume that all memory references +;; hit in dcache. + +(define_insn_reservation "606te_load1_op" 2 + (and (eq_attr "tune" "fa606te") + (eq_attr "type" "load1,load_byte")) + "fa606te_core") + +(define_insn_reservation "606te_load2_op" 3 + (and (eq_attr "tune" "fa606te") + (eq_attr "type" "load2")) + "fa606te_core*2") + +(define_insn_reservation "606te_load3_op" 4 + (and (eq_attr "tune" "fa606te") + (eq_attr "type" "load3")) + "fa606te_core*3") + +(define_insn_reservation "606te_load4_op" 5 + (and (eq_attr "tune" "fa606te") + (eq_attr "type" "load4")) + "fa606te_core*4") + +(define_insn_reservation "606te_store1_op" 0 + (and (eq_attr "tune" "fa606te") + (eq_attr "type" "store1")) + "fa606te_core") + +(define_insn_reservation "606te_store2_op" 1 + (and (eq_attr "tune" "fa606te") + (eq_attr "type" "store2")) + "fa606te_core*2") + +(define_insn_reservation "606te_store3_op" 2 + (and (eq_attr "tune" "fa606te") + (eq_attr "type" "store3")) + "fa606te_core*3") + +(define_insn_reservation "606te_store4_op" 3 + (and (eq_attr "tune" "fa606te") + (eq_attr "type" "store4")) + "fa606te_core*4") + + +;;(define_insn_reservation "606te_ldm_op" 9 +;; (and (eq_attr "tune" "fa606te") +;; (eq_attr "type" "load2,load3,load4,store2,store3,store4")) +;; "fa606te_core*7") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Branch and Call Instructions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; Branch instructions are difficult to model accurately. The FA606TE +;; core can predict most branches. If the branch is predicted +;; correctly, and predicted early enough, the branch can be completely +;; eliminated from the instruction stream. Some branches can +;; therefore appear to require zero cycles to execute. We assume that +;; all branches are predicted correctly, and that the latency is +;; therefore the minimum value. + +(define_insn_reservation "606te_branch_op" 0 + (and (eq_attr "tune" "fa606te") + (eq_attr "type" "branch")) + "fa606te_core") + +;; The latency for a call is actually the latency when the result is available. +;; i.e. R0 ready for int return value. For most cases, the return value is set +;; by a mov instruction, which has 1 cycle latency. +(define_insn_reservation "606te_call_op" 1 + (and (eq_attr "tune" "fa606te") + (eq_attr "type" "call")) + "fa606te_core") + diff --git a/gcc/config/arm/fa626te.md b/gcc/config/arm/fa626te.md new file mode 100644 index 00000000000..7fe1c8724be --- /dev/null +++ b/gcc/config/arm/fa626te.md @@ -0,0 +1,165 @@ +;; Faraday FA626TE Pipeline Description +;; Copyright (C) 2010 Free Software Foundation, Inc. +;; Written by I-Jui Sung, based on ARM926EJ-S Pipeline Description. +;; +;; 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/>. */ + +;; These descriptions are based on the information contained in the +;; FA626TE Core Design Note, Copyright (c) 2010 Faraday Technology Corp. + +;; Modeled pipeline characteristics: +;; ALU -> simple address LDR/STR: latency = 2 (available after 2 cycles). +;; ALU -> shifted address LDR/STR: latency = 3. +;; ( extra 1 cycle unavoidable stall). +;; ALU -> other use: latency = 2 (available after 2 cycles). +;; LD -> simple address LDR/STR: latency = 3 (available after 3 cycles). +;; LD -> shifted address LDR/STR: latency = 4 +;; ( extra 1 cycle unavoidable stall). +;; LD -> any other use: latency = 3 (available after 3 cycles). + +;; This automaton provides a pipeline description for the Faraday +;; FA626TE core. +;; +;; The model given here assumes that the condition for all conditional +;; instructions is "true", i.e., that all of the instructions are +;; actually executed. + +(define_automaton "fa626te") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Pipelines +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; There is a single pipeline +;; +;; The ALU pipeline has fetch, decode, execute, memory, and +;; write stages. We only need to model the execute, memory and write +;; stages. + +;; S E M W + +(define_cpu_unit "fa626te_core" "fa626te") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ALU Instructions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; ALU instructions require two cycles to execute, and use the ALU +;; pipeline in each of the three stages. The results are available +;; after the execute stage stage has finished. +;; +;; If the destination register is the PC, the pipelines are stalled +;; for several cycles. That case is not modeled here. + +;; ALU operations +(define_insn_reservation "626te_alu_op" 1 + (and (eq_attr "tune" "fa626,fa626te") + (eq_attr "type" "alu")) + "fa626te_core") + +(define_insn_reservation "626te_alu_shift_op" 2 + (and (eq_attr "tune" "fa626,fa626te") + (eq_attr "type" "alu_shift,alu_shift_reg")) + "fa626te_core") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Multiplication Instructions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(define_insn_reservation "626te_mult1" 2 + (and (eq_attr "tune" "fa626,fa626te") + (eq_attr "insn" "smulwy,smlawy,smulxy,smlaxy")) + "fa626te_core") + +(define_insn_reservation "626te_mult2" 2 + (and (eq_attr "tune" "fa626,fa626te") + (eq_attr "insn" "mul,mla")) + "fa626te_core") + +(define_insn_reservation "626te_mult3" 3 + (and (eq_attr "tune" "fa626,fa626te") + (eq_attr "insn" "muls,mlas,smull,smlal,umull,umlal,smlalxy,smlawx")) + "fa626te_core*2") + +(define_insn_reservation "626te_mult4" 4 + (and (eq_attr "tune" "fa626,fa626te") + (eq_attr "insn" "smulls,smlals,umulls,umlals")) + "fa626te_core*3") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Load/Store Instructions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; The models for load/store instructions do not accurately describe +;; the difference between operations with a base register writeback +;; (such as "ldm!"). These models assume that all memory references +;; hit in dcache. + +(define_insn_reservation "626te_load1_op" 3 + (and (eq_attr "tune" "fa626,fa626te") + (eq_attr "type" "load1,load_byte")) + "fa626te_core") + +(define_insn_reservation "626te_load2_op" 4 + (and (eq_attr "tune" "fa626,fa626te") + (eq_attr "type" "load2,load3")) + "fa626te_core*2") + +(define_insn_reservation "626te_load3_op" 5 + (and (eq_attr "tune" "fa626,fa626te") + (eq_attr "type" "load4")) + "fa626te_core*3") + +(define_insn_reservation "626te_store1_op" 0 + (and (eq_attr "tune" "fa626,fa626te") + (eq_attr "type" "store1")) + "fa626te_core") + +(define_insn_reservation "626te_store2_op" 1 + (and (eq_attr "tune" "fa626,fa626te") + (eq_attr "type" "store2,store3")) + "fa626te_core*2") + +(define_insn_reservation "626te_store3_op" 2 + (and (eq_attr "tune" "fa626,fa626te") + (eq_attr "type" "store4")) + "fa626te_core*3") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Branch and Call Instructions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; Branch instructions are difficult to model accurately. The FA626TE +;; core can predict most branches. If the branch is predicted +;; correctly, and predicted early enough, the branch can be completely +;; eliminated from the instruction stream. Some branches can +;; therefore appear to require zero cycle to execute. We assume that +;; all branches are predicted correctly, and that the latency is +;; therefore the minimum value. + +(define_insn_reservation "626te_branch_op" 0 + (and (eq_attr "tune" "fa626,fa626te") + (eq_attr "type" "branch")) + "fa626te_core") + +;; The latency for a call is actually the latency when the result is available. +;; i.e. R0 ready for int return value. +(define_insn_reservation "626te_call_op" 1 + (and (eq_attr "tune" "fa626,fa626te") + (eq_attr "type" "call")) + "fa626te_core") + diff --git a/gcc/config/arm/fa726te.md b/gcc/config/arm/fa726te.md new file mode 100644 index 00000000000..3c33d597104 --- /dev/null +++ b/gcc/config/arm/fa726te.md @@ -0,0 +1,218 @@ +;; Faraday FA726TE Pipeline Description +;; Copyright (C) 2010 Free Software Foundation, Inc. +;; Written by I-Jui Sung, based on ARM926EJ-S Pipeline Description. +;; +;; 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/>. */ + +;; These descriptions are based on the information contained in the +;; FA726TE Core Design Note, Copyright (c) 2010 Faraday Technology Corp. + +;; This automaton provides a pipeline description for the Faraday +;; FA726TE core. +;; +;; The model given here assumes that the condition for all conditional +;; instructions is "true", i.e., that all of the instructions are +;; actually executed. + +(define_automaton "fa726te") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Pipelines +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; The ALU pipeline has fetch, decode, execute, memory, and +;; write stages. We only need to model the execute, memory and write +;; stages. + +;; E1 E2 E3 E4 E5 WB +;;______________________________________________________ +;; +;; <-------------- LD/ST -----------> +;; shifter + LU <-- AU --> +;; <-- AU --> shifter + LU CPSR (Pipe 0) +;;______________________________________________________ +;; +;; <---------- MUL ---------> +;; shifter + LU <-- AU --> +;; <-- AU --> shifter + LU CPSR (Pipe 1) + + +(define_cpu_unit "fa726te_alu0_pipe,fa726te_alu1_pipe" "fa726te") +(define_cpu_unit "fa726te_mac_pipe" "fa726te") +(define_cpu_unit "fa726te_lsu_pipe_e,fa726te_lsu_pipe_w" "fa726te") + +;; Pretend we have 2 LSUs (the second is ONLY for LDR), which can possibly +;; improve code quality. +(define_query_cpu_unit "fa726te_lsu1_pipe_e,fa726te_lsu1_pipe_w" "fa726te") +(define_cpu_unit "fa726te_is0,fa726te_is1" "fa726te") + +(define_reservation "fa726te_issue" "(fa726te_is0|fa726te_is1)") +;; Reservation to restrict issue to 1. +(define_reservation "fa726te_blockage" "(fa726te_is0+fa726te_is1)") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ALU Instructions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; ALU instructions require three cycles to execute, and use the ALU +;; pipeline in each of the three stages. The results are available +;; after the execute stage stage has finished. +;; +;; If the destination register is the PC, the pipelines are stalled +;; for several cycles. That case is not modeled here. + +;; Move instructions. +(define_insn_reservation "726te_shift_op" 1 + (and (eq_attr "tune" "fa726te") + (eq_attr "insn" "mov,mvn")) + "fa726te_issue+(fa726te_alu0_pipe|fa726te_alu1_pipe)") + +;; ALU operations with no shifted operand will finished in 1 cycle +;; Other ALU instructions 2 cycles. +(define_insn_reservation "726te_alu_op" 1 + (and (eq_attr "tune" "fa726te") + (and (eq_attr "type" "alu") + (not (eq_attr "insn" "mov,mvn")))) + "fa726te_issue+(fa726te_alu0_pipe|fa726te_alu1_pipe)") + +;; ALU operations with a shift-by-register operand. +;; These really stall in the decoder, in order to read the shift value +;; in the first cycle. If the instruction uses both shifter and AU, +;; it takes 3 cycles. +(define_insn_reservation "726te_alu_shift_op" 3 + (and (eq_attr "tune" "fa726te") + (and (eq_attr "type" "alu_shift") + (not (eq_attr "insn" "mov,mvn")))) + "fa726te_issue+(fa726te_alu0_pipe|fa726te_alu1_pipe)") + +(define_insn_reservation "726te_alu_shift_reg_op" 3 + (and (eq_attr "tune" "fa726te") + (and (eq_attr "type" "alu_shift_reg") + (not (eq_attr "insn" "mov,mvn")))) + "fa726te_issue+(fa726te_alu0_pipe|fa726te_alu1_pipe)") +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Multiplication Instructions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; Multiplication instructions loop in the execute stage until the +;; instruction has been passed through the multiplier array enough +;; times. Multiply operations occur in both the execute and memory +;; stages of the pipeline + +(define_insn_reservation "726te_mult_op" 3 + (and (eq_attr "tune" "fa726te") + (eq_attr "insn" "smlalxy,mul,mla,muls,mlas,umull,umlal,smull,smlal,\ + umulls,umlals,smulls,smlals,smlawx,smulxy,smlaxy")) + "fa726te_issue+fa726te_mac_pipe") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Load/Store Instructions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; The models for load/store instructions do not accurately describe +;; the difference between operations with a base register writeback +;; (such as "ldm!"). These models assume that all memory references +;; hit in dcache. + +;; Loads with a shifted offset take 3 cycles, and are (a) probably the +;; most common and (b) the pessimistic assumption will lead to fewer stalls. + +;; Scalar loads are pipelined in FA726TE LSU pipe. +;; Here we model the resource conflict between Load@E3-stage & Store@W-stage. +;; The 2nd LSU (lsu1) is to model the fact that if 2 loads are scheduled in the +;; same "bundle", and the 2nd load will introudce another ISSUE stall but is +;; still ok to execute (and may be benefical sometimes). + +(define_insn_reservation "726te_load1_op" 3 + (and (eq_attr "tune" "fa726te") + (eq_attr "type" "load1,load_byte")) + "(fa726te_issue+fa726te_lsu_pipe_e+fa726te_lsu_pipe_w)\ + | (fa726te_issue+fa726te_lsu1_pipe_e+fa726te_lsu1_pipe_w,fa726te_blockage)") + +(define_insn_reservation "726te_store1_op" 1 + (and (eq_attr "tune" "fa726te") + (eq_attr "type" "store1")) + "fa726te_blockage*2") + +;; Load/Store Multiple blocks all pipelines in EX stages until WB. +;; No other instructions can be issued together. Since they essentially +;; prevent all scheduling opportunities, we model them together here. + +;; The LDM is breaking into multiple load instructions, later instruction in +;; the pipe 1 is stalled. +(define_insn_reservation "726te_ldm2_op" 4 + (and (eq_attr "tune" "fa726te") + (eq_attr "type" "load2,load3")) + "fa726te_blockage*4") + +(define_insn_reservation "726te_ldm3_op" 5 + (and (eq_attr "tune" "fa726te") + (eq_attr "type" "load4")) + "fa726te_blockage*5") + +(define_insn_reservation "726te_stm2_op" 2 + (and (eq_attr "tune" "fa726te") + (eq_attr "type" "store2,store3")) + "fa726te_blockage*3") + +(define_insn_reservation "726te_stm3_op" 3 + (and (eq_attr "tune" "fa726te") + (eq_attr "type" "store4")) + "fa726te_blockage*4") + +(define_bypass 1 "726te_load1_op,726te_ldm2_op,726te_ldm3_op" "726te_store1_op,\ + 726te_stm2_op,726te_stm3_op" "arm_no_early_store_addr_dep") +(define_bypass 0 "726te_shift_op,726te_alu_op,726te_alu_shift_op,\ + 726te_alu_shift_reg_op,726te_mult_op" "726te_store1_op" + "arm_no_early_store_addr_dep") +(define_bypass 0 "726te_shift_op,726te_alu_op" "726te_shift_op,726te_alu_op") +(define_bypass 1 "726te_alu_shift_op,726te_alu_shift_reg_op" + "726te_shift_op,726te_alu_op") +(define_bypass 1 "726te_alu_shift_op,726te_alu_shift_reg_op,726te_mult_op" + "726te_alu_shift_op" "arm_no_early_alu_shift_dep") +(define_bypass 1 "726te_alu_shift_op,726te_alu_shift_reg_op,726te_mult_op" + "726te_alu_shift_reg_op" "arm_no_early_alu_shift_value_dep") +(define_bypass 1 "726te_mult_op" "726te_shift_op,726te_alu_op") + +(define_bypass 4 "726te_load1_op" "726te_mult_op") +(define_bypass 5 "726te_ldm2_op" "726te_mult_op") +(define_bypass 6 "726te_ldm3_op" "726te_mult_op") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Branch and Call Instructions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; Branch instructions are difficult to model accurately. The FA726TE +;; core can predict most branches. If the branch is predicted +;; correctly, and predicted early enough, the branch can be completely +;; eliminated from the instruction stream. Some branches can +;; therefore appear to require zero cycle to execute. We assume that +;; all branches are predicted correctly, and that the latency is +;; therefore the minimum value. + +(define_insn_reservation "726te_branch_op" 0 + (and (eq_attr "tune" "fa726te") + (eq_attr "type" "branch")) + "fa726te_blockage") + +;; The latency for a call is actually the latency when the result is available. +;; i.e. R0 is ready for int return value. +(define_insn_reservation "726te_call_op" 1 + (and (eq_attr "tune" "fa726te") + (eq_attr "type" "call")) + "fa726te_blockage") + diff --git a/gcc/config/arm/fmp626.md b/gcc/config/arm/fmp626.md new file mode 100644 index 00000000000..9ba33ddec47 --- /dev/null +++ b/gcc/config/arm/fmp626.md @@ -0,0 +1,182 @@ +;; Faraday FA626TE Pipeline Description +;; Copyright (C) 2010 Free Software Foundation, Inc. +;; Written by Mingfeng Wu, based on ARM926EJ-S Pipeline Description. +;; +;; 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/>. */ + +;; These descriptions are based on the information contained in the +;; FMP626 Core Design Note, Copyright (c) 2010 Faraday Technology Corp. + +;; Pipeline architecture +;; S E M W(Q1) Q2 +;; ___________________________________________ +;; shifter alu +;; mul1 mul2 mul3 +;; ld/st1 ld/st2 ld/st3 ld/st4 ld/st5 + +;; This automaton provides a pipeline description for the Faraday +;; FMP626 core. +;; +;; The model given here assumes that the condition for all conditional +;; instructions is "true", i.e., that all of the instructions are +;; actually executed. + +(define_automaton "fmp626") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Pipelines +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; There is a single pipeline +;; +;; The ALU pipeline has fetch, decode, execute, memory, and +;; write stages. We only need to model the execute, memory and write +;; stages. + +(define_cpu_unit "fmp626_core" "fmp626") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ALU Instructions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; ALU instructions require two cycles to execute, and use the ALU +;; pipeline in each of the three stages. The results are available +;; after the execute stage stage has finished. +;; +;; If the destination register is the PC, the pipelines are stalled +;; for several cycles. That case is not modeled here. + +;; ALU operations +(define_insn_reservation "mp626_alu_op" 1 + (and (eq_attr "tune" "fmp626") + (eq_attr "type" "alu")) + "fmp626_core") + +(define_insn_reservation "mp626_alu_shift_op" 2 + (and (eq_attr "tune" "fmp626") + (eq_attr "type" "alu_shift,alu_shift_reg")) + "fmp626_core") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Multiplication Instructions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(define_insn_reservation "mp626_mult1" 2 + (and (eq_attr "tune" "fmp626") + (eq_attr "insn" "smulwy,smlawy,smulxy,smlaxy")) + "fmp626_core") + +(define_insn_reservation "mp626_mult2" 2 + (and (eq_attr "tune" "fmp626") + (eq_attr "insn" "mul,mla")) + "fmp626_core") + +(define_insn_reservation "mp626_mult3" 3 + (and (eq_attr "tune" "fmp626") + (eq_attr "insn" "muls,mlas,smull,smlal,umull,umlal,smlalxy,smlawx")) + "fmp626_core*2") + +(define_insn_reservation "mp626_mult4" 4 + (and (eq_attr "tune" "fmp626") + (eq_attr "insn" "smulls,smlals,umulls,umlals")) + "fmp626_core*3") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Load/Store Instructions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; The models for load/store instructions do not accurately describe +;; the difference between operations with a base register writeback +;; (such as "ldm!"). These models assume that all memory references +;; hit in dcache. + +(define_insn_reservation "mp626_load1_op" 5 + (and (eq_attr "tune" "fmp626") + (eq_attr "type" "load1,load_byte")) + "fmp626_core") + +(define_insn_reservation "mp626_load2_op" 6 + (and (eq_attr "tune" "fmp626") + (eq_attr "type" "load2,load3")) + "fmp626_core*2") + +(define_insn_reservation "mp626_load3_op" 7 + (and (eq_attr "tune" "fmp626") + (eq_attr "type" "load4")) + "fmp626_core*3") + +(define_insn_reservation "mp626_store1_op" 0 + (and (eq_attr "tune" "fmp626") + (eq_attr "type" "store1")) + "fmp626_core") + +(define_insn_reservation "mp626_store2_op" 1 + (and (eq_attr "tune" "fmp626") + (eq_attr "type" "store2,store3")) + "fmp626_core*2") + +(define_insn_reservation "mp626_store3_op" 2 + (and (eq_attr "tune" "fmp626") + (eq_attr "type" "store4")) + "fmp626_core*3") + +(define_bypass 1 "mp626_load1_op,mp626_load2_op,mp626_load3_op" + "mp626_store1_op,mp626_store2_op,mp626_store3_op" + "arm_no_early_store_addr_dep") +(define_bypass 1 "mp626_alu_op,mp626_alu_shift_op,mp626_mult1,mp626_mult2,\ + mp626_mult3,mp626_mult4" "mp626_store1_op" + "arm_no_early_store_addr_dep") +(define_bypass 1 "mp626_alu_shift_op" "mp626_alu_op") +(define_bypass 1 "mp626_alu_shift_op" "mp626_alu_shift_op" + "arm_no_early_alu_shift_dep") +(define_bypass 1 "mp626_mult1,mp626_mult2" "mp626_alu_shift_op" + "arm_no_early_alu_shift_dep") +(define_bypass 2 "mp626_mult3" "mp626_alu_shift_op" + "arm_no_early_alu_shift_dep") +(define_bypass 3 "mp626_mult4" "mp626_alu_shift_op" + "arm_no_early_alu_shift_dep") +(define_bypass 1 "mp626_mult1,mp626_mult2" "mp626_alu_op") +(define_bypass 2 "mp626_mult3" "mp626_alu_op") +(define_bypass 3 "mp626_mult4" "mp626_alu_op") +(define_bypass 4 "mp626_load1_op" "mp626_alu_op") +(define_bypass 5 "mp626_load2_op" "mp626_alu_op") +(define_bypass 6 "mp626_load3_op" "mp626_alu_op") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Branch and Call Instructions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; Branch instructions are difficult to model accurately. The FMP626 +;; core can predict most branches. If the branch is predicted +;; correctly, and predicted early enough, the branch can be completely +;; eliminated from the instruction stream. Some branches can +;; therefore appear to require zero cycle to execute. We assume that +;; all branches are predicted correctly, and that the latency is +;; therefore the minimum value. + +(define_insn_reservation "mp626_branch_op" 0 + (and (eq_attr "tune" "fmp626") + (eq_attr "type" "branch")) + "fmp626_core") + +;; The latency for a call is actually the latency when the result is available. +;; i.e. R0 ready for int return value. +(define_insn_reservation "mp626_call_op" 1 + (and (eq_attr "tune" "fmp626") + (eq_attr "type" "call")) + "fmp626_core") + diff --git a/gcc/config/arm/lib1funcs.asm b/gcc/config/arm/lib1funcs.asm index 085e69068ad..2e76c01df4b 100644 --- a/gcc/config/arm/lib1funcs.asm +++ b/gcc/config/arm/lib1funcs.asm @@ -641,7 +641,7 @@ pc .req r15 subhs \dividend, \dividend, \divisor, lsr #3 orrhs \result, \result, \curbit, lsr #3 cmp \dividend, #0 @ Early termination? - do_it hs, t + do_it ne, t movnes \curbit, \curbit, lsr #4 @ No, any more bits to do? movne \divisor, \divisor, lsr #4 bne 1b diff --git a/gcc/config/arm/t-arm b/gcc/config/arm/t-arm index e1aa815664c..0f05f0dea43 100644 --- a/gcc/config/arm/t-arm +++ b/gcc/config/arm/t-arm @@ -24,6 +24,11 @@ MD_INCLUDES= $(srcdir)/config/arm/arm-tune.md \ $(srcdir)/config/arm/arm1020e.md \ $(srcdir)/config/arm/arm1026ejs.md \ $(srcdir)/config/arm/arm1136jfs.md \ + $(srcdir)/config/arm/fa526.md \ + $(srcdir)/config/arm/fa606te.md \ + $(srcdir)/config/arm/fa626te.md \ + $(srcdir)/config/arm/fmp626.md \ + $(srcdir)/config/arm/fa726te.md \ $(srcdir)/config/arm/arm926ejs.md \ $(srcdir)/config/arm/cirrus.md \ $(srcdir)/config/arm/fpa.md \ diff --git a/gcc/config/arm/t-arm-elf b/gcc/config/arm/t-arm-elf index 8be87c8d947..eb2752cc67c 100644 --- a/gcc/config/arm/t-arm-elf +++ b/gcc/config/arm/t-arm-elf @@ -36,6 +36,10 @@ MULTILIB_DIRNAMES = arm thumb MULTILIB_EXCEPTIONS = MULTILIB_MATCHES = +#MULTILIB_OPTIONS += mcpu=fa526/mcpu=fa626/mcpu=fa606te/mcpu=fa626te/mcpu=fmp626/mcpu=fa726te +#MULTILIB_DIRNAMES += fa526 fa626 fa606te fa626te fmp626 fa726te +#MULTILIB_EXCEPTIONS += *mthumb*/*mcpu=fa526 *mthumb*/*mcpu=fa626 + #MULTILIB_OPTIONS += march=armv7 #MULTILIB_DIRNAMES += thumb2 #MULTILIB_EXCEPTIONS += march=armv7* marm/*march=armv7* @@ -52,6 +56,8 @@ MULTILIB_MATCHES = MULTILIB_OPTIONS += mfloat-abi=hard MULTILIB_DIRNAMES += fpu MULTILIB_EXCEPTIONS += *mthumb/*mfloat-abi=hard* +#MULTILIB_EXCEPTIONS += *mcpu=fa526/*mfloat-abi=hard* +#MULTILIB_EXCEPTIONS += *mcpu=fa626/*mfloat-abi=hard* # MULTILIB_OPTIONS += mcpu=ep9312 # MULTILIB_DIRNAMES += ep9312 diff --git a/gcc/config/arm/t-linux-eabi b/gcc/config/arm/t-linux-eabi index b8a5ce04e65..9a2f3b8d4ce 100644 --- a/gcc/config/arm/t-linux-eabi +++ b/gcc/config/arm/t-linux-eabi @@ -24,6 +24,10 @@ TARGET_LIBGCC2_CFLAGS = -fPIC MULTILIB_OPTIONS = MULTILIB_DIRNAMES = +#MULTILIB_OPTIONS += mcpu=fa606te/mcpu=fa626te/mcpu=fmp626/mcpu=fa726te +#MULTILIB_DIRNAMES += fa606te fa626te fmp626 fa726te +#MULTILIB_EXCEPTIONS += *mthumb/*mcpu=fa606te *mthumb/*mcpu=fa626te *mthumb/*mcpu=fmp626 *mthumb/*mcpu=fa726te* + # Use a version of div0 which raises SIGFPE, and a special __clear_cache. LIB1ASMFUNCS := $(filter-out _dvmd_tls,$(LIB1ASMFUNCS)) _dvmd_lnx _clear_cache diff --git a/gcc/config/darwin-sections.def b/gcc/config/darwin-sections.def index 198fdcbb29c..d6151977744 100644 --- a/gcc/config/darwin-sections.def +++ b/gcc/config/darwin-sections.def @@ -34,6 +34,24 @@ DEF_SECTION (text_unlikely_coal_section, SECTION_CODE|SECTION_NO_ANCHOR, ".section __TEXT,__text_unlikely_coal," "coalesced,pure_instructions", 0) +DEF_SECTION (text_hot_section, SECTION_CODE, + ".section __TEXT,__text_hot,regular,pure_instructions", 0) +DEF_SECTION (text_cold_section, SECTION_CODE, + ".section __TEXT,__text_cold,regular,pure_instructions", 0) +DEF_SECTION (text_startup_section, SECTION_CODE, + ".section __TEXT,__text_startup,regular,pure_instructions", 0) +DEF_SECTION (text_exit_section, SECTION_CODE, + ".section __TEXT,__text_exit,regular,pure_instructions", 0) + +DEF_SECTION (text_hot_coal_section, SECTION_CODE, + ".section __TEXT,__text_hot_coal,coalesced,pure_instructions", 0) +DEF_SECTION (text_cold_coal_section, SECTION_CODE, + ".section __TEXT,__text_cold_coal,coalesced,pure_instructions", 0) +DEF_SECTION (text_startup_coal_section, SECTION_CODE, + ".section __TEXT,__text_stt_coal,coalesced,pure_instructions", 0) +DEF_SECTION (text_exit_coal_section, SECTION_CODE, + ".section __TEXT,__text_exit_coal,coalesced,pure_instructions", 0) + /* const */ DEF_SECTION (const_section, 0, ".const", 0) DEF_SECTION (const_coal_section, SECTION_NO_ANCHOR, diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c index 8ae6409bcee..d9185dbeb76 100644 --- a/gcc/config/darwin.c +++ b/gcc/config/darwin.c @@ -90,6 +90,9 @@ int darwin_emit_branch_islands = false; functions). */ int darwin_running_cxx; +/* Some code-gen now depends on OS major version numbers (at least). */ +int generating_for_darwin_version ; + /* Section names. */ section * darwin_sections[NUM_DARWIN_SECTIONS]; @@ -1145,19 +1148,6 @@ darwin_mark_decl_preserved (const char *name) } static section * -darwin_text_section (int reloc, int weak) -{ - if (reloc) - return (weak - ? darwin_sections[text_unlikely_coal_section] - : unlikely_text_section ()); - else - return (weak - ? darwin_sections[text_coal_section] - : text_section); -} - -static section * darwin_rodata_section (int weak, bool zsize) { return (weak @@ -1267,17 +1257,7 @@ machopic_select_section (tree decl, switch (categorize_decl_for_section (decl, reloc)) { case SECCAT_TEXT: - { - struct cgraph_node *node; - if (decl && TREE_CODE (decl) == FUNCTION_DECL - && (node = cgraph_get_node (decl)) != NULL) - base_section = darwin_function_section (decl, - node->frequency, - node->only_called_at_startup, - node->only_called_at_exit); - if (!base_section) - base_section = darwin_text_section (reloc, weak); - } + gcc_unreachable (); break; case SECCAT_RODATA: @@ -1684,12 +1664,37 @@ darwin_handle_weak_import_attribute (tree *node, tree name, void darwin_emit_unwind_label (FILE *file, tree decl, int for_eh, int empty) { - char *lab; - - if (! for_eh) + char *lab ; + char buf[32]; + static int invok_count = 0; + static tree last_fun_decl = NULL_TREE; + + /* We use the linker to emit the .eh labels for Darwin 9 and above. */ + if (! for_eh || generating_for_darwin_version >= 9) return; - lab = concat (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), ".eh", NULL); + /* FIXME: This only works when the eh for all sections of a function is + emitted at the same time. If that changes, we would need to use a lookup + table of some form to determine what to do. Also, we should emit the + unadorned label for the partition containing the public label for a + function. This is of limited use, probably, since we do not currently + enable partitioning. */ + strcpy (buf, ".eh"); + if (decl && TREE_CODE (decl) == FUNCTION_DECL) + { + if (decl == last_fun_decl) + { + invok_count++; + snprintf (buf, 31, "$$part$$%d.eh", invok_count); + } + else + { + last_fun_decl = decl; + invok_count = 0; + } + } + + lab = concat (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), buf, NULL); if (TREE_PUBLIC (decl)) { @@ -2551,21 +2556,61 @@ darwin_kextabi_p (void) { void darwin_override_options (void) { - bool darwin9plus = (darwin_macosx_version_min - && strverscmp (darwin_macosx_version_min, "10.5") >= 0); + /* Keep track of which (major) version we're generating code for. */ + if (darwin_macosx_version_min) + { + if (strverscmp (darwin_macosx_version_min, "10.6") >= 0) + generating_for_darwin_version = 10; + else if (strverscmp (darwin_macosx_version_min, "10.5") >= 0) + generating_for_darwin_version = 9; + + /* Earlier versions are not specifically accounted, until required. */ + } /* Don't emit DWARF3/4 unless specifically selected. This is a workaround for tool bugs. */ if (!global_options_set.x_dwarf_strict) dwarf_strict = 1; - /* Disable -freorder-blocks-and-partition for darwin_emit_unwind_label. */ - if (flag_reorder_blocks_and_partition - && (targetm.asm_out.emit_unwind_label == darwin_emit_unwind_label)) + /* FIXME: Darwin cannot support multiple function sections until (a) the new code + atoms created have a proper start label and (b) there are suitable pubnames + emitted. This applies to all current Darwin versions (OSX <= 10.6.5). */ + if (global_options.x_flag_reorder_blocks_and_partition) + { + inform (input_location, + "-freorder-blocks-and-partition is currently disabled for this " + "platform"); + flag_reorder_blocks_and_partition = 0; + flag_reorder_blocks = 1; + } + + /* Do not allow unwind tables to be generated by default for m32. + fnon-call-exceptions will override this, regardless of what we do. */ + if (generating_for_darwin_version < 10 + && !global_options_set.x_flag_asynchronous_unwind_tables + && !TARGET_64BIT) + global_options.x_flag_asynchronous_unwind_tables = 0; + + /* Disable -freorder-blocks-and-partition when unwind tables are being emitted + for Darwin < 10 (OSX 10.6). + The strategy is, "Unless the User has specifically set/unset an unwind flag + we will switch off -freorder-blocks-and-partition when unwind tables will be + generated". If the User specifically sets flags... we assume (s)he knows + why... */ + if (generating_for_darwin_version < 10 + && global_options_set.x_flag_reorder_blocks_and_partition + && ((global_options.x_flag_exceptions /* User, c++, java */ + && !global_options_set.x_flag_exceptions) /* User specified... */ + || (global_options.x_flag_unwind_tables + && !global_options_set.x_flag_unwind_tables) + || (global_options.x_flag_non_call_exceptions + && !global_options_set.x_flag_non_call_exceptions) + || (global_options.x_flag_asynchronous_unwind_tables + && !global_options_set.x_flag_asynchronous_unwind_tables))) { inform (input_location, - "-freorder-blocks-and-partition does not work with exceptions " - "on this architecture"); + "-freorder-blocks-and-partition does not work with exceptions " + "on this architecture"); flag_reorder_blocks_and_partition = 0; flag_reorder_blocks = 1; } @@ -2590,7 +2635,7 @@ darwin_override_options (void) } if (flag_var_tracking - && darwin9plus + && (generating_for_darwin_version >= 9) && debug_info_level >= DINFO_LEVEL_NORMAL && debug_hooks->var_location != do_nothing_debug_hooks.var_location) flag_var_tracking_uninit = 1; @@ -2608,7 +2653,7 @@ darwin_override_options (void) } /* It is assumed that branch island stubs are needed for earlier systems. */ - if (!darwin9plus) + if (generating_for_darwin_version < 9) darwin_emit_branch_islands = true; else emit_aligned_common = true; /* Later systems can support aligned common. */ @@ -2968,33 +3013,56 @@ section * darwin_function_section (tree decl, enum node_frequency freq, bool startup, bool exit) { + /* Decide if we need to put this in a coalescable section. */ + bool weak = (decl + && DECL_WEAK (decl) + && (!DECL_ATTRIBUTES (decl) + || !lookup_attribute ("weak_import", + DECL_ATTRIBUTES (decl)))); + + /* If there is a specified section name, we should not be trying to + override. */ + if (decl && DECL_SECTION_NAME (decl) != NULL_TREE) + return get_named_section (decl, NULL, 0); + + /* Default when there is no function re-ordering. */ if (!flag_reorder_functions) - return NULL; + return (weak) + ? darwin_sections[text_coal_section] + : text_section; + /* Startup code should go to startup subsection unless it is unlikely executed (this happens especially with function splitting - where we can split away unnecesary parts of static constructors. */ + where we can split away unnecesary parts of static constructors). */ if (startup && freq != NODE_FREQUENCY_UNLIKELY_EXECUTED) - return get_named_text_section - (decl, "__TEXT,__startup,regular,pure_instructions", "_startup"); + return (weak) + ? darwin_sections[text_startup_coal_section] + : darwin_sections[text_startup_section]; /* Similarly for exit. */ if (exit && freq != NODE_FREQUENCY_UNLIKELY_EXECUTED) - return get_named_text_section (decl, - "__TEXT,__exit,regular,pure_instructions", - "_exit"); + return (weak) + ? darwin_sections[text_exit_coal_section] + : darwin_sections[text_exit_section]; /* Group cold functions together, similarly for hot code. */ switch (freq) { case NODE_FREQUENCY_UNLIKELY_EXECUTED: - return get_named_text_section - (decl, - "__TEXT,__unlikely,regular,pure_instructions", "_unlikely"); + return (weak) + ? darwin_sections[text_cold_coal_section] + : darwin_sections[text_cold_section]; + break; case NODE_FREQUENCY_HOT: - return get_named_text_section - (decl, "__TEXT,__hot,regular,pure_instructions", "_hot"); + return (weak) + ? darwin_sections[text_hot_coal_section] + : darwin_sections[text_hot_section]; + break; default: - return NULL; + return (weak) + ? darwin_sections[text_coal_section] + : text_section; + break; } } diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h index b6cb1f2b1b9..9092d6be397 100644 --- a/gcc/config/darwin.h +++ b/gcc/config/darwin.h @@ -140,6 +140,11 @@ extern GTY(()) int darwin_ms_struct; } while (0) #define SUBTARGET_C_COMMON_OVERRIDE_OPTIONS do { \ + /* Sort out ObjC exceptions: If the runtime is NeXT we default to \ + sjlj for m32 only. */ \ + if (!global_options_set.x_flag_objc_sjlj_exceptions) \ + global_options.x_flag_objc_sjlj_exceptions = \ + flag_next_runtime && !TARGET_64BIT; \ if (flag_mkernel || flag_apple_kext) \ { \ if (flag_use_cxa_atexit == 2) \ @@ -262,7 +267,7 @@ extern GTY(()) int darwin_ms_struct; %{Zdynamic:-dynamic}\ %{Zexported_symbols_list*:-exported_symbols_list %*} \ %{Zflat_namespace:-flat_namespace} \ - %{headerpad_max_install_names*} \ + %{headerpad_max_install_names} \ %{Zimage_base*:-image_base %*} \ %{Zinit*:-init %*} \ %{!mmacosx-version-min=*:-macosx_version_min %(darwin_minversion)} \ @@ -664,7 +669,7 @@ extern GTY(()) section * darwin_sections[NUM_DARWIN_SECTIONS]; #undef TARGET_ASM_SELECT_SECTION #define TARGET_ASM_SELECT_SECTION machopic_select_section -#define USE_SELECT_SECTION_FOR_FUNCTIONS + #undef TARGET_ASM_FUNCTION_SECTION #define TARGET_ASM_FUNCTION_SECTION darwin_function_section @@ -963,10 +968,11 @@ __enable_execute_stack (void *addr) \ #define TARGET_HAS_TARGETCM 1 -extern void darwin_driver_init (unsigned int *decoded_options_count, - struct cl_decoded_option **decoded_options); +#ifndef USED_FOR_TARGET +extern void darwin_driver_init (unsigned int *,struct cl_decoded_option **); #define GCC_DRIVER_HOST_INITIALIZATION \ darwin_driver_init (&decoded_options_count, &decoded_options) +#endif /* The Apple assembler and linker do not support constructor priorities. */ #undef SUPPORTS_INIT_PRIORITY diff --git a/gcc/config/darwin.opt b/gcc/config/darwin.opt index 0e234d9c62a..0d8c4b542c2 100644 --- a/gcc/config/darwin.opt +++ b/gcc/config/darwin.opt @@ -52,6 +52,9 @@ C ObjC C++ ObjC++ Separate Alias(MF) MissingArgError(missing filename after %qs) dylib_file Driver Separate Alias(Zdylib_file) +dylinker +Driver + dynamic Driver Alias(Zdynamic) @@ -88,6 +91,9 @@ Driver gused Driver +headerpad_max_install_names +Driver + image_base Driver Separate Alias(Zimage_base) @@ -97,6 +103,9 @@ Driver Separate Alias(Zinit) install_name Driver Separate Alias(Zinstall_name) +keep_private_externs +Driver + mconstant-cfstrings Target Report Var(darwin_constant_cfstrings) Init(1) Generate compile-time CFString objects @@ -113,6 +122,36 @@ Driver RejectNegative Separate Alias(Zmultiplydefinedunused) no_dead_strip_inits_and_terms Driver Alias(Zno_dead_strip_inits_and_terms) +nofixprebinding +Driver + +nomultidefs +Driver + +noprebind +Driver + +noseglinkedit +Driver + +object +Driver + +prebind +Driver + +prebind_all_twolevel_modules +Driver + +preload +Driver + +private_bundle +Driver + +pthread +Driver + seg_addr_table Driver Separate Alias(Zseg_addr_table) @@ -122,6 +161,9 @@ Driver Separate Alias(Zfn_seg_addr_table_filename) segaddr Driver Separate Args(2) Alias(Zsegaddr) +seglinkedit +Driver + segs_read_only_addr Driver Separate Alias(Zsegs_read_only_addr) @@ -131,6 +173,12 @@ Driver Separate Alias(Zsegs_read_write_addr) single_module Driver Alias(Zsingle_module) +twolevel_namespace +Driver + +twolevel_namespace_hints +Driver + umbrella Driver Separate Alias(Zumbrella) @@ -140,6 +188,18 @@ Driver Separate Alias(Zunexported_symbols_list) weak_reference_mismatches Driver Separate Alias(Zweak_reference_mismatches) +whatsloaded +Driver + +whyload +Driver + +y +Driver Joined + +Mach +Driver + Wnonportable-cfstrings Target Report Var(darwin_warn_nonportable_cfstrings) Init(1) Warning Warn if constant CFString objects contain non-portable characters @@ -181,6 +241,9 @@ iframework Target RejectNegative C ObjC C++ ObjC++ Joined Separate -iframework <dir> Add <dir> to the end of the system framework include path +X +Driver + Zall_load Driver diff --git a/gcc/config/darwin10.h b/gcc/config/darwin10.h index b1edf36ce3d..65ba2632a8f 100644 --- a/gcc/config/darwin10.h +++ b/gcc/config/darwin10.h @@ -23,8 +23,3 @@ unwinder in libSystem is fixed to digest new epilog unwinding notes. */ #undef LIB_SPEC #define LIB_SPEC "%{!static:-no_compact_unwind -lSystem}" - -/* Unwind labels are no longer required in darwin10. */ - -#undef TARGET_ASM_EMIT_UNWIND_LABEL -#define TARGET_ASM_EMIT_UNWIND_LABEL default_emit_unwind_label diff --git a/gcc/config/fp-bit.c b/gcc/config/fp-bit.c index 1cdac6ebeca..82d924ec2bf 100644 --- a/gcc/config/fp-bit.c +++ b/gcc/config/fp-bit.c @@ -1,7 +1,7 @@ /* This is a software floating point library which can be used for targets without hardware floating point. Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, - 2004, 2005, 2008, 2009 Free Software Foundation, Inc. + 2004, 2005, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -48,8 +48,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 8-bit processors. CMPtype: Specify the type that floating point compares should return. This defaults to SItype, aka int. - US_SOFTWARE_GOFAST: This makes all entry points use the same names as the - US Software goFast library. _DEBUG_BITFLOAT: This makes debugging the code a little easier, by adding two integers to the FLO_union_type. NO_DENORMALS: Disable handling of denormals. @@ -1179,8 +1177,6 @@ compare (FLO_type arg_a, FLO_type arg_b) } #endif /* L_compare_sf || L_compare_df */ -#ifndef US_SOFTWARE_GOFAST - /* These should be optimized for their specific tasks someday. */ #if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf) @@ -1308,8 +1304,6 @@ _le_f2 (FLO_type arg_a, FLO_type arg_b) } #endif /* L_le_sf || L_le_df */ -#endif /* ! US_SOFTWARE_GOFAST */ - #if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf) CMPtype _unord_f2 (FLO_type arg_a, FLO_type arg_b) @@ -1434,14 +1428,7 @@ float_to_si (FLO_type arg_a) } #endif /* L_sf_to_si || L_df_to_si */ -#if defined(L_sf_to_usi) || defined(L_df_to_usi) || defined(L_tf_to_usi) -#if defined US_SOFTWARE_GOFAST || defined(L_tf_to_usi) -/* While libgcc2.c defines its own __fixunssfsi and __fixunsdfsi routines, - we also define them for GOFAST because the ones in libgcc2.c have the - wrong names and I'd rather define these here and keep GOFAST CYG-LOC's - out of libgcc2.c. We can't define these here if not GOFAST because then - there'd be duplicate copies. */ - +#if defined(L_tf_to_usi) USItype float_to_usi (FLO_type arg_a) { @@ -1471,8 +1458,7 @@ float_to_usi (FLO_type arg_a) else return a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp); } -#endif /* US_SOFTWARE_GOFAST */ -#endif /* L_sf_to_usi || L_df_to_usi */ +#endif /* L_tf_to_usi */ #if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf) FLO_type diff --git a/gcc/config/fp-bit.h b/gcc/config/fp-bit.h index 3638cc53f8f..f0b07e91fb6 100644 --- a/gcc/config/fp-bit.h +++ b/gcc/config/fp-bit.h @@ -1,5 +1,6 @@ /* Header file for fp-bit.c. */ -/* Copyright (C) 2000, 2002, 2003, 2006, 2009 Free Software Foundation, Inc. +/* Copyright (C) 2000, 2002, 2003, 2006, 2009, 2010 + Free Software Foundation, Inc. This file is part of GCC. @@ -217,101 +218,67 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); typedef DItype intfrac; #endif /* FLOAT */ -#ifdef US_SOFTWARE_GOFAST -# ifdef TFLOAT -# error "GOFAST TFmode not supported" -# elif defined FLOAT -# define add fpadd -# define sub fpsub -# define multiply fpmul -# define divide fpdiv -# define compare fpcmp -# define _unord_f2 __unordsf2 -# define usi_to_float __floatunsisf -# define si_to_float sitofp -# define float_to_si fptosi -# define float_to_usi fptoui -# define negate __negsf2 -# define sf_to_df fptodp -# define sf_to_tf __extendsftf2 -# else -# define add dpadd -# define sub dpsub -# define multiply dpmul -# define divide dpdiv -# define compare dpcmp -# define _unord_f2 __unorddf2 -# define usi_to_float __floatunsidf -# define si_to_float litodp -# define float_to_si dptoli -# define float_to_usi dptoul -# define negate __negdf2 -# define df_to_sf dptofp -# define df_to_tf __extenddftf2 -# endif /* FLOAT */ +#ifdef TFLOAT +# define add __addtf3 +# define sub __subtf3 +# define multiply __multf3 +# define divide __divtf3 +# define compare __cmptf2 +# define _eq_f2 __eqtf2 +# define _ne_f2 __netf2 +# define _gt_f2 __gttf2 +# define _ge_f2 __getf2 +# define _lt_f2 __lttf2 +# define _le_f2 __letf2 +# define _unord_f2 __unordtf2 +# define usi_to_float __floatunsitf +# define si_to_float __floatsitf +# define float_to_si __fixtfsi +# define float_to_usi __fixunstfsi +# define negate __negtf2 +# define tf_to_sf __trunctfsf2 +# define tf_to_df __trunctfdf2 +#elif defined FLOAT +# define add __addsf3 +# define sub __subsf3 +# define multiply __mulsf3 +# define divide __divsf3 +# define compare __cmpsf2 +# define _eq_f2 __eqsf2 +# define _ne_f2 __nesf2 +# define _gt_f2 __gtsf2 +# define _ge_f2 __gesf2 +# define _lt_f2 __ltsf2 +# define _le_f2 __lesf2 +# define _unord_f2 __unordsf2 +# define usi_to_float __floatunsisf +# define si_to_float __floatsisf +# define float_to_si __fixsfsi +# define float_to_usi __fixunssfsi +# define negate __negsf2 +# define sf_to_df __extendsfdf2 +# define sf_to_tf __extendsftf2 #else -# ifdef TFLOAT -# define add __addtf3 -# define sub __subtf3 -# define multiply __multf3 -# define divide __divtf3 -# define compare __cmptf2 -# define _eq_f2 __eqtf2 -# define _ne_f2 __netf2 -# define _gt_f2 __gttf2 -# define _ge_f2 __getf2 -# define _lt_f2 __lttf2 -# define _le_f2 __letf2 -# define _unord_f2 __unordtf2 -# define usi_to_float __floatunsitf -# define si_to_float __floatsitf -# define float_to_si __fixtfsi -# define float_to_usi __fixunstfsi -# define negate __negtf2 -# define tf_to_sf __trunctfsf2 -# define tf_to_df __trunctfdf2 -# elif defined FLOAT -# define add __addsf3 -# define sub __subsf3 -# define multiply __mulsf3 -# define divide __divsf3 -# define compare __cmpsf2 -# define _eq_f2 __eqsf2 -# define _ne_f2 __nesf2 -# define _gt_f2 __gtsf2 -# define _ge_f2 __gesf2 -# define _lt_f2 __ltsf2 -# define _le_f2 __lesf2 -# define _unord_f2 __unordsf2 -# define usi_to_float __floatunsisf -# define si_to_float __floatsisf -# define float_to_si __fixsfsi -# define float_to_usi __fixunssfsi -# define negate __negsf2 -# define sf_to_df __extendsfdf2 -# define sf_to_tf __extendsftf2 -# else -# define add __adddf3 -# define sub __subdf3 -# define multiply __muldf3 -# define divide __divdf3 -# define compare __cmpdf2 -# define _eq_f2 __eqdf2 -# define _ne_f2 __nedf2 -# define _gt_f2 __gtdf2 -# define _ge_f2 __gedf2 -# define _lt_f2 __ltdf2 -# define _le_f2 __ledf2 -# define _unord_f2 __unorddf2 -# define usi_to_float __floatunsidf -# define si_to_float __floatsidf -# define float_to_si __fixdfsi -# define float_to_usi __fixunsdfsi -# define negate __negdf2 -# define df_to_sf __truncdfsf2 -# define df_to_tf __extenddftf2 -# endif /* FLOAT */ -#endif /* US_SOFTWARE_GOFAST */ +# define add __adddf3 +# define sub __subdf3 +# define multiply __muldf3 +# define divide __divdf3 +# define compare __cmpdf2 +# define _eq_f2 __eqdf2 +# define _ne_f2 __nedf2 +# define _gt_f2 __gtdf2 +# define _ge_f2 __gedf2 +# define _lt_f2 __ltdf2 +# define _le_f2 __ledf2 +# define _unord_f2 __unorddf2 +# define usi_to_float __floatunsidf +# define si_to_float __floatsidf +# define float_to_si __fixdfsi +# define float_to_usi __fixunsdfsi +# define negate __negdf2 +# define df_to_sf __truncdfsf2 +# define df_to_tf __extenddftf2 +#endif /* FLOAT */ #ifndef INLINE #define INLINE __inline__ @@ -437,8 +404,6 @@ extern int __fpcmp_parts (fp_number_type *, fp_number_type *); extern CMPtype compare (FLO_type, FLO_type); #endif -#ifndef US_SOFTWARE_GOFAST - #if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf) extern CMPtype _eq_f2 (FLO_type, FLO_type); #endif @@ -467,8 +432,6 @@ extern CMPtype _le_f2 (FLO_type, FLO_type); extern CMPtype _unord_f2 (FLO_type, FLO_type); #endif -#endif /* ! US_SOFTWARE_GOFAST */ - #if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf) extern FLO_type si_to_float (SItype); #endif @@ -477,11 +440,9 @@ extern FLO_type si_to_float (SItype); extern SItype float_to_si (FLO_type); #endif -#if defined(L_sf_to_usi) || defined(L_df_to_usi) || defined(L_tf_to_usi) -#if defined(US_SOFTWARE_GOFAST) || defined(L_tf_to_usi) +#if defined(L_tf_to_usi) extern USItype float_to_usi (FLO_type); #endif -#endif #if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf) extern FLO_type usi_to_float (USItype); diff --git a/gcc/config/gofast.h b/gcc/config/gofast.h deleted file mode 100644 index 69e9eddf009..00000000000 --- a/gcc/config/gofast.h +++ /dev/null @@ -1,80 +0,0 @@ -/* US Software GOFAST floating point library support. - Copyright (C) 1994, 1998, 1999, 2002, 2003, 2004, 2007 - Free Software Foundation, 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/>. */ - -/* The US Software GOFAST library requires special optabs support. - This file is intended to be included by config/ARCH/ARCH.c. It - defines one function, gofast_maybe_init_libfuncs, which should be - called from the TARGET_INIT_LIBFUNCS hook. When tm.h has defined - US_SOFTWARE_GOFAST, this function will adjust all the optabs and - libfuncs appropriately. Otherwise it will do nothing. */ - -static void -gofast_maybe_init_libfuncs (void) -{ -#ifdef US_SOFTWARE_GOFAST - int mode; - - set_optab_libfunc (add_optab, SFmode, "fpadd"); - set_optab_libfunc (add_optab, DFmode, "dpadd"); - set_optab_libfunc (sub_optab, SFmode, "fpsub"); - set_optab_libfunc (sub_optab, DFmode, "dpsub"); - set_optab_libfunc (smul_optab, SFmode, "fpmul"); - set_optab_libfunc (smul_optab, DFmode, "dpmul"); - set_optab_libfunc (sdiv_optab, SFmode, "fpdiv"); - set_optab_libfunc (sdiv_optab, DFmode, "dpdiv"); - set_optab_libfunc (cmp_optab, SFmode, "fpcmp"); - set_optab_libfunc (cmp_optab, DFmode, "dpcmp"); - - /* GOFAST does not provide libfuncs for negation, so we use the - standard names. */ - - /* GCC does not use fpcmp/dpcmp for gt or ge because its own - FP-emulation library returns +1 for both > and unord. So we - leave gt and ge unset, such that, instead of fpcmp(a,b) >[=], we - generate fpcmp(b,a) <[=] 0, which is unambiguous. For unord - libfuncs, we use our own functions, since GOFAST doesn't supply - them. */ - - set_optab_libfunc (eq_optab, SFmode, "fpcmp"); - set_optab_libfunc (ne_optab, SFmode, "fpcmp"); - set_optab_libfunc (gt_optab, SFmode, 0); - set_optab_libfunc (ge_optab, SFmode, 0); - set_optab_libfunc (lt_optab, SFmode, "fpcmp"); - set_optab_libfunc (le_optab, SFmode, "fpcmp"); - - set_optab_libfunc (eq_optab, DFmode, "dpcmp"); - set_optab_libfunc (ne_optab, DFmode, "dpcmp"); - set_optab_libfunc (gt_optab, DFmode, 0); - set_optab_libfunc (ge_optab, DFmode, 0); - set_optab_libfunc (lt_optab, DFmode, "dpcmp"); - set_optab_libfunc (le_optab, DFmode, "dpcmp"); - - set_conv_libfunc (sext_optab, DFmode, SFmode, "fptodp"); - set_conv_libfunc (trunc_optab, SFmode, DFmode, "dptofp"); - - set_conv_libfunc (sfix_optab, SImode, SFmode, "fptosi"); - set_conv_libfunc (sfix_optab, SImode, DFmode, "dptoli"); - set_conv_libfunc (ufix_optab, SImode, SFmode, "fptoui"); - set_conv_libfunc (ufix_optab, SImode, DFmode, "dptoul"); - - set_conv_libfunc (sfloat_optab, SFmode, SImode, "sitofp"); - set_conv_libfunc (sfloat_optab, DFmode, SImode, "litodp"); -#endif -} diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index e9c14d0d95a..40999c86ccc 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -131,7 +131,7 @@ move_or_delete_vzeroupper_2 (basic_block bb, int count = BLOCK_INFO (bb)->count; if (dump_file) - fprintf (dump_file, " BB [%i] entry: upper 128bits: %d\n", + fprintf (dump_file, " [bb %i] entry: upper 128bits: %d\n", bb->index, state); /* BB_END changes when it is deleted. */ @@ -267,7 +267,7 @@ move_or_delete_vzeroupper_2 (basic_block bb, } if (dump_file) - fprintf (dump_file, " BB [%i] exit: upper 128bits: %d\n", + fprintf (dump_file, " [bb %i] exit: upper 128bits: %d\n", bb->index, state); } @@ -282,7 +282,7 @@ move_or_delete_vzeroupper_1 (basic_block block) enum upper_128bits_state state; if (dump_file) - fprintf (dump_file, " Process BB [%i]: status: %d\n", + fprintf (dump_file, " Process [bb %i]: status: %d\n", block->index, BLOCK_INFO (block)->processed); if (BLOCK_INFO (block)->processed) @@ -331,7 +331,7 @@ rescan_move_or_delete_vzeroupper (basic_block block) enum upper_128bits_state state; if (dump_file) - fprintf (dump_file, " Rescan BB [%i]: status: %d\n", + fprintf (dump_file, " Rescan [bb %i]: status: %d\n", block->index, BLOCK_INFO (block)->rescanned); if (BLOCK_INFO (block)->rescanned) @@ -359,6 +359,9 @@ rescan_move_or_delete_vzeroupper (basic_block block) { if (state == used) BLOCK_INFO (block)->state = state; + if (dump_file) + fprintf (dump_file, " [bb %i] exit: upper 128bits: %d\n", + block->index, BLOCK_INFO (block)->state); } else move_or_delete_vzeroupper_2 (block, state); @@ -5433,6 +5436,19 @@ ix86_eax_live_at_start_p (void) return REGNO_REG_SET_P (df_get_live_out (ENTRY_BLOCK_PTR), 0); } +static bool +ix86_keep_aggregate_return_pointer (tree fntype) +{ + tree attr; + + attr = lookup_attribute ("callee_pop_aggregate_return", + TYPE_ATTRIBUTES (fntype)); + if (attr) + return (TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr))) == 0); + + return KEEP_AGGREGATE_RETURN_POINTER != 0; +} + /* Value is the number of bytes of arguments automatically popped when returning from a subroutine call. FUNDECL is the declaration node of the function (as a tree), @@ -5477,7 +5493,7 @@ ix86_return_pops_args (tree fundecl, tree funtype, int size) /* Lose any fake structure return argument if it is passed on the stack. */ if (aggregate_value_p (TREE_TYPE (funtype), fundecl) - && !KEEP_AGGREGATE_RETURN_POINTER) + && !ix86_keep_aggregate_return_pointer (funtype)) { int nregs = ix86_function_regparm (funtype, fundecl); if (nregs == 0) @@ -29057,6 +29073,58 @@ x86_order_regs_for_local_alloc (void) reg_alloc_order [pos++] = 0; } +/* Handle a "callee_pop_aggregate_return" attribute; arguments as + in struct attribute_spec handler. */ +static tree +ix86_handle_callee_pop_aggregate_return (tree *node, tree name, + tree args, + int flags ATTRIBUTE_UNUSED, + bool *no_add_attrs) +{ + if (TREE_CODE (*node) != FUNCTION_TYPE + && TREE_CODE (*node) != METHOD_TYPE + && TREE_CODE (*node) != FIELD_DECL + && TREE_CODE (*node) != TYPE_DECL) + { + warning (OPT_Wattributes, "%qE attribute only applies to functions", + name); + *no_add_attrs = true; + return NULL_TREE; + } + if (TARGET_64BIT) + { + warning (OPT_Wattributes, "%qE attribute only available for 32-bit", + name); + *no_add_attrs = true; + return NULL_TREE; + } + if (is_attribute_p ("callee_pop_aggregate_return", name)) + { + tree cst; + + cst = TREE_VALUE (args); + if (TREE_CODE (cst) != INTEGER_CST) + { + warning (OPT_Wattributes, + "%qE attribute requires an integer constant argument", + name); + *no_add_attrs = true; + } + else if (compare_tree_int (cst, 0) != 0 + && compare_tree_int (cst, 1) != 0) + { + warning (OPT_Wattributes, + "argument to %qE attribute is neither zero, nor one", + name); + *no_add_attrs = true; + } + + return NULL_TREE; + } + + return NULL_TREE; +} + /* Handle a "ms_abi" or "sysv" attribute; arguments as in struct attribute_spec.handler. */ static tree @@ -32226,6 +32294,8 @@ static const struct attribute_spec ix86_attribute_table[] = { "ms_abi", 0, 0, false, true, true, ix86_handle_abi_attribute }, { "sysv_abi", 0, 0, false, true, true, ix86_handle_abi_attribute }, { "ms_hook_prologue", 0, 0, true, false, false, ix86_handle_fndecl_attribute }, + { "callee_pop_aggregate_return", 1, 1, false, true, true, + ix86_handle_callee_pop_aggregate_return }, /* End element. */ { NULL, 0, 0, false, false, false, NULL } }; diff --git a/gcc/config/i386/netware.h b/gcc/config/i386/netware.h index 4b5e31f1462..72d9e340658 100644 --- a/gcc/config/i386/netware.h +++ b/gcc/config/i386/netware.h @@ -26,6 +26,9 @@ along with GCC; see the file COPYING3. If not see #undef CPP_SPEC #define CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT}" +#undef ASM_SPEC +#define ASM_SPEC "" + #undef LIB_SPEC #define LIB_SPEC "" @@ -107,6 +110,12 @@ do { \ /* Default structure packing is 1-byte. */ #define TARGET_DEFAULT_PACK_STRUCT 1 +#undef SIZE_TYPE +#define SIZE_TYPE "unsigned int" + +#undef PTRDIFF_TYPE +#define PTRDIFF_TYPE "int" + #undef WCHAR_TYPE #define WCHAR_TYPE "short unsigned int" diff --git a/gcc/config/i386/nto.h b/gcc/config/i386/nto.h index 9a4cdec7508..0a54ce02cd5 100644 --- a/gcc/config/i386/nto.h +++ b/gcc/config/i386/nto.h @@ -83,6 +83,11 @@ crti.o%s \ -m i386nto \ %{!shared: --dynamic-linker /usr/lib/ldqnx.so.2}" +#undef LIB_SPEC +#define LIB_SPEC "%{!shared:%{!symbolic:-lc}}" + +#undef ASM_SPEC +#define ASM_SPEC "" #undef SIZE_TYPE #define SIZE_TYPE "unsigned int" @@ -99,3 +104,5 @@ crti.o%s \ #define NO_IMPLICIT_EXTERN_C 1 #define TARGET_POSIX_IO + +#undef DBX_REGISTER_NUMBER diff --git a/gcc/config/i386/sol2.h b/gcc/config/i386/sol2.h index a717b533463..411e02dc8d5 100644 --- a/gcc/config/i386/sol2.h +++ b/gcc/config/i386/sol2.h @@ -176,4 +176,10 @@ along with GCC; see the file COPYING3. If not see #define LIBGCC2_TF_CEXT q #define TF_SIZE 113 +#undef SIZE_TYPE +#define SIZE_TYPE "unsigned int" + +#undef PTRDIFF_TYPE +#define PTRDIFF_TYPE "int" + #define MD_UNWIND_SUPPORT "config/i386/sol2-unwind.h" diff --git a/gcc/config/i386/vxworksae.h b/gcc/config/i386/vxworksae.h index 29fa8af20d9..b4c9fe4eb47 100644 --- a/gcc/config/i386/vxworksae.h +++ b/gcc/config/i386/vxworksae.h @@ -1,5 +1,5 @@ /* IA32 VxWorks AE target definitions for GNU compiler. - Copyright (C) 2005, 2007 Free Software Foundation, Inc. + Copyright (C) 2005, 2007, 2010 Free Software Foundation, Inc. Contributed by CodeSourcery, LLC. This file is part of GCC. @@ -24,3 +24,12 @@ along with GCC; see the file COPYING3. If not see do \ builtin_define ("CPU=SIMNT"); \ while (0) + +#undef ASM_SPEC +#define ASM_SPEC "" + +#undef SIZE_TYPE +#define SIZE_TYPE "unsigned int" + +#undef PTRDIFF_TYPE +#define PTRDIFF_TYPE "int" diff --git a/gcc/config/interix.h b/gcc/config/interix.h index aa3871214e8..e9d1cc21f55 100644 --- a/gcc/config/interix.h +++ b/gcc/config/interix.h @@ -50,7 +50,6 @@ for windows/multi thread */ %{shared:--shared -Bdynamic} \ %{G:--shared -Bdynamic} \ %{symbolic:--shared -Bsymbolic -Bdynamic} \ - %{soname*:--soname %*} \ %{rpath*:--rpath %*} \ " diff --git a/gcc/config/interix.opt b/gcc/config/interix.opt new file mode 100644 index 00000000000..5c95b250236 --- /dev/null +++ b/gcc/config/interix.opt @@ -0,0 +1,33 @@ +; Interix options. + +; Copyright (C) 2010 +; Free Software Foundation, 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/>. + +; See the GCC internals manual (options.texi) for a description of +; this file's format. + +; Please try to keep this file in ASCII collating order. + +dynamic +Driver + +G +Driver + +; This comment is to ensure we retain the blank line above. diff --git a/gcc/config/linux.h b/gcc/config/linux.h index 1c4ea1c7bb0..d53468e4e2e 100644 --- a/gcc/config/linux.h +++ b/gcc/config/linux.h @@ -80,9 +80,15 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define LIB_SPEC LINUX_TARGET_LIB_SPEC /* C libraries supported on Linux. */ +#ifdef SINGLE_LIBC +#define OPTION_GLIBC (DEFAULT_LIBC == LIBC_GLIBC) +#define OPTION_UCLIBC (DEFAULT_LIBC == LIBC_UCLIBC) +#define OPTION_BIONIC (DEFAULT_LIBC == LIBC_BIONIC) +#else #define OPTION_GLIBC (linux_libc == LIBC_GLIBC) #define OPTION_UCLIBC (linux_libc == LIBC_UCLIBC) #define OPTION_BIONIC (linux_libc == LIBC_BIONIC) +#endif #define LINUX_TARGET_OS_CPP_BUILTINS() \ do { \ diff --git a/gcc/config/mips/elforion.h b/gcc/config/mips/elforion.h index 71ea25f3eab..5560580c274 100644 --- a/gcc/config/mips/elforion.h +++ b/gcc/config/mips/elforion.h @@ -1,6 +1,5 @@ -/* Definitions of target machine for GNU compiler. MIPS ORION version with - GOFAST floating point library. - Copyright (C) 1994, 1998, 2007 Free Software Foundation, Inc. +/* Definitions of target machine for GNU compiler. MIPS ORION version. + Copyright (C) 1994, 1998, 2007, 2010 Free Software Foundation, Inc. This file is part of GCC. diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 74f7a7951ec..883747ecba4 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -11149,8 +11149,6 @@ mips_preferred_simd_mode (enum machine_mode mode ATTRIBUTE_UNUSED) /* Implement TARGET_INIT_LIBFUNCS. */ -#include "config/gofast.h" - static void mips_init_libfuncs (void) { @@ -11209,9 +11207,6 @@ mips_init_libfuncs (void) "__mips16_floatunsidf"); } } - else - /* Register the gofast functions if selected using --enable-gofast. */ - gofast_maybe_init_libfuncs (); /* The MIPS16 ISA does not have an encoding for "sync", so we rely on an external non-MIPS16 routine to implement __sync_synchronize. */ diff --git a/gcc/config/mips/t-sr71k b/gcc/config/mips/t-sr71k index 534da28fd99..5eb96a12e43 100644 --- a/gcc/config/mips/t-sr71k +++ b/gcc/config/mips/t-sr71k @@ -1,4 +1,4 @@ -# Copyright (C) 2002, 2003 Free Software Foundation, Inc. +# Copyright (C) 2002, 2003, 2010 Free Software Foundation, Inc. # # This file is part of GCC. # @@ -49,7 +49,6 @@ dp-bit.c: $(srcdir)/config/fp-bit.c echo '#ifdef __MIPSEL__' > dp-bit.c echo '#define FLOAT_BIT_ORDER_MISMATCH' >> dp-bit.c echo '#endif' >> dp-bit.c - echo '#define US_SOFTWARE_GOFAST' >> dp-bit.c cat $(srcdir)/config/fp-bit.c >> dp-bit.c fp-bit.c: $(srcdir)/config/fp-bit.c @@ -57,7 +56,6 @@ fp-bit.c: $(srcdir)/config/fp-bit.c echo '#ifdef __MIPSEL__' >> fp-bit.c echo '#define FLOAT_BIT_ORDER_MISMATCH' >> fp-bit.c echo '#endif' >> fp-bit.c - echo '#define US_SOFTWARE_GOFAST' >> fp-bit.c cat $(srcdir)/config/fp-bit.c >> fp-bit.c # Build the libraries for both hard and soft floating point diff --git a/gcc/config/mn10300/mn10300.c b/gcc/config/mn10300/mn10300.c index a4e0bc432df..23b198a44af 100644 --- a/gcc/config/mn10300/mn10300.c +++ b/gcc/config/mn10300/mn10300.c @@ -1867,26 +1867,39 @@ mn10300_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, rtx mn10300_legitimize_pic_address (rtx orig, rtx reg) { + rtx x; + if (GET_CODE (orig) == LABEL_REF || (GET_CODE (orig) == SYMBOL_REF && (CONSTANT_POOL_ADDRESS_P (orig) || ! MN10300_GLOBAL_P (orig)))) { - if (reg == 0) + if (reg == NULL) reg = gen_reg_rtx (Pmode); - emit_insn (gen_symGOTOFF2reg (reg, orig)); - return reg; + x = gen_rtx_UNSPEC (SImode, gen_rtvec (1, orig), UNSPEC_GOTOFF); + x = gen_rtx_CONST (SImode, x); + emit_move_insn (reg, x); + + x = emit_insn (gen_addsi3 (reg, reg, pic_offset_table_rtx)); } else if (GET_CODE (orig) == SYMBOL_REF) { - if (reg == 0) + if (reg == NULL) reg = gen_reg_rtx (Pmode); - emit_insn (gen_symGOT2reg (reg, orig)); - return reg; + x = gen_rtx_UNSPEC (SImode, gen_rtvec (1, orig), UNSPEC_GOT); + x = gen_rtx_CONST (SImode, x); + x = gen_rtx_PLUS (SImode, pic_offset_table_rtx, x); + x = gen_const_mem (SImode, x); + + x = emit_move_insn (reg, x); } - return orig; + else + return orig; + + set_unique_reg_note (x, REG_EQUAL, orig); + return reg; } /* Return zero if X references a SYMBOL_REF or LABEL_REF whose symbol diff --git a/gcc/config/mn10300/mn10300.md b/gcc/config/mn10300/mn10300.md index 1028357d61c..3fad021b527 100644 --- a/gcc/config/mn10300/mn10300.md +++ b/gcc/config/mn10300/mn10300.md @@ -2133,33 +2133,32 @@ [(call (match_operand:QI 0 "general_operand") (match_operand:SI 1 "general_operand"))] "" - " { - if (flag_pic && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF) + rtx fn = XEXP (operands[0], 0); + + if (flag_pic && GET_CODE (fn) == SYMBOL_REF) { - if (MN10300_GLOBAL_P (XEXP (operands[0], 0))) + if (MN10300_GLOBAL_P (fn)) { /* The PLT code won't run on AM30, but then, there's no shared library support for AM30 either, so we just assume the linker is going to adjust all @PLT relocs to the actual symbols. */ emit_use (pic_offset_table_rtx); - XEXP (operands[0], 0) = gen_sym2PLT (XEXP (operands[0], 0)); + fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PLT); } else - XEXP (operands[0], 0) = gen_sym2PIC (XEXP (operands[0], 0)); + fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PIC); } - if (! call_address_operand (XEXP (operands[0], 0), VOIDmode)) - XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0)); - emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1])); - DONE; -}") + if (! call_address_operand (fn, VOIDmode)) + fn = force_reg (SImode, fn); + + XEXP (operands[0], 0) = fn; +}) -;; NB: Mode on match_operand 0 deliberately omitted in -;; order to be able to match UNSPECs in PIC mode. -(define_insn "call_internal" - [(call (mem:QI (match_operand 0 "call_address_operand" "a,S")) - (match_operand:SI 1 "general_operand" "g,g"))] +(define_insn "*call_internal" + [(call (mem:QI (match_operand:SI 0 "call_address_operand" "a,S")) + (match_operand:SI 1 "" ""))] "" "@ calls %C0 @@ -2181,36 +2180,33 @@ (call (match_operand:QI 1 "general_operand") (match_operand:SI 2 "general_operand")))] "" - " { - if (flag_pic && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF) + rtx fn = XEXP (operands[1], 0); + + if (flag_pic && GET_CODE (fn) == SYMBOL_REF) { - if (MN10300_GLOBAL_P (XEXP (operands[1], 0))) + if (MN10300_GLOBAL_P (fn)) { /* The PLT code won't run on AM30, but then, there's no shared library support for AM30 either, so we just assume the linker is going to adjust all @PLT relocs to the actual symbols. */ emit_use (pic_offset_table_rtx); - XEXP (operands[1], 0) = gen_sym2PLT (XEXP (operands[1], 0)); + fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PLT); } else - XEXP (operands[1], 0) = gen_sym2PIC (XEXP (operands[1], 0)); + fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PIC); } - if (! call_address_operand (XEXP (operands[1], 0), VOIDmode)) - XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0)); - emit_call_insn (gen_call_value_internal (operands[0], - XEXP (operands[1], 0), - operands[2])); - DONE; -}") + if (! call_address_operand (fn, VOIDmode)) + fn = force_reg (SImode, fn); + + XEXP (operands[1], 0) = fn; +}) -;; NB: Mode on match_operands 0 and 1 deliberately omitted -;; in order to be able to match UNSPECs in PIC mode. (define_insn "call_value_internal" - [(set (match_operand 0 "register_operand" "=dax,dax") - (call (mem:QI (match_operand 1 "call_address_operand" "a,S")) - (match_operand:SI 2 "general_operand" "g,g")))] + [(set (match_operand 0 "" "") + (call (mem:QI (match_operand:SI 1 "call_address_operand" "a,S")) + (match_operand:SI 2 "" "")))] "" "@ calls %C1 @@ -3119,58 +3115,3 @@ "" "operands[3] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);" ) - -(define_expand "symGOT2reg" - [(match_operand:SI 0 "") - (match_operand:SI 1 "")] - "" - " -{ - rtx insn = emit_insn (gen_symGOT2reg_i (operands[0], operands[1])); - - MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1; - - set_unique_reg_note (insn, REG_EQUAL, operands[1]); - - DONE; -}") - -(define_expand "symGOT2reg_i" - [(set (match_operand:SI 0 "") - (mem:SI (plus:SI (reg:SI PIC_REG) - (const (unspec [(match_operand:SI 1 "")] - UNSPEC_GOT)))))] - "" - "") - -(define_expand "symGOTOFF2reg" - [(match_operand:SI 0 "") (match_operand:SI 1 "")] - "" - " -{ - rtx insn = emit_insn (gen_symGOTOFF2reg_i (operands[0], operands[1])); - - set_unique_reg_note (insn, REG_EQUAL, operands[1]); - - DONE; -}") - -(define_expand "symGOTOFF2reg_i" - [(set (match_operand:SI 0 "") - (const (unspec [(match_operand:SI 1 "")] UNSPEC_GOTOFF))) - (parallel [(set (match_dup 0) - (plus:SI (match_dup 0) - (reg:SI PIC_REG))) - (clobber (reg:CC CC_REG)) - ]) - ] - "" - "") - -(define_expand "sym2PIC" - [(unspec [(match_operand:SI 0 "")] UNSPEC_PIC)] - "" "") - -(define_expand "sym2PLT" - [(unspec [(match_operand:SI 0 "")] UNSPEC_PLT)] - "" "") diff --git a/gcc/config/netbsd-elf.opt b/gcc/config/netbsd-elf.opt new file mode 100644 index 00000000000..1b468c631a7 --- /dev/null +++ b/gcc/config/netbsd-elf.opt @@ -0,0 +1,33 @@ +; NetBSD ELF-only options. + +; Copyright (C) 2010 +; Free Software Foundation, 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/>. + +; See the GCC internals manual (options.texi) for a description of +; this file's format. + +; Please try to keep this file in ASCII collating order. + +rdynamic +Driver + +rpath= +Driver JoinedOrMissing + +; This comment is to ensure we retain the blank line above. diff --git a/gcc/config/netbsd.opt b/gcc/config/netbsd.opt new file mode 100644 index 00000000000..f90fb029e2f --- /dev/null +++ b/gcc/config/netbsd.opt @@ -0,0 +1,36 @@ +; NetBSD options. + +; Copyright (C) 2010 +; Free Software Foundation, 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/>. + +; See the GCC internals manual (options.texi) for a description of +; this file's format. + +; Please try to keep this file in ASCII collating order. + +assert= +Driver JoinedOrMissing + +posix +Driver + +pthread +Driver + +; This comment is to ensure we retain the blank line above. diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index ab54e4b4d13..89f7e500820 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -6188,35 +6188,92 @@ pa_scalar_mode_supported_p (enum machine_mode mode) } /* Return TRUE if INSN, a jump insn, has an unfilled delay slot and - it branches to the next real instruction. Otherwise, return FALSE. */ + it branches into the delay slot. Otherwise, return FALSE. */ static bool branch_to_delay_slot_p (rtx insn) { + rtx jump_insn; + if (dbr_sequence_length ()) return FALSE; - return next_real_insn (JUMP_LABEL (insn)) == next_real_insn (insn); + jump_insn = next_active_insn (JUMP_LABEL (insn)); + while (insn) + { + insn = next_active_insn (insn); + if (jump_insn == insn) + return TRUE; + + /* We can't rely on the length of asms. So, we return FALSE when + the branch is followed by an asm. */ + if (!insn + || GET_CODE (PATTERN (insn)) == ASM_INPUT + || extract_asm_operands (PATTERN (insn)) != NULL_RTX + || get_attr_length (insn) > 0) + break; + } + + return FALSE; } -/* Return TRUE if INSN, a jump insn, needs a nop in its delay slot. +/* Return TRUE if INSN, a forward jump insn, needs a nop in its delay slot. This occurs when INSN has an unfilled delay slot and is followed - by an ASM_INPUT. Disaster can occur if the ASM_INPUT is empty and - the jump branches into the delay slot. So, we add a nop in the delay - slot just to be safe. This messes up our instruction count, but we - don't know how big the ASM_INPUT insn is anyway. */ + by an asm. Disaster can occur if the asm is empty and the jump + branches into the delay slot. So, we add a nop in the delay slot + when this occurs. */ static bool branch_needs_nop_p (rtx insn) { - rtx next_insn; + rtx jump_insn; if (dbr_sequence_length ()) return FALSE; - next_insn = next_real_insn (insn); - return GET_CODE (PATTERN (next_insn)) == ASM_INPUT; + jump_insn = next_active_insn (JUMP_LABEL (insn)); + while (insn) + { + insn = next_active_insn (insn); + if (!insn || jump_insn == insn) + return TRUE; + + if (!(GET_CODE (PATTERN (insn)) == ASM_INPUT + || extract_asm_operands (PATTERN (insn)) != NULL_RTX) + && get_attr_length (insn) > 0) + break; + } + + return FALSE; +} + +/* Return TRUE if INSN, a forward jump insn, can use nullification + to skip the following instruction. This avoids an extra cycle due + to a mis-predicted branch when we fall through. */ + +static bool +use_skip_p (rtx insn) +{ + rtx jump_insn = next_active_insn (JUMP_LABEL (insn)); + + while (insn) + { + insn = next_active_insn (insn); + + /* We can't rely on the length of asms, so we can't skip asms. */ + if (!insn + || GET_CODE (PATTERN (insn)) == ASM_INPUT + || extract_asm_operands (PATTERN (insn)) != NULL_RTX) + break; + if (get_attr_length (insn) == 4 + && jump_insn == next_active_insn (insn)) + return TRUE; + if (get_attr_length (insn) > 0) + break; + } + + return FALSE; } /* This routine handles all the normal conditional branch sequences we @@ -6230,7 +6287,7 @@ const char * output_cbranch (rtx *operands, int negated, rtx insn) { static char buf[100]; - int useskip = 0; + bool useskip; int nullify = INSN_ANNULLED_BRANCH_P (insn); int length = get_attr_length (insn); int xdelay; @@ -6268,12 +6325,7 @@ output_cbranch (rtx *operands, int negated, rtx insn) /* A forward branch over a single nullified insn can be done with a comclr instruction. This avoids a single cycle penalty due to mis-predicted branch if we fall through (branch not taken). */ - if (length == 4 - && next_real_insn (insn) != 0 - && get_attr_length (next_real_insn (insn)) == 4 - && JUMP_LABEL (insn) == next_nonnote_insn (next_real_insn (insn)) - && nullify) - useskip = 1; + useskip = (length == 4 && nullify) ? use_skip_p (insn) : FALSE; switch (length) { @@ -6561,7 +6613,7 @@ const char * output_bb (rtx *operands ATTRIBUTE_UNUSED, int negated, rtx insn, int which) { static char buf[100]; - int useskip = 0; + bool useskip; int nullify = INSN_ANNULLED_BRANCH_P (insn); int length = get_attr_length (insn); int xdelay; @@ -6587,13 +6639,7 @@ output_bb (rtx *operands ATTRIBUTE_UNUSED, int negated, rtx insn, int which) /* A forward branch over a single nullified insn can be done with a extrs instruction. This avoids a single cycle penalty due to mis-predicted branch if we fall through (branch not taken). */ - - if (length == 4 - && next_real_insn (insn) != 0 - && get_attr_length (next_real_insn (insn)) == 4 - && JUMP_LABEL (insn) == next_nonnote_insn (next_real_insn (insn)) - && nullify) - useskip = 1; + useskip = (length == 4 && nullify) ? use_skip_p (insn) : FALSE; switch (length) { @@ -6752,7 +6798,7 @@ const char * output_bvb (rtx *operands ATTRIBUTE_UNUSED, int negated, rtx insn, int which) { static char buf[100]; - int useskip = 0; + bool useskip; int nullify = INSN_ANNULLED_BRANCH_P (insn); int length = get_attr_length (insn); int xdelay; @@ -6778,13 +6824,7 @@ output_bvb (rtx *operands ATTRIBUTE_UNUSED, int negated, rtx insn, int which) /* A forward branch over a single nullified insn can be done with a extrs instruction. This avoids a single cycle penalty due to mis-predicted branch if we fall through (branch not taken). */ - - if (length == 4 - && next_real_insn (insn) != 0 - && get_attr_length (next_real_insn (insn)) == 4 - && JUMP_LABEL (insn) == next_nonnote_insn (next_real_insn (insn)) - && nullify) - useskip = 1; + useskip = (length == 4 && nullify) ? use_skip_p (insn) : FALSE; switch (length) { diff --git a/gcc/config/rs6000/freebsd.h b/gcc/config/rs6000/freebsd.h index 2c36bab1e62..bd3045ea181 100644 --- a/gcc/config/rs6000/freebsd.h +++ b/gcc/config/rs6000/freebsd.h @@ -69,6 +69,5 @@ /* Override rs6000.h definition. */ #undef ASM_APP_OFF #define ASM_APP_OFF "#NO_APP\n" -/* Define SVR4_ASM_SPEC, we use GAS by default. See svr4.h for details. */ -#define SVR4_ASM_SPEC \ - "" + +#define DBX_REGISTER_NUMBER(REGNO) rs6000_dbx_register_number (REGNO) diff --git a/gcc/config/rs6000/linux.h b/gcc/config/rs6000/linux.h index 464cd8ee430..ed1d09ec14d 100644 --- a/gcc/config/rs6000/linux.h +++ b/gcc/config/rs6000/linux.h @@ -27,7 +27,11 @@ /* We use glibc _mcount for profiling. */ #define NO_PROFILE_COUNTERS 1 +#ifdef SINGLE_LIBC +#define OPTION_GLIBC (DEFAULT_LIBC == LIBC_GLIBC) +#else #define OPTION_GLIBC (linux_libc == LIBC_GLIBC) +#endif /* glibc has float and long double forms of math functions. */ #undef TARGET_C99_FUNCTIONS diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h index 20bd257975c..06e08a108c6 100644 --- a/gcc/config/rs6000/linux64.h +++ b/gcc/config/rs6000/linux64.h @@ -308,7 +308,11 @@ extern int dot_symbols; process. */ #define OS_MISSING_POWERPC64 !TARGET_64BIT +#ifdef SINGLE_LIBC +#define OPTION_GLIBC (DEFAULT_LIBC == LIBC_GLIBC) +#else #define OPTION_GLIBC (linux_libc == LIBC_GLIBC) +#endif /* glibc has float and long double forms of math functions. */ #undef TARGET_C99_FUNCTIONS diff --git a/gcc/config/rs6000/lynx.h b/gcc/config/rs6000/lynx.h index 30dd2999ce6..1e923ea38e3 100644 --- a/gcc/config/rs6000/lynx.h +++ b/gcc/config/rs6000/lynx.h @@ -1,5 +1,5 @@ /* Definitions for Rs6000 running LynxOS. - Copyright (C) 1995, 1996, 2000, 2002, 2003, 2004, 2005, 2007 + Copyright (C) 1995, 1996, 2000, 2002, 2003, 2004, 2005, 2007, 2010 Free Software Foundation, Inc. Contributed by David Henkel-Wallace, Cygnus Support (gumby@cygnus.com) Rewritten by Adam Nemet, LynuxWorks Inc. @@ -105,6 +105,8 @@ #undef HAVE_AS_TLS #define HAVE_AS_TLS 0 +#define DBX_REGISTER_NUMBER(REGNO) rs6000_dbx_register_number (REGNO) + #ifdef CRT_BEGIN /* This function is part of crtbegin*.o which is at the beginning of the link and is called from .fini which is usually toward the end diff --git a/gcc/config/rs6000/netbsd.h b/gcc/config/rs6000/netbsd.h index 637060e63f5..de16b37227c 100644 --- a/gcc/config/rs6000/netbsd.h +++ b/gcc/config/rs6000/netbsd.h @@ -1,6 +1,6 @@ /* Definitions of target machine for GNU compiler, for PowerPC NetBSD systems. - Copyright 2002, 2003, 2007, 2008 Free Software Foundation, Inc. + Copyright 2002, 2003, 2007, 2008, 2010 Free Software Foundation, Inc. Contributed by Wasabi Systems, Inc. This file is part of GCC. @@ -89,3 +89,5 @@ #undef TARGET_VERSION #define TARGET_VERSION fprintf (stderr, " (NetBSD/powerpc ELF)"); + +#define DBX_REGISTER_NUMBER(REGNO) rs6000_dbx_register_number (REGNO) diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h index 8365a8fafcf..5c6745b7071 100644 --- a/gcc/config/rs6000/sysv4.h +++ b/gcc/config/rs6000/sysv4.h @@ -266,6 +266,10 @@ do { \ #define RESTORE_FP_PREFIX "_restfpr_" #define RESTORE_FP_SUFFIX "" +/* Type used for size_t, as a string used in a declaration. */ +#undef SIZE_TYPE +#define SIZE_TYPE "unsigned int" + /* Type used for ptrdiff_t, as a string used in a declaration. */ #define PTRDIFF_TYPE "int" @@ -550,9 +554,8 @@ extern int fixuplabelno; /* Override svr4.h definition. */ #undef ASM_SPEC #define ASM_SPEC "%(asm_cpu) \ -%{,assembler|,assembler-with-cpp: %{mregnames} %{mno-regnames}}" \ -SVR4_ASM_SPEC \ -"%{mrelocatable} %{mrelocatable-lib} %{fpic|fpie|fPIC|fPIE:-K PIC} \ +%{,assembler|,assembler-with-cpp: %{mregnames} %{mno-regnames}} \ +%{mrelocatable} %{mrelocatable-lib} %{fpic|fpie|fPIC|fPIE:-K PIC} \ %{memb|msdata=eabi: -memb} \ %{mlittle|mlittle-endian:-mlittle; \ mbig|mbig-endian :-mbig; \ @@ -1077,3 +1080,5 @@ ncrtn.o%s" /* This target uses the sysv4.opt file. */ #define TARGET_USES_SYSV4_OPT 1 + +#undef DBX_REGISTER_NUMBER diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 034b171711f..2fdf03a7c25 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -204,6 +204,7 @@ static tree sh_handle_renesas_attribute (tree *, tree, tree, int, bool *); static void sh_print_operand (FILE *, rtx, int); static void sh_print_operand_address (FILE *, rtx); static bool sh_print_operand_punct_valid_p (unsigned char code); +static bool sh_asm_output_addr_const_extra (FILE *file, rtx x); static void sh_output_function_epilogue (FILE *, HOST_WIDE_INT); static void sh_insert_attributes (tree, tree *); static const char *sh_check_pch_target_flags (int); @@ -372,7 +373,9 @@ static const struct default_options sh_option_optimization_table[] = #define TARGET_PRINT_OPERAND_ADDRESS sh_print_operand_address #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P #define TARGET_PRINT_OPERAND_PUNCT_VALID_P sh_print_operand_punct_valid_p - +#undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA +#define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA sh_asm_output_addr_const_extra + #undef TARGET_ASM_FUNCTION_EPILOGUE #define TARGET_ASM_FUNCTION_EPILOGUE sh_output_function_epilogue @@ -1453,6 +1456,115 @@ sh_print_operand_punct_valid_p (unsigned char code) return (code == '.' || code == '#' || code == '@' || code == ',' || code == '$' || code == '\'' || code == '>'); } + +/* Implement TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA. */ + +static bool +sh_asm_output_addr_const_extra (FILE *file, rtx x) +{ + if (GET_CODE (x) == UNSPEC) + { + switch (XINT (x, 1)) + { + case UNSPEC_DATALABEL: + fputs ("datalabel ", file); + output_addr_const (file, XVECEXP (x, 0, 0)); + break; + case UNSPEC_PIC: + /* GLOBAL_OFFSET_TABLE or local symbols, no suffix. */ + output_addr_const (file, XVECEXP (x, 0, 0)); + break; + case UNSPEC_GOT: + output_addr_const (file, XVECEXP (x, 0, 0)); + fputs ("@GOT", file); + break; + case UNSPEC_GOTOFF: + output_addr_const (file, XVECEXP (x, 0, 0)); + fputs ("@GOTOFF", file); + break; + case UNSPEC_PLT: + output_addr_const (file, XVECEXP (x, 0, 0)); + fputs ("@PLT", file); + break; + case UNSPEC_GOTPLT: + output_addr_const (file, XVECEXP (x, 0, 0)); + fputs ("@GOTPLT", file); + break; + case UNSPEC_DTPOFF: + output_addr_const (file, XVECEXP (x, 0, 0)); + fputs ("@DTPOFF", file); + break; + case UNSPEC_GOTTPOFF: + output_addr_const (file, XVECEXP (x, 0, 0)); + fputs ("@GOTTPOFF", file); + break; + case UNSPEC_TPOFF: + output_addr_const (file, XVECEXP (x, 0, 0)); + fputs ("@TPOFF", file); + break; + case UNSPEC_CALLER: + { + char name[32]; + /* LPCS stands for Label for PIC Call Site. */ + targetm.asm_out.generate_internal_label (name, "LPCS", + INTVAL (XVECEXP (x, 0, 0))); + assemble_name (file, name); + } + break; + case UNSPEC_EXTRACT_S16: + case UNSPEC_EXTRACT_U16: + { + rtx val, shift; + + val = XVECEXP (x, 0, 0); + shift = XVECEXP (x, 0, 1); + fputc ('(', file); + if (shift != const0_rtx) + fputc ('(', file); + if (GET_CODE (val) == CONST + || GET_RTX_CLASS (GET_CODE (val)) != RTX_OBJ) + { + fputc ('(', file); + output_addr_const (file, val); + fputc (')', file); + } + else + output_addr_const (file, val); + if (shift != const0_rtx) + { + fputs (" >> ", file); + output_addr_const (file, shift); + fputc (')', file); + } + fputs (" & 65535)", file); + } + break; + case UNSPEC_SYMOFF: + output_addr_const (file, XVECEXP (x, 0, 0)); + fputc ('-', file); + if (GET_CODE (XVECEXP (x, 0, 1)) == CONST) + { + fputc ('(', file); + output_addr_const (file, XVECEXP (x, 0, 1)); + fputc (')', file); + } + else + output_addr_const (file, XVECEXP (x, 0, 1)); + break; + case UNSPEC_PCREL_SYMOFF: + output_addr_const (file, XVECEXP (x, 0, 0)); + fputs ("-(", file); + output_addr_const (file, XVECEXP (x, 0, 1)); + fputs ("-.)", file); + break; + default: + return false; + } + return true; + } + else + return false; +} /* Encode symbol attributes of a SYMBOL_REF into its diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h index 9960ae12bc1..c07ff083d88 100644 --- a/gcc/config/sh/sh.h +++ b/gcc/config/sh/sh.h @@ -2353,114 +2353,6 @@ struct sh_args { #define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \ final_prescan_insn ((INSN), (OPVEC), (NOPERANDS)) -/* Recognize machine-specific patterns that may appear within - constants. Used for PIC-specific UNSPECs. */ -#define OUTPUT_ADDR_CONST_EXTRA(STREAM, X, FAIL) \ - do \ - if (GET_CODE (X) == UNSPEC) \ - { \ - switch (XINT ((X), 1)) \ - { \ - case UNSPEC_DATALABEL: \ - fputs ("datalabel ", (STREAM)); \ - output_addr_const ((STREAM), XVECEXP ((X), 0, 0)); \ - break; \ - case UNSPEC_PIC: \ - /* GLOBAL_OFFSET_TABLE or local symbols, no suffix. */ \ - output_addr_const ((STREAM), XVECEXP ((X), 0, 0)); \ - break; \ - case UNSPEC_GOT: \ - output_addr_const ((STREAM), XVECEXP ((X), 0, 0)); \ - fputs ("@GOT", (STREAM)); \ - break; \ - case UNSPEC_GOTOFF: \ - output_addr_const ((STREAM), XVECEXP ((X), 0, 0)); \ - fputs ("@GOTOFF", (STREAM)); \ - break; \ - case UNSPEC_PLT: \ - output_addr_const ((STREAM), XVECEXP ((X), 0, 0)); \ - fputs ("@PLT", (STREAM)); \ - break; \ - case UNSPEC_GOTPLT: \ - output_addr_const ((STREAM), XVECEXP ((X), 0, 0)); \ - fputs ("@GOTPLT", (STREAM)); \ - break; \ - case UNSPEC_DTPOFF: \ - output_addr_const ((STREAM), XVECEXP ((X), 0, 0)); \ - fputs ("@DTPOFF", (STREAM)); \ - break; \ - case UNSPEC_GOTTPOFF: \ - output_addr_const ((STREAM), XVECEXP ((X), 0, 0)); \ - fputs ("@GOTTPOFF", (STREAM)); \ - break; \ - case UNSPEC_TPOFF: \ - output_addr_const ((STREAM), XVECEXP ((X), 0, 0)); \ - fputs ("@TPOFF", (STREAM)); \ - break; \ - case UNSPEC_CALLER: \ - { \ - char name[32]; \ - /* LPCS stands for Label for PIC Call Site. */ \ - ASM_GENERATE_INTERNAL_LABEL \ - (name, "LPCS", INTVAL (XVECEXP ((X), 0, 0))); \ - assemble_name ((STREAM), name); \ - } \ - break; \ - case UNSPEC_EXTRACT_S16: \ - case UNSPEC_EXTRACT_U16: \ - { \ - rtx val, shift; \ - \ - val = XVECEXP (X, 0, 0); \ - shift = XVECEXP (X, 0, 1); \ - fputc ('(', STREAM); \ - if (shift != const0_rtx) \ - fputc ('(', STREAM); \ - if (GET_CODE (val) == CONST \ - || GET_RTX_CLASS (GET_CODE (val)) != RTX_OBJ) \ - { \ - fputc ('(', STREAM); \ - output_addr_const (STREAM, val); \ - fputc (')', STREAM); \ - } \ - else \ - output_addr_const (STREAM, val); \ - if (shift != const0_rtx) \ - { \ - fputs (" >> ", STREAM); \ - output_addr_const (STREAM, shift); \ - fputc (')', STREAM); \ - } \ - fputs (" & 65535)", STREAM); \ - } \ - break; \ - case UNSPEC_SYMOFF: \ - output_addr_const (STREAM, XVECEXP (X, 0, 0)); \ - fputc ('-', STREAM); \ - if (GET_CODE (XVECEXP (X, 0, 1)) == CONST) \ - { \ - fputc ('(', STREAM); \ - output_addr_const (STREAM, XVECEXP (X, 0, 1)); \ - fputc (')', STREAM); \ - } \ - else \ - output_addr_const (STREAM, XVECEXP (X, 0, 1)); \ - break; \ - case UNSPEC_PCREL_SYMOFF: \ - output_addr_const (STREAM, XVECEXP (X, 0, 0)); \ - fputs ("-(", STREAM); \ - output_addr_const (STREAM, XVECEXP (X, 0, 1)); \ - fputs ("-.)", STREAM); \ - break; \ - default: \ - goto FAIL; \ - } \ - break; \ - } \ - else \ - goto FAIL; \ - while (0) - extern struct rtx_def *sh_compare_op0; extern struct rtx_def *sh_compare_op1; diff --git a/gcc/config/sparc/leon.md b/gcc/config/sparc/leon.md new file mode 100644 index 00000000000..bc77c6ab928 --- /dev/null +++ b/gcc/config/sparc/leon.md @@ -0,0 +1,56 @@ +;; Scheduling description for LEON. +;; Copyright (C) 2010 Free Software Foundation, 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/>. + + +(define_automaton "leon") + +(define_cpu_unit "leon_memory, leon_fpalu" "leon") +(define_cpu_unit "leon_fpmds" "leon") +(define_cpu_unit "write_buf" "leon") + +(define_insn_reservation "leon_load" 1 + (and (eq_attr "cpu" "leon") + (eq_attr "type" "load,sload,fpload")) + "leon_memory") + +(define_insn_reservation "leon_store" 1 + (and (eq_attr "cpu" "leon") + (eq_attr "type" "store,fpstore")) + "leon_memory+write_buf") + +(define_insn_reservation "leon_fp_alu" 1 + (and (eq_attr "cpu" "leon") + (eq_attr "type" "fp,fpmove")) + "leon_fpalu, nothing") + +(define_insn_reservation "leon_fp_mult" 1 + (and (eq_attr "cpu" "leon") + (eq_attr "type" "fpmul")) + "leon_fpmds, nothing") + +(define_insn_reservation "leon_fp_div" 16 + (and (eq_attr "cpu" "leon") + (eq_attr "type" "fpdivs,fpdivd")) + "leon_fpmds, nothing*15") + +(define_insn_reservation "leon_fp_sqrt" 23 + (and (eq_attr "cpu" "leon") + (eq_attr "type" "fpsqrts,fpsqrtd")) + "leon_fpmds, nothing*21") + diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 223408def9e..a066b2ab305 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -129,6 +129,30 @@ struct processor_costs hypersparc_costs = { }; static const +struct processor_costs leon_costs = { + COSTS_N_INSNS (1), /* int load */ + COSTS_N_INSNS (1), /* int signed load */ + COSTS_N_INSNS (1), /* int zeroed load */ + COSTS_N_INSNS (1), /* float load */ + COSTS_N_INSNS (1), /* fmov, fneg, fabs */ + COSTS_N_INSNS (1), /* fadd, fsub */ + COSTS_N_INSNS (1), /* fcmp */ + COSTS_N_INSNS (1), /* fmov, fmovr */ + COSTS_N_INSNS (1), /* fmul */ + COSTS_N_INSNS (15), /* fdivs */ + COSTS_N_INSNS (15), /* fdivd */ + COSTS_N_INSNS (23), /* fsqrts */ + COSTS_N_INSNS (23), /* fsqrtd */ + COSTS_N_INSNS (5), /* imul */ + COSTS_N_INSNS (5), /* imulX */ + 0, /* imul bit factor */ + COSTS_N_INSNS (5), /* idiv */ + COSTS_N_INSNS (5), /* idivX */ + COSTS_N_INSNS (1), /* movcc/movr */ + 0, /* shift penalty */ +}; + +static const struct processor_costs sparclet_costs = { COSTS_N_INSNS (3), /* int load */ COSTS_N_INSNS (3), /* int signed load */ @@ -367,7 +391,7 @@ static rtx sparc_builtin_saveregs (void); static int epilogue_renumber (rtx *, int); static bool sparc_assemble_integer (rtx, unsigned int, int); static int set_extends (rtx); -static void load_pic_register (void); +static void load_got_register (void); static int save_or_restore_regs (int, int, rtx, int, int); static void emit_save_or_restore_regs (int); static void sparc_asm_function_prologue (FILE *, HOST_WIDE_INT); @@ -698,19 +722,20 @@ sparc_option_override (void) { NULL, (enum cmodel) 0 } }; const struct code_model *cmodel; - /* Map TARGET_CPU_DEFAULT to value for -m{arch,tune}=. */ + /* Map TARGET_CPU_DEFAULT to value for -m{cpu,tune}=. */ static struct cpu_default { const int cpu; const char *const name; } const cpu_default[] = { /* There must be one entry here for each TARGET_CPU value. */ { TARGET_CPU_sparc, "cypress" }, - { TARGET_CPU_sparclet, "tsc701" }, - { TARGET_CPU_sparclite, "f930" }, { TARGET_CPU_v8, "v8" }, + { TARGET_CPU_supersparc, "supersparc" }, { TARGET_CPU_hypersparc, "hypersparc" }, + { TARGET_CPU_leon, "leon" }, + { TARGET_CPU_sparclite, "f930" }, { TARGET_CPU_sparclite86x, "sparclite86x" }, - { TARGET_CPU_supersparc, "supersparc" }, + { TARGET_CPU_sparclet, "tsc701" }, { TARGET_CPU_v9, "v9" }, { TARGET_CPU_ultrasparc, "ultrasparc" }, { TARGET_CPU_ultrasparc3, "ultrasparc3" }, @@ -731,28 +756,32 @@ sparc_option_override (void) { "v8", PROCESSOR_V8, MASK_ISA, MASK_V8 }, /* TI TMS390Z55 supersparc */ { "supersparc", PROCESSOR_SUPERSPARC, MASK_ISA, MASK_V8 }, + { "hypersparc", PROCESSOR_HYPERSPARC, MASK_ISA, MASK_V8|MASK_FPU }, + /* LEON */ + { "leon", PROCESSOR_LEON, MASK_ISA, MASK_V8|MASK_FPU }, { "sparclite", PROCESSOR_SPARCLITE, MASK_ISA, MASK_SPARCLITE }, - /* The Fujitsu MB86930 is the original sparclite chip, with no fpu. - The Fujitsu MB86934 is the recent sparclite chip, with an fpu. */ + /* The Fujitsu MB86930 is the original sparclite chip, with no FPU. */ { "f930", PROCESSOR_F930, MASK_ISA|MASK_FPU, MASK_SPARCLITE }, + /* The Fujitsu MB86934 is the recent sparclite chip, with an FPU. */ { "f934", PROCESSOR_F934, MASK_ISA, MASK_SPARCLITE|MASK_FPU }, - { "hypersparc", PROCESSOR_HYPERSPARC, MASK_ISA, MASK_V8|MASK_FPU }, { "sparclite86x", PROCESSOR_SPARCLITE86X, MASK_ISA|MASK_FPU, MASK_SPARCLITE }, { "sparclet", PROCESSOR_SPARCLET, MASK_ISA, MASK_SPARCLET }, /* TEMIC sparclet */ { "tsc701", PROCESSOR_TSC701, MASK_ISA, MASK_SPARCLET }, { "v9", PROCESSOR_V9, MASK_ISA, MASK_V9 }, - /* TI ultrasparc I, II, IIi */ - { "ultrasparc", PROCESSOR_ULTRASPARC, MASK_ISA, MASK_V9 - /* Although insns using %y are deprecated, it is a clear win on current - ultrasparcs. */ - |MASK_DEPRECATED_V8_INSNS}, - /* TI ultrasparc III */ - /* ??? Check if %y issue still holds true in ultra3. */ - { "ultrasparc3", PROCESSOR_ULTRASPARC3, MASK_ISA, MASK_V9|MASK_DEPRECATED_V8_INSNS}, + /* UltraSPARC I, II, IIi */ + { "ultrasparc", PROCESSOR_ULTRASPARC, MASK_ISA, + /* Although insns using %y are deprecated, it is a clear win. */ + MASK_V9|MASK_DEPRECATED_V8_INSNS}, + /* UltraSPARC III */ + /* ??? Check if %y issue still holds true. */ + { "ultrasparc3", PROCESSOR_ULTRASPARC3, MASK_ISA, + MASK_V9|MASK_DEPRECATED_V8_INSNS}, /* UltraSPARC T1 */ - { "niagara", PROCESSOR_NIAGARA, MASK_ISA, MASK_V9|MASK_DEPRECATED_V8_INSNS}, + { "niagara", PROCESSOR_NIAGARA, MASK_ISA, + MASK_V9|MASK_DEPRECATED_V8_INSNS}, + /* UltraSPARC T2 */ { "niagara2", PROCESSOR_NIAGARA, MASK_ISA, MASK_V9}, { 0, (enum processor_type) 0, 0, 0 } }; @@ -907,6 +936,9 @@ sparc_option_override (void) case PROCESSOR_SPARCLITE86X: sparc_costs = &hypersparc_costs; break; + case PROCESSOR_LEON: + sparc_costs = &leon_costs; + break; case PROCESSOR_SPARCLET: case PROCESSOR_TSC701: sparc_costs = &sparclet_costs; @@ -2988,26 +3020,39 @@ sparc_cannot_force_const_mem (rtx x) } } -/* PIC support. */ -static GTY(()) bool pic_helper_needed = false; -static GTY(()) rtx pic_helper_symbol; -static GTY(()) rtx global_offset_table; +/* Global Offset Table support. */ +static GTY(()) rtx got_helper_rtx = NULL_RTX; +static GTY(()) rtx global_offset_table_rtx = NULL_RTX; + +/* Return the SYMBOL_REF for the Global Offset Table. */ + +static GTY(()) rtx sparc_got_symbol = NULL_RTX; + +static rtx +sparc_got (void) +{ + if (!sparc_got_symbol) + sparc_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_"); + + return sparc_got_symbol; +} /* Ensure that we are not using patterns that are not OK with PIC. */ int check_pic (int i) { + rtx op; + switch (flag_pic) { case 1: - gcc_assert (GET_CODE (recog_data.operand[i]) != SYMBOL_REF - && (GET_CODE (recog_data.operand[i]) != CONST - || (GET_CODE (XEXP (recog_data.operand[i], 0)) == MINUS - && (XEXP (XEXP (recog_data.operand[i], 0), 0) - == global_offset_table) - && (GET_CODE (XEXP (XEXP (recog_data.operand[i], 0), 1)) - == CONST)))); + op = recog_data.operand[i]; + gcc_assert (GET_CODE (op) != SYMBOL_REF + && (GET_CODE (op) != CONST + || (GET_CODE (XEXP (op, 0)) == MINUS + && XEXP (XEXP (op, 0), 0) == sparc_got () + && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST))); case 2: default: return 1; @@ -3242,9 +3287,9 @@ sparc_legitimate_address_p (enum machine_mode mode, rtx addr, bool strict) return 1; } -/* Construct the SYMBOL_REF for the tls_get_offset function. */ +/* Return the SYMBOL_REF for the tls_get_addr function. */ -static GTY(()) rtx sparc_tls_symbol; +static GTY(()) rtx sparc_tls_symbol = NULL_RTX; static rtx sparc_tls_get_addr (void) @@ -3255,21 +3300,28 @@ sparc_tls_get_addr (void) return sparc_tls_symbol; } +/* Return the Global Offset Table to be used in TLS mode. */ + static rtx sparc_tls_got (void) { - rtx temp; + /* In PIC mode, this is just the PIC offset table. */ if (flag_pic) { crtl->uses_pic_offset_table = 1; return pic_offset_table_rtx; } - if (!global_offset_table) - global_offset_table = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_"); - temp = gen_reg_rtx (Pmode); - emit_move_insn (temp, global_offset_table); - return temp; + /* In non-PIC mode, Sun as (unlike GNU as) emits PC-relative relocations for + the GOT symbol with the 32-bit ABI, so we reload the GOT register. */ + if (TARGET_SUN_TLS && TARGET_ARCH32) + { + load_got_register (); + return global_offset_table_rtx; + } + + /* In all other cases, we load a new pseudo with the GOT symbol. */ + return copy_to_reg (sparc_got ()); } /* Return true if X contains a thread-local symbol. */ @@ -3709,59 +3761,69 @@ sparc_mode_dependent_address_p (const_rtx addr) static void get_pc_thunk_name (char name[32], unsigned int regno) { - const char *pic_name = reg_names[regno]; + const char *reg_name = reg_names[regno]; /* Skip the leading '%' as that cannot be used in a symbol name. */ - pic_name += 1; + reg_name += 1; if (USE_HIDDEN_LINKONCE) - sprintf (name, "__sparc_get_pc_thunk.%s", pic_name); + sprintf (name, "__sparc_get_pc_thunk.%s", reg_name); else ASM_GENERATE_INTERNAL_LABEL (name, "LADDPC", regno); } -/* Emit code to load the PIC register. */ +/* Wrapper around the load_pcrel_sym{si,di} patterns. */ -static void -load_pic_register (void) +static rtx +gen_load_pcrel_sym (rtx op0, rtx op1, rtx op2, rtx op3) { int orig_flag_pic = flag_pic; + rtx insn; - if (TARGET_VXWORKS_RTP) - { - emit_insn (gen_vxworks_load_got ()); - emit_use (pic_offset_table_rtx); - return; - } - - /* If we haven't initialized the special PIC symbols, do so now. */ - if (!pic_helper_needed) - { - char name[32]; + /* The load_pcrel_sym{si,di} patterns require absolute addressing. */ + flag_pic = 0; + if (TARGET_ARCH64) + insn = gen_load_pcrel_symdi (op0, op1, op2, op3); + else + insn = gen_load_pcrel_symsi (op0, op1, op2, op3); + flag_pic = orig_flag_pic; - pic_helper_needed = true; + return insn; +} - get_pc_thunk_name (name, REGNO (pic_offset_table_rtx)); - pic_helper_symbol = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name)); +/* Emit code to load the GOT register. */ - global_offset_table = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_"); - } +static void +load_got_register (void) +{ + /* In PIC mode, this will retrieve pic_offset_table_rtx. */ + if (!global_offset_table_rtx) + global_offset_table_rtx = gen_rtx_REG (Pmode, GLOBAL_OFFSET_TABLE_REGNUM); - flag_pic = 0; - if (TARGET_ARCH64) - emit_insn (gen_load_pcrel_symdi (pic_offset_table_rtx, global_offset_table, - pic_helper_symbol)); + if (TARGET_VXWORKS_RTP) + emit_insn (gen_vxworks_load_got ()); else - emit_insn (gen_load_pcrel_symsi (pic_offset_table_rtx, global_offset_table, - pic_helper_symbol)); - flag_pic = orig_flag_pic; + { + /* The GOT symbol is subject to a PC-relative relocation so we need a + helper function to add the PC value and thus get the final value. */ + if (!got_helper_rtx) + { + char name[32]; + get_pc_thunk_name (name, GLOBAL_OFFSET_TABLE_REGNUM); + got_helper_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name)); + } + + emit_insn (gen_load_pcrel_sym (global_offset_table_rtx, sparc_got (), + got_helper_rtx, + GEN_INT (GLOBAL_OFFSET_TABLE_REGNUM))); + } /* Need to emit this whether or not we obey regdecls, since setjmp/longjmp can cause life info to screw up. ??? In the case where we don't obey regdecls, this is not sufficient since we may not fall out the bottom. */ - emit_use (pic_offset_table_rtx); + emit_use (global_offset_table_rtx); } /* Emit a call instruction with the pattern given by PAT. ADDR is the @@ -4447,7 +4509,7 @@ gen_stack_pointer_dec (rtx decrement) /* Expand the function prologue. The prologue is responsible for reserving storage for the frame, saving the call-saved registers and loading the - PIC register if needed. */ + GOT register if needed. */ void sparc_expand_prologue (void) @@ -4555,9 +4617,9 @@ sparc_expand_prologue (void) if (num_gfregs) emit_save_or_restore_regs (SORR_SAVE); - /* Load the PIC register if needed. */ - if (flag_pic && crtl->uses_pic_offset_table) - load_pic_register (); + /* Load the GOT register if needed. */ + if (crtl->uses_pic_offset_table) + load_got_register (); } /* This function generates the assembly code for function entry, which boils @@ -8466,7 +8528,6 @@ sparc_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED) } /* libfunc renaming. */ -#include "config/gofast.h" static void sparc_init_libfuncs (void) @@ -8560,8 +8621,6 @@ sparc_init_libfuncs (void) set_conv_libfunc (ufix_optab, DImode, DFmode, "__dtoul"); } } - - gofast_maybe_init_libfuncs (); } #define def_builtin(NAME, CODE, TYPE) \ @@ -9128,7 +9187,7 @@ sparc_rtx_costs (rtx x, int code, int outer_code, int *total, /* Emit the sequence of insns SEQ while preserving the registers REG and REG2. This is achieved by means of a manual dynamic stack space allocation in the current frame. We make the assumption that SEQ doesn't contain any - function calls, with the possible exception of calls to the PIC helper. */ + function calls, with the possible exception of calls to the GOT helper. */ static void emit_and_preserve (rtx seq, rtx reg, rtx reg2) @@ -9291,20 +9350,19 @@ sparc_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED, { /* The hoops we have to jump through in order to generate a sibcall without using delay slots... */ - rtx spill_reg, spill_reg2, seq, scratch = gen_rtx_REG (Pmode, 1); + rtx spill_reg, seq, scratch = gen_rtx_REG (Pmode, 1); if (flag_pic) { spill_reg = gen_rtx_REG (word_mode, 15); /* %o7 */ - spill_reg2 = gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM); start_sequence (); - /* Delay emitting the PIC helper function because it needs to + /* Delay emitting the GOT helper function because it needs to change the section and we are emitting assembly code. */ - load_pic_register (); /* clobbers %o7 */ + load_got_register (); /* clobbers %o7 */ scratch = sparc_legitimize_pic_address (funexp, scratch); seq = get_insns (); end_sequence (); - emit_and_preserve (seq, spill_reg, spill_reg2); + emit_and_preserve (seq, spill_reg, pic_offset_table_rtx); } else if (TARGET_ARCH32) { @@ -9455,17 +9513,15 @@ sparc_output_dwarf_dtprel (FILE *file, int size, rtx x) static void sparc_file_end (void) { - /* If need to emit the special PIC helper function, do so now. */ - if (pic_helper_needed) + /* If we need to emit the special GOT helper function, do so now. */ + if (got_helper_rtx) { - unsigned int regno = REGNO (pic_offset_table_rtx); - const char *pic_name = reg_names[regno]; - char name[32]; + const char *name = XSTR (got_helper_rtx, 0); + const char *reg_name = reg_names[GLOBAL_OFFSET_TABLE_REGNUM]; #ifdef DWARF2_UNWIND_INFO bool do_cfi; #endif - get_pc_thunk_name (name, regno); if (USE_HIDDEN_LINKONCE) { tree decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, @@ -9500,10 +9556,10 @@ sparc_file_end (void) #endif if (flag_delayed_branch) fprintf (asm_out_file, "\tjmp\t%%o7+8\n\t add\t%%o7, %s, %s\n", - pic_name, pic_name); + reg_name, reg_name); else fprintf (asm_out_file, "\tadd\t%%o7, %s, %s\n\tjmp\t%%o7+8\n\t nop\n", - pic_name, pic_name); + reg_name, reg_name); #ifdef DWARF2_UNWIND_INFO if (do_cfi) fprintf (asm_out_file, "\t.cfi_endproc\n"); diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 596fc15953c..c41a623577b 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -228,21 +228,25 @@ extern enum cmodel sparc_cmodel; /* Note that TARGET_CPU_v9 is assumed to start the list of 64-bit capable cpu's. */ #define TARGET_CPU_sparc 0 -#define TARGET_CPU_v7 0 /* alias for previous */ -#define TARGET_CPU_sparclet 1 -#define TARGET_CPU_sparclite 2 -#define TARGET_CPU_v8 3 /* generic v8 implementation */ -#define TARGET_CPU_supersparc 4 -#define TARGET_CPU_hypersparc 5 -#define TARGET_CPU_sparc86x 6 +#define TARGET_CPU_v7 0 /* alias */ +#define TARGET_CPU_cypress 0 /* alias */ +#define TARGET_CPU_v8 1 /* generic v8 implementation */ +#define TARGET_CPU_supersparc 2 +#define TARGET_CPU_hypersparc 3 +#define TARGET_CPU_leon 4 +#define TARGET_CPU_sparclite 5 +#define TARGET_CPU_f930 5 /* alias */ +#define TARGET_CPU_f934 5 /* alias */ #define TARGET_CPU_sparclite86x 6 -#define TARGET_CPU_v9 7 /* generic v9 implementation */ -#define TARGET_CPU_sparcv9 7 /* alias */ -#define TARGET_CPU_sparc64 7 /* alias */ -#define TARGET_CPU_ultrasparc 8 -#define TARGET_CPU_ultrasparc3 9 -#define TARGET_CPU_niagara 10 -#define TARGET_CPU_niagara2 11 +#define TARGET_CPU_sparclet 7 +#define TARGET_CPU_tsc701 7 /* alias */ +#define TARGET_CPU_v9 8 /* generic v9 implementation */ +#define TARGET_CPU_sparcv9 8 /* alias */ +#define TARGET_CPU_sparc64 8 /* alias */ +#define TARGET_CPU_ultrasparc 9 +#define TARGET_CPU_ultrasparc3 10 +#define TARGET_CPU_niagara 11 +#define TARGET_CPU_niagara2 12 #if TARGET_CPU_DEFAULT == TARGET_CPU_v9 \ || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc \ @@ -299,6 +303,11 @@ extern enum cmodel sparc_cmodel; #define ASM_CPU32_DEFAULT_SPEC "-Asparclite" #endif +#if TARGET_CPU_DEFAULT == TARGET_CPU_sparclite86x +#define CPP_CPU32_DEFAULT_SPEC "-D__sparclite86x__" +#define ASM_CPU32_DEFAULT_SPEC "-Asparclite" +#endif + #if TARGET_CPU_DEFAULT == TARGET_CPU_supersparc #define CPP_CPU32_DEFAULT_SPEC "-D__supersparc__ -D__sparc_v8__" #define ASM_CPU32_DEFAULT_SPEC "" @@ -309,9 +318,9 @@ extern enum cmodel sparc_cmodel; #define ASM_CPU32_DEFAULT_SPEC "" #endif -#if TARGET_CPU_DEFAULT == TARGET_CPU_sparclite86x -#define CPP_CPU32_DEFAULT_SPEC "-D__sparclite86x__" -#define ASM_CPU32_DEFAULT_SPEC "-Asparclite" +#if TARGET_CPU_DEFAULT == TARGET_CPU_leon +#define CPP_CPU32_DEFAULT_SPEC "-D__leon__ -D__sparc_v8__" +#define ASM_CPU32_DEFAULT_SPEC "" #endif #endif @@ -360,10 +369,11 @@ extern enum cmodel sparc_cmodel; %{mcpu=sparclet:-D__sparclet__} %{mcpu=tsc701:-D__sparclet__} \ %{mcpu=sparclite:-D__sparclite__} \ %{mcpu=f930:-D__sparclite__} %{mcpu=f934:-D__sparclite__} \ +%{mcpu=sparclite86x:-D__sparclite86x__} \ %{mcpu=v8:-D__sparc_v8__} \ %{mcpu=supersparc:-D__supersparc__ -D__sparc_v8__} \ %{mcpu=hypersparc:-D__hypersparc__ -D__sparc_v8__} \ -%{mcpu=sparclite86x:-D__sparclite86x__} \ +%{mcpu=leon:-D__leon__ -D__sparc_v8__} \ %{mcpu=v9:-D__sparc_v9__} \ %{mcpu=ultrasparc:-D__sparc_v9__} \ %{mcpu=ultrasparc3:-D__sparc_v9__} \ @@ -526,10 +536,11 @@ enum processor_type { PROCESSOR_CYPRESS, PROCESSOR_V8, PROCESSOR_SUPERSPARC, + PROCESSOR_HYPERSPARC, + PROCESSOR_LEON, PROCESSOR_SPARCLITE, PROCESSOR_F930, PROCESSOR_F934, - PROCESSOR_HYPERSPARC, PROCESSOR_SPARCLITE86X, PROCESSOR_SPARCLET, PROCESSOR_TSC701, @@ -895,10 +906,15 @@ extern int sparc_mode_class[]; not be a register used by the prologue. */ #define STATIC_CHAIN_REGNUM (TARGET_ARCH64 ? 5 : 2) +/* Register which holds the global offset table, if any. */ + +#define GLOBAL_OFFSET_TABLE_REGNUM 23 + /* Register which holds offset table for position-independent data references. */ -#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 23 : INVALID_REGNUM) +#define PIC_OFFSET_TABLE_REGNUM \ + (flag_pic ? GLOBAL_OFFSET_TABLE_REGNUM : INVALID_REGNUM) /* Pick a default value we can notice from override_options: !v9: Default is on. diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index 16b1116f7eb..853bd2fbdcc 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -104,9 +104,14 @@ cypress, v8, supersparc, - sparclite,f930,f934, - hypersparc,sparclite86x, - sparclet,tsc701, + hypersparc, + leon, + sparclite, + f930, + f934, + sparclite86x, + sparclet, + tsc701, v9, ultrasparc, ultrasparc3, @@ -339,6 +344,7 @@ (include "cypress.md") (include "supersparc.md") (include "hypersparc.md") +(include "leon.md") (include "sparclet.md") (include "ultra1_2.md") (include "ultra3.md") @@ -1107,14 +1113,15 @@ ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic ;; value subject to a PC-relative relocation. Operand 2 is a helper function -;; that adds the PC value at the call point to operand 0. +;; that adds the PC value at the call point to register #(operand 3). (define_insn "load_pcrel_sym<P:mode>" [(set (match_operand:P 0 "register_operand" "=r") (unspec:P [(match_operand:P 1 "symbolic_operand" "") - (match_operand:P 2 "call_address_operand" "")] UNSPEC_LOAD_PCREL_SYM)) + (match_operand:P 2 "call_address_operand" "") + (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM)) (clobber (reg:P 15))] - "" + "REGNO (operands[0]) == INTVAL (operands[3])" { if (flag_delayed_branch) return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0"; diff --git a/gcc/config/sparc/t-elf b/gcc/config/sparc/t-elf index 2d7dc9e1bae..18ed2de16e6 100644 --- a/gcc/config/sparc/t-elf +++ b/gcc/config/sparc/t-elf @@ -1,5 +1,5 @@ -# Copyright (C) 1997, 1998, 1999, 2001, 2002, 2005, -# 2007 Free Software Foundation, Inc. +# Copyright (C) 1997, 1998, 1999, 2001, 2002, 2005, 2007, 2010 +# Free Software Foundation, Inc. # # This file is part of GCC. # @@ -32,17 +32,9 @@ fp-bit.c: $(srcdir)/config/fp-bit.c echo '#define FLOAT' > fp-bit.c cat $(srcdir)/config/fp-bit.c >> fp-bit.c -# MULTILIB_OPTIONS should have msparclite too, but we'd have to make -# gas build... MULTILIB_OPTIONS = msoft-float mcpu=v8 MULTILIB_DIRNAMES = soft v8 MULTILIB_MATCHES = msoft-float=mno-fpu mcpu?v8=mv8 LIBGCC = stmp-multilib INSTALL_LIBGCC = install-multilib - -# Assemble startup files. -$(T)crti.o: $(srcdir)/config/sparc/sol2-ci.asm $(GCC_PASSES) - $(GCC_FOR_TARGET) -c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/sparc/sol2-ci.asm -$(T)crtn.o: $(srcdir)/config/sparc/sol2-cn.asm $(GCC_PASSES) - $(GCC_FOR_TARGET) -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/sparc/sol2-cn.asm diff --git a/gcc/config/sparc/t-leon b/gcc/config/sparc/t-leon new file mode 100644 index 00000000000..6573f824e8b --- /dev/null +++ b/gcc/config/sparc/t-leon @@ -0,0 +1,42 @@ +# Copyright (C) 2010 Free Software Foundation, 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/>. + +LIB1ASMSRC = sparc/lb1spc.asm +LIB1ASMFUNCS = _mulsi3 _divsi3 _modsi3 + +# We want fine grained libraries, so use the new code to build the +# floating point emulation libraries. +FPBIT = fp-bit.c +DPBIT = dp-bit.c + +dp-bit.c: $(srcdir)/config/fp-bit.c + cat $(srcdir)/config/fp-bit.c > dp-bit.c + +fp-bit.c: $(srcdir)/config/fp-bit.c + echo '#define FLOAT' > fp-bit.c + cat $(srcdir)/config/fp-bit.c >> fp-bit.c + +# Multilibs for LEON +# LEON is a SPARC-V8, but the AT697 implementation has a bug in the +# V8-specific instructions. +MULTILIB_OPTIONS = mcpu=v7 msoft-float +MULTILIB_DIRNAMES = v7 soft +MULTILIB_MATCHES = mcpu?v7=mv7 msoft-float=mno-fpu + +LIBGCC = stmp-multilib +INSTALL_LIBGCC = install-multilib diff --git a/gcc/config/mips/t-gofast b/gcc/config/sparc/t-leon3 index ba5d61b8598..ce57d16751b 100644 --- a/gcc/config/mips/t-gofast +++ b/gcc/config/sparc/t-leon3 @@ -1,4 +1,4 @@ -# Copyright (C) 2002 Free Software Foundation, Inc. +# Copyright (C) 2010 Free Software Foundation, Inc. # # This file is part of GCC. # @@ -22,16 +22,16 @@ FPBIT = fp-bit.c DPBIT = dp-bit.c dp-bit.c: $(srcdir)/config/fp-bit.c - echo '#ifdef __MIPSEL__' > dp-bit.c - echo '#define FLOAT_BIT_ORDER_MISMATCH' >> dp-bit.c - echo '#endif' >> dp-bit.c - echo '#define US_SOFTWARE_GOFAST' >> dp-bit.c - cat $(srcdir)/config/fp-bit.c >> dp-bit.c + cat $(srcdir)/config/fp-bit.c > dp-bit.c fp-bit.c: $(srcdir)/config/fp-bit.c echo '#define FLOAT' > fp-bit.c - echo '#ifdef __MIPSEL__' >> fp-bit.c - echo '#define FLOAT_BIT_ORDER_MISMATCH' >> fp-bit.c - echo '#endif' >> fp-bit.c - echo '#define US_SOFTWARE_GOFAST' >> fp-bit.c cat $(srcdir)/config/fp-bit.c >> fp-bit.c + +# Multilibs for LEON3 +MULTILIB_OPTIONS = msoft-float +MULTILIB_DIRNAMES = soft +MULTILIB_MATCHES = msoft-float=mno-fpu + +LIBGCC = stmp-multilib +INSTALL_LIBGCC = install-multilib diff --git a/gcc/config/spu/spu.h b/gcc/config/spu/spu.h index 234ff49f114..d56a52b5504 100644 --- a/gcc/config/spu/spu.h +++ b/gcc/config/spu/spu.h @@ -65,9 +65,16 @@ extern GTY(()) int spu_tune; #define UNITS_PER_WORD (BITS_PER_WORD/BITS_PER_UNIT) -/* We never actually change UNITS_PER_WORD, but defining this causes - libgcc to use some different sizes of types when compiling. */ -#define MIN_UNITS_PER_WORD 4 +/* When building libgcc, we need to assume 4 words per units even + though UNITS_PER_WORD is 16, because the SPU has basically a 32-bit + instruction set although register size is 128 bits. In particular, + this causes libgcc to contain __divdi3 instead of __divti3 etc. + However, we allow this default to be re-defined on the command + line, so that we can use the LIB2_SIDITI_CONV_FUNCS mechanism + to get (in addition) TImode versions of some routines. */ +#ifndef LIBGCC2_UNITS_PER_WORD +#define LIBGCC2_UNITS_PER_WORD 4 +#endif #define POINTER_SIZE 32 diff --git a/gcc/config/spu/spu.md b/gcc/config/spu/spu.md index 528a07cfd03..c9bf3c828d5 100644 --- a/gcc/config/spu/spu.md +++ b/gcc/config/spu/spu.md @@ -753,6 +753,73 @@ DONE; }) +(define_expand "floattisf2" + [(set (match_operand:SF 0 "register_operand" "") + (float:SF (match_operand:TI 1 "register_operand" "")))] + "" + { + rtx c0 = gen_reg_rtx (SImode); + rtx r0 = gen_reg_rtx (TImode); + rtx r1 = gen_reg_rtx (SFmode); + rtx r2 = gen_reg_rtx (SImode); + rtx setneg = gen_reg_rtx (SImode); + rtx isneg = gen_reg_rtx (SImode); + rtx neg = gen_reg_rtx (TImode); + rtx mask = gen_reg_rtx (TImode); + + emit_move_insn (c0, GEN_INT (-0x80000000ll)); + + emit_insn (gen_negti2 (neg, operands[1])); + emit_insn (gen_cgt_ti_m1 (isneg, operands[1])); + emit_insn (gen_extend_compare (mask, isneg)); + emit_insn (gen_selb (r0, neg, operands[1], mask)); + emit_insn (gen_andc_si (setneg, c0, isneg)); + + emit_insn (gen_floatunstisf2 (r1, r0)); + + emit_insn (gen_iorsi3 (r2, gen_rtx_SUBREG (SImode, r1, 0), setneg)); + emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, r2, 0)); + DONE; + }) + +(define_insn_and_split "floatunstisf2" + [(set (match_operand:SF 0 "register_operand" "=r") + (unsigned_float:SF (match_operand:TI 1 "register_operand" "r"))) + (clobber (match_scratch:SF 2 "=r")) + (clobber (match_scratch:SF 3 "=r")) + (clobber (match_scratch:SF 4 "=r"))] + "" + "#" + "reload_completed" + [(set (match_dup:SF 0) + (unsigned_float:SF (match_dup:TI 1)))] + { + rtx op1_v4si = gen_rtx_REG (V4SImode, REGNO (operands[1])); + rtx op2_v4sf = gen_rtx_REG (V4SFmode, REGNO (operands[2])); + rtx op2_ti = gen_rtx_REG (TImode, REGNO (operands[2])); + rtx op3_ti = gen_rtx_REG (TImode, REGNO (operands[3])); + + REAL_VALUE_TYPE scale; + real_2expN (&scale, 32, SFmode); + + emit_insn (gen_floatunsv4siv4sf2 (op2_v4sf, op1_v4si)); + emit_insn (gen_shlqby_ti (op3_ti, op2_ti, GEN_INT (4))); + + emit_move_insn (operands[4], + CONST_DOUBLE_FROM_REAL_VALUE (scale, SFmode)); + emit_insn (gen_fmasf4 (operands[2], + operands[2], operands[4], operands[3])); + + emit_insn (gen_shlqby_ti (op3_ti, op3_ti, GEN_INT (4))); + emit_insn (gen_fmasf4 (operands[2], + operands[2], operands[4], operands[3])); + + emit_insn (gen_shlqby_ti (op3_ti, op3_ti, GEN_INT (4))); + emit_insn (gen_fmasf4 (operands[0], + operands[2], operands[4], operands[3])); + DONE; + }) + ;; Do (double)(operands[1]+0x80000000u)-(double)0x80000000 (define_expand "floatsidf2" [(set (match_operand:DF 0 "register_operand" "") @@ -3218,6 +3285,13 @@ DONE; }) +(define_insn "cgt_ti_m1" + [(set (match_operand:SI 0 "spu_reg_operand" "=r") + (gt:SI (match_operand:TI 1 "spu_reg_operand" "r") + (const_int -1)))] + "" + "cgti\t%0,%1,-1") + (define_insn "cgt_ti" [(set (match_operand:SI 0 "spu_reg_operand" "=r") (gt:SI (match_operand:TI 1 "spu_reg_operand" "r") diff --git a/gcc/config/spu/t-spu-elf b/gcc/config/spu/t-spu-elf index cc8c94b387b..a131f64883b 100644 --- a/gcc/config/spu/t-spu-elf +++ b/gcc/config/spu/t-spu-elf @@ -1,4 +1,4 @@ -# Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +# Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, 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 @@ -26,8 +26,8 @@ TARGET_LIBGCC2_CFLAGS = -fPIC -mwarn-reloc -D__IN_LIBGCC2 # We exclude those because the libgcc2.c default versions do not support # the SPU single-precision format (round towards zero). We provide our -# own versions below. -LIB2FUNCS_EXCLUDE = _floatdisf _floatundisf +# own versions below and/or via direct expansion. +LIB2FUNCS_EXCLUDE = _floatdisf _floatundisf _floattisf _floatunstisf # We provide our own version of __divdf3 that performs better and has # better support for non-default rounding modes. @@ -55,14 +55,16 @@ FPBIT = fp-bit.c DPBIT = dp-bit.c dp-bit.c: $(srcdir)/config/fp-bit.c $(srcdir)/config/spu/t-spu-elf - echo '#undef US_SOFTWARE_GOFAST' > dp-bit.c cat $(srcdir)/config/fp-bit.c >> dp-bit.c fp-bit.c: $(srcdir)/config/fp-bit.c $(srcdir)/config/spu/t-spu-elf echo '#define FLOAT' > fp-bit.c - echo '#undef US_SOFTWARE_GOFAST' >> fp-bit.c cat $(srcdir)/config/fp-bit.c >> fp-bit.c +# Build TImode conversion routines to support Fortran 128-bit +# integer data types. +LIB2_SIDITI_CONV_FUNCS=yes + # Don't let CTOR_LIST end up in sdata section. CRTSTUFF_T_CFLAGS = |