diff options
author | Claudiu Zissulescu <claziss@synopsys.com> | 2016-02-16 15:11:24 +0100 |
---|---|---|
committer | Claudiu Zissulescu <claziss@gcc.gnu.org> | 2016-02-16 15:11:24 +0100 |
commit | 8f3304d019bd1f9a8eb08b9dba3a430a59f52994 (patch) | |
tree | da942afd8cfd2f846b537d732131dfa2f973eb74 /gcc/config/arc/fpu.md | |
parent | d5b1a52eec591a9a995e47880c87333b42ebb870 (diff) | |
download | gcc-8f3304d019bd1f9a8eb08b9dba3a430a59f52994.zip gcc-8f3304d019bd1f9a8eb08b9dba3a430a59f52994.tar.gz gcc-8f3304d019bd1f9a8eb08b9dba3a430a59f52994.tar.bz2 |
[ARC] Add single/double IEEE precission FPU support.
gcc/
2016-02-16 Claudiu Zissulescu <claziss@synopsys.com>
* config/arc/arc-modes.def (CC_FPU, CC_FPU_UNEQ): New modes.
* config/arc/arc-opts.h (FPU_SP, FPU_SF, FPU_SC, FPU_SD, FPU_DP)
(FPU_DF, FPU_DC, FPU_DD, FXP_DP): Define.
* config/arc/arc.c (arc_init): Check FPU options.
(get_arc_condition_code): Handle new CC_FPU* modes.
(arc_select_cc_mode): Likewise.
(arc_conditional_register_usage): Allow 64 bit datum into even-odd
register pair only. Allow access for ARCv2 accumulator.
(gen_compare_reg): Whenever we have FPU support use FPU compare
instructions.
(arc_reorg): Don't generate brcc insns when FPU compare
instructions are involved.
* config/arc/arc.h (TARGET_DPFP): Add TARGET_FP_DPAX condition.
(TARGET_OPTFPE): Add condition when ARC EM can use optimized
floating point emulation.
(ACC_REG_FIRST, ACC_REG_LAST, ACCL_REGNO, ACCH_REGNO): Define.
(REVERSE_CONDITION): Add new CC_FPU* modes.
(TARGET_FP_SP_BASE): Define.
(TARGET_FP_DP_BASE): Likewise.
(TARGET_FP_SP_FUSED): Likewise.
(TARGET_FP_DP_FUSED): Likewise.
(TARGET_FP_SP_CONV): Likewise.
(TARGET_FP_DP_CONV): Likewise.
(TARGET_FP_SP_SQRT): Likewise.
(TARGET_FP_DP_SQRT): Likewise.
(TARGET_FP_DP_AX): Likewise.
* config/arc/arc.md (ARCV2_ACC): New constant.
(type): New fpu type attribute.
(SDF): Conditional iterator.
(cstore<mode>, cbranch<mode>): Change expand condition.
(addsf3, subsf3, mulsf3, adddf3, subdf3, muldf3): New expands,
handles FPU/FPX cases as well.
* config/arc/arc.opt (mfpu): New option.
* config/arc/fpx.md (addsf3_fpx, subsf3_fpx, mulsf3_fpx):
Renamed.
(adddf3, muldf3, subdf3): Removed.
* config/arc/predicates.md (proper_comparison_operator): Recognize
CC_FPU* modes.
* config/arc/fpu.md: New file.
* doc/invoke.texi (ARC Options): Document mfpu option.
From-SVN: r233451
Diffstat (limited to 'gcc/config/arc/fpu.md')
-rw-r--r-- | gcc/config/arc/fpu.md | 566 |
1 files changed, 566 insertions, 0 deletions
diff --git a/gcc/config/arc/fpu.md b/gcc/config/arc/fpu.md new file mode 100644 index 0000000..9b0a65d --- /dev/null +++ b/gcc/config/arc/fpu.md @@ -0,0 +1,566 @@ +;; :::::::::::::::::::: +;; :: +;; :: 32-bit floating point arithmetic +;; :: +;; :::::::::::::::::::: + +;; Addition +(define_insn "*addsf3_fpu" + [(set (match_operand:SF 0 "register_operand" "=r,r,r,r,r") + (plus:SF (match_operand:SF 1 "nonmemory_operand" "%0,r,0,r,F") + (match_operand:SF 2 "nonmemory_operand" "r,r,F,F,r")))] + "TARGET_FP_SP_BASE + && (register_operand (operands[1], SFmode) + || register_operand (operands[2], SFmode))" + "fsadd%? %0,%1,%2" + [(set_attr "length" "4,4,8,8,8") + (set_attr "iscompact" "false") + (set_attr "type" "fpu") + (set_attr "predicable" "yes,no,yes,no,no") + (set_attr "cond" "canuse,nocond,canuse_limm,nocond,nocond") + ]) + +;; Subtraction +(define_insn "*subsf3_fpu" + [(set (match_operand:SF 0 "register_operand" "=r,r,r,r,r") + (minus:SF (match_operand:SF 1 "nonmemory_operand" "0,r,0,r,F") + (match_operand:SF 2 "nonmemory_operand" "r,r,F,F,r")))] + "TARGET_FP_SP_BASE + && (register_operand (operands[1], SFmode) + || register_operand (operands[2], SFmode))" + "fssub%? %0,%1,%2" + [(set_attr "length" "4,4,8,8,8") + (set_attr "iscompact" "false") + (set_attr "type" "fpu") + (set_attr "predicable" "yes,no,yes,no,no") + (set_attr "cond" "canuse,nocond,canuse_limm,nocond,nocond") + ]) + +;; Multiplication +(define_insn "*mulsf3_fpu" + [(set (match_operand:SF 0 "register_operand" "=r,r,r,r,r") + (mult:SF (match_operand:SF 1 "nonmemory_operand" "%0,r,0,r,F") + (match_operand:SF 2 "nonmemory_operand" "r,r,F,F,r")))] + "TARGET_FP_SP_BASE + && (register_operand (operands[1], SFmode) + || register_operand (operands[2], SFmode))" + "fsmul%? %0,%1,%2" + [(set_attr "length" "4,4,8,8,8") + (set_attr "iscompact" "false") + (set_attr "type" "fpu") + (set_attr "predicable" "yes,no,yes,no,no") + (set_attr "cond" "canuse,nocond,canuse_limm,nocond,nocond") + ]) + +;; Multiplication with addition/subtraction +(define_expand "fmasf4" + [(set (match_operand:SF 0 "register_operand" "") + (fma:SF (match_operand:SF 1 "nonmemory_operand" "") + (match_operand:SF 2 "nonmemory_operand" "") + (match_operand:SF 3 "nonmemory_operand" "")))] + "TARGET_FP_SP_FUSED" + "{ + rtx tmp; + tmp = gen_rtx_REG (SFmode, ACCL_REGNO); + emit_move_insn (tmp, operands[3]); + operands[3] = tmp; + }") + +(define_expand "fnmasf4" + [(set (match_operand:SF 0 "register_operand" "") + (fma:SF (neg:SF (match_operand:SF 1 "nonmemory_operand" "")) + (match_operand:SF 2 "nonmemory_operand" "") + (match_operand:SF 3 "nonmemory_operand" "")))] + "TARGET_FP_SP_FUSED" + "{ + rtx tmp; + tmp = gen_rtx_REG (SFmode, ACCL_REGNO); + emit_move_insn (tmp, operands[3]); + operands[3] = tmp; +}") + +(define_insn "fmasf4_fpu" + [(set (match_operand:SF 0 "register_operand" "=r,r,r,r,r") + (fma:SF (match_operand:SF 1 "nonmemory_operand" "%0,r,0,r,F") + (match_operand:SF 2 "nonmemory_operand" "r,r,F,F,r") + (match_operand:SF 3 "mlo_operand" "")))] + "TARGET_FP_SP_FUSED + && (register_operand (operands[1], SFmode) + || register_operand (operands[2], SFmode))" + "fsmadd%? %0,%1,%2" + [(set_attr "length" "4,4,8,8,8") + (set_attr "predicable" "yes,no,yes,no,no") + (set_attr "cond" "canuse,nocond,canuse_limm,nocond,nocond") + (set_attr "iscompact" "false") + (set_attr "type" "fpu")]) + +(define_insn "fnmasf4_fpu" + [(set (match_operand:SF 0 "register_operand" "=r,r,r,r,r") + (fma:SF (neg:SF (match_operand:SF 1 "nonmemory_operand" "%0,r,0,r,F")) + (match_operand:SF 2 "nonmemory_operand" "r,r,F,F,r") + (match_operand:SF 3 "mlo_operand" "")))] + "TARGET_FP_SP_FUSED + && (register_operand (operands[1], SFmode) + || register_operand (operands[2], SFmode))" + "fsmsub%? %0,%1,%2" + [(set_attr "length" "4,4,8,8,8") + (set_attr "predicable" "yes,no,yes,no,no") + (set_attr "cond" "canuse,nocond,canuse_limm,nocond,nocond") + (set_attr "iscompact" "false") + (set_attr "type" "fpu")]) + +(define_expand "fmadf4" + [(match_operand:DF 0 "even_register_operand" "") + (match_operand:DF 1 "even_register_operand" "") + (match_operand:DF 2 "even_register_operand" "") + (match_operand:DF 3 "even_register_operand" "")] + "TARGET_FP_DP_FUSED" + "{ + emit_insn (gen_fmadf4_split (operands[0], operands[1], operands[2], operands[3])); + DONE; + }") + +(define_insn_and_split "fmadf4_split" + [(set (match_operand:DF 0 "even_register_operand" "") + (fma:DF (match_operand:DF 1 "even_register_operand" "") + (match_operand:DF 2 "even_register_operand" "") + (match_operand:DF 3 "even_register_operand" ""))) + (clobber (reg:DF ARCV2_ACC))] + "TARGET_FP_DP_FUSED" + "#" + "TARGET_FP_DP_FUSED" + [(const_int 0)] + "{ + rtx acc_reg = gen_rtx_REG (DFmode, ACC_REG_FIRST); + emit_move_insn (acc_reg, operands[3]); + emit_insn (gen_fmadf4_fpu (operands[0], operands[1], operands[2])); + DONE; + }" +) + +(define_expand "fnmadf4" + [(match_operand:DF 0 "even_register_operand" "") + (match_operand:DF 1 "even_register_operand" "") + (match_operand:DF 2 "even_register_operand" "") + (match_operand:DF 3 "even_register_operand" "")] + "TARGET_FP_DP_FUSED" + "{ + emit_insn (gen_fnmadf4_split (operands[0], operands[1], operands[2], operands[3])); + DONE; + }") + +(define_insn_and_split "fnmadf4_split" + [(set (match_operand:DF 0 "even_register_operand" "") + (fma:DF (neg:DF (match_operand:DF 1 "even_register_operand" "")) + (match_operand:DF 2 "even_register_operand" "") + (match_operand:DF 3 "even_register_operand" ""))) + (clobber (reg:DF ARCV2_ACC))] + "TARGET_FP_DP_FUSED" + "#" + "TARGET_FP_DP_FUSED" + [(const_int 0)] + "{ + rtx acc_reg = gen_rtx_REG (DFmode, ACC_REG_FIRST); + emit_move_insn (acc_reg, operands[3]); + emit_insn (gen_fnmadf4_fpu (operands[0], operands[1], operands[2])); + DONE; + }") + +(define_insn "fmadf4_fpu" + [(set (match_operand:DF 0 "even_register_operand" "=r,r") + (fma:DF (match_operand:DF 1 "even_register_operand" "%0,r") + (match_operand:DF 2 "even_register_operand" "r,r") + (reg:DF ARCV2_ACC)))] + "TARGET_FP_DP_FUSED" + "fdmadd%? %0,%1,%2" + [(set_attr "length" "4,4") + (set_attr "predicable" "yes,no") + (set_attr "cond" "canuse,nocond") + (set_attr "iscompact" "false") + (set_attr "type" "fpu")]) + +(define_insn "fnmadf4_fpu" + [(set (match_operand:DF 0 "even_register_operand" "=r,r") + (fma:DF (neg:DF (match_operand:DF 1 "even_register_operand" "%0,r")) + (match_operand:DF 2 "even_register_operand" "r,r") + (reg:DF ARCV2_ACC)))] + "TARGET_FP_DP_FUSED" + "fdmsub%? %0,%1,%2" + [(set_attr "length" "4,4") + (set_attr "predicable" "yes,no") + (set_attr "cond" "canuse,nocond") + (set_attr "iscompact" "false") + (set_attr "type" "fpu")]) + +;; Division +(define_insn "divsf3" + [(set (match_operand:SF 0 "register_operand" "=r,r,r,r,r") + (div:SF (match_operand:SF 1 "nonmemory_operand" "0,r,0,r,F") + (match_operand:SF 2 "nonmemory_operand" "r,r,F,F,r")))] + "TARGET_FP_SP_SQRT" + "fsdiv%? %0,%1,%2" + [(set_attr "length" "4,4,8,8,8") + (set_attr "iscompact" "false") + (set_attr "type" "fpu") + (set_attr "predicable" "yes,no,yes,no,no") + (set_attr "cond" "canuse,nocond,canuse_limm,nocond,nocond") + ]) + +;; Negation +;; see pattern in arc.md + +;; Absolute value +;; see pattern in arc.md + +;; Square root +(define_insn "sqrtsf2" + [(set (match_operand:SF 0 "register_operand" "=r,r") + (sqrt:SF (match_operand:SF 1 "nonmemory_operand" "r,F")))] + "TARGET_FP_SP_SQRT" + "fssqrt %0,%1" + [(set_attr "length" "4,8") + (set_attr "type" "fpu")]) + +;; Comparison +(define_insn "*cmpsf_fpu" + [(set (reg:CC_FPU CC_REG) + (compare:CC_FPU (match_operand:SF 0 "register_operand" "r,r") + (match_operand:SF 1 "nonmemory_operand" "r,F")))] + "TARGET_FP_SP_BASE" + "fscmp%? %0, %1" + [(set_attr "length" "4,8") + (set_attr "iscompact" "false") + (set_attr "cond" "set") + (set_attr "type" "fpu") + (set_attr "predicable" "yes,yes")]) + +(define_insn "*cmpsf_fpu_uneq" + [(set (reg:CC_FPU_UNEQ CC_REG) + (compare:CC_FPU_UNEQ + (match_operand:SF 0 "register_operand" "r,r") + (match_operand:SF 1 "nonmemory_operand" "r,F")))] + "TARGET_FP_SP_BASE" + "fscmp %0, %1\\n\\tmov.v.f 0,0\\t;set Z flag" + [(set_attr "length" "8,12") + (set_attr "iscompact" "false") + (set_attr "cond" "set") + (set_attr "type" "fpu")]) + +;; :::::::::::::::::::: +;; :: +;; :: 64-bit floating point arithmetic +;; :: +;; :::::::::::::::::::: + +;; Addition +(define_insn "*adddf3_fpu" + [(set (match_operand:DF 0 "even_register_operand" "=r,r") + (plus:DF (match_operand:DF 1 "even_register_operand" "%0,r") + (match_operand:DF 2 "even_register_operand" "r,r")))] + "TARGET_FP_DP_BASE" + "fdadd%? %0,%1,%2" + [(set_attr "length" "4,4") + (set_attr "iscompact" "false") + (set_attr "type" "fpu") + (set_attr "predicable" "yes,no") + (set_attr "cond" "canuse,nocond") + ]) + + +;; Subtraction +(define_insn "*subdf3_fpu" + [(set (match_operand:DF 0 "even_register_operand" "=r,r") + (minus:DF (match_operand:DF 1 "even_register_operand" "0,r") + (match_operand:DF 2 "even_register_operand" "r,r")))] + "TARGET_FP_DP_BASE" + "fdsub%? %0,%1,%2" + [(set_attr "length" "4,4") + (set_attr "iscompact" "false") + (set_attr "type" "fpu") + (set_attr "predicable" "yes,no") + (set_attr "cond" "canuse,nocond") + ]) + +;; Multiplication +(define_insn "*muldf3_fpu" + [(set (match_operand:DF 0 "even_register_operand" "=r,r") + (mult:DF (match_operand:DF 1 "even_register_operand" "%0,r") + (match_operand:DF 2 "even_register_operand" "r,r")))] + "TARGET_FP_DP_BASE" + "fdmul%? %0,%1,%2" + [(set_attr "length" "4,4") + (set_attr "iscompact" "false") + (set_attr "type" "fpu") + (set_attr "predicable" "yes,no") + (set_attr "cond" "canuse,nocond") + ]) + +;; Division +(define_insn "divdf3" + [(set (match_operand:DF 0 "even_register_operand" "=r,r") + (div:DF (match_operand:DF 1 "even_register_operand" "0,r") + (match_operand:DF 2 "even_register_operand" "r,r")))] + "TARGET_FP_DP_SQRT" + "fddiv%? %0,%1,%2" + [(set_attr "length" "4,4") + (set_attr "iscompact" "false") + (set_attr "type" "fpu") + (set_attr "predicable" "yes,no") + (set_attr "cond" "canuse,nocond") + ]) + +;; Square root +(define_insn "sqrtdf2" + [(set (match_operand:DF 0 "even_register_operand" "=r") + (sqrt:DF (match_operand:DF 1 "even_register_operand" "r")))] + "TARGET_FP_DP_SQRT" + "fdsqrt %0,%1" + [(set_attr "length" "4") + (set_attr "type" "fpu")]) + +;; Comparison +(define_insn "*cmpdf_fpu" + [(set (reg:CC_FPU CC_REG) + (compare:CC_FPU (match_operand:DF 0 "even_register_operand" "r") + (match_operand:DF 1 "even_register_operand" "r")))] + "TARGET_FP_DP_BASE" + "fdcmp%? %0, %1" + [(set_attr "length" "4") + (set_attr "iscompact" "false") + (set_attr "cond" "set") + (set_attr "type" "fpu") + (set_attr "predicable" "yes")]) + +(define_insn "*cmpdf_fpu_uneq" + [(set (reg:CC_FPU_UNEQ CC_REG) + (compare:CC_FPU_UNEQ + (match_operand:DF 0 "even_register_operand" "r") + (match_operand:DF 1 "even_register_operand" "r")))] + "TARGET_FP_DP_BASE" + "fdcmp %0, %1\\n\\tmov.v.f 0,0\\t;set Z flag" + [(set_attr "length" "8") + (set_attr "iscompact" "false") + (set_attr "cond" "set") + (set_attr "type" "fpu")]) + +;; :::::::::::::::::::: +;; :: +;; :: Conversion routines +;; :: +;; :::::::::::::::::::: + +;; SF->DF +(define_insn "extendsfdf2" + [(set (match_operand:DF 0 "even_register_operand" "=r,r") + (float_extend:DF (match_operand:SF 1 "register_operand" "0,r")))] + "TARGET_FP_DP_CONV" + "fcvt32_64%? %0,%1,0x04\\t;fs2d %0,%1" + [(set_attr "length" "4,4") + (set_attr "iscompact" "false") + (set_attr "type" "fpu") + (set_attr "predicable" "yes,no")] +) + +;; SI->DF +(define_insn "floatsidf2" + [(set (match_operand:DF 0 "even_register_operand" "=r,r") + (float:DF (match_operand:SI 1 "register_operand" "0,r")))] + "TARGET_FP_DP_CONV" + "fcvt32_64%? %0,%1,0x02\\t;fint2d %0,%1" + [(set_attr "length" "4,4") + (set_attr "iscompact" "false") + (set_attr "type" "fpu") + (set_attr "predicable" "yes,no")] +) + +;; uSI->DF +(define_insn "floatunssidf2" + [(set (match_operand:DF 0 "even_register_operand" "=r,r") + (unsigned_float:DF (match_operand:SI 1 "register_operand" "0,r")))] + "TARGET_FP_DP_CONV" + "fcvt32_64%? %0,%1,0x00\\t;fuint2d %0,%1" + [(set_attr "length" "4,4") + (set_attr "iscompact" "false") + (set_attr "type" "fpu") + (set_attr "predicable" "yes,no")] +) + +;; SF->uDI (using rounding towards zero) +(define_insn "fixuns_truncsfdi2" + [(set (match_operand:DI 0 "even_register_operand" "=r,r") + (unsigned_fix:DI (fix:SF (match_operand:SF 1 "register_operand" "0,r"))))] + "TARGET_FP_DP_CONV" + "fcvt32_64%? %0,%1,0x09\\t;fs2ul_rz %0,%1" + [(set_attr "length" "4,4") + (set_attr "iscompact" "false") + (set_attr "type" "fpu") + (set_attr "predicable" "yes,no")] +) + +;; SF->DI (using rounding towards zero) +(define_insn "fix_truncsfdi2" + [(set (match_operand:DI 0 "even_register_operand" "=r,r") + (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "0,r"))))] + "TARGET_FP_DP_CONV" + "fcvt32_64%? %0,%1,0x0B\\t;fs2l_rz %0,%1" + [(set_attr "length" "4,4") + (set_attr "iscompact" "false") + (set_attr "type" "fpu") + (set_attr "predicable" "yes,no")] +) + +;; SI->SF +(define_insn "floatsisf2" + [(set (match_operand:SF 0 "register_operand" "=r,r") + (float:SF (match_operand:SI 1 "register_operand" "0,r")))] + "TARGET_FP_SP_CONV" + "fcvt32%? %0,%1,0x02\\t;fint2s %0,%1" + [(set_attr "length" "4,4") + (set_attr "iscompact" "false") + (set_attr "type" "fpu") + (set_attr "predicable" "yes,no")] +) + +;; uSI->SF +(define_insn "floatunssisf2" + [(set (match_operand:SF 0 "register_operand" "=r,r") + (unsigned_float:SF (match_operand:SI 1 "register_operand" "0,r")))] + "TARGET_FP_SP_CONV" + "fcvt32%? %0,%1,0x00\\t;fuint2s %0,%1" + [(set_attr "length" "4,4") + (set_attr "iscompact" "false") + (set_attr "type" "fpu") + (set_attr "predicable" "yes,no")] +) + +;; SF->uSI (using rounding towards zero) +(define_insn "fixuns_truncsfsi2" + [(set (match_operand:SI 0 "register_operand" "=r,r") + (unsigned_fix:SI (fix:SF (match_operand:SF 1 "register_operand" "0,r"))))] + "TARGET_FP_SP_CONV" + "fcvt32%? %0,%1,0x09\\t;fs2uint_rz %0,%1" + [(set_attr "length" "4,4") + (set_attr "iscompact" "false") + (set_attr "type" "fpu") + (set_attr "predicable" "yes,no")] +) + +;; SF->SI (using rounding towards zero) +(define_insn "fix_truncsfsi2" + [(set (match_operand:SI 0 "register_operand" "=r,r") + (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "0,r"))))] + "TARGET_FP_SP_CONV" + "fcvt32%? %0,%1,0x0B\\t;fs2int_rz %0,%1" + [(set_attr "length" "4,4") + (set_attr "iscompact" "false") + (set_attr "type" "fpu") + (set_attr "predicable" "yes,no")] +) + +;; DI->DF +(define_insn "floatdidf2" + [(set (match_operand:DF 0 "even_register_operand" "=r,r") + (float:DF (match_operand:DI 1 "even_register_operand" "0,r")))] + "TARGET_FP_DP_CONV" + "fcvt64%? %0,%1,0x02\\t;fl2d %0,%1" + [(set_attr "length" "4,4") + (set_attr "iscompact" "false") + (set_attr "type" "fpu") + (set_attr "predicable" "yes,no")] +) + +;; uDI->DF +(define_insn "floatunsdidf2" + [(set (match_operand:DF 0 "even_register_operand" "=r,r") + (unsigned_float:DF (match_operand:DI 1 "even_register_operand" "0,r")))] + "TARGET_FP_DP_CONV" + "fcvt64%? %0,%1,0x00\\t;ful2d %0,%1" + [(set_attr "length" "4,4") + (set_attr "iscompact" "false") + (set_attr "type" "fpu") + (set_attr "predicable" "yes,no")] +) + +;; DF->uDI (using rounding towards zero) +(define_insn "fixuns_truncdfdi2" + [(set (match_operand:DI 0 "even_register_operand" "=r,r") + (unsigned_fix:DI (fix:DF (match_operand:DF 1 "even_register_operand" "0,r"))))] + "TARGET_FP_DP_CONV" + "fcvt64%? %0,%1,0x09\\t;fd2ul_rz %0,%1" + [(set_attr "length" "4,4") + (set_attr "iscompact" "false") + (set_attr "type" "fpu") + (set_attr "predicable" "yes,no")] +) + +;; DF->DI (using rounding towards zero) +(define_insn "fix_truncdfdi2" + [(set (match_operand:DI 0 "even_register_operand" "=r,r") + (fix:DI (fix:DF (match_operand:DF 1 "even_register_operand" "0,r"))))] + "TARGET_FP_DP_CONV" + "fcvt64%? %0,%1,0x0B\\t;fd2l_rz %0,%1" + [(set_attr "length" "4,4") + (set_attr "iscompact" "false") + (set_attr "type" "fpu") + (set_attr "predicable" "yes,no")] +) + +;; DF->SF +(define_insn "truncdfsf2" + [(set (match_operand:SF 0 "register_operand" "=r,r") + (float_truncate:SF (match_operand:DF 1 "even_register_operand" "0,r")))] + "TARGET_FP_DP_CONV" + "fcvt64_32%? %0,%1,0x04\\t;fd2s %0,%1" + [(set_attr "length" "4,4") + (set_attr "iscompact" "false") + (set_attr "type" "fpu") + (set_attr "predicable" "yes,no")] +) + +;; DI->SF +(define_insn "floatdisf2" + [(set (match_operand:SF 0 "register_operand" "=r,r") + (float:SF (match_operand:DI 1 "even_register_operand" "0,r")))] + "TARGET_FP_DP_CONV" + "fcvt64_32%? %0,%1,0x02\\t;fl2s %0,%1" + [(set_attr "length" "4,4") + (set_attr "iscompact" "false") + (set_attr "type" "fpu") + (set_attr "predicable" "yes,no")] +) + +;; uDI->SF +(define_insn "floatunsdisf2" + [(set (match_operand:SF 0 "register_operand" "=r,r") + (unsigned_float:SF (match_operand:DI 1 "even_register_operand" "0,r")))] + "TARGET_FP_DP_CONV" + "fcvt64_32%? %0,%1,0x00\\t;ful2s %0,%1" + [(set_attr "length" "4,4") + (set_attr "iscompact" "false") + (set_attr "type" "fpu") + (set_attr "predicable" "yes,no")] +) + +;; DF->uSI (using rounding towards zero) +(define_insn "fixuns_truncdfsi2" + [(set (match_operand:SI 0 "register_operand" "=r,r") + (unsigned_fix:SI (fix:DF (match_operand:DF 1 "even_register_operand" "0,r"))))] + "TARGET_FP_DP_CONV" + "fcvt64_32%? %0,%1,0x09\\t;fd2uint_rz %0,%1" + [(set_attr "length" "4,4") + (set_attr "iscompact" "false") + (set_attr "type" "fpu") + (set_attr "predicable" "yes,no")] +) + +;; DF->SI (using rounding towards zero) +(define_insn "fix_truncdfsi2" + [(set (match_operand:SI 0 "register_operand" "=r,r") + (fix:SI (fix:DF (match_operand:DF 1 "even_register_operand" "0,r"))))] + "TARGET_FP_DP_CONV" + "fcvt64_32%? %0,%1,0x0B\\t;fd2int_rz %0,%1" + [(set_attr "length" "4,4") + (set_attr "iscompact" "false") + (set_attr "type" "fpu") + (set_attr "predicable" "yes,no")] +) |