From 849170fd9b6064f9c489fc2730561561cdbc05b0 Mon Sep 17 00:00:00 2001 From: erich Date: Thu, 8 May 1997 22:17:34 +0000 Subject: [PATCH] (attr cpu): Add new cpu types for arm8 and strongarm. (attr ldsched): New attribute, set if processor has a load_delay slot. (function_unit core): Rework to handle load delay slots. (function_unit loader): New function unit. (movsi): Handle pic. (pic_load_addr): New expand. (*pic_load_addr_based_insn, pic_add_dot_plus_eight): New patterns. (peepholes to cause flow to return to a label after a function call): Delete, these have been disabled for a while now. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@14052 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/config/arm/arm.md | 164 +++++++++++++++++++++----------------------------- 1 file changed, 68 insertions(+), 96 deletions(-) diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 444e9adcc17..d28a3a0bf32 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -1,5 +1,5 @@ ;;- Machine description for Advanced RISC Machines' ARM for GNU compiler -;; Copyright (C) 1991, 1993, 1994, 1995, 1996 Free Software Foundation, Inc. +;; Copyright (C) 1991, 93, 94, 95, 96, 1997 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) @@ -49,7 +49,7 @@ ; 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" +(define_attr "cpu" "arm2,arm3,arm6,arm7,arm8,st_arm" (const (symbol_ref "arm_cpu_attr"))) ; Floating Point Unit. If we only have floating point emulation, then there @@ -102,6 +102,12 @@ "normal,mult,block,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith,float_em,f_load,f_store,f_mem_r,r_mem_f,f_2_r,r_2_f,call,load,store1,store2,store3,store4" (const_string "normal")) +; Load scheduling, set from the cpu characteristic +(define_attr "ldsched" "no,yes" + (if_then_else (eq_attr "cpu" "arm8,st_arm") + (const_string "yes") + (const_string "no"))) + ; condition codes: this one is used by final_prescan_insn to speed up ; conditionalizing instructions. It saves having to scan the rtl to see if ; it uses or alters the condition codes. @@ -210,13 +216,23 @@ (define_function_unit "write_blockage" 1 0 (eq_attr "write_conflict" "yes") 1 1) + + (define_function_unit "core" 1 1 (eq_attr "core_cycles" "single") 1 1) -(define_function_unit "core" 1 1 (eq_attr "type" "load") 2 2) +(define_function_unit "core" 1 1 + (and (eq_attr "ldsched" "yes") (eq_attr "type" "load")) 1 1) + +(define_function_unit "core" 1 1 + (and (eq_attr "ldsched" "!yes") (eq_attr "type" "load")) 2 2) (define_function_unit "core" 1 1 (eq_attr "type" "mult") 16 16) -(define_function_unit "core" 1 1 (eq_attr "type" "store1") 2 2) +(define_function_unit "core" 1 1 + (and (eq_attr "ldsched" "yes") (eq_attr "type" "store1")) 1 1) + +(define_function_unit "core" 1 1 + (and (eq_attr "ldsched" "!yes") (eq_attr "type" "store1")) 2 2) (define_function_unit "core" 1 1 (eq_attr "type" "store2") 3 3) @@ -228,6 +244,9 @@ (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) + ;; 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 @@ -2420,6 +2439,11 @@ : preserve_subexpressions_p ())); DONE; } + if (CONSTANT_P (operands[1]) && flag_pic) + operands[1] = legitimize_pic_address (operands[1], SImode, + ((reload_in_progress + || reload_completed) + ? operands[0] : 0)); ") (define_insn "*movsi_insn" @@ -2463,6 +2487,46 @@ && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT))" "adr%?\\t%0, %a1") +/* When generating pic, we need to load the symbol offset into a register. + So that the optimizer does not confuse this with a normal symbol load + we use an unspec. The offset will be loaded from a constant pool entry, + since that is the only type of relocation we can use. */ + +(define_insn "pic_load_addr" + [(set (match_operand:SI 0 "s_register_operand" "=r") + (unspec:SI [(match_operand 1 "" "")] 3))] + "flag_pic" + "ldr%?\\t%0, %a1" + [(set_attr "type" "load")]) + +;; This variant is used for AOF assembly, since it needs to mention the +;; pic register in the rtl. +(define_expand "pic_load_addr_based" + [(set (match_operand:SI 0 "s_register_operand" "=r") + (unspec:SI [(match_operand 1 "" "") (match_dup 2)] 3))] + "flag_pic" + "operands[2] = pic_offset_table_rtx;") + +(define_insn "*pic_load_addr_based_insn" + [(set (match_operand:SI 0 "s_register_operand" "=r") + (unspec:SI [(match_operand 1 "" "") + (match_operand 2 "s_register_operand" "r")] 3))] + "flag_pic && operands[2] == pic_offset_table_rtx" + "* +#ifdef AOF_ASSEMBLER + operands[1] = aof_pic_entry (operands[1]); +#endif + output_asm_insn (\"ldr%?\\t%0, %a1\", operands); + return \"\"; +" [(set_attr "type" "load")]) + +(define_insn "pic_add_dot_plus_eight" + [(set (pc) (label_ref (match_operand 0 "" ""))) + (set (match_operand 1 "register_operand" "+r") + (plus:SI (match_dup 1) (const (plus:SI (pc) (const_int 8)))))] + "flag_pic" + "add%?\\t%1, %|pc, %1") + ;; If copying one reg to another we can set the condition codes according to ;; its value. Such a move is common after a return from subroutine and the ;; result is being tested against zero. @@ -5775,98 +5839,6 @@ [(set_attr "type" "call") (set_attr "length" "8")]) -;; If calling a subroutine and then jumping back to somewhere else, but not -;; too far away, then we can set the link register with the branch address -;; and jump direct to the subroutine. On return from the subroutine -;; execution continues at the branch; this avoids a prefetch stall. -;; We use the length attribute (via short_branch ()) to establish whether or -;; not this is possible, this is the same as the sparc does. - -(define_peephole - [(parallel[(call (mem:SI (match_operand:SI 0 "" "X")) - (match_operand:SI 1 "general_operand" "g")) - (clobber (reg:SI 14))]) - (set (pc) - (label_ref (match_operand 2 "" "")))] - "0 && GET_CODE (operands[0]) == SYMBOL_REF - && short_branch (INSN_UID (insn), INSN_UID (operands[2])) - && arm_insn_not_targeted (insn)" - "* -{ - int backward = arm_backwards_branch (INSN_UID (insn), - INSN_UID (operands[2])); - -#if 0 - /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or - * above, leaving it out means that the code will still run on an arm 2 or 3 - */ - if (TARGET_6) - { - if (backward) - output_asm_insn (\"sub%?\\t%|lr, %|pc, #(8 + . -%l2)\", operands); - else - output_asm_insn (\"add%?\\t%|lr, %|pc, #(%l2 - . -8)\", operands); - } - else -#endif - { - output_asm_insn (\"mov%?\\t%|lr, %|pc\\t%@ protect cc\", operands); - if (backward) - output_asm_insn (\"sub%?\\t%|lr, %|lr, #(4 + . -%l2)\", operands); - else - output_asm_insn (\"add%?\\t%|lr, %|lr, #(%l2 - . -4)\", operands); - } - return \"b%?\\t%a0\"; -}" -[(set_attr "type" "call") - (set (attr "length") - (if_then_else (eq_attr "prog_mode" "prog32") - (const_int 8) - (const_int 12)))]) - -(define_peephole - [(parallel[(set (match_operand:SI 0 "s_register_operand" "=r") - (call (mem:SI (match_operand:SI 1 "" "X")) - (match_operand:SI 2 "general_operand" "g"))) - (clobber (reg:SI 14))]) - (set (pc) - (label_ref (match_operand 3 "" "")))] - "0 && GET_CODE (operands[0]) == SYMBOL_REF - && short_branch (INSN_UID (insn), INSN_UID (operands[3])) - && arm_insn_not_targeted (insn)" - "* -{ - int backward = arm_backwards_branch (INSN_UID (insn), - INSN_UID (operands[3])); - -#if 0 - /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or - * above, leaving it out means that the code will still run on an arm 2 or 3 - */ - if (TARGET_6) - { - if (backward) - output_asm_insn (\"sub%?\\t%|lr, %|pc, #(8 + . -%l3)\", operands); - else - output_asm_insn (\"add%?\\t%|lr, %|pc, #(%l3 - . -8)\", operands); - } - else -#endif - { - output_asm_insn (\"mov%?\\t%|lr, %|pc\\t%@ protect cc\", operands); - if (backward) - output_asm_insn (\"sub%?\\t%|lr, %|lr, #(4 + . -%l3)\", operands); - else - output_asm_insn (\"add%?\\t%|lr, %|lr, #(%l3 - . -4)\", operands); - } - return \"b%?\\t%a1\"; -}" -[(set_attr "type" "call") - (set (attr "length") - (if_then_else (eq_attr "prog_mode" "prog32") - (const_int 8) - (const_int 12)))]) - (define_split [(set (match_operand:SI 0 "s_register_operand" "") (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "") -- 2.11.4.GIT