c4x.h (MD_INIT_BUILTINS, [...]): Define.
authorMichael Hayes <m.hayes@elec.canterbury.ac.nz>
Sat, 16 Dec 2000 23:13:15 +0000 (23:13 +0000)
committerMichael Hayes <m.hayes@gcc.gnu.org>
Sat, 16 Dec 2000 23:13:15 +0000 (23:13 +0000)
* config/c4x/c4x.h (MD_INIT_BUILTINS, MD_EXPAND_BUILTIN): Define.

* config/c4x/c4x-protos.h (c4x_init_builtins): New prototype.
(c4x_expand_builtin): Likewise.

* config/c4x/c4x.c (c4x_init_builtins): New function.
(c4x_expand_builtin): Likewise.

* config/c4x/c4x.md (floatunsqihf2): New pattern.
(*floatqihf2_set, *fixhfqi_set, fix_trunchfqi2): Likewise.
(fixuns_trunchfqi2, toieee, frieee, *ldhf_conditional): Likewise.
(*ldhf_conditional_noov, movhfcc, trap, cond_trap_cc): Likewise.
(*toieee_movqf_clobber, *frieee_movqf_clobber): Likewise.

Co-Authored-By: Herman A.J. ten Brugge <Haj.Ten.Brugge@net.HCC.nl>
From-SVN: r38315

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

index 696ce4bae844e33a2f4d23e117e2974519f1a317..4a729a8ea95e2c2a4c7de2ca98327d82ed2715da 100644 (file)
@@ -1,5 +1,22 @@
 2000-12-17  Michael Hayes  <m.hayes@elec.canterbury.ac.nz>
+            Herman A.J. ten Brugge <Haj.Ten.Brugge@net.HCC.nl>
 
+       * config/c4x/c4x.h (MD_INIT_BUILTINS, MD_EXPAND_BUILTIN): Define.
+
+       * config/c4x/c4x-protos.h (c4x_init_builtins): New prototype.
+       (c4x_expand_builtin): Likewise.
+
+       * config/c4x/c4x.c (c4x_init_builtins): New function.
+       (c4x_expand_builtin): Likewise.
+
+       * config/c4x/c4x.md (floatunsqihf2): New pattern.
+       (*floatqihf2_set, *fixhfqi_set, fix_trunchfqi2): Likewise.
+       (fixuns_trunchfqi2, toieee, frieee, *ldhf_conditional): Likewise.
+       (*ldhf_conditional_noov, movhfcc, trap, cond_trap_cc): Likewise.
+       (*toieee_movqf_clobber, *frieee_movqf_clobber): Likewise.
+
+2000-12-17  Michael Hayes  <m.hayes@elec.canterbury.ac.nz>
+       
        * libgcc2.h: Use Wtype for SItype and DWtype for DItype in prototypes.
        * libgcc2.c (__absvsi2): Use Wtype and DWtype.
        (__absvdi2, __addvsi3, __addvdi3, __subvsi3): Likewise.
index a9fb5e6bde29ec89c7ea2ee654011fceb6c19dfd..62fae3b809c1bdcd9cdbe10a909ed580e268b489 100644 (file)
@@ -62,6 +62,7 @@ extern struct rtx_def *c4x_function_arg PARAMS ((CUMULATIVE_ARGS *,
 extern void c4x_encode_section_info PARAMS ((tree));
 
 extern int c4x_valid_type_attribute_p PARAMS ((tree, tree, tree, tree));
+
 #endif /* TREE_CODE */
 
 
@@ -71,6 +72,9 @@ extern void c4x_init_cumulative_args PARAMS ((CUMULATIVE_ARGS *c, tree, rtx));
 extern void c4x_va_start PARAMS ((int, tree, rtx));
 
 extern struct rtx_def *c4x_va_arg PARAMS ((tree, tree));
+
+extern rtx c4x_expand_builtin PARAMS((tree, rtx, rtx,
+                                     enum machine_mode, int));
 #endif /* TREE_CODE and RTX_CODE*/
 
 
@@ -271,6 +275,8 @@ extern int valid_parallel_operands_5 PARAMS ((rtx *, enum machine_mode));
 
 extern int valid_parallel_operands_6 PARAMS ((rtx *, enum machine_mode));
 
+extern void c4x_init_builtins PARAMS((void));
+
 extern rtx smulhi3_libfunc;
 extern rtx umulhi3_libfunc;
 extern rtx fix_truncqfhi2_libfunc;
index d6881b5c223905a6559fe40f5dac2c4124a76c1b..406ec0e8daabc28ee676646ad64d3c181b83ebbf 100644 (file)
@@ -315,6 +315,7 @@ c4x_output_ascii (stream, ptr, len)
   char sbuf[C4X_ASCII_LIMIT + 1];
   int s, l, special, first, onlys;
 
+  first = 0;
   if (len)
     {
       fprintf (stream, "\t.byte\t");
@@ -4855,3 +4856,181 @@ c4x_adjust_cost (insn, link, dep_insn, cost)
   else
     abort ();
 }
+
+void
+c4x_init_builtins ()
+{
+  tree endlink = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
+
+  builtin_function ("abs",
+                   build_function_type
+                   (integer_type_node, 
+                    tree_cons (NULL_TREE, integer_type_node, endlink)),
+                   C4X_BUILTIN_ABS, BUILT_IN_MD, NULL_PTR);
+  builtin_function ("fabs",
+                   build_function_type
+                   (double_type_node, 
+                    tree_cons (NULL_TREE, double_type_node, endlink)),
+                   C4X_BUILTIN_FABS, BUILT_IN_MD, NULL_PTR);
+  builtin_function ("labs",
+                   build_function_type 
+                   (long_integer_type_node, 
+                    tree_cons (NULL_TREE, long_integer_type_node, endlink)),
+                   C4X_BUILTIN_LABS, BUILT_IN_MD, NULL_PTR);
+  builtin_function ("fast_ftoi",
+                   build_function_type 
+                   (integer_type_node,
+                    tree_cons (NULL_TREE, double_type_node, endlink)),
+                   C4X_BUILTIN_FIX, BUILT_IN_MD, NULL_PTR);
+  builtin_function ("ansi_ftoi",
+                   build_function_type 
+                   (integer_type_node, 
+                    tree_cons (NULL_TREE, double_type_node, endlink)),
+                   C4X_BUILTIN_FIX_ANSI, BUILT_IN_MD, NULL_PTR);
+  if (TARGET_C3X)
+    builtin_function ("fast_imult",
+                     build_function_type
+                     (integer_type_node, 
+                      tree_cons (NULL_TREE, integer_type_node,
+                                 tree_cons (NULL_TREE,
+                                            integer_type_node, endlink))),
+                     C4X_BUILTIN_MPYI, BUILT_IN_MD, NULL_PTR);
+  else
+    {
+      builtin_function ("toieee",
+                       build_function_type 
+                       (double_type_node,
+                        tree_cons (NULL_TREE, double_type_node, endlink)),
+                       C4X_BUILTIN_TOIEEE, BUILT_IN_MD, NULL_PTR);
+      builtin_function ("frieee",
+                       build_function_type
+                       (double_type_node, 
+                        tree_cons (NULL_TREE, double_type_node, endlink)),
+                       C4X_BUILTIN_FRIEEE, BUILT_IN_MD, NULL_PTR);
+      builtin_function ("fast_invf",
+                       build_function_type 
+                       (double_type_node, 
+                        tree_cons (NULL_TREE, double_type_node, endlink)),
+                       C4X_BUILTIN_RCPF, BUILT_IN_MD, NULL_PTR);
+    }
+}
+
+
+rtx
+c4x_expand_builtin (exp, target, subtarget, mode, ignore)
+     tree exp;
+     rtx target;
+     rtx subtarget ATTRIBUTE_UNUSED;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+     int ignore ATTRIBUTE_UNUSED;
+{
+  tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
+  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+  tree arglist = TREE_OPERAND (exp, 1);
+  tree arg0, arg1;
+  rtx r0, r1;
+
+  switch (fcode)
+    {
+    case C4X_BUILTIN_ABS:
+      arg0 = TREE_VALUE (arglist);
+      r0 = expand_expr (arg0, NULL_RTX, QImode, 0);
+      r0 = protect_from_queue (r0, 0);
+      if (! target || ! register_operand (target, QImode))
+       target = gen_reg_rtx (QImode);
+      emit_insn (gen_absqi2 (target, r0));
+      return target;
+
+    case C4X_BUILTIN_FABS:
+      arg0 = TREE_VALUE (arglist);
+      r0 = expand_expr (arg0, NULL_RTX, QFmode, 0);
+      r0 = protect_from_queue (r0, 0);
+      if (! target || ! register_operand (target, QFmode))
+       target = gen_reg_rtx (QFmode);
+      emit_insn (gen_absqf2 (target, r0));
+      return target;
+
+    case C4X_BUILTIN_LABS:
+      arg0 = TREE_VALUE (arglist);
+      r0 = expand_expr (arg0, NULL_RTX, QImode, 0);
+      r0 = protect_from_queue (r0, 0);
+      if (! target || ! register_operand (target, QImode))
+       target = gen_reg_rtx (QImode);
+      emit_insn (gen_absqi2 (target, r0));
+      return target;
+
+    case C4X_BUILTIN_FIX:
+      arg0 = TREE_VALUE (arglist);
+      r0 = expand_expr (arg0, NULL_RTX, QFmode, 0);
+      r0 = protect_from_queue (r0, 0);
+      if (! target || ! register_operand (target, QImode))
+       target = gen_reg_rtx (QImode);
+      emit_insn (gen_fixqfqi_clobber (target, r0));
+      return target;
+
+    case C4X_BUILTIN_FIX_ANSI:
+      arg0 = TREE_VALUE (arglist);
+      r0 = expand_expr (arg0, NULL_RTX, QFmode, 0);
+      r0 = protect_from_queue (r0, 0);
+      if (! target || ! register_operand (target, QImode))
+       target = gen_reg_rtx (QImode);
+      emit_insn (gen_fix_truncqfqi2 (target, r0));
+      return target;
+
+    case C4X_BUILTIN_MPYI:
+      if (! TARGET_C3X)
+       break;
+      arg0 = TREE_VALUE (arglist);
+      arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+      r0 = expand_expr (arg0, NULL_RTX, QImode, 0);
+      r1 = expand_expr (arg1, NULL_RTX, QImode, 0);
+      r0 = protect_from_queue (r0, 0);
+      r1 = protect_from_queue (r1, 0);
+      if (! target || ! register_operand (target, QImode))
+       target = gen_reg_rtx (QImode);
+      emit_insn (gen_mulqi3_24_clobber (target, r0, r1));
+      return target;
+
+    case C4X_BUILTIN_TOIEEE:
+      if (TARGET_C3X)
+       break;
+      arg0 = TREE_VALUE (arglist);
+      r0 = expand_expr (arg0, NULL_RTX, QFmode, 0);
+      r0 = protect_from_queue (r0, 0);
+      if (! target || ! register_operand (target, QFmode))
+       target = gen_reg_rtx (QFmode);
+      emit_insn (gen_toieee (target, r0));
+      return target;
+
+    case C4X_BUILTIN_FRIEEE:
+      if (TARGET_C3X)
+       break;
+      arg0 = TREE_VALUE (arglist);
+      if (TREE_CODE (arg0) == VAR_DECL || TREE_CODE (arg0) == PARM_DECL)
+       put_var_into_stack (arg0);
+      r0 = expand_expr (arg0, NULL_RTX, QFmode, 0);
+      r0 = protect_from_queue (r0, 0);
+      if (register_operand (r0, QFmode))
+       {
+         r1 = assign_stack_local (QFmode, GET_MODE_SIZE (QFmode), 0);
+         emit_move_insn (r1, r0);
+         r0 = r1;
+       }
+      if (! target || ! register_operand (target, QFmode))
+       target = gen_reg_rtx (QFmode);
+      emit_insn (gen_frieee (target, r0));
+      return target;
+
+    case C4X_BUILTIN_RCPF:
+      if (TARGET_C3X)
+       break;
+      arg0 = TREE_VALUE (arglist);
+      r0 = expand_expr (arg0, NULL_RTX, QFmode, 0);
+      r0 = protect_from_queue (r0, 0);
+      if (! target || ! register_operand (target, QFmode))
+       target = gen_reg_rtx (QFmode);
+      emit_insn (gen_rcpfqf_clobber (target, r0));
+      return target;
+    }
+  return NULL_RTX;
+}
index 3a6dae34e830d193977ea270e4245b0b00ab1911..0ccc26eb45eb6a3d2ef46f6d04e9c22651dd8f2c 100644 (file)
@@ -2609,7 +2609,7 @@ do { fprintf (asm_out_file, "\t.sdef\t");         \
 /* MOVE_RATIO is the number of move instructions that is better than a
    block move.  */
 
-#define MOVE_RATIO 2           /* Default value.  */
+#define MOVE_RATIO 3
 
 #define BSS_SECTION_ASM_OP "\t.bss"
 
@@ -2638,20 +2638,23 @@ do { fprintf (asm_out_file, "\t.sdef\t");               \
 
 #define MACHINE_DEPENDENT_REORG(INSNS) c4x_process_after_reload(INSNS)
 
-#define DBR_OUTPUT_SEQEND(FILE)                \
-if (final_sequence != NULL_RTX)                \
-{                                      \
- int count;                            \
- int laj = GET_CODE (XVECEXP (final_sequence, 0, 0)) == CALL_INSN; \
-                                       \
- count = dbr_sequence_length();                \
- while (count < (laj ? 2 : 3))         \
- {                                     \
-    fputs("\tnop\n", FILE);            \
-    count++;                           \
- }                                     \
- if (laj)                              \
-    fputs("\tpush\tr11\n", FILE);      \
+#define DBR_OUTPUT_SEQEND(FILE)                                \
+if (final_sequence != NULL_RTX)                                \
+{                                                      \
+ int count;                                            \
+ rtx insn = XVECEXP (final_sequence, 0, 0);            \
+ int laj = GET_CODE (insn) == CALL_INSN                \
+          || (GET_CODE (insn) == INSN                  \
+              && GET_CODE (PATTERN (insn)) == TRAP_IF);\
+                                                       \
+ count = dbr_sequence_length();                                \
+ while (count < (laj ? 2 : 3))                         \
+ {                                                     \
+    fputs("\tnop\n", FILE);                            \
+    count++;                                           \
+ }                                                     \
+ if (laj)                                              \
+    fputs("\tpush\tr11\n", FILE);                      \
 }
 
 #define NO_FUNCTION_CSE
@@ -2692,3 +2695,27 @@ if (final_sequence != NULL_RTX)          \
   {"parallel_operand", {SUBREG, REG, MEM}},                    \
   {"symbolic_address_operand", {SYMBOL_REF, LABEL_REF, CONST}},        \
   {"mem_operand", {MEM}},                                      
+
+
+/* Define the intrinsic functions for the c3x/c4x.  */
+
+enum c4x_builtins
+{
+                       /*      intrinsic name          */
+  C4X_BUILTIN_ABS,     /*      abs                     */
+  C4X_BUILTIN_FABS,    /*      fabs                    */
+  C4X_BUILTIN_LABS,    /*      labs                    */
+  C4X_BUILTIN_FIX,     /*      fast_ftoi               */
+  C4X_BUILTIN_FIX_ANSI,        /*      ansi_ftoi               */
+  C4X_BUILTIN_MPYI,    /*      fast_imult (only C3x)   */
+  C4X_BUILTIN_TOIEEE,  /*      toieee     (only C4x)   */
+  C4X_BUILTIN_FRIEEE,  /*      frieee     (only C4x)   */
+  C4X_BUILTIN_RCPF     /*      fast_invf  (only C4x)   */
+};
+
+#define MD_INIT_BUILTINS do { \
+    c4x_init_builtins (); \
+  } while (0)
+
+#define MD_EXPAND_BUILTIN(EXP, TARGET, SUBTARGET, MODE, IGNORE) \
+    c4x_expand_builtin ((EXP), (TARGET), (SUBTARGET), (MODE), (IGNORE))
index bd9cc9648267c5b1be33708484b0e5640a1ddb61..022c92cd7b7d73218dfad512bb5f414b81870c54 100644 (file)
 
 ; Additional C30/C40 instructions not coded:
 ; CALLcond, IACK, IDLE, LDE, LDFI, LDII, LDM, NORM, RETIcond
-; ROLC, RORC, SIGI, STFI, STII, SUBC, SWI, TRAPcond
+; ROLC, RORC, SIGI, STFI, STII, SUBC, SWI
 
 ; Additional C40 instructions not coded:
-; LDEP, LDPE, LWRct, FRIEEE, TOIEEE, LAJcond, LATcond, RETIcondD
+; LDEP, LDPE, LWRct, LAJcond, RETIcondD
 
 ;
 ; C4x MODES
                (const_string "true")
                (const_string "false")))
 
+/* Disable ldp because the c4x contains a bug. The ldp insn modifies
+   the dp register when the insn is anulled or not.  */
 (define_attr "in_annul_slot_3" "false,true"
   (if_then_else (and (eq_attr "cpu" "c4x")
-                    (eq_attr "type" "!jump,call,rets,jmpc,db,dbc,repeat,repeat_top,laj,push,pop,multi"))
+                    (eq_attr "type" "!jump,call,rets,jmpc,db,dbc,repeat,repeat_top,laj,push,pop,ldp,multi"))
                (const_string "true")
                (const_string "false")))
 
 ; 19 popqf_unspec
 ; 20 andn_st
 ; 22 rptb_init
+; 23 toieee
+; 24 frieee
 
 ;
 ; C4x FUNCTIONAL UNITS
   [(set_attr "type" "unary")])
 
 (define_insn "set_lo_sum"
-  [(set (match_operand:QI 0 "std_reg_operand" "=c")
+  [(set (match_operand:QI 0 "std_reg_operand" "+c")
         (lo_sum:QI (match_dup 0)
                    (match_operand:QI 1 "symbolic_address_operand" "")))]
   "! TARGET_TI"
 
 ; The C3x multiply instruction assumes 24-bit signed integer operands
 ; and the 48-bit result is truncated to 32-bits.
-(define_insn "*mulqi3_24_clobber"
+(define_insn "mulqi3_24_clobber"
   [(set (match_operand:QI 0 "reg_operand" "=d,d,?d,c,c,?c")
         (mult:QI
          (sign_extend:QI
  ")
 
 (define_insn "*insv_clobber"
-  [(set (zero_extract:QI (match_operand:QI 0 "reg_operand" "=d,c")
+  [(set (zero_extract:QI (match_operand:QI 0 "reg_operand" "+d,c")
                          (match_operand:QI 1 "const_int_operand" "n,n")
                          (match_operand:QI 2 "const_int_operand" "n,n"))
         (match_operand:QI 3 "src_operand" "rLm,rLm"))
    (set_attr "data" "uint16,uint16")])
 
 (define_peephole
-  [(parallel [(set (zero_extract:QI (match_operand:QI 0 "ext_reg_operand" "=d")
+  [(parallel [(set (zero_extract:QI (match_operand:QI 0 "ext_reg_operand" "+d")
                                     (match_operand:QI 1 "const_int_operand" "n")
                                     (match_operand:QI 2 "const_int_operand" "n"))
                    (match_operand:QI 3 "src_operand" "rLm"))
   emit_move_insn (operands[5], 
    immed_real_const_1 (REAL_VALUE_ATOF (\"4294967296.0\", QFmode), QFmode));")
 
+(define_expand "floatunsqihf2"
+ [(set (match_dup 2) (match_dup 3))
+  (parallel [(set (reg:CC 21)
+                  (compare:CC (float:HF (match_operand:QI 1 "src_operand" ""))
+                              (match_dup 3)))
+             (set (match_dup 4)
+                  (float:HF (match_dup 1)))])
+  (set (match_dup 6)
+       (if_then_else:HF (lt (reg:CC 21) (const_int 0))
+                        (match_dup 5)
+                        (match_dup 2)))
+  (parallel [(set (match_operand:HF 0 "reg_operand" "")
+                  (plus:HF (match_dup 6) (match_dup 4)))
+             (clobber (reg:CC_NOOV 21))])]
+ ""
+ "operands[2] = gen_reg_rtx (HFmode);
+  operands[3] = CONST0_RTX (HFmode); 
+  operands[4] = gen_reg_rtx (HFmode);
+  operands[5] = gen_reg_rtx (HFmode);
+  operands[6] = gen_reg_rtx (HFmode);
+  emit_move_insn (operands[5], 
+   immed_real_const_1 (REAL_VALUE_ATOF (\"4294967296.0\", HFmode), HFmode));")
+
 (define_insn "floatqihf2"
   [(set (match_operand:HF 0 "reg_operand" "=h")
         (float:HF (match_operand:QI 1 "src_operand" "rIm")))
  "float\\t%1,%0"
   [(set_attr "type" "unarycc")])
 
+(define_insn "*floatqihf2_set"
+  [(set (reg:CC 21)
+       (compare:CC (float:HF (match_operand:QI 1 "src_operand" "rIm"))
+                    (match_operand:QF 2 "fp_zero_operand" "G")))
+   (set (match_operand:HF 0 "reg_operand" "=h")
+        (float:HF (match_dup 1)))]
+ ""
+ "float\\t%1,%0"
+  [(set_attr "type" "unarycc")])
+
 ;
 ; FIX
 ;
  "fix\\t%1,%0"
   [(set_attr "type" "unarycc")])
 
+(define_insn "*fixhfqi_set"
+  [(set (reg:CC 21)
+        (compare:CC (fix:QI (match_operand:HF 1 "src_operand" "fH"))
+                    (const_int 0)))
+   (set (match_operand:QI 0 "ext_reg_operand" "=d")
+        (fix:QI (match_dup 1)))]
+ ""
+ "fix\\t%1,%0"
+  [(set_attr "type" "unarycc")])
+
 ;
 ; The C[34]x fix instruction implements a floor, not a straight trunc,
 ; so we have to invert the number, fix it, and reinvert it if negative
   operands[5] = gen_reg_rtx (QImode);
  ")
 
+(define_expand "fix_trunchfqi2"
+  [(parallel [(set (match_dup 2)
+                   (fix:QI (match_operand:HF 1 "src_operand" "")))
+              (clobber (reg:CC 21))])
+   (parallel [(set (match_dup 3) (neg:HF (match_dup 1)))
+              (clobber (reg:CC_NOOV 21))])
+   (parallel [(set (match_dup 4) (fix:QI (match_dup 3)))
+              (clobber (reg:CC 21))])
+   (parallel [(set (reg:CC_NOOV 21)
+                   (compare:CC_NOOV (neg:QI (match_dup 4)) (const_int 0)))
+              (set (match_dup 5) (neg:QI (match_dup 4)))])
+   (set (match_dup 2)
+        (if_then_else:QI (le (reg:CC 21) (const_int 0))
+                         (match_dup 5)
+                         (match_dup 2)))
+   (set (match_operand:QI 0 "reg_operand" "=r") (match_dup 2))]
+ ""
+ "if (TARGET_FAST_FIX)
+    {
+       emit_insn (gen_fixhfqi_clobber (operands[0], operands[1]));
+       DONE;
+    }
+  operands[2] = gen_reg_rtx (QImode);
+  operands[3] = gen_reg_rtx (HFmode);
+  operands[4] = gen_reg_rtx (QImode);
+  operands[5] = gen_reg_rtx (QImode);
+ ")
+
 (define_expand "fix_truncqfhi2"
   [(parallel [(set (match_operand:HI 0 "reg_operand" "")
                    (fix:HI (match_operand:QF 1 "src_operand" "")))
   emit_move_insn (operands[5],
    immed_real_const_1 (REAL_VALUE_ATOF (\"4294967296.0\", QFmode), QFmode));")
 
+(define_expand "fixuns_trunchfqi2"
+ [(parallel [(set (match_dup 2)
+                 (fix:QI (match_operand:HF 1 "src_operand" "hH")))
+            (clobber (reg:CC 21))])
+  (parallel [(set (match_dup 3)
+                 (minus:HF (match_dup 1) (match_dup 5)))
+            (clobber (reg:CC_NOOV 21))])
+  (parallel [(set (reg:CC 21)
+                 (compare:CC (fix:QI (match_dup 3))
+                             (const_int 0)))
+            (set (match_dup 4)
+                 (fix:QI (match_dup 3)))])
+  (parallel [(set (match_dup 4) (unspec:QI [(match_dup 2)] 13))
+             (use (reg:CC 21))])
+  (set (match_operand:QI 0 "reg_operand" "=r") (match_dup 4))]
+ ""
+ "operands[2] = gen_reg_rtx (QImode);
+  operands[3] = gen_reg_rtx (HFmode);
+  operands[4] = gen_reg_rtx (QImode);
+  operands[5] = gen_reg_rtx (HFmode);
+  emit_move_insn (operands[5],
+   immed_real_const_1 (REAL_VALUE_ATOF (\"4294967296.0\", HFmode), HFmode));")
+
 (define_expand "fixuns_truncqfhi2"
   [(parallel [(set (match_operand:HI 0 "reg_operand" "")
                    (unsigned_fix:HI (match_operand:QF 1 "src_operand" "")))
 ;
 ; RCPF
 ;
-(define_insn "*rcpfqf_clobber"
+(define_insn "rcpfqf_clobber"
   [(set (match_operand:QF 0 "reg_operand" "=f")
         (unspec:QF [(match_operand:QF 1 "src_operand" "fHm")] 5))
    (clobber (reg:CC_NOOV 21))]
   "emit_insn (gen_sqrtqf2_inline (operands[0], operands[1]));
    DONE;")
 
+;
+; TOIEEE / FRIEEE
+;
+(define_insn "toieee"
+  [(set (match_operand:QF 0 "reg_operand" "=f")
+        (unspec:QF [(match_operand:QF 1 "src_operand" "fHm")] 23))
+   (clobber (reg:CC 21))]
+ ""
+ "toieee\\t%1,%0")
+
+(define_insn "frieee"
+  [(set (match_operand:QF 0 "reg_operand" "=f")
+        (unspec:QF [(match_operand:QF 1 "memory_operand" "m")] 24))
+   (clobber (reg:CC 21))]
+ ""
+ "frieee\\t%1,%0")
+
 ;
 ; THREE OPERAND FLOAT INSTRUCTIONS
 ;
                                           operands[2], operands[3])));
     DONE;}")
 
+(define_insn "*ldhf_conditional"
+  [(set (match_operand:HF 0 "reg_operand" "=h,h")
+        (if_then_else:HF (match_operator 1 "comparison_operator"
+                          [(reg:CC 21) (const_int 0)])
+                         (match_operand:HF 2 "src_operand" "hH,0")
+                         (match_operand:HF 3 "src_operand" "0,hH")))]
+ ""
+ "@
+  ldf%1\\t%2,%0
+  ldf%I1\\t%3,%0"
+ [(set_attr "type" "binary")])
+
+(define_insn "*ldhf_conditional_noov"
+  [(set (match_operand:HF 0 "reg_operand" "=h,h")
+        (if_then_else:HF (match_operator 1 "comparison_operator"
+                          [(reg:CC_NOOV 21) (const_int 0)])
+                         (match_operand:HF 2 "src_operand" "hH,0")
+                         (match_operand:HF 3 "src_operand" "0,hH")))]
+ "GET_CODE (operands[1]) != LE
+  && GET_CODE (operands[1]) != GE
+  && GET_CODE (operands[1]) != LT
+  && GET_CODE (operands[1]) != GT"
+ "@
+  ldf%1\\t%2,%0
+  ldf%I1\\t%3,%0"
+ [(set_attr "type" "binary")])
+
+(define_expand "movhfcc"
+  [(set (match_operand:HF 0 "reg_operand" "")
+        (if_then_else:HF (match_operand 1 "comparison_operator" "")
+                         (match_operand:HF 2 "src_operand" "")
+                         (match_operand:HF 3 "src_operand" "")))]
+ ""
+ "{ 
+    enum rtx_code code = GET_CODE (operands[1]);
+    rtx ccreg = c4x_gen_compare_reg (code, c4x_compare_op0, c4x_compare_op1);
+    if (ccreg == NULL_RTX) FAIL;
+    emit_insn (gen_rtx_SET (HFmode, operands[0],
+                            gen_rtx_IF_THEN_ELSE (HFmode,
+                                 gen_rtx (code, VOIDmode, ccreg, const0_rtx),
+                                          operands[2], operands[3])));
+    DONE;}")
+
 (define_expand "seq"
  [(set (match_operand:QI 0 "reg_operand" "")
        (const_int 0))
   "subf3\\t%2,%1,%0\\n||\\tstf\\t%4,%3"
   [(set_attr "type" "binarycc")])
 
+;
+; TOIEEE/STF
+;
+
+(define_insn "*toieee_movqf_clobber"
+  [(set (match_operand:QF 0 "ext_low_reg_operand" "=q")
+       (unspec:QF [(match_operand:QF 1 "par_ind_operand" "S<>")] 23))
+   (set (match_operand:QF 2 "par_ind_operand" "=S<>")
+        (match_operand:QF 3 "ext_low_reg_operand" "q"))
+   (clobber (reg:CC 21))]
+  "TARGET_PARALLEL && valid_parallel_operands_4 (operands, QFmode)"
+  "toieee\\t%1,%0\\n||\\tstf\\t%3,%2"
+  [(set_attr "type" "binarycc")])
+
+;
+; FRIEEE/STF
+;
+
+(define_insn "*frieee_movqf_clobber"
+  [(set (match_operand:QF 0 "ext_low_reg_operand" "=q")
+       (unspec:QF [(match_operand:QF 1 "par_ind_operand" "S<>")] 24))
+   (set (match_operand:QF 2 "par_ind_operand" "=S<>")
+        (match_operand:QF 3 "ext_low_reg_operand" "q"))
+   (clobber (reg:CC 21))]
+  "TARGET_PARALLEL && valid_parallel_operands_4 (operands, QFmode)"
+  "frieee\\t%1,%0\\n||\\tstf\\t%3,%2"
+  [(set_attr "type" "binarycc")])
+
 ;
 ; PARALLEL INTEGER INSTRUCTIONS
 ;
   "br%#\\t%l0"
   [(set_attr "type" "jump")])
 
+(define_insn "trap"
+  [(trap_if (const_int 1) (const_int 31))]
+  ""
+  "trapu\\t31"
+  [(set_attr "type" "call")])
+
+(define_expand "conditional_trap"
+ [(trap_if (match_operand 0 "comparison_operator" "")
+          (match_operand 1 "const_int_operand" ""))]
+ ""
+ "{
+    enum rtx_code code = GET_CODE (operands[1]);
+    rtx ccreg = c4x_gen_compare_reg (code, c4x_compare_op0, c4x_compare_op1);
+    if (ccreg == NULL_RTX) FAIL;
+    if (GET_MODE (ccreg) == CCmode)
+      emit_insn (gen_cond_trap_cc (operands[0], operands[1]));
+    else 
+      emit_insn (gen_cond_trap_cc_noov (operands[0], operands[1]));
+    DONE;}")
+
+(define_insn "cond_trap_cc"
+  [(trap_if (match_operator 0 "comparison_operator"
+            [(reg:CC 21) (const_int 0)])
+           (match_operand 1 "const_int_operand" ""))]
+  ""
+  "trap%0\\t31"
+  [(set_attr "type" "call")])
+
+(define_insn "cond_trap_cc_noov"
+  [(trap_if (match_operator 0 "comparison_operator"
+            [(reg:CC_NOOV 21) (const_int 0)])
+           (match_operand 1 "const_int_operand" ""))]
+  "GET_CODE (operands[0]) != LE
+   && GET_CODE (operands[0]) != GE
+   && GET_CODE (operands[0]) != LT
+   && GET_CODE (operands[0]) != GT"
+  "trap%0\\t31"
+  [(set_attr "type" "call")])
+
 ;
 ; DBcond
 ;
   [(set_attr "type" "unary")])
 
 (define_insn "*loadhf_int"
- [(set (match_operand:HF 0 "reg_operand" "=h")
+ [(set (match_operand:HF 0 "reg_operand" "+h")
        (unspec:HF [(subreg:QI (match_dup 0) 0)
                    (match_operand:QI 1 "src_operand" "rIm")] 8))]
  ""
  "")
 
 (define_insn "*pophf_int"
- [(set (match_operand:HF 0 "reg_operand" "=h")
+ [(set (match_operand:HF 0 "reg_operand" "+h")
        (unspec:HF [(subreg:QI (match_dup 0) 0)
                    (mem:QI (post_dec:QI (reg:QI 20)))] 8))
   (clobber (reg:CC 21))]
 (define_expand "neghf2"
   [(parallel [(set (match_operand:HF 0 "reg_operand" "")
                    (neg:HF (match_operand:HF 1 "reg_or_const_operand" "")))
-              (clobber (reg:CC 21))])]
+              (clobber (reg:CC_NOOV 21))])]
 ""
 "")
 
 (define_insn "*neghf2_clobber"
   [(set (match_operand:HF 0 "reg_operand" "=h")
         (neg:HF (match_operand:HF 1 "reg_or_const_operand" "hH")))
-   (clobber (reg:CC 21))]
+   (clobber (reg:CC_NOOV 21))]
   ""
   "negf\\t%1,%0"
   [(set_attr "type" "unarycc")])
 
 (define_insn "*neghf2_test"
-  [(set (reg:CC 21)
-        (compare:CC (neg:HF (match_operand:HF 1 "reg_or_const_operand" "hH"))
-                    (match_operand:HF 2 "fp_zero_operand" "G")))
+  [(set (reg:CC_NOOV 21)
+        (compare:CC_NOOV (neg:HF (match_operand:HF 1 "reg_or_const_operand" "hH"))
+                         (match_operand:HF 2 "fp_zero_operand" "G")))
    (clobber (match_scratch:HF 0 "=h"))]
   ""
   "negf\\t%1,%0"
   [(set_attr "type" "unarycc")])
 
 (define_insn "*neghf2_set"
-  [(set (reg:CC 21)
-        (compare:CC (neg:HF (match_operand:HF 1 "reg_or_const_operand" "hH"))
-                    (match_operand:HF 2 "fp_zero_operand" "G")))
+  [(set (reg:CC_NOOV 21)
+        (compare:CC_NOOV (neg:HF (match_operand:HF 1 "reg_or_const_operand" "hH"))
+                         (match_operand:HF 2 "fp_zero_operand" "G")))
    (set (match_operand:HF 0 "reg_operand" "=h")
         (neg:HF (match_dup 1)))]
   ""