aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/arm/arm.md
diff options
context:
space:
mode:
authorRichard Earnshaw <rearnsha@arm.com>1999-02-06 04:09:55 +0000
committerRichard Earnshaw <rearnsha@gcc.gnu.org>1999-02-06 04:09:55 +0000
commitb36ba79f65f341f556662aea2d2f7c14c4fb1ec5 (patch)
treeaee5871e6a231914d436ff68b5140b74e13c8796 /gcc/config/arm/arm.md
parent6ea296f8bf495790cf5ebebaef290f2a8810eb83 (diff)
downloadgcc-b36ba79f65f341f556662aea2d2f7c14c4fb1ec5.zip
gcc-b36ba79f65f341f556662aea2d2f7c14c4fb1ec5.tar.gz
gcc-b36ba79f65f341f556662aea2d2f7c14c4fb1ec5.tar.bz2
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
Diffstat (limited to 'gcc/config/arm/arm.md')
-rw-r--r--gcc/config/arm/arm.md219
1 files changed, 118 insertions, 101 deletions
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index c717d45..96843f0 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -1,8 +1,8 @@
-;;- Machine description for Advanced RISC Machines' ARM for GNU compiler
+;;- Machine description for ARM for GNU compiler
;; Copyright (C) 1991, 93-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.
@@ -45,11 +45,9 @@
; by the -mapcs-{32,26} flag, and possibly the -mcpu=... option.
(define_attr "prog_mode" "prog26,prog32" (const (symbol_ref "arm_prog_mode")))
-; CPU attribute is used to determine whether condition codes are clobbered
-; by a call insn: on the arm6 they are if in 32-bit addressing mode; on the
-; arm2 and arm3 the condition codes are restored by the return.
-
-(define_attr "cpu" "arm2,arm3,arm6,arm7,arm8,st_arm"
+; CPU attribute is used to determine the best instruction mix for performance
+; on the named processor.
+(define_attr "cpu" "arm2,arm3,arm6,arm7,arm8,arm9,st_arm"
(const (symbol_ref "arm_cpu_attr")))
; Floating Point Unit. If we only have floating point emulation, then there
@@ -104,7 +102,7 @@
; Load scheduling, set from the cpu characteristic
(define_attr "ldsched" "no,yes"
- (if_then_else (eq_attr "cpu" "arm8,st_arm")
+ (if_then_else (eq_attr "cpu" "arm8,arm9,st_arm")
(const_string "yes")
(const_string "no")))
@@ -135,6 +133,15 @@
(const_string "clob") (const_string "nocond"))
(const_string "nocond")))
+; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
+; have one. Later ones, such as StrongARM, have write-back caches, so don't
+; suffer blockages enough to warrent modelling this (and it can adversely
+; affect the schedule).
+(define_attr "model_wbuf" "no,yes"
+ (if_then_else (eq_attr "cpu" "arm6,arm7")
+ (const_string "yes")
+ (const_string "no")))
+
(define_attr "write_conflict" "no,yes"
(if_then_else (eq_attr "type"
"block,float_em,f_load,f_store,f_mem_r,r_mem_f,call,load")
@@ -194,59 +201,85 @@
(define_function_unit "fpa_mem" 1 0 (and (eq_attr "fpu" "fpa")
(eq_attr "type" "f_load")) 3 1)
-(define_function_unit "write_buf" 1 2 (eq_attr "type" "store1") 5 3)
-(define_function_unit "write_buf" 1 2 (eq_attr "type" "store2") 7 4)
-(define_function_unit "write_buf" 1 2 (eq_attr "type" "store3") 9 5)
-(define_function_unit "write_buf" 1 2 (eq_attr "type" "store4") 11 6)
-(define_function_unit "write_buf" 1 2 (eq_attr "type" "r_mem_f") 5 3)
-
-;; The write_blockage unit models (partially), the fact that writes will stall
+;;--------------------------------------------------------------------
+;; Write buffer
+;;--------------------------------------------------------------------
+;; Strictly we should model a 4-deep write buffer for ARM7xx based chips
+(define_function_unit "write_buf" 1 2
+ (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "type" "store1,r_mem_f")) 5 3)
+(define_function_unit "write_buf" 1 2
+ (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "type" "store2")) 7 4)
+(define_function_unit "write_buf" 1 2
+ (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "type" "store3")) 9 5)
+(define_function_unit "write_buf" 1 2
+ (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "type" "store4")) 11 6)
+
+;;--------------------------------------------------------------------
+;; Write blockage unit
+;;--------------------------------------------------------------------
+;; The write_blockage unit models (partially), the fact that reads will stall
;; until the write buffer empties.
-
-(define_function_unit "write_blockage" 1 0 (eq_attr "type" "store1") 5 5
- [(eq_attr "write_conflict" "yes")])
-(define_function_unit "write_blockage" 1 0 (eq_attr "type" "store2") 7 7
+;; The f_mem_r and r_mem_f could also block, but they are to the stack,
+;; so we don't model them here
+(define_function_unit "write_blockage" 1 0 (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "type" "store1")) 5 5
[(eq_attr "write_conflict" "yes")])
-(define_function_unit "write_blockage" 1 0 (eq_attr "type" "store3") 9 9
+(define_function_unit "write_blockage" 1 0 (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "type" "store2")) 7 7
[(eq_attr "write_conflict" "yes")])
-(define_function_unit "write_blockage" 1 0 (eq_attr "type" "store4") 11 11
+(define_function_unit "write_blockage" 1 0 (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "type" "store3")) 9 9
[(eq_attr "write_conflict" "yes")])
-(define_function_unit "write_blockage" 1 0 (eq_attr "type" "r_mem_f") 5 5
+(define_function_unit "write_blockage" 1 0
+ (and (eq_attr "model_wbuf" "yes") (eq_attr "type" "store4")) 11 11
[(eq_attr "write_conflict" "yes")])
-(define_function_unit "write_blockage" 1 0
- (eq_attr "write_conflict" "yes") 1 1)
-
+(define_function_unit "write_blockage" 1 0
+ (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "write_conflict" "yes")) 1 1)
+
+;;--------------------------------------------------------------------
+;; Core unit
+;;--------------------------------------------------------------------
+;; Everything must spend at least one cycle in the core unit
+(define_function_unit "core" 1 0
+ (and (eq_attr "ldsched" "yes") (eq_attr "type" "store1")) 1 1)
+(define_function_unit "core" 1 0
+ (and (eq_attr "ldsched" "yes") (eq_attr "type" "load")) 2 1)
-(define_function_unit "core" 1 1 (eq_attr "core_cycles" "single") 1 1)
+(define_function_unit "core" 1 0
+ (and (eq_attr "ldsched" "!yes") (eq_attr "type" "load,store1")) 2 2)
-(define_function_unit "core" 1 1
- (and (eq_attr "ldsched" "yes") (eq_attr "type" "load")) 1 1)
+(define_function_unit "core" 1 0
+ (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_load")) 3 3)
-(define_function_unit "core" 1 1
- (and (eq_attr "ldsched" "!yes") (eq_attr "type" "load")) 2 2)
+(define_function_unit "core" 1 0
+ (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_store")) 4 4)
-(define_function_unit "core" 1 1 (eq_attr "type" "mult") 16 16)
+(define_function_unit "core" 1 0
+ (and (eq_attr "fpu" "fpa") (eq_attr "type" "r_mem_f")) 6 6)
-(define_function_unit "core" 1 1
- (and (eq_attr "ldsched" "yes") (eq_attr "type" "store1")) 1 1)
+(define_function_unit "core" 1 0
+ (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_mem_r")) 7 7)
-(define_function_unit "core" 1 1
- (and (eq_attr "ldsched" "!yes") (eq_attr "type" "store1")) 2 2)
+(define_function_unit "core" 1 0
+ (and (eq_attr "cpu" "!arm8,st_arm") (eq_attr "type" "mult")) 16 16)
-(define_function_unit "core" 1 1 (eq_attr "type" "store2") 3 3)
+(define_function_unit "core" 1 0
+ (and (eq_attr "cpu" "arm8") (eq_attr "type" "mult")) 4 4)
-(define_function_unit "core" 1 1 (eq_attr "type" "store3") 4 4)
+(define_function_unit "core" 1 0
+ (and (eq_attr "cpu" "st_arm") (eq_attr "type" "mult")) 3 2)
-(define_function_unit "core" 1 1 (eq_attr "type" "store4") 5 5)
+(define_function_unit "core" 1 0 (eq_attr "type" "store2") 3 3)
-(define_function_unit "core" 1 1
- (and (eq_attr "core_cycles" "multi")
- (eq_attr "type" "!mult,load,store2,store3,store4")) 32 32)
-
-(define_function_unit "loader" 1 0
- (and (eq_attr "ldsched" "yes") (eq_attr "type" "load")) 2 1)
+(define_function_unit "core" 1 0 (eq_attr "type" "store3") 4 4)
+(define_function_unit "core" 1 0 (eq_attr "type" "store4") 5 5)
;; Note: For DImode insns, there is normally no reason why operands should
;; not be in the same register, what we don't want is for something being
@@ -3048,7 +3081,7 @@
[(set_attr "type" "*,*,load,store1")])
(define_insn "*movhi_insn_littleend"
- [(set (match_operand:HI 0 "general_operand" "=r,r,r")
+ [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
(match_operand:HI 1 "general_operand" "rI,K,m"))]
"! arm_arch4
&& ! BYTES_BIG_ENDIAN
@@ -4252,7 +4285,7 @@
;; Often the return insn will be the same as loading from memory, so set attr
(define_insn "return"
[(return)]
- "USE_RETURN_INSN"
+ "USE_RETURN_INSN(FALSE)"
"*
{
extern int arm_ccfsm_state;
@@ -4272,7 +4305,7 @@
[(match_operand 1 "cc_register" "") (const_int 0)])
(return)
(pc)))]
- "USE_RETURN_INSN"
+ "USE_RETURN_INSN(TRUE)"
"*
{
extern int arm_ccfsm_state;
@@ -4293,7 +4326,7 @@
[(match_operand 1 "cc_register" "") (const_int 0)])
(pc)
(return)))]
- "USE_RETURN_INSN"
+ "USE_RETURN_INSN(TRUE)"
"*
{
extern int arm_ccfsm_state;
@@ -4895,7 +4928,7 @@
(plus:SI
(match_operand:SI 2 "s_register_operand" "r,r")
(match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
- (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
+ (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
(clobber (reg:CC 24))]
""
"#"
@@ -4903,32 +4936,30 @@
(set_attr "length" "8,12")])
(define_insn "*if_plus_move"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r")
+ [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
(if_then_else:SI
(match_operator 4 "comparison_operator"
[(match_operand 5 "cc_register" "") (const_int 0)])
(plus:SI
- (match_operand:SI 2 "s_register_operand" "r,r,r,r,r,r")
- (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L,rI,L"))
- (match_operand:SI 1 "arm_rhsm_operand" "0,0,?rI,?rI,m,m")))]
+ (match_operand:SI 2 "s_register_operand" "r,r,r,r")
+ (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
+ (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
""
"@
add%d4\\t%0, %2, %3
sub%d4\\t%0, %2, #%n3
add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
- sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1
- add%d4\\t%0, %2, %3\;ldr%D4\\t%0, %1
- sub%d4\\t%0, %2, #%n3\;ldr%D4\\t%0, %1"
+ sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
[(set_attr "conds" "use")
- (set_attr "length" "4,4,8,8,8,8")
- (set_attr "type" "*,*,*,*,load,load")])
+ (set_attr "length" "4,4,8,8")
+ (set_attr "type" "*,*,*,*")])
(define_insn "*ifcompare_move_plus"
[(set (match_operand:SI 0 "s_register_operand" "=r,r")
(if_then_else:SI (match_operator 6 "comparison_operator"
[(match_operand:SI 4 "s_register_operand" "r,r")
(match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
- (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
+ (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
(plus:SI
(match_operand:SI 2 "s_register_operand" "r,r")
(match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
@@ -4939,25 +4970,23 @@
(set_attr "length" "8,12")])
(define_insn "*if_move_plus"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r")
+ [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
(if_then_else:SI
(match_operator 4 "comparison_operator"
[(match_operand 5 "cc_register" "") (const_int 0)])
- (match_operand:SI 1 "arm_rhsm_operand" "0,0,?rI,?rI,m,m")
+ (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
(plus:SI
- (match_operand:SI 2 "s_register_operand" "r,r,r,r,r,r")
- (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L,rI,L"))))]
+ (match_operand:SI 2 "s_register_operand" "r,r,r,r")
+ (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
""
"@
add%D4\\t%0, %2, %3
sub%D4\\t%0, %2, #%n3
add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
- sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1
- add%D4\\t%0, %2, %3\;ldr%d4\\t%0, %1
- sub%D4\\t%0, %2, #%n3\;ldr%d4\\t%0, %1"
+ sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
[(set_attr "conds" "use")
- (set_attr "length" "4,4,8,8,8,8")
- (set_attr "type" "*,*,*,*,load,load")])
+ (set_attr "length" "4,4,8,8")
+ (set_attr "type" "*,*,*,*")])
(define_insn "*ifcompare_arith_arith"
[(set (match_operand:SI 0 "s_register_operand" "=r")
@@ -4999,7 +5028,7 @@
(match_operator:SI 7 "shiftable_operator"
[(match_operand:SI 4 "s_register_operand" "r,r")
(match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
- (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
+ (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
(clobber (reg:CC 24))]
""
"*
@@ -5025,40 +5054,34 @@
output_asm_insn (\"cmp\\t%2, %3\", operands);
output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
if (which_alternative != 0)
- {
- if (GET_CODE (operands[1]) == MEM)
- return \"ldr%D6\\t%0, %1\";
- else
- return \"mov%D6\\t%0, %1\";
- }
+ return \"mov%D6\\t%0, %1\";
return \"\";
"
[(set_attr "conds" "clob")
(set_attr "length" "8,12")])
(define_insn "*if_arith_move"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
+ [(set (match_operand:SI 0 "s_register_operand" "=r,r")
(if_then_else:SI (match_operator 4 "comparison_operator"
[(match_operand 6 "cc_register" "") (const_int 0)])
(match_operator:SI 5 "shiftable_operator"
- [(match_operand:SI 2 "s_register_operand" "r,r,r")
- (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI")])
- (match_operand:SI 1 "arm_rhsm_operand" "0,?rI,m")))]
+ [(match_operand:SI 2 "s_register_operand" "r,r")
+ (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
+ (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
""
"@
%I5%d4\\t%0, %2, %3
- %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
- %I5%d4\\t%0, %2, %3\;ldr%D4\\t%0, %1"
+ %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
[(set_attr "conds" "use")
- (set_attr "length" "4,8,8")
- (set_attr "type" "*,*,load")])
+ (set_attr "length" "4,8")
+ (set_attr "type" "*,*")])
(define_insn "*ifcompare_move_arith"
[(set (match_operand:SI 0 "s_register_operand" "=r,r")
(if_then_else:SI (match_operator 6 "comparison_operator"
[(match_operand:SI 4 "s_register_operand" "r,r")
(match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
- (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
+ (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
(match_operator:SI 7 "shiftable_operator"
[(match_operand:SI 2 "s_register_operand" "r,r")
(match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
@@ -5088,34 +5111,28 @@
output_asm_insn (\"cmp\\t%4, %5\", operands);
if (which_alternative != 0)
- {
- if (GET_CODE (operands[1]) == MEM)
- output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
- else
- output_asm_insn (\"mov%d6\\t%0, %1\", operands);
- }
+ output_asm_insn (\"mov%d6\\t%0, %1\", operands);
return \"%I7%D6\\t%0, %2, %3\";
"
[(set_attr "conds" "clob")
(set_attr "length" "8,12")])
(define_insn "*if_move_arith"
- [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
+ [(set (match_operand:SI 0 "s_register_operand" "=r,r")
(if_then_else:SI
(match_operator 4 "comparison_operator"
[(match_operand 6 "cc_register" "") (const_int 0)])
- (match_operand:SI 1 "arm_rhsm_operand" "0,?rI,m")
+ (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
(match_operator:SI 5 "shiftable_operator"
- [(match_operand:SI 2 "s_register_operand" "r,r,r")
- (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI")])))]
+ [(match_operand:SI 2 "s_register_operand" "r,r")
+ (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
""
"@
%I5%D4\\t%0, %2, %3
- %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
- %I5%D4\\t%0, %2, %3\;ldr%d4\\t%0, %1"
+ %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
[(set_attr "conds" "use")
- (set_attr "length" "4,8,8")
- (set_attr "type" "*,*,load")])
+ (set_attr "length" "4,8")
+ (set_attr "type" "*,*")])
(define_insn "*ifcompare_move_not"
[(set (match_operand:SI 0 "s_register_operand" "=r,r")
@@ -5975,7 +5992,7 @@
(match_operand:SI 1 "general_operand" "g"))
(clobber (reg:SI 14))])
(return)]
- "(GET_CODE (operands[0]) == SYMBOL_REF && USE_RETURN_INSN
+ "(GET_CODE (operands[0]) == SYMBOL_REF && USE_RETURN_INSN(FALSE)
&& !get_frame_size () && !current_function_calls_alloca
&& !frame_pointer_needed && !current_function_args_size)"
"*
@@ -6003,7 +6020,7 @@
(match_operand:SI 2 "general_operand" "g")))
(clobber (reg:SI 14))])
(return)]
- "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
+ "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN(FALSE)
&& !get_frame_size () && !current_function_calls_alloca
&& !frame_pointer_needed && !current_function_args_size)"
"*
@@ -6035,7 +6052,7 @@
(clobber (reg:SI 14))])
(use (match_dup 0))
(return)]
- "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
+ "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN(FALSE)
&& !get_frame_size () && !current_function_calls_alloca
&& !frame_pointer_needed && !current_function_args_size)"
"*