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>
* 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.
Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
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.
......@@ -41,7 +41,7 @@ Boston, MA 02111-1307, USA. */
/* The maximum number of insns skipped which will be conditionalised if
possible. */
#define MAX_INSNS_SKIPPED 5
static int max_insns_skipped = 5;
/* Some function declarations. */
extern FILE *asm_out_file;
......@@ -200,6 +200,11 @@ static struct processors all_procs[] =
| FL_ARCH4)},
{"arm810", PROCESSOR_ARM8, (FL_FAST_MULT | FL_MODE32 | FL_MODE26
| 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
| FL_ARCH4)},
{"strongarm110", PROCESSOR_STARM, (FL_FAST_MULT | FL_MODE32 | FL_MODE26
......@@ -362,13 +367,53 @@ arm_override_options ()
target_flags &= ~ARM_FLAG_THUMB;
}
if (TARGET_FPE && arm_fpu != FP_HARD)
arm_fpu = FP_SOFT2;
if (TARGET_FPE && arm_fpu == FP_HARD)
arm_fpu = FP_SOFT3;
/* If optimizing for space, don't synthesize constants */
if (optimize_size)
arm_constant_limit = 1;
/* Override a few things based on the tuning pararmeters. */
switch (arm_cpu)
{
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;
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;
}
/* 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) && arm_cpu == PROCESSOR_ARM2)
flag_schedule_insns = flag_schedule_insns_after_reload = 0;
/* 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;
......@@ -383,11 +428,11 @@ arm_override_options ()
}
}
/* Return 1 if it is possible to return using a single instruction */
int
use_return_insn ()
use_return_insn (iscond)
int iscond;
{
int regno;
......@@ -398,8 +443,12 @@ use_return_insn ()
return 0;
/* Can't be done if interworking with Thumb, and any registers have been
stacked */
if (TARGET_THUMB_INTERWORK)
stacked. Similarly, on StrongARM, conditional returns are expensive
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++)
if (regs_ever_live[regno] && ! call_used_regs[regno])
return 0;
......@@ -1604,6 +1653,11 @@ arm_adjust_cost (insn, link, dep, cost)
{
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
&& GET_CODE (SET_SRC (i_pat)) == MEM
&& (d_pat = single_set (dep)) != NULL
......@@ -2537,6 +2591,13 @@ load_multiple_sequence (operands, nops, regs, base, load_offset)
if (unsorted_offsets[order[nops - 1]] == -4)
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
no more than one insn. */
return (const_ok_for_arm (unsorted_offsets[order[0]])
......@@ -5009,7 +5070,7 @@ output_func_epilogue (f, frame_size)
int volatile_func = (optimize > 0
&& 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
&& !(frame_pointer_needed || TARGET_APCS))
......@@ -5830,7 +5891,7 @@ final_prescan_insn (insn, opvec, noperands)
insns are okay, and the label or unconditional branch to the same
label is not too far away, succeed. */
for (insns_skipped = 0;
!fail && !succeed && insns_skipped++ < MAX_INSNS_SKIPPED;)
!fail && !succeed && insns_skipped++ < max_insns_skipped;)
{
rtx scanbody;
......@@ -5892,7 +5953,7 @@ final_prescan_insn (insn, opvec, noperands)
this_insn = next_nonnote_insn (this_insn);
if (this_insn && this_insn == label
&& insns_skipped < MAX_INSNS_SKIPPED)
&& insns_skipped < max_insns_skipped)
{
if (jump_clobbers)
{
......@@ -5927,6 +5988,12 @@ final_prescan_insn (insn, opvec, noperands)
else if (GET_CODE (SET_SRC (scanbody)) == IF_THEN_ELSE)
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
&& seeking_return)
{
......
......@@ -53,6 +53,8 @@ Boston, MA 02111-1307, USA. */
#define TARGET_CPU_arm810 0x0020
#define TARGET_CPU_strongarm 0x0040
#define TARGET_CPU_strongarm110 0x0040
#define TARGET_CPU_arm9 0x0080
#define TARGET_CPU_arm9tdmi 0x0080
/* Configure didn't specify */
#define TARGET_CPU_generic 0x8000
......@@ -95,7 +97,7 @@ extern int frame_pointer_needed;
#if TARGET_CPU_DEFAULT == TARGET_CPU_arm7m
#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_3M__"
#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__"
#else
#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.
%{march=arm7tdmi:-D__ARM_ARCH_4T__} \
%{march=arm8:-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=strongarm110:-D__ARM_ARCH_4__} \
%{march=armv2:-D__ARM_ARCH_2__} \
......@@ -167,6 +171,8 @@ Unrecognized value in TARGET_CPU_DEFAULT.
%{mcpu=arm7tdmi:-D__ARM_ARCH_4T__} \
%{mcpu=arm8:-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=strongarm110:-D__ARM_ARCH_4__} \
%{!mcpu*:%{!m6:%{!m2:%{!m3:%(cpp_cpu_arch_default)}}}}} \
......@@ -427,6 +433,7 @@ enum processor_type
PROCESSOR_ARM6,
PROCESSOR_ARM7,
PROCESSOR_ARM8,
PROCESSOR_ARM9,
PROCESSOR_STARM,
PROCESSOR_NONE /* NOTE: This must be last, since it doesn't
appear in the attr_cpu list */
......@@ -1165,7 +1172,7 @@ do { \
/* Determine if the epilogue should be output as RTL.
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.
......@@ -2050,7 +2057,7 @@ do { \
fully defined yet. */
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_op (/* HOST_WIDE_INT, enum rtx_code,
enum machine_mode */);
......
/* Configuration for GCC for ARM running NetBSD as host. */
#include <arm/xm-arm.h>
#ifndef SYS_SIGLIST_DECLARED
#define SYS_SIGLIST_DECLARED
#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