c4x.md (set_ldp_prologue): Add for RTL prologue/epilogue.
authorHerman A.J. ten Brugge <Haj.Ten.Brugge@net.HCC.nl>
Sun, 30 Jul 2000 09:12:46 +0000 (11:12 +0200)
committerMichael Hayes <m.hayes@gcc.gnu.org>
Sun, 30 Jul 2000 09:12:46 +0000 (09:12 +0000)
* config/c4x/c4x.md (set_ldp_prologue): Add for RTL prologue/epilogue.
(push_st, push_dp, pop_st, pop_dp, popqi_unspec): Likewise.
(nodb_call, return_from_epilogue): Likewise.
(return_from_interrupt_epilogue, prologue, epilogue): Likewise.
* config/c4x/c4x.c (c4x_expand_prologue, c4x_expand_eplilogue): Add.
* config/c4x/c4x-protos.h (c4x_interrupt_function_p): Add.
(c4x_expand_prologue, c4x_expand_epilogue): Likewise.
(c4x_valid_type_attribute_p): Likewise.
* config/c4x/c4x.h (FUNCTION_PROLOGUE, FUNCTION_EPILOGUE): Delete.
(FUNCTION_BLOCK_PROFILER_EXIT): Convert to emit RTL.

Co-Authored-By: Michael Hayes <m.hayes@elec.canterbury.ac.nz>
From-SVN: r35341

gcc/ChangeLog
gcc/config/c4x/c4x-protos.h
gcc/config/c4x/c4x.c
gcc/config/c4x/c4x.h
gcc/config/c4x/c4x.md

index 9bf128e481b11be02e6e44e0e810aa8f23a95ae6..593527044899d3fb51247d88482b422d62dc2d11 100644 (file)
@@ -1,3 +1,17 @@
+2000-07-30 Herman A.J. ten Brugge <Haj.Ten.Brugge@net.HCC.nl>
+          Michael Hayes  <m.hayes@elec.canterbury.ac.nz>
+
+       * config/c4x/c4x.md (set_ldp_prologue): Add for RTL prologue/epilogue.
+       (push_st, push_dp, pop_st, pop_dp, popqi_unspec): Likewise.
+       (nodb_call, return_from_epilogue): Likewise.
+       (return_from_interrupt_epilogue, prologue, epilogue): Likewise.
+       * config/c4x/c4x.c (c4x_expand_prologue, c4x_expand_eplilogue): Add.
+       * config/c4x/c4x-protos.h (c4x_interrupt_function_p): Add.
+       (c4x_expand_prologue, c4x_expand_epilogue): Likewise.
+       (c4x_valid_type_attribute_p): Likewise.
+       * config/c4x/c4x.h (FUNCTION_PROLOGUE, FUNCTION_EPILOGUE): Delete.
+       (FUNCTION_BLOCK_PROFILER_EXIT): Convert to emit RTL.
+       
 2000-07-30  Michael Hayes  <m.hayes@elec.canterbury.ac.nz>
 
        * config/c4x/c4x.c (c4x_emit_move_sequence): Use loadqi_big_constant
index 9a5e70ac62bb3772dd9c682a6f69c0d80e85da98..cd7c0292bb5f1af467120a4f0a18275c40133085 100644 (file)
@@ -28,9 +28,11 @@ extern void c4x_optimization_options PARAMS ((int, int));
 
 extern void c4x_output_ascii PARAMS ((FILE *, const char *, int));
 
-extern void c4x_function_prologue PARAMS ((FILE *, int));
+extern int c4x_interrupt_function_p PARAMS ((void));
 
-extern void c4x_function_epilogue PARAMS ((FILE *, int));
+extern void c4x_expand_prologue PARAMS ((void));
+
+extern void c4x_expand_epilogue PARAMS ((void));
 
 extern int c4x_null_epilogue_p PARAMS ((void));
 
@@ -55,6 +57,8 @@ extern struct rtx_def *c4x_function_arg PARAMS ((CUMULATIVE_ARGS *,
                                                 int));
 
 extern void c4x_encode_section_info PARAMS ((tree));
+
+extern int c4x_valid_type_attribute_p PARAMS ((tree, tree, tree, tree));
 #endif /* TREE_CODE */
 
 
@@ -72,7 +76,7 @@ extern struct rtx_def *c4x_gen_compare_reg PARAMS ((enum rtx_code, rtx, rtx));
 
 extern int c4x_check_legit_addr PARAMS ((enum machine_mode, rtx, int));
 
-extern int c4x_hard_regno_mode_ok PARAMS ((int, enum machine_mode));
+extern int c4x_hard_regno_mode_ok PARAMS ((unsigned int, enum machine_mode));
 
 extern struct rtx_def *c4x_legitimize_address PARAMS ((rtx,
                                                       enum machine_mode));
@@ -91,7 +95,7 @@ extern enum reg_class c4x_preferred_reload_class PARAMS ((rtx,
 extern struct rtx_def *c4x_operand_subword PARAMS ((rtx, int, int,
                                                   enum machine_mode));
 
-extern char *c4x_output_cbranch PARAMS ((char *, rtx));
+extern char *c4x_output_cbranch PARAMS ((const char *, rtx));
 
 extern int c4x_label_conflict PARAMS ((rtx, rtx, rtx));
 
@@ -101,12 +105,16 @@ extern int c4x_adjust_cost PARAMS ((rtx, rtx, rtx, int));
 
 extern void c4x_process_after_reload PARAMS ((rtx));
 
+extern void c4x_rptb_insert PARAMS ((rtx insn));
+
 extern int c4x_rptb_nop_p PARAMS ((rtx));
 
 extern int c4x_rptb_rpts_p PARAMS ((rtx, rtx));
 
 extern int c4x_autoinc_operand PARAMS ((rtx, enum machine_mode));
 
+extern int any_operand PARAMS ((rtx, enum machine_mode));
+
 extern int fp_zero_operand PARAMS ((rtx, enum machine_mode));
 
 extern int const_operand PARAMS ((rtx, enum machine_mode));
index 15d04f76b7ed080dd8ab5ceb68b17d0fa569f314..9afe59a7bdb2104d92aa9f654db4d61b9f33f27a 100644 (file)
@@ -1346,24 +1346,6 @@ c4x_emit_move_sequence (operands, mode)
       return 1;
     }
 
-  if (mode == QImode
-      && reg_operand (op0, mode)
-      && const_int_operand (op1, mode)
-      && ! IS_INT16_CONST (INTVAL (op1))
-      && ! IS_HIGH_CONST (INTVAL (op1)))
-    {
-      emit_insn (gen_loadqi_big_constant (op0, op1));
-      return 1;
-    }
-
-  if (mode == HImode
-      && reg_operand (op0, mode)
-      && const_int_operand (op1, mode))
-    {
-      emit_insn (gen_loadhi_big_constant (op0, op1));
-      return 1;
-    }
-
   /* Adjust operands in case we have modified them.  */
   operands[0] = op0;
   operands[1] = op1;
index ca80cd77d9fac0d483753a24329761ac142b6107..7cc8169cbabf8af4489b0489cf0aa2944a893623 100644 (file)
@@ -1153,12 +1153,6 @@ CUMULATIVE_ARGS;
 #define EXPAND_BUILTIN_VA_ARG(valist, type) \
   c4x_va_arg (valist, type)
 
-/* Function Entry and Exit.  */
-
-#define FUNCTION_PROLOGUE(FILE, SIZE)  c4x_function_prologue(FILE, SIZE)
-#define FUNCTION_EPILOGUE(FILE, SIZE)  c4x_function_epilogue(FILE, SIZE)
-
-
 /* Generating Code for Profiling.  */
 
 /* Note that the generated assembly uses the ^ operator to load the 16
@@ -1378,13 +1372,16 @@ CUMULATIVE_ARGS;
       }                                                                \
     }
 
-#define FUNCTION_BLOCK_PROFILER_EXIT(FILE)                     \
+#define FUNCTION_BLOCK_PROFILER_EXIT                           \
     {                                                          \
-       fprintf (FILE, "\tpush\tst\n");                         \
-       fprintf (FILE, "\tpush\tar2\n");                        \
-       fprintf (FILE, "\tcall\t___bb_trace_ret\n");            \
-       fprintf (FILE, "\tpop\tar2\n");                         \
-       fprintf (FILE, "\tpop\tst\n");                          \
+      emit_insn (gen_push_st ());                              \
+      emit_insn (gen_pushqi (                                  \
+               gen_rtx_REG (QImode, AR2_REGNO)));              \
+      emit_call_insn (gen_nodb_call (                          \
+               gen_rtx_SYMBOL_REF (QImode, "__bb_trace_ret")));\
+      emit_insn (gen_popqi_unspec (                            \
+               gen_rtx_REG (QImode, AR2_REGNO)));              \
+      emit_insn (gen_pop_st ());                               \
     }
 
 #define        MACHINE_STATE_SAVE(ID)          \
index 12da60ed0a94c24f1613228a6c56e0ee4a284009..99ca228c65c0a3696c232cccd750083aacb38027 100644 (file)
 ; 11 loadqf_int
 ; 12 storeqf_int
 ; 13 Conditional load on overflow
+; 14 push_st
+; 15 pop_st
+; 16 push_dp
+; 17 pop_dp
+; 18 popqi_unspec
+; 19 popqf_unspec
+; 20 andn_st
 ; 22 rptb_init
 
 ;
 (define_function_unit "dummy" 1 0 (const_int 0) 2 1)
 (define_function_unit "dummy" 1 0 (const_int 0) 3 1)
 
-;(define_function_unit "ar0" 1 0
-;       (and (eq_attr "cpu" "c4x")
-;            (and (eq_attr "setar0" "1")
-;                 (eq_attr "usear0" "1")))
-;       3 1 )
-
-;(define_function_unit "ar0" 1 0
-;       (and (eq_attr "cpu" "c4x")
-;            (and (eq_attr "setlda_ar0" "1")
-;                 (eq_attr "usear0" "1")))
-;       2 1 )
-
-;(define_function_unit "ar0" 1 0
-;       (and (eq_attr "cpu" "c4x")
-;            (and (eq_attr "usear0" "1")
-;                 (eq_attr "readar0" "1")))
-;       2 1 )
-
 ; The attribute setar0 is set to 1 for insns where ar0 is a dst operand.
 ; Note that the attributes unarycc and binarycc do not apply
 ; if ar0 is a dst operand (only loading an ext. prec. reg. sets CC)
                                      (const_int 1) (const_int 0))]
              (const_int 0)))
 
-;(define_function_unit "ar1" 1 0
-;       (and (eq_attr "cpu" "c4x")
-;            (and (eq_attr "setar1" "1")
-;                 (eq_attr "usear1" "1")))
-;       3 1 )
-
-;(define_function_unit "ar1" 1 0
-;       (and (eq_attr "cpu" "c4x")
-;            (and (eq_attr "setlda_ar1" "1")
-;                 (eq_attr "usear1" "1")))
-;       2 1 )
-
-;(define_function_unit "ar1" 1 0
-;       (and (eq_attr "cpu" "c4x")
-;            (and (eq_attr "usear1" "1")
-;                 (eq_attr "readar1" "1")))
-;       2 1 )
-
 (define_attr "setar1" ""
        (cond [(eq_attr "type" "unary,binary")
                        (if_then_else (match_operand 0 "ar1_reg_operand" "")
                                      (const_int 1) (const_int 0))]
              (const_int 0)))
 
-;(define_function_unit "ar2" 1 0
-;       (and (eq_attr "cpu" "c4x")
-;            (and (eq_attr "setar2" "1")
-;                 (eq_attr "usear2" "1")))
-;       3 1 )
-
-;(define_function_unit "ar2" 1 0
-;       (and (eq_attr "cpu" "c4x")
-;            (and (eq_attr "setlda_ar2" "1")
-;                 (eq_attr "usear2" "1")))
-;       2 1 )
-
-;(define_function_unit "ar2" 1 0
-;       (and (eq_attr "cpu" "c4x")
-;            (and (eq_attr "usear2" "1")
-;                 (eq_attr "readar2" "1")))
-;       2 1 )
-
 (define_attr "setar2" ""
        (cond [(eq_attr "type" "unary,binary")
                        (if_then_else (match_operand 0 "ar2_reg_operand" "")
                                      (const_int 1) (const_int 0))]
              (const_int 0)))
 
-;(define_function_unit "ar3" 1 0
-;       (and (eq_attr "cpu" "c4x")
-;            (and (eq_attr "setar3" "1")
-;                 (eq_attr "usear3" "1")))
-;       3 1 )
-
-;(define_function_unit "ar3" 1 0
-;       (and (eq_attr "cpu" "c4x")
-;            (and (eq_attr "setlda_ar3" "1")
-;                 (eq_attr "usear3" "1")))
-;       2 1 )
-
-;(define_function_unit "ar3" 1 0
-;       (and (eq_attr "cpu" "c4x")
-;            (and (eq_attr "usear3" "1")
-;                 (eq_attr "readar3" "1")))
-;       2 1 )
-
 (define_attr "setar3" ""
        (cond [(eq_attr "type" "unary,binary")
                        (if_then_else (match_operand 0 "ar3_reg_operand" "")
                                      (const_int 1) (const_int 0))]
              (const_int 0)))
 
-;(define_function_unit "ar4" 1 0
-;       (and (eq_attr "cpu" "c4x")
-;            (and (eq_attr "setar4" "1")
-;                 (eq_attr "usear4" "1")))
-;       3 1 )
-
-;(define_function_unit "ar4" 1 0
-;       (and (eq_attr "cpu" "c4x")
-;            (and (eq_attr "setlda_ar4" "1")
-;                 (eq_attr "usear4" "1")))
-;       2 1 )
-
-;(define_function_unit "ar4" 1 0
-;       (and (eq_attr "cpu" "c4x")
-;            (and (eq_attr "usear4" "1")
-;                 (eq_attr "readar4" "1")))
-;       2 1 )
-
 (define_attr "setar4" ""
        (cond [(eq_attr "type" "unary,binary")
                        (if_then_else (match_operand 0 "ar4_reg_operand" "")
                                      (const_int 1) (const_int 0))]
              (const_int 0)))
 
-;(define_function_unit "ar5" 1 0
-;       (and (eq_attr "cpu" "c4x")
-;            (and (eq_attr "setar5" "1")
-;                 (eq_attr "usear5" "1")))
-;       3 1 )
-
-;(define_function_unit "ar5" 1 0
-;       (and (eq_attr "cpu" "c4x")
-;            (and (eq_attr "setlda_ar5" "1")
-;                 (eq_attr "usear5" "1")))
-;       2 1 )
-
-;(define_function_unit "ar5" 1 0
-;       (and (eq_attr "cpu" "c4x")
-;            (and (eq_attr "usear5" "1")
-;                 (eq_attr "readar5" "1")))
-;       2 1 )
-
 (define_attr "setar5" ""
        (cond [(eq_attr "type" "unary,binary")
                        (if_then_else (match_operand 0 "ar5_reg_operand" "")
                                      (const_int 1) (const_int 0))]
              (const_int 0)))
 
-;(define_function_unit "ar6" 1 0
-;       (and (eq_attr "cpu" "c4x")
-;            (and (eq_attr "setar6" "1")
-;                 (eq_attr "usear6" "1")))
-;       3 1 )
-
-;(define_function_unit "ar6" 1 0
-;       (and (eq_attr "cpu" "c4x")
-;            (and (eq_attr "setlda_ar6" "1")
-;                 (eq_attr "usear6" "1")))
-;       2 1 )
-
-;(define_function_unit "ar6" 1 0
-;       (and (eq_attr "cpu" "c4x")
-;            (and (eq_attr "usear6" "1")
-;                 (eq_attr "readar6" "1")))
-;       2 1 )
-
 (define_attr "setar6" ""
        (cond [(eq_attr "type" "unary,binary")
                        (if_then_else (match_operand 0 "ar6_reg_operand" "")
                                      (const_int 1) (const_int 0))]
              (const_int 0)))
 
-;(define_function_unit "ar7" 1 0
-;       (and (eq_attr "cpu" "c4x")
-;            (and (eq_attr "setar7" "1")
-;                 (eq_attr "usear7" "1")))
-;       3 1 )
-
-;(define_function_unit "ar7" 1 0
-;       (and (eq_attr "cpu" "c4x")
-;            (and (eq_attr "setlda_ar7" "1")
-;                 (eq_attr "usear7" "1")))
-;       2 1 )
-
-;(define_function_unit "ar7" 1 0
-;       (and (eq_attr "cpu" "c4x")
-;            (and (eq_attr "usear7" "1")
-;                 (eq_attr "readar7" "1")))
-;       2 1 )
-
 (define_attr "setar7" ""
        (cond [(eq_attr "type" "unary,binary")
                        (if_then_else (match_operand 0 "ar7_reg_operand" "")
                                      (const_int 1) (const_int 0))]
              (const_int 0)))
 
-;(define_function_unit "ir0" 1 0
-;       (and (eq_attr "cpu" "c4x")
-;            (and (eq_attr "setir0" "1")
-;                 (eq_attr "useir0" "1")))
-;       3 1 )
-
-;(define_function_unit "ir0" 1 0
-;       (and (eq_attr "cpu" "c4x")
-;            (and (eq_attr "setlda_ir0" "1")
-;                 (eq_attr "useir0" "1")))
-;       2 1 )
-
 (define_attr "setir0" ""
        (cond [(eq_attr "type" "unary,binary")
                        (if_then_else (match_operand 0 "ir0_reg_operand" "")
                                      (const_int 1) (const_int 0))]
              (const_int 0)))
 
-;(define_function_unit "ir1" 1 0
-;       (and (eq_attr "cpu" "c4x")
-;            (and (eq_attr "setir1" "1")
-;                 (eq_attr "useir1" "1")))
-;       3 1 )
-
-;(define_function_unit "ir1" 1 0
-;       (and (eq_attr "cpu" "c4x")
-;            (and (eq_attr "setlda_ir1" "1")
-;                 (eq_attr "useir1" "1")))
-;       2 1 )
-
 (define_attr "setir1" ""
        (cond [(eq_attr "type" "unary,binary")
                        (if_then_else (match_operand 0 "ir1_reg_operand" "")
 ; Let's ignore functional groups 2 and 3 for now, since they are not
 ; so important.
 
-;(define_function_unit "group1" 1 0
-;       (and (eq_attr "cpu" "c3x")
-;            (and (eq_attr "setgroup1" "1")
-;                 (eq_attr "usegroup1" "1")))
-;       3 1)
-
-;(define_function_unit "group1" 1 0
-;       (and (eq_attr "cpu" "c3x")
-;            (and (eq_attr "usegroup1" "1")
-;                 (eq_attr "readarx" "1")))
-;       2 1)
-
 (define_attr "setgroup1" ""
        (cond [(eq_attr "type" "lda,unary,binary")
                   (if_then_else (match_operand 0 "group1_reg_operand" "")
   "* return (TARGET_C3X) ? \"ldp\\t%A1\" : \"ldpk\\t%A1\";"
   [(set_attr "type" "ldp")])
 
+(define_insn "set_ldp_prologue"
+  [(set (match_operand:QI 0 "dp_reg_operand" "=z")
+        (high:QI (match_operand:QI 1 "" "")))]
+  "TARGET_SMALL && TARGET_PARANOID"
+  "* return (TARGET_C3X) ? \"ldp\\t@data_sec\" : \"ldpk\\t@data_sec\";"
+  [(set_attr "type" "ldp")])
+
 (define_insn "set_high"
   [(set (match_operand:QI 0 "std_reg_operand" "=c")
         (high:QI (match_operand:QI 1 "symbolic_address_operand" "")))]
 }")
 
 
+; As far as GCC is concerned, the moves are performed in parallel
+; thus it must be convinced that there is no aliasing.
+; It also assumes that the input operands are simultaneously loaded
+; and then the output operands are simultaneously stored.
+; With the C4x, if there are parallel stores to the same address
+; both stores are executed.
+; If there is a parallel load and store to the same address,
+; the load is performed first.
+; The problem with this pattern is that reload can spoil
+; the show when it eliminates a reference to the frame pointer.
+; This can invalidate the memory addressing mode, i.e., when
+; the displacement is greater than 1.
 (define_insn "movqi_parallel"
   [(set (match_operand:QI 0 "parallel_operand" "=q,S<>!V,q,S<>!V")
         (match_operand:QI 1 "parallel_operand" "S<>!V,q,S<>!V,q"))
 ;
 ; PUSH/POP
 ;
-(define_insn "*pushqi"
+(define_insn "pushqi"
   [(set (mem:QI (pre_inc:QI (reg:QI 20)))
         (match_operand:QI 0 "reg_operand" "r"))]
   ""
   "push\\t%0"
   [(set_attr "type" "push")])
 
-(define_insn "*popqi"
+(define_insn "push_st"
+  [(set (mem:QI (pre_inc:QI (reg:QI 20))) (unspec:QI [(reg:QI 21)] 14))
+   (use (reg:QI 21))]
+  ""
+  "push\\tst"
+  [(set_attr "type" "push")])
+
+(define_insn "push_dp"
+  [(set (mem:QI (pre_inc:QI (reg:QI 20))) (unspec:QI [(reg:QI 16)] 16))
+   (use (reg:QI 16))]
+  ""
+  "push\\tdp"
+  [(set_attr "type" "push")])
+
+(define_insn "popqi"
   [(set (match_operand:QI 0 "reg_operand" "=r")
         (mem:QI (post_dec:QI (reg:QI 20))))
    (clobber (reg:CC 21))]
   "pop\\t%0"
   [(set_attr "type" "pop")])
 
+(define_insn "pop_st"
+  [(set (unspec:QI [(reg:QI 21)] 15) (mem:QI (post_dec:QI (reg:QI 20))))
+   (clobber (reg:CC 21))]
+  ""
+  "pop\\tst"
+  [(set_attr "type" "pop")])
+
+(define_insn "pop_dp"
+  [(set (unspec:QI [(reg:QI 16)] 17) (mem:QI (post_dec:QI (reg:QI 20))))
+   (clobber (reg:CC 16))]
+  ""
+  "pop\\tdp"
+  [(set_attr "type" "pop")])
+
+(define_insn "popqi_unspec"
+  [(set (unspec:QI [(match_operand:QI 0 "reg_operand" "=r")] 18)
+        (mem:QI (post_dec:QI (reg:QI 20))))
+   (clobber (match_dup 0))
+   (clobber (reg:CC 21))]
+  ""
+  "pop\\t%0"
+  [(set_attr "type" "pop")])
+
 ;
 ; ABSI
 ;
   [(set_attr "type" "binary,binary,binary,binary")
    (set_attr "data" "not_uint16,uint16,int16,uint16")])
 
+(define_insn "andn_st"
+  [(set (unspec:QI [(reg:QI 21)] 20)
+        (and:QI (unspec:QI [(reg:QI 21)] 20)
+                (match_operand:QI 0 "" "N")))
+   (use (match_dup 0))
+   (use (reg:CC 21))
+   (clobber (reg:CC 21))]
+  ""
+  "@
+   andn\\t%N0,st"
+  [(set_attr "type" "misc")
+   (set_attr "data" "not_uint16")])
+
 (define_split
   [(set (match_operand:QI 0 "std_reg_operand" "")
         (and:QI (match_operand:QI 1 "src_operand" "")
 ;
 ; PUSH/POP
 ;
-(define_insn "*pushqf"
+(define_insn "pushqf"
   [(set (mem:QF (pre_inc:QI (reg:QI 20)))
         (match_operand:QF 0 "reg_operand" "f"))]
  ""
  "pushf\\t%0"
  [(set_attr "type" "push")])
 
-(define_insn "*popqf"
+(define_insn "popqf"
   [(set (match_operand:QF 0 "reg_operand" "=f")
         (mem:QF (post_dec:QI (reg:QI 20))))
    (clobber (reg:CC 21))]
  "popf\\t%0"
  [(set_attr "type" "pop")])
 
+(define_insn "popqf_unspec"
+  [(set (unspec:QF [(match_operand:QF 0 "reg_operand" "=f")] 19)
+        (mem:QF (post_dec:QI (reg:QI 20))))
+   (clobber (match_dup 0))
+   (clobber (reg:CC 21))]
+ ""
+ "popf\\t%0"
+ [(set_attr "type" "pop")])
 
 ;
 ; ABSF
   ""
   "@
    ldiv\\t%1,%0"
-  [(set_attr "type" "binary")])
+  [(set_attr "type" "unary")])
 
 ; Move operand 2 to operand 0 if condition (operand 1) is true
 ; else move operand 3 to operand 0.
                               force_reg (Pmode, XEXP (operands[0], 0)));
 }")
 
+(define_insn "nodb_call"
+ [(call (mem:QI (match_operand:QI 0 "call_address_operand" "Ur"))
+       (const_int 0))]
+  ""
+  "call%U0\\t%C0"
+  [(set_attr "type" "call")])
+
 (define_insn "*callv_c3x"
  [(set (match_operand 0 "" "=r")
        (call (mem:QI (match_operand:QI 1 "call_address_operand" "Ur"))
   "rets"
   [(set_attr "type" "rets")])
 
+(define_insn "return_from_epilogue"
+  [(return)]
+  "reload_completed && ! c4x_interrupt_function_p ()"
+  "rets"
+  [(set_attr "type" "rets")])
+
+(define_insn "return_from_interrupt_epilogue"
+  [(return)]
+  "reload_completed && c4x_interrupt_function_p ()"
+  "reti"
+  [(set_attr "type" "rets")])
+
 (define_insn "*return_cc"
   [(set (pc)
         (if_then_else (match_operator 0 "comparison_operator"
    (set (match_dup 0)
         (plus:QI (match_dup 0)
                  (const_int -1)))
+   (use (reg:QI 20))
    (clobber (reg:CC_NOOV 21))]
   "TARGET_DB && TARGET_LOOP_UNSIGNED"
   "*
    (set (match_dup 0)
         (plus:QI (match_dup 0)
                  (const_int -1)))
+   (use (reg:QI 20))
    (clobber (reg:CC_NOOV 21))]
   "reload_completed && TARGET_DB && TARGET_LOOP_UNSIGNED"
   [(parallel [(set (pc)
    (set (match_dup 0)
         (plus:QI (match_dup 0)
                  (const_int -1)))
+   (use (reg:QI 20))
    (clobber (reg:CC_NOOV 21))]
   "TARGET_DB && (find_reg_note (insn, REG_NONNEG, 0) || TARGET_LOOP_UNSIGNED)"
   "*
    (set (match_dup 0)
         (plus:QI (match_dup 0)
                  (const_int -1)))
+   (use (reg:QI 20))
    (clobber (reg:CC_NOOV 21))]
   "reload_completed && TARGET_DB && TARGET_LOOP_UNSIGNED"
   [(parallel [(set (pc)
   "nop")
 ; Default to misc type attr.
 
+(define_expand "prologue"
+  [(const_int 1)]
+  ""                           
+  "c4x_expand_prologue (); DONE;")
+
+(define_expand "epilogue"
+  [(const_int 1)]
+  ""
+  "c4x_expand_epilogue (); DONE;")
 
 ;
 ; RPTB
                  (const_int -1)))
    (use (reg:QI 25))
    (use (reg:QI 26))
+   (use (reg:QI 20))
    (clobber (reg:CC_NOOV 21))]
   ""
   "*
    (use (match_operand:QI 4 "const_int_operand" ""))
    (use (reg:QI 25))
    (use (reg:QI 26))
+   (use (reg:QI 20))
    (clobber (reg:CC_NOOV 21))]
   "reload_completed"
   [(parallel [(set (pc)
 ;
 ; PUSH/POP
 ;
-(define_insn "*pushhf"
+(define_insn "pushhf"
   [(set (mem:HF (pre_inc:QI (reg:QI 20)))
         (match_operand:HF 0 "reg_operand" "h"))]
  ""
  [(set_attr "type" "push")])
 
 ; we can not use this because the popf will destroy the low 8 bits
-;(define_insn "*pophf"
+;(define_insn "pophf"
 ;  [(set (match_operand:HF 0 "reg_operand" "=h")
 ;        (mem:HF (post_dec:QI (reg:QI 20))))
 ;   (clobber (reg:CC 21))]
  ""
  "@
   popf\\t%0"
-  [(set_attr "type" "unary")])
+  [(set_attr "type" "pop")])
 
 ;
 ; FIX
    c4x_compare_op1 = operands[1];
    DONE;")
 
+(define_insn "*cmphi_cc"
+  [(set (reg:CC 21)
+        (compare:CC (match_operand:HI 0 "src_operand" "rR,rS<>")
+                    (match_operand:HI 1 "src_operand" "R,rS<>")))]
+  "valid_operands (COMPARE, operands, HImode)"
+  "#"
+  [(set_attr "type" "multi")])
+
+(define_insn "*cmphi_cc_noov"
+  [(set (reg:CC_NOOV 21)
+        (compare:CC_NOOV (match_operand:HI 0 "src_operand" "rR,rS<>")
+                         (match_operand:HI 1 "src_operand" "R,rS<>")))]
+  "valid_operands (COMPARE, operands, HImode)"
+  "#"
+  [(set_attr "type" "multi")])
+
 ; This works only before reload because we need 2 extra registers.
 ; Use unspec to avoid recursive split.
 (define_split
   "")
 
 ; This is normally not used. The define splits above are used first.
+(define_split
+  [(set (reg:CC 21)
+        (compare:CC (match_operand:HI 0 "src_operand" "")
+                    (match_operand:HI 1 "src_operand" "")))]
+  "reload_completed"
+  [(parallel [(set (reg:CC 21)
+                   (compare:CC (match_dup 0) (match_dup 1)))
+              (use (reg:QI 20))])]
+  "")
+
+(define_split
+  [(set (reg:CC_NOOV 21)
+        (compare:CC_NOOV (match_operand:HI 0 "src_operand" "")
+                         (match_operand:HI 1 "src_operand" "")))]
+  "reload_completed"
+  [(parallel [(set (reg:CC_NOOV 21)
+                   (compare:CC_NOOV (match_dup 0) (match_dup 1)))
+              (use (reg:QI 20))])]
+  "")
+
 (define_insn "*cmphi"
   [(set (reg:CC 21)
         (compare:CC (match_operand:HI 0 "src_operand" "rR,rS<>")
-                    (match_operand:HI 1 "src_operand" "R,rS<>")))]
+                    (match_operand:HI 1 "src_operand" "R,rS<>")))
+   (use (reg:QI 20))]
   "valid_operands (COMPARE, operands, HImode)"
   "*
    {
 (define_insn "*cmphi_noov"
   [(set (reg:CC_NOOV 21)
         (compare:CC_NOOV (match_operand:HI 0 "src_operand" "rR,rS<>")
-                    (match_operand:HI 1 "src_operand" "R,rS<>")))]
+                         (match_operand:HI 1 "src_operand" "R,rS<>")))
+   (use (reg:QI 20))]
   "valid_operands (COMPARE, operands, HImode)"
   "*
    {
      (set (match_dup 0)
           (plus:QI (match_dup 0)
                    (const_int -1)))
+     (use (reg:QI 20))
      (clobber (reg:CC_NOOV 21))])]
   "! c4x_label_conflict (insn, operands[2], operands[1])"
   "db%I3\\t%0,%l1\\n\\tb%3\\t%l2"