;; C-SKY FPUV3 instruction descriptions.
;; Copyright (C) 2018-2022 Free Software Foundation, Inc.
;; Contributed by C-SKY Microsystems and Mentor Graphics.
;;
;; This file is part of GCC.
;;
;; GCC is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;;
;; GCC is distributed in the hope that it will be useful, but
;; WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GCC; see the file COPYING3. If not see
;; . */
(define_c_enum "unspec" [
UNSPEC_MAXNM_F3
UNSPEC_MINNM_F3
])
;; -------------------------------------------------------------------------
;; Float mov instructions
;; -------------------------------------------------------------------------
(define_insn "*fpv3_movhf"
[(set (match_operand:HF 0 "nonimmediate_operand" "=r,r,v,r,m,r,Q,v,v,v, v")
(match_operand:HF 1 "general_operand" " r,F,r,v,r,m,v,Q,v,W,Dv"))]
"CSKY_ISA_FEATURE(fpv3_hf)"
"*
switch (which_alternative)
{
case 2:
return \"fmtvr.16\\t%0, %1\";
case 3:
return \"fmfvr.16\\t%0, %1\";
case 6:
case 7:
case 9:
return fpuv3_output_move(operands);
case 8:
return \"fmov.16\\t%0, %1\";
case 10:
return \"fmovi.16\\t%0, %1\";
case 1:
{
long bits;
rtx ops[4];
bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]), HFmode);
ops[0] = operands[0];
ops[1] = GEN_INT (bits);
output_asm_insn (\"lrw\\t%0, %1\", ops);
return \"\";
}
default:
return csky_output_move(insn, operands, HFmode);
}
"
)
(define_insn "*fpv3_movsf"
[(set (match_operand:SF 0 "nonimmediate_operand" "=r,r, r,m,v,r,Q,v,v,v, v")
(match_operand:SF 1 "general_operand" " r,m,mF,r,r,v,v,Q,v,W,Dv"))]
"CSKY_ISA_FEATURE(fpv3_sf)"
"*
switch (which_alternative)
{
case 4:
return \"fmtvr.32.1\\t%0, %1\";
case 5:
return \"fmfvr.32.1\\t%0, %1\";
case 6:
case 7:
case 9:
return fpuv3_output_move(operands);
case 8:
return \"fmov.32\\t%0, %1\";
case 10:
return \"fmovi.32\\t%0, %1\";
default:
return csky_output_move(insn, operands, SFmode);
}
"
)
(define_insn "*fpv3_movdf"
[(set (match_operand:DF 0 "nonimmediate_operand" "=r, v,?r,Q,v,v,v, v,r, r,Y")
(match_operand:DF 1 "general_operand" " r,?r, v,v,Q,v,m,Dv,Y,YF,r"))]
"CSKY_ISA_FEATURE(fpv3_df)"
"*
switch (which_alternative)
{
case 1:
if (TARGET_BIG_ENDIAN)
return \"fmtvr.64\\t%0, %R1, %1\";
return \"fmtvr.64\\t%0, %1, %R1\";
case 2:
if (TARGET_BIG_ENDIAN)
return \"fmfvr.64\\t%R0, %0, %1\";
return \"fmfvr.64\\t%0, %R0, %1\";
case 3:
case 4:
case 6:
return fpuv3_output_move(operands);
case 5:
return \"fmov.64\\t%0, %1\";
case 7:
return \"fmovi.64\\t%0, %1\";
default:
return csky_output_movedouble(operands, DFmode);
}
"
)
;; -------------------------------------------------------------------------
;; Float Mul instructions
;; -------------------------------------------------------------------------
(define_insn "*fpv3_mul3"
[(set (match_operand:F3ANY 0 "register_operand" "=v")
(mult:F3ANY (match_operand:F3ANY 1 "register_operand" " v")
(match_operand:F3ANY 2 "register_operand" " v")))]
"CSKY_ISA_FEATURE(fpv3_)"
"fmul.\t%0, %1, %2"
)
;; -------------------------------------------------------------------------
;; Float Muladd and mulsub instructions
;; -------------------------------------------------------------------------
(define_insn "*fpv3_mula3"
[(set (match_operand:F3ANY 0 "register_operand" "+v")
(plus:F3ANY (mult:F3ANY (match_operand:F3ANY 1 "register_operand" " v")
(match_operand:F3ANY 2 "register_operand" " v"))
(match_dup 0)))]
"CSKY_ISA_FEATURE(fpv3_)"
"fmula.\t%0, %1, %2"
)
(define_insn "*fpv3_muls3"
[(set (match_operand:F3ANY 0 "register_operand" "+v")
(minus:F3ANY (match_dup 0)
(mult:F3ANY (match_operand:F3ANY 1 "register_operand" " v")
(match_operand:F3ANY 2 "register_operand" " v"))))]
"CSKY_ISA_FEATURE(fpv3_)"
"fmuls.\t%0, %1, %2"
)
;; -------------------------------------------------------------------------
;; Float fmula/fmuls/fnmula/fnmuls instructions
;; -------------------------------------------------------------------------
(define_insn "*fpv3_fmuls_4"
[(set (match_operand:F3ANY 0 "register_operand" "=v")
(fma:F3ANY (neg:F3ANY (match_operand:F3ANY 1 "register_operand" "v"))
(match_operand:F3ANY 2 "register_operand" "v")
(match_operand:F3ANY 3 "register_operand" "0")))]
"CSKY_ISA_FEATURE(fpv3_)"
"ffmuls.\t%0, %1, %2"
)
(define_insn "*fpv3_fmula_4"
[(set (match_operand:F3ANY 0 "register_operand" "=v")
(fma:F3ANY (match_operand:F3ANY 1 "register_operand" " v")
(match_operand:F3ANY 2 "register_operand" " v")
(match_operand:F3ANY 3 "register_operand" "0")))]
"CSKY_ISA_FEATURE(fpv3_)"
"ffmula.\t%0, %1, %2"
)
(define_insn "*fpv3_fnmula_4"
[(set (match_operand:F3ANY 0 "register_operand" "=v")
(neg: F3ANY (fma:F3ANY (match_operand:F3ANY 1 "register_operand" " v")
(match_operand:F3ANY 2 "register_operand" " v")
(match_operand:F3ANY 3 "register_operand" "0"))))]
"CSKY_ISA_FEATURE(fpv3_)"
"ffnmula.\t%0, %1, %2"
)
(define_insn "*fpv3_fnmuls_4"
[(set (match_operand:F3ANY 0 "register_operand" "=v")
(fma:F3ANY (match_operand:F3ANY 1 "register_operand" " v")
(match_operand:F3ANY 2 "register_operand" " v")
(neg:F3ANY (match_operand:F3ANY 3 "register_operand" "0"))))]
"CSKY_ISA_FEATURE(fpv3_sf)"
"ffnmuls.\t%0, %1, %2"
)
;; -------------------------------------------------------------------------
;; Float div/recipe/sqrt instructions
;; -------------------------------------------------------------------------
(define_insn "*fpv3_div3"
[(set (match_operand:F3ANY 0 "register_operand" "=v")
(div:F3ANY (match_operand:F3ANY 1 "register_operand" " v")
(match_operand:F3ANY 2 "register_operand" " v")))]
"CSKY_ISA_FEATURE(fpv3_)"
"fdiv.\t%0, %1, %2"
)
(define_insn "*fpv3_recip3"
[(set (match_operand:F3ANY 0 "register_operand" "=v")
(div:F3ANY (match_operand:F3ANY 1 "csky_const_float1_operand" " i")
(match_operand:F3ANY 2 "register_operand" " v")))]
"CSKY_ISA_FEATURE(fpv3_)"
"frecip.\t%0, %2"
)
(define_insn "*fpv3_sqrt2"
[(set (match_operand:F3ANY 0 "register_operand" "=v")
(sqrt:F3ANY (match_operand:F3ANY 1 "register_operand" " v")))]
"CSKY_ISA_FEATURE(fpv3_)"
"fsqrt.\t%0, %1"
)
;; -------------------------------------------------------------------------
;; Float fmax/fmin instructions
;; -------------------------------------------------------------------------
(define_insn "fmax3"
[(set (match_operand:F3ANY 0 "register_operand" "=v")
(unspec:F3ANY [(match_operand:F3ANY 1 "register_operand" " v")
(match_operand:F3ANY 2 "register_operand" " v")]
UNSPEC_MAXNM_F3))]
"CSKY_ISA_FEATURE(fpv3_)"
"fmaxnm.\t%0, %1, %2"
)
(define_insn "fmin3"
[(set (match_operand:F3ANY 0 "register_operand" "=v")
(unspec:F3ANY [(match_operand:F3ANY 1 "register_operand" " v")
(match_operand:F3ANY 2 "register_operand" " v")]
UNSPEC_MINNM_F3))]
"CSKY_ISA_FEATURE(fpv3_)"
"fminnm.\t%0, %1, %2"
)
;; -------------------------------------------------------------------------
;; Float compare instructions
;; -------------------------------------------------------------------------
(define_insn "*fpv3__3"
[(set (reg:CC CSKY_CC_REGNUM)
(FCMPZ:CC (match_operand:F3ANY 0 "register_operand" "v")
(match_operand:F3ANY 1 "csky_const_float0_operand" "i")))]
"CSKY_ISA_FEATURE(fpv3_)"
"fcmp.\t%0"
)
(define_insn "*fpv3__3"
[(set (reg:CC CSKY_CC_REGNUM)
(FCMP:CC (match_operand:F3ANY 0 "register_operand" "v")
(match_operand:F3ANY 1 "register_operand" "v")))]
"CSKY_ISA_FEATURE(fpv3_)"
"fcmp.\t%0, %1"
)
(define_insn "*fpv3_gt3"
[(set (reg:CC CSKY_CC_REGNUM)
(gt:CC (match_operand:F3ANY 0 "register_operand" "v")
(match_operand:F3ANY 1 "register_operand" "v")))]
"CSKY_ISA_FEATURE(fpv3_)"
"fcmplt.\t%1, %0"
)
(define_insn "*fpv3_le3"
[(set (reg:CC CSKY_CC_REGNUM)
(le:CC (match_operand:F3ANY 0 "register_operand" "v")
(match_operand:F3ANY 1 "register_operand" "v")))]
"CSKY_ISA_FEATURE(fpv3_)"
"fcmphs.\t%1, %0"
)
(define_insn "*fpv3_unordered"
[(set (reg:CC CSKY_CC_REGNUM)
(unordered:CC (match_operand:F3ANY 0 "register_operand" "v")
(match_operand:F3ANY 1 "register_operand" "v")))]
"CSKY_ISA_FEATURE(fpv3_)"
"fcmpuo.\t%0, %1")
(define_insn "*fpv3_unordered_zero"
[(set (reg:CC CSKY_CC_REGNUM)
(unordered:CC (match_operand:F3ANY 0 "register_operand" "v")
(match_operand:F3ANY 1 "csky_const_float0_operand" "i")))]
"CSKY_ISA_FEATURE(fpv3_)"
"fcmpuoz.\t%0")
;; -------------------------------------------------------------------------
;; Float ADD instructions
;; -------------------------------------------------------------------------
(define_insn "*fpv3_add3"
[(set (match_operand:F3ANY 0 "register_operand" "=v")
(plus:F3ANY (match_operand:F3ANY 1 "register_operand" " v")
(match_operand:F3ANY 2 "register_operand" " v")))]
"CSKY_ISA_FEATURE(fpv3_)"
"fadd.\t%0, %1, %2"
)
;; -------------------------------------------------------------------------
;; Float SUB instructions
;; -------------------------------------------------------------------------
(define_insn "*fpv3_sub3"
[(set (match_operand:F3ANY 0 "register_operand" "=v")
(minus:F3ANY (match_operand:F3ANY 1 "register_operand" " v")
(match_operand:F3ANY 2 "register_operand" " v")))]
"CSKY_ISA_FEATURE(fpv3_)"
"fsub.\t%0, %1, %2"
)
;; -------------------------------------------------------------------------
;; Float NEG instructions
;; -------------------------------------------------------------------------
(define_insn "*fpv3_neg2"
[(set (match_operand:F3ANY 0 "register_operand" "=v")
(neg:F3ANY (match_operand:F3ANY 1 "register_operand" " v")))]
"CSKY_ISA_FEATURE(fpv3_)"
"fneg.\t%0, %1"
)
;; -------------------------------------------------------------------------
;; Float ABS instructions
;; -------------------------------------------------------------------------
(define_insn "*fpv3_abs2"
[(set (match_operand:F3ANY 0 "register_operand" "=v")
(abs:F3ANY (match_operand:F3ANY 1 "register_operand" " v")))]
"CSKY_ISA_FEATURE(fpv3_)"
"fabs.\t%0, %1"
)
;; -------------------------------------------------------------------------
;; Float common convert instructions
;; -------------------------------------------------------------------------
;; SF <- HF
(define_insn "*fpv3_extendhfsf2"
[(set (match_operand:SF 0 "register_operand" "=v")
(float_extend:SF (match_operand:HF 1 "register_operand" "v")))]
"CSKY_ISA_FEATURE(fpv3_hf)"
"fhtos\t%0, %1")
;; HF <- SF
(define_insn "*fpv3_truncsfhf2"
[(set (match_operand:HF 0 "register_operand" "=v")
(float_truncate:HF (match_operand:SF 1 "register_operand" "v")))]
"CSKY_ISA_FEATURE(fpv3_hf)"
"fstoh\t%0, %1")
;; DF <- SF
(define_insn "*fpv3_extendsfdf2"
[(set (match_operand:DF 0 "register_operand" "=v")
(float_extend:DF (match_operand:SF 1 "register_operand" "v")))]
"CSKY_ISA_FEATURE(fpv3_df)"
"fstod\t%0, %1")
;; SF <- DF
(define_insn "*fpv3_truncdfsf2"
[(set (match_operand:SF 0 "register_operand" "=v")
(float_truncate:SF (match_operand:DF 1 "register_operand" "v")))]
"CSKY_ISA_FEATURE(fpv3_df)"
"fdtos\t%0, %1")
;; DF,SF,HF <- unsigned SI,SI
(define_insn "*fpv3_floatsi2"
[(set (match_operand:F3ANY 0 "register_operand" "=v")
(FLOAT_SU:F3ANY (match_operand:SI 1 "register_operand" "v")))]
"CSKY_ISA_FEATURE(fpv3_)"
"fitof.32.f\t%0, %1")
;; HF <- unsigned HI,HI
(define_insn "*fpv3_floathihf2"
[(set (match_operand:HF 0 "register_operand" "=v")
(FLOAT_SU:HF (match_operand:HI 1 "register_operand" "v")))]
"CSKY_ISA_FEATURE(fpv3_hi) && CSKY_ISA_FEATURE(fpv3_hf)"
"fitof.16.f16\t%0, %1")
;; unsigned SI,SI <- DF,SF,HF
(define_insn "*fpv3_fix_truncsi2"
[(set (match_operand:SI 0 "register_operand" "=v")
(FIX_SU:SI (fix:F3ANY (match_operand:F3ANY 1 "register_operand" "v"))))]
"CSKY_ISA_FEATURE(fpv3_)"
"fftoi.f.32.rz\t%0, %1")
;; -------------------------------------------------------------------------
;; Float complex convert instructions
;; -------------------------------------------------------------------------
;; Fixed point to floating point conversions.
;(define_insn "*combine_fcvt_fixed16_"
; [(set (match_operand:F3ANY 0 "register_operand" "=v")
; (mult:F3ANY (float:F3ANY (match_operand:HI 1 "register_operand" "0"))
; (match_operand 2
; "const_double_fcvt_power_of_two_reciprocal_hq" "Dt")))]
; "CSKY_ISA_FEATURE(fpv3_) && !flag_rounding_math
; && CSKY_ISA_FEATURE(fpv3_hi)"
; "fxtof.s16.f\t%0, %1, %v2")
;
;(define_insn "*combine_fcvt_fixed32_"
; [(set (match_operand:F3ANY 0 "register_operand" "=v")
; (mult:F3ANY (float:F3ANY (match_operand:SI 1 "register_operand" "0"))
; (match_operand 2
; "const_double_fcvt_power_of_two_reciprocal_sq" "Dt")))]
; "CSKY_ISA_FEATURE(fpv3_) && !flag_rounding_math"
; "fxtof.s32.f\t%0, %1, %v2")
;
;(define_insn "*combine_fcvt_unfixed16_"
; [(set (match_operand:F3ANY 0 "register_operand" "=v")
; (mult:F3ANY (unsigned_float:F3ANY (match_operand:HI 1 "register_operand" "0"))
; (match_operand 2
; "const_double_fcvt_power_of_two_reciprocal_hq" "Dt")))]
; "CSKY_ISA_FEATURE(fpv3_) && !flag_rounding_math
; && CSKY_ISA_FEATURE(fpv3_hi)"
; "fxtof.u16.f\t%0, %1, %v2")
;
;(define_insn "*combine_fcvt_unfixed32_"
; [(set (match_operand:F3ANY 0 "register_operand" "=v")
; (mult:F3ANY (unsigned_float:F3ANY (match_operand:SI 1 "register_operand" "0"))
; (match_operand 2
; "const_double_fcvt_power_of_two_reciprocal_sq" "Dt")))]
; "CSKY_ISA_FEATURE(fpv3_) && !flag_rounding_math"
; "fxtof.u32.f\t%0, %1, %v2")
;; Floating point to fixed point conversions.
;(define_insn "*combine_fcvt_fixed16"
; [(set (match_operand:HI 0 "register_operand" "=v")
; (fix:HI (fix:F3ANY (mult:F3ANY (match_operand:F3ANY 1 "register_operand" "0")
; (match_operand 2
; "const_double_fcvt_power_of_two_hq" "Du")))))]
; "CSKY_ISA_FEATURE(fpv3_) && !flag_rounding_math
; && CSKY_ISA_FEATURE(fpv3_hi)"
; "fftox.f.s16\t%0, %1, %v2"
; )
;
;(define_insn "*combine_fcvt_fixed32"
; [(set (match_operand:SI 0 "register_operand" "=v")
; (fix:SI (fix:F3ANY (mult:F3ANY (match_operand:F3ANY 1 "register_operand" "0")
; (match_operand 2
; "const_double_fcvt_power_of_two_sq" "Du")))))]
; "CSKY_ISA_FEATURE(fpv3_) && !flag_rounding_math"
; "fftox.f.s32\t%0, %1, %v2"
; )
;
;(define_insn "*combine_fcvt_unfixed16"
; [(set (match_operand:HI 0 "register_operand" "=v")
; (unsigned_fix:HI (fix:F3ANY (mult:F3ANY (match_operand:F3ANY 1 "register_operand" "0")
; (match_operand 2
; "const_double_fcvt_power_of_two_hq" "Du")))))]
; "CSKY_ISA_FEATURE(fpv3_) && !flag_rounding_math
; && CSKY_ISA_FEATURE(fpv3_hi)"
; "fftox.f.u16\t%0, %1, %v2"
; )
;
;(define_insn "*combine_fcvt_unfixed32"
; [(set (match_operand:SI 0 "register_operand" "=v")
; (unsigned_fix:SI (fix:F3ANY (mult:F3ANY (match_operand:F3ANY 1 "register_operand" "0")
; (match_operand 2
; "const_double_fcvt_power_of_two_sq" "Du")))))]
; "CSKY_ISA_FEATURE(fpv3_) && !flag_rounding_math"
; "fftox.f.u32\t%0, %1, %v2"
; )
;; conversions need to be rounding to nearest.
(define_insn "lsi2"
[(set (match_operand:SI 0 "register_operand" "=v")
(FIX_SU:SI (unspec:F3ANY [(match_operand:F3ANY 1 "register_operand" "0")]
FRM)))]
"CSKY_ISA_FEATURE(fpv3_)"
"fftoi.f.32\t%0, %1"
)
(define_insn "2"
[(set (match_operand:F3ANY 0 "register_operand" "=v")
(unspec:F3ANY [(match_operand:F3ANY 1 "register_operand" "0")] FRMF))]
"CSKY_ISA_FEATURE(fpv3_)"
"fftofi.f\t%0, %1"
)
;; Write Floating-point Control Register.
(define_insn "csky_setfcrsi"
[(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] VUNSPEC_SET_FCR)]
"CSKY_ISA_FEATURE(fcr)"
"mtcr\t%0, fcr"
)
;; Read Floating-point Control Register.
(define_insn "csky_getfcrsi"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec_volatile:SI [(const_int 0)] VUNSPEC_GET_FCR))]
"CSKY_ISA_FEATURE(fcr)"
"mfcr\t%0, fcr"
)
;; Insert Floating-point Control Register.
(define_insn "csky_insfcrsi"
[(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
(match_operand:SI 1 "const_int_operand" "i")
(match_operand:SI 2 "const_int_operand" "i")]VUNSPEC_INS_FCR)
(clobber (reg: SI 13))]
"CSKY_ISA_FEATURE(fcr)"
{
operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]) - 1);
return "mfcr\tt1, fcr\n\tins\tt1, %0, %1, %2\n\tmtcr\tt1, fcr";
}
)