]> gcc.gnu.org Git - gcc.git/commitdiff
lcm.c (optimize_mode_switching): Change NORMAL_MODE to MODE_ENTRY and MODE_EXIT.
authorEric Christopher <echristo@redhat.com>
Fri, 10 Oct 2003 21:28:56 +0000 (21:28 +0000)
committerEric Christopher <echristo@gcc.gnu.org>
Fri, 10 Oct 2003 21:28:56 +0000 (21:28 +0000)
2003-10-10  Eric Christopher  <echristo@redhat.com>

        * lcm.c (optimize_mode_switching): Change NORMAL_MODE
        to MODE_ENTRY and MODE_EXIT. Add MODE_AFTER for insns
        that set mode.
        * config/sh/sh.h (MODE_ENTRY): New macro.
        (MODE_EXIT): Ditto.
        (MODE_AFTER): Ditto.
        * config/sh/sh.md: Change for MODE_AFTER. Add
        fp_set attribute.
        * doc/tm.texi: Document MODE_AFTER, MODE_ENTRY, and MODE_EXIT.

From-SVN: r72315

gcc/ChangeLog
gcc/config/sh/sh.h
gcc/config/sh/sh.md
gcc/doc/tm.texi
gcc/lcm.c

index c8f18a0bf22b005de92138a43a9dc78252f0de8f..5cf9983411a9aa960cf6ea92ac32ac5fce2e23e9 100644 (file)
@@ -1,3 +1,15 @@
+2003-10-10  Eric Christopher  <echristo@redhat.com>
+
+        * lcm.c (optimize_mode_switching): Change NORMAL_MODE
+        to MODE_ENTRY and MODE_EXIT. Add MODE_AFTER for insns
+        that set mode.
+        * config/sh/sh.h (MODE_ENTRY): New macro.
+        (MODE_EXIT): Ditto.
+        (MODE_AFTER): Ditto.
+        * config/sh/sh.md: Change for MODE_AFTER. Add
+        fp_set attribute.
+        * doc/tm.texi: Document MODE_AFTER, MODE_ENTRY, and MODE_EXIT.
+
 2003-10-10  Zack Weinberg  <zack@codesourcery.com>
 
        * genmodes.c, mode-classes.def: New files.
index fdd29fb39c0f5713bdfde4419b3818c34a497467..acd9650b254f182337895a2e11d89ccdb550677c 100644 (file)
@@ -1254,7 +1254,7 @@ enum reg_class
   { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000000ff },      \
 /* ALL_REGS:  */                                                       \
   { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01ffffff },      \
-}                                                                       
+}
 
 /* The same information, inverted:
    Return the class number of the smallest class containing
@@ -1645,7 +1645,7 @@ extern enum reg_class reg_class_from_letter[];
                 || TREE_CODE (VALTYPE) == OFFSET_TYPE))                \
            ? (TARGET_SHMEDIA ? DImode : SImode) : TYPE_MODE (VALTYPE)), \
           BASE_RETURN_VALUE_REG (TYPE_MODE (VALTYPE)))
-     
+
 /* Define how to find the value returned by a library function
    assuming the value has mode MODE.  */
 #define LIBCALL_VALUE(MODE) \
@@ -2073,7 +2073,7 @@ struct sh_args {
 
 #define EXIT_IGNORE_STACK 1
 
-/* 
+/*
    On the SH, the trampoline looks like
    2 0002 D202                 mov.l   l2,r2
    1 0000 D301                 mov.l   l1,r3
@@ -3189,7 +3189,7 @@ extern int rtx_equal_function_value_matters;
 #define any_register_operand register_operand
 
 /* Define this macro if it is advisable to hold scalars in registers
-   in a wider mode than that declared by the program.  In such cases, 
+   in a wider mode than that declared by the program.  In such cases,
    the value is constrained to be within the bounds of the declared
    type, but kept valid in the wider mode.  The signedness of the
    extension may differ from that of the type.
@@ -3234,6 +3234,11 @@ extern int rtx_equal_function_value_matters;
    ? (TARGET_FMOVD ? FP_MODE_DOUBLE : FP_MODE_NONE) \
    : ACTUAL_NORMAL_MODE (ENTITY))
 
+#define MODE_ENTRY(ENTITY) NORMAL_MODE (ENTITY)
+
+#define MODE_EXIT(ENTITY) \
+  (sh_cfun_attr_renesas_p () ? FP_MODE_NONE : NORMAL_MODE (ENTITY))
+
 #define EPILOGUE_USES(REGNO)       ((TARGET_SH2E || TARGET_SH4)                \
                                    && (REGNO) == FPSCR_REG)
 
@@ -3242,6 +3247,12 @@ extern int rtx_equal_function_value_matters;
    ? get_attr_fp_mode (INSN)                                           \
    : FP_MODE_NONE)
 
+#define MODE_AFTER(MODE, INSN)                  \
+     (recog_memoized (INSN) >= 0                \
+      && get_attr_fp_set (INSN) != FP_SET_NONE  \
+      ? get_attr_fp_set (INSN)                  \
+      : (MODE))
+
 #define MODE_PRIORITY_TO_MODE(ENTITY, N) \
   ((TARGET_FPU_SINGLE != 0) ^ (N) ? FP_MODE_SINGLE : FP_MODE_DOUBLE)
 
index adbd4b8e25abb91fb9ffaac9adcb7ef947def188..bad8c66edc9c66e87dd7058bcd154527b19c9561 100644 (file)
   (UNSPECV_CONST8      6)
   (UNSPECV_WINDOW_END  10)
   (UNSPECV_CONST_END   11)
-])  
+])
 
 ;; -------------------------------------------------------------------------
 ;; Attributes
 ;; ftrc_s      fix_truncsfsi2_i4
 ;; dfdiv       double precision floating point divide (or square root)
 ;; cwb         ic_invalidate_line_i
-;; tls_load     load TLS related address 
+;; tls_load     load TLS related address
 ;; arith_media SHmedia arithmetic, logical, and shift instructions
 ;; cbranch_media SHmedia conditional branch instructions
 ;; cmp_media   SHmedia compare instructions
 
 (define_attr "fp_mode" "single,double,none" (const_string "none"))
 
+;; Indicate if the fpu mode is set by this instruction
+;; "unknown" must have the value as "none" in fp_mode, and means
+;; that the instruction/abi has left the processor in an unknown
+;; state.
+;; "none" means that nothing has changed and no mode is set.
+;; This attribute is only used for the Renesas ABI.
+(define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
+
 ; If a conditional branch destination is within -252..258 bytes away
 ; from the instruction it can be 2 bytes long.  Something in the
 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
 ;; delay slot scheduling from the target.
 (define_insn "indirect_jump_scratch"
   [(set (match_operand:SI 0 "register_operand" "=r")
-       (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR)) 
+       (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
   "TARGET_SH1"
   ""
    (set (attr "fp_mode")
        (if_then_else (eq_attr "fpu_single" "yes")
                      (const_string "single") (const_string "double")))
-   (set_attr "needs_delay_slot" "yes")])
+   (set_attr "needs_delay_slot" "yes")
+   (set_attr "fp_set" "unknown")])
 
 ;; This is a pc-rel call, using bsrf, for use with PIC.
 
    (set (attr "fp_mode")
        (if_then_else (eq_attr "fpu_single" "yes")
                      (const_string "single") (const_string "double")))
-   (set_attr "needs_delay_slot" "yes")])
+   (set_attr "needs_delay_slot" "yes")
+   (set_attr "fp_set" "unknown")])
 
 (define_insn_and_split "call_pcrel"
   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
    (set (attr "fp_mode")
        (if_then_else (eq_attr "fpu_single" "yes")
                      (const_string "single") (const_string "double")))
-   (set_attr "needs_delay_slot" "yes")])
+   (set_attr "needs_delay_slot" "yes")
+   (set_attr "fp_set" "unknown")])
 
 (define_insn "call_compact"
   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
    (set (attr "fp_mode")
        (if_then_else (eq_attr "fpu_single" "yes")
                      (const_string "single") (const_string "double")))
-   (set_attr "needs_delay_slot" "yes")])
+   (set_attr "needs_delay_slot" "yes")
+   (set_attr "fp_set" "unknown")])
 
 (define_insn "call_valuei_pcrel"
   [(set (match_operand 0 "" "=rf")
    (set (attr "fp_mode")
        (if_then_else (eq_attr "fpu_single" "yes")
                      (const_string "single") (const_string "double")))
-   (set_attr "needs_delay_slot" "yes")])
+   (set_attr "needs_delay_slot" "yes")
+   (set_attr "fp_set" "unknown")])
 
 (define_insn_and_split "call_value_pcrel"
   [(set (match_operand 0 "" "=rf")
    (set (attr "fp_mode")
        (if_then_else (eq_attr "fpu_single" "yes")
                      (const_string "single") (const_string "double")))
-   (set_attr "needs_delay_slot" "yes")])
+   (set_attr "needs_delay_slot" "yes")
+   (set_attr "fp_set" "unknown")])
 
 (define_insn "call_value_compact"
   [(set (match_operand 0 "" "=rf")
@@ -8169,7 +8183,8 @@ mov.l\\t1f,r0\\n\\
   [(set (reg:PSI FPSCR_REG)
        (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
   "TARGET_SH4"
-  "fschg")
+  "fschg"
+  [(set_attr "fp_set" "unknown")])
 
 (define_expand "addsf3"
   [(set (match_operand:SF 0 "arith_reg_operand" "")
@@ -10359,7 +10374,7 @@ mov.l\\t1f,r0\\n\\
                        (const_int 4294967295))
                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
                            (const_int 32))))]
-                               
+
   "TARGET_SHMEDIA"
   "mshflo.l    %N1, %N2, %0"
   [(set_attr "type" "arith_media")])
@@ -10370,7 +10385,7 @@ mov.l\\t1f,r0\\n\\
                            (const_int 32))
                (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
                        (const_int 4294967295))))]
-                               
+
   "TARGET_SHMEDIA"
   "mshflo.l    %N2, %N1, %0"
   [(set_attr "type" "arith_media")])
@@ -10404,7 +10419,7 @@ mov.l\\t1f,r0\\n\\
                                 "rZ"))
                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
                            (const_int 32))))]
-                               
+
   "TARGET_SHMEDIA"
   "mshflo.l    %N1, %N2, %0"
   [(set_attr "type" "arith_media")])
@@ -10414,7 +10429,7 @@ mov.l\\t1f,r0\\n\\
 ;;     (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
        (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
                         (match_operand:SF 2 "register_operand" "rZ,f,f")))]
-                               
+
   "TARGET_SHMEDIA"
   "@
        mshflo.l        %N1, %N2, %0
@@ -10436,7 +10451,7 @@ mov.l\\t1f,r0\\n\\
        (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
                            (const_int 32))
                (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
-                               
+
   "TARGET_SHMEDIA"
   "mshflo.l    %N2, %N1, %0"
   [(set_attr "type" "arith_media")])
@@ -10675,16 +10690,16 @@ mov.l\\t1f,r0\\n\\
   [(set_attr "type" "arith_media")])
 
 ;; The following description  models the
-;; SH4 pipeline using the DFA based scheduler. 
-;; The DFA based description is better way to model 
+;; SH4 pipeline using the DFA based scheduler.
+;; The DFA based description is better way to model
 ;; a superscalar pipeline as compared to function unit
-;; reservation model.   
-;; 1. The function unit based model is oriented to describe at most one 
-;;    unit reservation by each insn. It is difficult to model unit reservations in multiple 
+;; reservation model.
+;; 1. The function unit based model is oriented to describe at most one
+;;    unit reservation by each insn. It is difficult to model unit reservations in multiple
 ;;    pipeline units by same insn. This can be done using DFA based description.
 ;; 2. The execution performance of DFA based scheduler does not depend on processor complexity.
-;; 3. Writing all unit reservations for an instruction class is more natural description 
-;;    of the pipeline and makes interface of the hazard recognizer simpler than the 
+;; 3. Writing all unit reservations for an instruction class is more natural description
+;;    of the pipeline and makes interface of the hazard recognizer simpler than the
 ;;    old function unit based model.
 ;; 4. The DFA model is richer and is a part of greater overall framework of RCSP.
 
@@ -10695,7 +10710,7 @@ mov.l\\t1f,r0\\n\\
 (define_automaton "inst_pipeline,fpu_pipe")
 
 ;; This unit is basically the decode unit of the processor.
-;; Since SH4 is a dual issue machine,it is as if there are two 
+;; Since SH4 is a dual issue machine,it is as if there are two
 ;; units so that any insn can be processed by either one
 ;; of the decoding unit.
 
@@ -10728,8 +10743,8 @@ mov.l\\t1f,r0\\n\\
 
 ;; The address calculator used for branch instructions.
 ;; This will be reserved after "issue" of branch instructions
-;; and this is to make sure that no two branch instructions 
-;; can be issued in parallel. 
+;; and this is to make sure that no two branch instructions
+;; can be issued in parallel.
 
 (define_cpu_unit "pcr_addrcalc" "inst_pipeline")
 
@@ -10751,14 +10766,14 @@ mov.l\\t1f,r0\\n\\
 
 (define_reservation "fpu" "F1+F2")
 
-;; This is to highlight the fact that f1 
+;; This is to highlight the fact that f1
 ;; cannot overlap with F1.
 
 (exclusion_set  "f1_1,f1_2" "F1")
 
 (define_insn_reservation "nil" 0 (eq_attr "type" "nil") "nothing")
 
-;; Although reg moves have a latency of zero 
+;; Although reg moves have a latency of zero
 ;; we need to highlight that they use D stage
 ;; for one cycle.
 
@@ -10806,7 +10821,7 @@ mov.l\\t1f,r0\\n\\
 ;; Latency:    1
 ;; Issue Rate:         1
 
-(define_insn_reservation "sh4_simple_arith" 1 
+(define_insn_reservation "sh4_simple_arith" 1
   (and (eq_attr "pipe_model" "sh4")
        (eq_attr "insn_class" "ex_group"))
   "issue,int")
@@ -10913,7 +10928,7 @@ mov.l\\t1f,r0\\n\\
 ;; Group:      CO
 ;; Latency:    5
 ;; Issue Rate:         5
-;; this instruction can be executed in any of the pipelines 
+;; this instruction can be executed in any of the pipelines
 ;; and blocks the pipeline for next 4 stages.
 
 (define_insn_reservation "sh4_return_from_exp" 5
@@ -10932,7 +10947,7 @@ mov.l\\t1f,r0\\n\\
   (and (eq_attr "pipe_model" "sh4")
        (eq_attr "type" "cwb"))
   "d_lock*2,(d_lock+memory)*3,issue+load_store+memory,memory*2")
-               
+
 ;; LDS to PR,JSR
 ;; Group:      CO
 ;; Latency:    3
@@ -10944,7 +10959,7 @@ mov.l\\t1f,r0\\n\\
 ;; scheduling.  For the function call case, it's really best that we end with
 ;; something that models an rts.
 
-(define_insn_reservation "sh4_lds_to_pr" 3 
+(define_insn_reservation "sh4_lds_to_pr" 3
   (and (eq_attr "pipe_model" "sh4")
        (eq_attr "type" "prset") )
   "d_lock*2")
@@ -10957,17 +10972,17 @@ mov.l\\t1f,r0\\n\\
 ;; We could, of course, provide exact scheduling information for specific
 ;; sfuncs, if that should prove useful.
 
-(define_insn_reservation "sh4_call" 16 
+(define_insn_reservation "sh4_call" 16
   (and (eq_attr "pipe_model" "sh4")
        (eq_attr "type" "call,sfunc"))
   "d_lock*16")
 
-;; LDS.L to PR 
+;; LDS.L to PR
 ;; Group:      CO
 ;; Latency:    3
 ;; Issue Rate:         2
 ;; The SX unit is blocked for last 2 cycles.
+
 (define_insn_reservation "ldsmem_to_pr"  3
   (and (eq_attr "pipe_model" "sh4")
        (eq_attr "type" "pload"))
@@ -10989,7 +11004,7 @@ mov.l\\t1f,r0\\n\\
 ;; Latency:    2
 ;; Issue Rate:         2
 
-(define_insn_reservation "sh4_prstore_mem" 2 
+(define_insn_reservation "sh4_prstore_mem" 2
   (and (eq_attr "pipe_model" "sh4")
        (eq_attr "type" "pstore"))
   "d_lock*2,nothing,memory")
@@ -10998,7 +11013,7 @@ mov.l\\t1f,r0\\n\\
 ;; Group:      CO
 ;; Latency:    4
 ;; Issue Rate:         1
-;; F1 is blocked for last three cycles. 
+;; F1 is blocked for last three cycles.
 
 (define_insn_reservation "fpscr_load" 4
   (and (eq_attr "pipe_model" "sh4")
@@ -11079,7 +11094,7 @@ mov.l\\t1f,r0\\n\\
        (eq_attr "type" "dfp_conv"))
   "issue,F01,F1+F2,F2")
 
-;; Double-precision floating-point (FADD,FMUL,FSUB) 
+;; Double-precision floating-point (FADD,FMUL,FSUB)
 ;; Group:      FE
 ;; Latency:    (7,8)/9
 ;; Issue Rate:         1
@@ -11089,12 +11104,12 @@ mov.l\\t1f,r0\\n\\
        (eq_attr "type" "dfp_arith"))
   "issue,F01,F1+F2,fpu*4,F2")
 
-;; Double-precision FCMP (FCMP/EQ,FCMP/GT) 
+;; Double-precision FCMP (FCMP/EQ,FCMP/GT)
 ;; Group:      CO
 ;; Latency:    3/5
 ;; Issue Rate:         2
 
-(define_insn_reservation "fp_double_cmp" 3 
+(define_insn_reservation "fp_double_cmp" 3
   (and (eq_attr "pipe_model" "sh4")
        (eq_attr "type" "dfp_cmp"))
   "d_lock,(d_lock+F01),F1+F2,F2")
index 1645319dff0f707b74785d368033129bed97b887..b420bfb419db5ea50c39c1940d630aa86f4d89db 100644 (file)
@@ -320,14 +320,14 @@ default value of this macro, will expand to the value of
 @end defmac
 
 @defmac SYSROOT_SUFFIX_SPEC
-Define this macro to add a suffix to the target sysroot when GCC is 
-configured with a sysroot.  This will cause GCC to search for usr/lib, 
-et al, within sysroot+suffix. 
+Define this macro to add a suffix to the target sysroot when GCC is
+configured with a sysroot.  This will cause GCC to search for usr/lib,
+et al, within sysroot+suffix.
 @end defmac
 
 @defmac SYSROOT_HEADERS_SUFFIX_SPEC
-Define this macro to add a headers_suffix to the target sysroot when 
-GCC is configured with a sysroot.  This will cause GCC to pass the 
+Define this macro to add a headers_suffix to the target sysroot when
+GCC is configured with a sysroot.  This will cause GCC to pass the
 updated sysroot+headers_suffix to CPP@, causing it to search for
 usr/include, et al, within sysroot+headers_suffix.
 @end defmac
@@ -2696,11 +2696,11 @@ A C expression that defines the optional machine-dependent constraint
 letters, amongst those accepted by @code{EXTRA_CONSTRAINT}, that should
 be treated like memory constraints by the reload pass.
 
-It should return 1 if the operand type represented by the constraint 
+It should return 1 if the operand type represented by the constraint
 at the start of @var{str}, the first letter of which is the letter @var{c},
  comprises a subset of all memory references including
-all those whose address is simply a base register.  This allows the reload 
-pass to reload an operand, if it does not directly correspond to the operand 
+all those whose address is simply a base register.  This allows the reload
+pass to reload an operand, if it does not directly correspond to the operand
 type of @var{c}, by copying its address into a base register.
 
 For example, on the S/390, some instructions do not accept arbitrary
@@ -2720,15 +2720,15 @@ letters, amongst those accepted by @code{EXTRA_CONSTRAINT} /
 @code{EXTRA_CONSTRAINT_STR}, that should
 be treated like address constraints by the reload pass.
 
-It should return 1 if the operand type represented by the constraint 
+It should return 1 if the operand type represented by the constraint
 at the start of @var{str}, which starts with the letter @var{c}, comprises
 a subset of all memory addresses including
-all those that consist of just a base register.  This allows the reload 
-pass to reload an operand, if it does not directly correspond to the operand 
+all those that consist of just a base register.  This allows the reload
+pass to reload an operand, if it does not directly correspond to the operand
 type of @var{str}, by copying it into a base register.
 
 Any constraint marked as @code{EXTRA_ADDRESS_CONSTRAINT} can only
-be used with the @code{address_operand} predicate.  It is treated 
+be used with the @code{address_operand} predicate.  It is treated
 analogously to the @samp{p} constraint.
 @end defmac
 
@@ -2905,9 +2905,9 @@ If this RTL is a @code{REG}, you should also define
 @end defmac
 
 @defmac DWARF_ALT_FRAME_RETURN_COLUMN
-A C expression whose value is an integer giving a DWARF 2 column 
+A C expression whose value is an integer giving a DWARF 2 column
 number that may be used as an alternate return column.  This should
-be defined only if @code{DWARF_FRAME_RETURN_COLUMN} is set to a 
+be defined only if @code{DWARF_FRAME_RETURN_COLUMN} is set to a
 general register, but an alternate column needs to be used for
 signal frames.
 @end defmac
@@ -2970,10 +2970,10 @@ Typically this is a call-clobbered hard register that is otherwise
 untouched by the epilogue, but could also be a stack slot.
 
 Do not define this macro if the stack pointer is saved and restored
-by the regular prolog and epilog code in the call frame itself; in 
-this case, the exception handling library routines will update the 
-stack location to be restored in place.  Otherwise, you must define 
-this macro if you want to support call frame exception handling like 
+by the regular prolog and epilog code in the call frame itself; in
+this case, the exception handling library routines will update the
+stack location to be restored in place.  Otherwise, you must define
+this macro if you want to support call frame exception handling like
 that provided by DWARF 2.
 @end defmac
 
@@ -2986,8 +2986,8 @@ Typically this is the location in the call frame at which the normal
 return address is stored.  For targets that return by popping an
 address off the stack, this might be a memory address just below
 the @emph{target} call frame rather than inside the current call
-frame.  If defined, @code{EH_RETURN_STACKADJ_RTX} will have already 
-been assigned, so it may be used to calculate the location of the 
+frame.  If defined, @code{EH_RETURN_STACKADJ_RTX} will have already
+been assigned, so it may be used to calculate the location of the
 target call frame.
 
 Some targets have more complex requirements than storing to an
@@ -3265,7 +3265,7 @@ is different than the internal representation for unwind column.
 Given a dwarf register, this macro should return the internal unwind
 column number to use instead.
 
-See the PowerPC's SPE target for an example.  
+See the PowerPC's SPE target for an example.
 @end defmac
 
 @node Elimination
@@ -4666,7 +4666,7 @@ don't need to define this macro.
 @findex gofast_maybe_init_libfuncs
 @defmac US_SOFTWARE_GOFAST
 Define this macro if your system C library uses the US Software GOFAST
-library to provide floating point emulation.  
+library to provide floating point emulation.
 
 In addition to defining this macro, your architecture must set
 @code{TARGET_INIT_LIBFUNCS} to @code{gofast_maybe_init_libfuncs}, or
@@ -6510,7 +6510,7 @@ provided.
 A C statement (sans semicolon) to output to the stdio stream
 @var{stream} a directive telling the assembler to calculate the size of
 the symbol @var{name} by subtracting its address from the current
-address.  
+address.
 
 If you define @code{SIZE_ASM_OP}, a default definition of this macro is
 provided.  The default assumes that the assembler recognizes a special
@@ -8226,7 +8226,8 @@ return nonzero for any @var{entity} that needs mode-switching.
 If you define this macro, you also have to define
 @code{NUM_MODES_FOR_MODE_SWITCHING}, @code{MODE_NEEDED},
 @code{MODE_PRIORITY_TO_MODE} and @code{EMIT_MODE_SET}.
-@code{NORMAL_MODE} is optional.
+@code{MODE_AFTER}, @code{MODE_ENTRY}, and @code{MODE_EXIT}
+are optional.
 @end defmac
 
 @defmac NUM_MODES_FOR_MODE_SWITCHING
@@ -8250,10 +8251,24 @@ return an integer value not larger than the corresponding element in
 be switched into prior to the execution of @var{insn}.
 @end defmac
 
-@defmac NORMAL_MODE (@var{entity})
+@defmac MODE_AFTER (@var{mode}, @var{insn})
+If this macro is defined, it is evaluated for every @var{insn} during
+mode switching. It determines the mode that an insn results in (if
+different from the incoming mode).
+@end defmac
+
+@defmac MODE_ENTRY (@var{entity})
+If this macro is defined, it is evaluated for every @var{entity} that needs
+mode switching. It should evaluate to an integer, which is a mode that
+@var{entity} is assumed to be switched to at function entry. If @code{MODE_ENTRY}
+is defined then @code{MODE_EXIT} must be defined.
+@end defmac
+
+@defmac MODE_EXIT (@var{entity})
 If this macro is defined, it is evaluated for every @var{entity} that needs
-mode switching.  It should evaluate to an integer, which is a mode that
-@var{entity} is assumed to be switched to at function entry and exit.
+mode switching. It should evaluate to an integer, which is a mode that
+@var{entity} is assumed to be switched to at function exit. If @code{MODE_EXIT}
+is defined then @code{MODE_ENTRY} must be defined.
 @end defmac
 
 @defmac MODE_PRIORITY_TO_MODE (@var{entity}, @var{n})
@@ -9152,7 +9167,7 @@ to reserve space for caller-saved target registers.
 @end deftypefn
 
 @defmac POWI_MAX_MULTS
-If defined, this macro is interpreted as a signed integer C expression 
+If defined, this macro is interpreted as a signed integer C expression
 that specifies the maximum number of floating point multiplications
 that should be emitted when expanding exponentiation by an integer
 constant inline.  When this value is defined, exponentiation requiring
@@ -9160,4 +9175,3 @@ more than this number of multiplications is implemented by calling the
 system library's @code{pow}, @code{powf} or @code{powl} routines.
 The default value places no upper bound on the multiplication count.
 @end defmac
-
index 0e47507752d6fb264dd75087f1c5dd4f66fd7bde..68b49efb01516aca4aa9cd128a35979634c818e3 100644 (file)
--- a/gcc/lcm.c
+++ b/gcc/lcm.c
@@ -958,6 +958,12 @@ reg_becomes_live (rtx reg, rtx setter ATTRIBUTE_UNUSED, void *live)
       SET_HARD_REG_BIT (* (HARD_REG_SET *) live, regno + nregs);
 }
 
+/* Make sure if MODE_ENTRY is defined the MODE_EXIT is defined
+   and vice versa.  */
+#if defined (MODE_ENTRY) != defined (MODE_EXIT)
+ #error "Both MODE_ENTRY and MODE_EXIT must be defined"
+#endif
+
 /* Find all insns that need a particular mode setting, and insert the
    necessary mode switches.  Return true if we did work.  */
 
@@ -990,7 +996,7 @@ optimize_mode_switching (FILE *file)
        /* Create the list of segments within each basic block.
           If NORMAL_MODE is defined, allow for two extra
           blocks split from the entry and exit block.  */
-#ifdef NORMAL_MODE
+#if defined (MODE_ENTRY) && defined (MODE_EXIT)
        entry_exit_extra = 2;
 #endif
        bb_info[n_entities]
@@ -1003,7 +1009,7 @@ optimize_mode_switching (FILE *file)
   if (! n_entities)
     return 0;
 
-#ifdef NORMAL_MODE
+#if defined (MODE_ENTRY) && defined (MODE_EXIT)
   {
     /* Split the edge from the entry block and the fallthrough edge to the
        exit block, so that we can note that there NORMAL_MODE is supplied /
@@ -1068,7 +1074,9 @@ optimize_mode_switching (FILE *file)
                      add_seginfo (info + bb->index, ptr);
                      RESET_BIT (transp[bb->index], j);
                    }
-
+#ifdef MODE_AFTER
+                 last_mode = MODE_AFTER (last_mode, insn);
+#endif
                  /* Update LIVE_NOW.  */
                  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
                    if (REG_NOTE_KIND (link) == REG_DEAD)
@@ -1089,9 +1097,9 @@ optimize_mode_switching (FILE *file)
              add_seginfo (info + bb->index, ptr);
            }
        }
-#ifdef NORMAL_MODE
+#if defined (MODE_ENTRY) && defined (MODE_EXIT)
       {
-       int mode = NORMAL_MODE (e);
+       int mode = MODE_ENTRY (e);
 
        if (mode != no_mode)
          {
@@ -1109,7 +1117,7 @@ optimize_mode_switching (FILE *file)
            info[bb->index].computing = mode;
 
            if (pre_exit)
-             info[pre_exit->index].seginfo->mode = mode;
+             info[pre_exit->index].seginfo->mode = MODE_EXIT (e);
          }
       }
 #endif /* NORMAL_MODE */
@@ -1285,7 +1293,7 @@ optimize_mode_switching (FILE *file)
   if (need_commit)
     commit_edge_insertions ();
 
-#ifdef NORMAL_MODE
+#if defined (MODE_ENTRY) && defined (MODE_EXIT)
   cleanup_cfg (CLEANUP_NO_INSN_DEL);
 #else
   if (!need_commit && !emited)
This page took 0.106984 seconds and 5 git commands to generate.