From 8a119a7d47ae53af38e44ac19c110758221c99ee Mon Sep 17 00:00:00 2001 From: Michael Hayes Date: Sat, 16 Dec 2000 23:13:15 +0000 Subject: [PATCH] c4x.h (MD_INIT_BUILTINS, [...]): Define. * 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 From-SVN: r38315 --- gcc/ChangeLog | 17 +++ gcc/config/c4x/c4x-protos.h | 6 + gcc/config/c4x/c4x.c | 179 +++++++++++++++++++++++++ gcc/config/c4x/c4x.h | 57 +++++--- gcc/config/c4x/c4x.md | 261 +++++++++++++++++++++++++++++++++--- 5 files changed, 487 insertions(+), 33 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 696ce4bae84..4a729a8ea95 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,22 @@ 2000-12-17 Michael Hayes + Herman A.J. ten Brugge + * 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 + * 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 a9fb5e6bde2..62fae3b809c 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 d6881b5c223..406ec0e8daa 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 3a6dae34e83..0ccc26eb45e 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 bd9cc964826..022c92cd7b7 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))] @@ -3895,6 +3993,23 @@ "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 ; @@ -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)) @@ -4537,6 +4695,34 @@ "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 ; @@ -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)))] "" -- 2.30.2