aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog17
-rw-r--r--gcc/config/c4x/c4x-protos.h6
-rw-r--r--gcc/config/c4x/c4x.c179
-rw-r--r--gcc/config/c4x/c4x.h57
-rw-r--r--gcc/config/c4x/c4x.md261
5 files changed, 487 insertions, 33 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 696ce4b..4a729a8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/c4x/c4x-protos.h b/gcc/config/c4x/c4x-protos.h
index a9fb5e6..62fae3b 100644
--- a/gcc/config/c4x/c4x-protos.h
+++ b/gcc/config/c4x/c4x-protos.h
@@ -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;
diff --git a/gcc/config/c4x/c4x.c b/gcc/config/c4x/c4x.c
index d6881b5..406ec0e 100644
--- a/gcc/config/c4x/c4x.c
+++ b/gcc/config/c4x/c4x.c
@@ -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;
+}
diff --git a/gcc/config/c4x/c4x.h b/gcc/config/c4x/c4x.h
index 3a6dae3..0ccc26e 100644
--- a/gcc/config/c4x/c4x.h
+++ b/gcc/config/c4x/c4x.h
@@ -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))
diff --git a/gcc/config/c4x/c4x.md b/gcc/config/c4x/c4x.md
index bd9cc96..022c92c 100644
--- a/gcc/config/c4x/c4x.md
+++ b/gcc/config/c4x/c4x.md
@@ -33,10 +33,10 @@
; 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
@@ -376,9 +376,11 @@
(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")))
@@ -463,6 +465,8 @@
; 19 popqf_unspec
; 20 andn_st
; 22 rptb_init
+; 23 toieee
+; 24 frieee
;
; C4x FUNCTIONAL UNITS
@@ -950,7 +954,7 @@
[(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"
@@ -2168,7 +2172,7 @@
; 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
@@ -3344,7 +3348,7 @@
")
(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"))
@@ -3373,7 +3377,7 @@
(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"))
@@ -3712,6 +3716,29 @@
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")))
@@ -3720,6 +3747,16 @@
"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
;
@@ -3741,6 +3778,16 @@
"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
@@ -3773,6 +3820,34 @@
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" "")))
@@ -3804,6 +3879,29 @@
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" "")))
@@ -3816,7 +3914,7 @@
;
; 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))]
@@ -3896,6 +3994,23 @@
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
;
@@ -4239,6 +4354,49 @@
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))
@@ -4538,6 +4696,34 @@
[(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
;
@@ -5090,6 +5276,45 @@
"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
;
@@ -5710,7 +5935,7 @@
[(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))]
""
@@ -5806,7 +6031,7 @@
"")
(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))]
@@ -5879,31 +6104,31 @@
(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)))]
""