Commit b36ba79f by Richard Earnshaw Committed by Richard Earnshaw

Support for ARM9

Support for ARM9
* config/arm/arm.c (all_procs): Add arm9 and arm9tdmi.
* config/arm/arm.h ((TARGET_CPU_arm9, TARGET_CPUD_arm9tdmi): Define.
(TARGET_CPU_DEFAULT): Rework to support ARM9.
(CPP_CPU_ARCH_SPEC): Likewise.
(enum processor_type): Likewise.
* config/arm/arm.md (attr cpu): Add arm9.
General scheduling changes
* config/arm/arm.c (MAX_INSNS_SKIPPED): Delete.
(max_insns_skipped): New variable.
(arm_override_options): If generating hard floating point code for
the FPA, emit code for version 3.
When optimizing for space, don't synthesize constants.
Reword several flags based on the requested processor and optimization
level.
(use_return_insn): New argument iscond, all callers changed.  Don't
use a return insn if it will be conditional and that would be
expensive; eg on StrongARM.
(arm_adjust_cost): Anti- and output- dependencies normally have no
cost.
(load_multiple_sequence): Newer ARMs don't benefit from ldm if
the sequence is short.
(final_prescan_insn): Use max_insns_skipped instead of
MAX_INSNS_SKIPPED.  Note whether we will make a return instruction
conditional, and aviod this if it would be expensive.
* config/arm/arm.md (scheduling attributes and function units):
Rewrite to better describe ARM8, 9 and StrongARM.
* config/arm/arm.md (*movhi_insn_littleend): Make op0 predicate
s_register_operand.
(*ifcompare_plus_move): Use arm_rhs_operand in place of
arm_rhsm_operand.  Rework constraints.
(*if_plus_move): Likewise.
(*ifcompare_move_plus): Likewise.
(*if_move_plus): Likewise.
(*ifcompre_arith_move): Likewise.
(*if_arith_move): Likewise.
(*ifcompare_move_arith): Likewise.
(*if_move_arith): Likewise.
* config/arm/xm-netbsd.h: Don't include arm/xm-arm.h.

From-SVN: r25053
parent 6ea296f8
Sat Feb 6 11:17:03 1999 Richard Earnshaw <rearnsha@arm.com>
Support for ARM9
* config/arm/arm.c (all_procs): Add arm9 and arm9tdmi.
* config/arm/arm.h ((TARGET_CPU_arm9, TARGET_CPUD_arm9tdmi): Define.
(TARGET_CPU_DEFAULT): Rework to support ARM9.
(CPP_CPU_ARCH_SPEC): Likewise.
(enum processor_type): Likewise.
* config/arm/arm.md (attr cpu): Add arm9.
General scheduling changes
* config/arm/arm.c (MAX_INSNS_SKIPPED): Delete.
(max_insns_skipped): New variable.
(arm_override_options): If generating hard floating point code for
the FPA, emit code for version 3.
When optimizing for space, don't synthesize constants.
Reword several flags based on the requested processor and optimization
level.
(use_return_insn): New argument iscond, all callers changed. Don't
use a return insn if it will be conditional and that would be
expensive; eg on StrongARM.
(arm_adjust_cost): Anti- and output- dependencies normally have no
cost.
(load_multiple_sequence): Newer ARMs don't benefit from ldm if
the sequence is short.
(final_prescan_insn): Use max_insns_skipped instead of
MAX_INSNS_SKIPPED. Note whether we will make a return instruction
conditional, and aviod this if it would be expensive.
* config/arm/arm.md (scheduling attributes and function units):
Rewrite to better describe ARM8, 9 and StrongARM.
* config/arm/arm.md (*movhi_insn_littleend): Make op0 predicate
s_register_operand.
(*ifcompare_plus_move): Use arm_rhs_operand in place of
arm_rhsm_operand. Rework constraints.
(*if_plus_move): Likewise.
(*ifcompare_move_plus): Likewise.
(*if_move_plus): Likewise.
(*ifcompre_arith_move): Likewise.
(*if_arith_move): Likewise.
(*ifcompare_move_arith): Likewise.
(*if_move_arith): Likewise.
* config/arm/xm-netbsd.h: Don't include arm/xm-arm.h.
1999-02-05 Michael Meissner <meissner@cygnus.com> 1999-02-05 Michael Meissner <meissner@cygnus.com>
* loop.c (check_dbra_loop): A store using an address giv for which * loop.c (check_dbra_loop): A store using an address giv for which
......
/* Output routines for GCC for ARM/RISCiX. /* Output routines for GCC for ARM.
Copyright (C) 1991, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. Copyright (C) 1991, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl) Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
and Martin Simmons (@harleqn.co.uk). and Martin Simmons (@harleqn.co.uk).
More major hacks by Richard Earnshaw (rwe11@cl.cam.ac.uk) More major hacks by Richard Earnshaw (rearnsha@arm.com).
This file is part of GNU CC. This file is part of GNU CC.
...@@ -41,7 +41,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -41,7 +41,7 @@ Boston, MA 02111-1307, USA. */
/* The maximum number of insns skipped which will be conditionalised if /* The maximum number of insns skipped which will be conditionalised if
possible. */ possible. */
#define MAX_INSNS_SKIPPED 5 static int max_insns_skipped = 5;
/* Some function declarations. */ /* Some function declarations. */
extern FILE *asm_out_file; extern FILE *asm_out_file;
...@@ -200,6 +200,11 @@ static struct processors all_procs[] = ...@@ -200,6 +200,11 @@ static struct processors all_procs[] =
| FL_ARCH4)}, | FL_ARCH4)},
{"arm810", PROCESSOR_ARM8, (FL_FAST_MULT | FL_MODE32 | FL_MODE26 {"arm810", PROCESSOR_ARM8, (FL_FAST_MULT | FL_MODE32 | FL_MODE26
| FL_ARCH4)}, | FL_ARCH4)},
/* The next two are the same, but arm9 only exists in the thumb variant */
{"arm9", PROCESSOR_ARM9, (FL_FAST_MULT | FL_MODE32 | FL_ARCH4
| FL_THUMB)},
{"arm9tdmi", PROCESSOR_ARM9, (FL_FAST_MULT | FL_MODE32 | FL_ARCH4
| FL_THUMB)},
{"strongarm", PROCESSOR_STARM, (FL_FAST_MULT | FL_MODE32 | FL_MODE26 {"strongarm", PROCESSOR_STARM, (FL_FAST_MULT | FL_MODE32 | FL_MODE26
| FL_ARCH4)}, | FL_ARCH4)},
{"strongarm110", PROCESSOR_STARM, (FL_FAST_MULT | FL_MODE32 | FL_MODE26 {"strongarm110", PROCESSOR_STARM, (FL_FAST_MULT | FL_MODE32 | FL_MODE26
...@@ -362,13 +367,53 @@ arm_override_options () ...@@ -362,13 +367,53 @@ arm_override_options ()
target_flags &= ~ARM_FLAG_THUMB; target_flags &= ~ARM_FLAG_THUMB;
} }
if (TARGET_FPE && arm_fpu != FP_HARD) if (TARGET_FPE && arm_fpu == FP_HARD)
arm_fpu = FP_SOFT2; arm_fpu = FP_SOFT3;
/* If optimizing for space, don't synthesize constants */
if (optimize_size)
arm_constant_limit = 1;
/* For arm2/3 there is no need to do any scheduling if there is only /* Override a few things based on the tuning pararmeters. */
a floating point emulator, or we are doing software floating-point. */ switch (arm_cpu)
if ((TARGET_SOFT_FLOAT || arm_fpu != FP_HARD) && arm_cpu == PROCESSOR_ARM2) {
case PROCESSOR_ARM2:
case PROCESSOR_ARM3:
/* For arm2/3 there is no need to do any scheduling if there is
only a floating point emulator, or we are doing software
floating-point. */
if (TARGET_SOFT_FLOAT || arm_fpu != FP_HARD)
flag_schedule_insns = flag_schedule_insns_after_reload = 0; flag_schedule_insns = flag_schedule_insns_after_reload = 0;
break;
case PROCESSOR_ARM6:
case PROCESSOR_ARM7:
break;
case PROCESSOR_ARM8:
case PROCESSOR_ARM9:
/* For these processors, it never costs more than 2 cycles to load a
constant, and the load scheduler may well reduce that to 1. */
arm_constant_limit = 1;
break;
case PROCESSOR_STARM:
/* Same as above */
arm_constant_limit = 1;
/* StrongARM has early execution of branches, a sequence that is worth
skipping is shorter. */
max_insns_skipped = 3;
break;
default:
fatal ("Unknown cpu type selected");
break;
}
/* If optimizing for size, bump the number of instructions that we
are prepared to conditionally execute (even on a StrongARM). */
if (optimize_size)
max_insns_skipped = 6;
arm_prog_mode = TARGET_APCS_32 ? PROG_MODE_PROG32 : PROG_MODE_PROG26; arm_prog_mode = TARGET_APCS_32 ? PROG_MODE_PROG32 : PROG_MODE_PROG26;
...@@ -383,11 +428,11 @@ arm_override_options () ...@@ -383,11 +428,11 @@ arm_override_options ()
} }
} }
/* Return 1 if it is possible to return using a single instruction */ /* Return 1 if it is possible to return using a single instruction */
int int
use_return_insn () use_return_insn (iscond)
int iscond;
{ {
int regno; int regno;
...@@ -398,8 +443,12 @@ use_return_insn () ...@@ -398,8 +443,12 @@ use_return_insn ()
return 0; return 0;
/* Can't be done if interworking with Thumb, and any registers have been /* Can't be done if interworking with Thumb, and any registers have been
stacked */ stacked. Similarly, on StrongARM, conditional returns are expensive
if (TARGET_THUMB_INTERWORK) if they aren't taken and registers have been stacked. */
if (iscond && arm_cpu == PROCESSOR_STARM && frame_pointer_needed)
return 0;
else if ((iscond && arm_cpu == PROCESSOR_STARM)
|| TARGET_THUMB_INTERWORK)
for (regno = 0; regno < 16; regno++) for (regno = 0; regno < 16; regno++)
if (regs_ever_live[regno] && ! call_used_regs[regno]) if (regs_ever_live[regno] && ! call_used_regs[regno])
return 0; return 0;
...@@ -1604,6 +1653,11 @@ arm_adjust_cost (insn, link, dep, cost) ...@@ -1604,6 +1653,11 @@ arm_adjust_cost (insn, link, dep, cost)
{ {
rtx i_pat, d_pat; rtx i_pat, d_pat;
/* XXX This is not strictly true for the FPA. */
if (REG_NOTE_KIND(link) == REG_DEP_ANTI
|| REG_NOTE_KIND(link) == REG_DEP_OUTPUT)
return 0;
if ((i_pat = single_set (insn)) != NULL if ((i_pat = single_set (insn)) != NULL
&& GET_CODE (SET_SRC (i_pat)) == MEM && GET_CODE (SET_SRC (i_pat)) == MEM
&& (d_pat = single_set (dep)) != NULL && (d_pat = single_set (dep)) != NULL
...@@ -2537,6 +2591,13 @@ load_multiple_sequence (operands, nops, regs, base, load_offset) ...@@ -2537,6 +2591,13 @@ load_multiple_sequence (operands, nops, regs, base, load_offset)
if (unsorted_offsets[order[nops - 1]] == -4) if (unsorted_offsets[order[nops - 1]] == -4)
return 4; /* ldmdb */ return 4; /* ldmdb */
/* For ARM8,9 & StrongARM, 2 ldr instructions are faster than an ldm if
the offset isn't small enough */
if (nops == 2
&& (arm_cpu == PROCESSOR_ARM8 || arm_cpu == PROCESSOR_ARM9
|| arm_cpu == PROCESSOR_STARM))
return 0;
/* Can't do it without setting up the offset, only do this if it takes /* Can't do it without setting up the offset, only do this if it takes
no more than one insn. */ no more than one insn. */
return (const_ok_for_arm (unsorted_offsets[order[0]]) return (const_ok_for_arm (unsorted_offsets[order[0]])
...@@ -5009,7 +5070,7 @@ output_func_epilogue (f, frame_size) ...@@ -5009,7 +5070,7 @@ output_func_epilogue (f, frame_size)
int volatile_func = (optimize > 0 int volatile_func = (optimize > 0
&& TREE_THIS_VOLATILE (current_function_decl)); && TREE_THIS_VOLATILE (current_function_decl));
if (use_return_insn() && return_used_this_function) if (use_return_insn (FALSE) && return_used_this_function)
{ {
if ((frame_size + current_function_outgoing_args_size) != 0 if ((frame_size + current_function_outgoing_args_size) != 0
&& !(frame_pointer_needed || TARGET_APCS)) && !(frame_pointer_needed || TARGET_APCS))
...@@ -5830,7 +5891,7 @@ final_prescan_insn (insn, opvec, noperands) ...@@ -5830,7 +5891,7 @@ final_prescan_insn (insn, opvec, noperands)
insns are okay, and the label or unconditional branch to the same insns are okay, and the label or unconditional branch to the same
label is not too far away, succeed. */ label is not too far away, succeed. */
for (insns_skipped = 0; for (insns_skipped = 0;
!fail && !succeed && insns_skipped++ < MAX_INSNS_SKIPPED;) !fail && !succeed && insns_skipped++ < max_insns_skipped;)
{ {
rtx scanbody; rtx scanbody;
...@@ -5892,7 +5953,7 @@ final_prescan_insn (insn, opvec, noperands) ...@@ -5892,7 +5953,7 @@ final_prescan_insn (insn, opvec, noperands)
this_insn = next_nonnote_insn (this_insn); this_insn = next_nonnote_insn (this_insn);
if (this_insn && this_insn == label if (this_insn && this_insn == label
&& insns_skipped < MAX_INSNS_SKIPPED) && insns_skipped < max_insns_skipped)
{ {
if (jump_clobbers) if (jump_clobbers)
{ {
...@@ -5927,6 +5988,12 @@ final_prescan_insn (insn, opvec, noperands) ...@@ -5927,6 +5988,12 @@ final_prescan_insn (insn, opvec, noperands)
else if (GET_CODE (SET_SRC (scanbody)) == IF_THEN_ELSE) else if (GET_CODE (SET_SRC (scanbody)) == IF_THEN_ELSE)
fail = TRUE; fail = TRUE;
} }
/* Fail if a conditional return is undesirable (eg on a
StrongARM), but still allow this if optimizing for size. */
else if (GET_CODE (scanbody) == RETURN
&& ! use_return_insn (TRUE)
&& ! optimize_size)
fail = TRUE;
else if (GET_CODE (scanbody) == RETURN else if (GET_CODE (scanbody) == RETURN
&& seeking_return) && seeking_return)
{ {
......
...@@ -53,6 +53,8 @@ Boston, MA 02111-1307, USA. */ ...@@ -53,6 +53,8 @@ Boston, MA 02111-1307, USA. */
#define TARGET_CPU_arm810 0x0020 #define TARGET_CPU_arm810 0x0020
#define TARGET_CPU_strongarm 0x0040 #define TARGET_CPU_strongarm 0x0040
#define TARGET_CPU_strongarm110 0x0040 #define TARGET_CPU_strongarm110 0x0040
#define TARGET_CPU_arm9 0x0080
#define TARGET_CPU_arm9tdmi 0x0080
/* Configure didn't specify */ /* Configure didn't specify */
#define TARGET_CPU_generic 0x8000 #define TARGET_CPU_generic 0x8000
...@@ -95,7 +97,7 @@ extern int frame_pointer_needed; ...@@ -95,7 +97,7 @@ extern int frame_pointer_needed;
#if TARGET_CPU_DEFAULT == TARGET_CPU_arm7m #if TARGET_CPU_DEFAULT == TARGET_CPU_arm7m
#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_3M__" #define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_3M__"
#else #else
#if TARGET_CPU_DEFAULT == TARGET_CPU_arm7tdmi #if TARGET_CPU_DEFAULT == TARGET_CPU_arm7tdmi || TARGET_CPU_DEFAULT == TARGET_CPU_ARM9
#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_4T__" #define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_4T__"
#else #else
#if TARGET_CPU_DEFAULT == TARGET_CPU_arm8 || TARGET_CPU_DEFAULT == TARGET_CPU_arm810 || TARGET_CPU_DEFAULT == TARGET_CPU_strongarm #if TARGET_CPU_DEFAULT == TARGET_CPU_arm8 || TARGET_CPU_DEFAULT == TARGET_CPU_arm810 || TARGET_CPU_DEFAULT == TARGET_CPU_strongarm
...@@ -140,6 +142,8 @@ Unrecognized value in TARGET_CPU_DEFAULT. ...@@ -140,6 +142,8 @@ Unrecognized value in TARGET_CPU_DEFAULT.
%{march=arm7tdmi:-D__ARM_ARCH_4T__} \ %{march=arm7tdmi:-D__ARM_ARCH_4T__} \
%{march=arm8:-D__ARM_ARCH_4__} \ %{march=arm8:-D__ARM_ARCH_4__} \
%{march=arm810:-D__ARM_ARCH_4__} \ %{march=arm810:-D__ARM_ARCH_4__} \
%{march=arm9:-D__ARM_ARCH_4T__} \
%{march=arm9tdmi:-D__ARM_ARCH_4T__} \
%{march=strongarm:-D__ARM_ARCH_4__} \ %{march=strongarm:-D__ARM_ARCH_4__} \
%{march=strongarm110:-D__ARM_ARCH_4__} \ %{march=strongarm110:-D__ARM_ARCH_4__} \
%{march=armv2:-D__ARM_ARCH_2__} \ %{march=armv2:-D__ARM_ARCH_2__} \
...@@ -167,6 +171,8 @@ Unrecognized value in TARGET_CPU_DEFAULT. ...@@ -167,6 +171,8 @@ Unrecognized value in TARGET_CPU_DEFAULT.
%{mcpu=arm7tdmi:-D__ARM_ARCH_4T__} \ %{mcpu=arm7tdmi:-D__ARM_ARCH_4T__} \
%{mcpu=arm8:-D__ARM_ARCH_4__} \ %{mcpu=arm8:-D__ARM_ARCH_4__} \
%{mcpu=arm810:-D__ARM_ARCH_4__} \ %{mcpu=arm810:-D__ARM_ARCH_4__} \
%{mcpu=arm9:-D__ARM_ARCH_4T__} \
%{mcpu=arm9tdmi:-D__ARM_ARCH_4T__} \
%{mcpu=strongarm:-D__ARM_ARCH_4__} \ %{mcpu=strongarm:-D__ARM_ARCH_4__} \
%{mcpu=strongarm110:-D__ARM_ARCH_4__} \ %{mcpu=strongarm110:-D__ARM_ARCH_4__} \
%{!mcpu*:%{!m6:%{!m2:%{!m3:%(cpp_cpu_arch_default)}}}}} \ %{!mcpu*:%{!m6:%{!m2:%{!m3:%(cpp_cpu_arch_default)}}}}} \
...@@ -427,6 +433,7 @@ enum processor_type ...@@ -427,6 +433,7 @@ enum processor_type
PROCESSOR_ARM6, PROCESSOR_ARM6,
PROCESSOR_ARM7, PROCESSOR_ARM7,
PROCESSOR_ARM8, PROCESSOR_ARM8,
PROCESSOR_ARM9,
PROCESSOR_STARM, PROCESSOR_STARM,
PROCESSOR_NONE /* NOTE: This must be last, since it doesn't PROCESSOR_NONE /* NOTE: This must be last, since it doesn't
appear in the attr_cpu list */ appear in the attr_cpu list */
...@@ -1165,7 +1172,7 @@ do { \ ...@@ -1165,7 +1172,7 @@ do { \
/* Determine if the epilogue should be output as RTL. /* Determine if the epilogue should be output as RTL.
You should override this if you define FUNCTION_EXTRA_EPILOGUE. */ You should override this if you define FUNCTION_EXTRA_EPILOGUE. */
#define USE_RETURN_INSN use_return_insn () #define USE_RETURN_INSN(ISCOND) use_return_insn (ISCOND)
/* Definitions for register eliminations. /* Definitions for register eliminations.
...@@ -2050,7 +2057,7 @@ do { \ ...@@ -2050,7 +2057,7 @@ do { \
fully defined yet. */ fully defined yet. */
void arm_override_options (/* void */); void arm_override_options (/* void */);
int use_return_insn (/* void */); int use_return_insn (/* int */);
int const_ok_for_arm (/* HOST_WIDE_INT */); int const_ok_for_arm (/* HOST_WIDE_INT */);
int const_ok_for_op (/* HOST_WIDE_INT, enum rtx_code, int const_ok_for_op (/* HOST_WIDE_INT, enum rtx_code,
enum machine_mode */); enum machine_mode */);
......
/* Configuration for GCC for ARM running NetBSD as host. */ /* Configuration for GCC for ARM running NetBSD as host. */
#include <arm/xm-arm.h>
#ifndef SYS_SIGLIST_DECLARED #ifndef SYS_SIGLIST_DECLARED
#define SYS_SIGLIST_DECLARED #define SYS_SIGLIST_DECLARED
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment