;;- Machine description for GNU compiler
;;- Motorola 68000 Version
-;; Copyright (C) 1987, 1988 Free Software Foundation, Inc.
+;; Copyright (C) 1987, 1988, 1993 Free Software Foundation, Inc.
;; This file is part of GNU CC.
}
")
+(define_expand "movxf"
+ [(set (match_operand:XF 0 "nonimmediate_operand" "")
+ (match_operand:XF 1 "general_operand" ""))]
+ "TARGET_68881"
+ "
+{
+ if (CONSTANT_P (operands[1]))
+ {
+ operands[1] = force_const_mem (XFmode, operands[1]);
+ if (! memory_address_p (XFmode, XEXP (operands[1], 0))
+ && ! reload_in_progress)
+ operands[1] = change_address (operands[1], XFmode,
+ XEXP (operands[1], 0));
+ }
+}")
+
+(define_insn ""
+ [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,!r,!f")
+ (match_operand:XF 1 "nonimmediate_operand" "m,f,f,f,r"))]
+ "TARGET_68881"
+ "*
+{
+ if (FP_REG_P (operands[0]))
+ {
+ if (FP_REG_P (operands[1]))
+ return \"fmove%.x %1,%0\";
+ if (REG_P (operands[1]))
+ {
+ rtx xoperands[2];
+ xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 2);
+ output_asm_insn (\"move%.l %1,%-\", xoperands);
+ xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
+ output_asm_insn (\"move%.l %1,%-\", xoperands);
+ output_asm_insn (\"move%.l %1,%-\", operands);
+ return \"fmove%.x %+,%0\";
+ }
+ if (GET_CODE (operands[1]) == CONST_DOUBLE)
+ return \"fmove%.x %1,%0\";
+ return \"fmove%.x %f1,%0\";
+ }
+ if (REG_P (operands[0]))
+ {
+ output_asm_insn (\"fmove%.x %f1,%-\;move%.l %+,%0\", operands);
+ operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
+ output_asm_insn (\"move%.l %+,%0\", operands);
+ operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
+ return \"move%.l %+,%0\";
+ }
+ return \"fmove%.x %f1,%0\";
+}
+")
+
;; movdi can apply to fp regs in some cases
(define_insn "movdi"
;; Let's see if it really still needs to handle fp regs, and, if so, why.
;; New routines to convert floating-point values to integers
;; to be used on the '040. These should be faster than trapping
;; into the kernel to emulate fintrz. They should also be faster
-;; than calling the subroutines fixsfsi() or fixdfsi().
+;; than calling the subroutines fixsfsi or fixdfsi.
(define_insn "fix_truncdfsi2"
[(set (match_operand:SI 0 "general_operand" "=dm")
fpsm%.s %3,%w2,%w1,%0
fpsm%.s %x3,%2,%x1,%0
fpsm%.s %x3,%2,%x1,%0")
+
+(define_insn "tstxf"
+ [(set (cc0)
+ (match_operand:XF 0 "nonimmediate_operand" "fm"))]
+ "TARGET_68881"
+ "*
+{
+ cc_status.flags = CC_IN_68881;
+ return \"ftst%.x %0\";
+}")
+
+
+(define_expand "cmpxf"
+ [(set (cc0)
+ (compare (match_operand:XF 0 "general_operand" "f,mG")
+ (match_operand:XF 1 "general_operand" "fmG,f")))]
+ "TARGET_68881"
+ "
+{
+ if (CONSTANT_P (operands[0]))
+ operands[0] = force_const_mem (XFmode, operands[0]);
+ if (CONSTANT_P (operands[1]))
+ operands[1] = force_const_mem (XFmode, operands[1]);
+}")
+
+(define_insn ""
+ [(set (cc0)
+ (compare (match_operand:XF 0 "nonimmediate_operand" "f,mG")
+ (match_operand:XF 1 "nonimmediate_operand" "fmG,f")))]
+ "TARGET_68881"
+ "*
+{
+ cc_status.flags = CC_IN_68881;
+#ifdef HPUX_ASM
+ if (REG_P (operands[0]))
+ {
+ if (REG_P (operands[1]))
+ return \"fcmp%.x %0,%1\";
+ else
+ return \"fcmp%.x %0,%f1\";
+ }
+ cc_status.flags |= CC_REVERSED;
+ return \"fcmp%.x %1,%f0\";
+#else
+ if (REG_P (operands[0]))
+ {
+ if (REG_P (operands[1]))
+ return \"fcmp%.x %1,%0\";
+ else
+ return \"fcmp%.x %f1,%0\";
+ }
+ cc_status.flags |= CC_REVERSED;
+ return \"fcmp%.x %f0,%1\";
+#endif
+}")
+
+(define_insn "extendsfxf2"
+ [(set (match_operand:XF 0 "general_operand" "=fm,f")
+ (float_extend:XF (match_operand:SF 1 "general_operand" "f,m")))]
+ "TARGET_68881"
+ "*
+{
+ if (FP_REG_P (operands[0]) && FP_REG_P (operands[1]))
+ {
+ if (REGNO (operands[0]) == REGNO (operands[1]))
+ {
+ /* Extending float to double in an fp-reg is a no-op.
+ NOTICE_UPDATE_CC has already assumed that the
+ cc will be set. So cancel what it did. */
+ cc_status = cc_prev_status;
+ return \"\";
+ }
+ return \"f%$move%.x %1,%0\";
+ }
+ if (FP_REG_P (operands[0]))
+ return \"f%$move%.s %f1,%0\";
+ return \"fmove%.x %f1,%0\";
+}")
+
+
+(define_insn "extenddfxf2"
+ [(set (match_operand:XF 0 "general_operand" "=fm,f")
+ (float_extend:XF
+ (match_operand:DF 1 "general_operand" "f,m")))]
+ "TARGET_68881"
+ "*
+{
+ if (FP_REG_P (operands[0]) && FP_REG_P (operands[1]))
+ {
+ if (REGNO (operands[0]) == REGNO (operands[1]))
+ {
+ /* Extending float to double in an fp-reg is a no-op.
+ NOTICE_UPDATE_CC has already assumed that the
+ cc will be set. So cancel what it did. */
+ cc_status = cc_prev_status;
+ return \"\";
+ }
+ return \"fmove%.x %1,%0\";
+ }
+ if (FP_REG_P (operands[0]))
+ return \"f%&move%.d %f1,%0\";
+ return \"fmove%.x %f1,%0\";
+}")
+
+(define_insn "truncxfdf2"
+ [(set (match_operand:DF 0 "general_operand" "=m,!r")
+ (float_truncate:DF
+ (match_operand:XF 1 "general_operand" "f,f")))]
+ "TARGET_68881"
+ "*
+{
+ if (REG_P (operands[0]))
+ {
+ output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands);
+ operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
+ return \"move%.l %+,%0\";
+ }
+ return \"fmove%.d %f1,%0\";
+}")
+
+(define_insn "truncxfsf2"
+ [(set (match_operand:SF 0 "general_operand" "=dm")
+ (float_truncate:SF
+ (match_operand:XF 1 "general_operand" "f")))]
+ "TARGET_68881"
+ "fmove%.s %f1,%0")
+
+(define_insn "floatsixf2"
+ [(set (match_operand:XF 0 "general_operand" "=f")
+ (float:XF (match_operand:SI 1 "general_operand" "dmi")))]
+ "TARGET_68881"
+ "fmove%.l %1,%0")
+
+(define_insn "floathixf2"
+ [(set (match_operand:XF 0 "general_operand" "=f")
+ (float:XF (match_operand:HI 1 "general_operand" "dmn")))]
+ "TARGET_68881"
+ "fmove%.w %1,%0")
+
+(define_insn "floatqixf2"
+ [(set (match_operand:XF 0 "general_operand" "=f")
+ (float:XF (match_operand:QI 1 "general_operand" "dmn")))]
+ "TARGET_68881"
+ "fmove%.b %1,%0")
+
+(define_insn "ftruncxf2"
+ [(set (match_operand:XF 0 "general_operand" "=f")
+ (fix:XF (match_operand:XF 1 "general_operand" "fFm")))]
+ "TARGET_68881"
+ "*
+{
+ if (FP_REG_P (operands[1]))
+ return \"fintrz%.x %f1,%0\";
+ return \"fintrz%.x %f1,%0\";
+}")
+
+(define_insn "fixxfqi2"
+ [(set (match_operand:QI 0 "general_operand" "=dm")
+ (fix:QI (match_operand:XF 1 "general_operand" "f")))]
+ "TARGET_68881"
+ "fmove%.b %1,%0")
+
+(define_insn "fixxfhi2"
+ [(set (match_operand:HI 0 "general_operand" "=dm")
+ (fix:HI (match_operand:XF 1 "general_operand" "f")))]
+ "TARGET_68881"
+ "fmove%.w %1,%0")
+
+(define_insn "fixxfsi2"
+ [(set (match_operand:SI 0 "general_operand" "=dm")
+ (fix:SI (match_operand:XF 1 "general_operand" "f")))]
+ "TARGET_68881"
+ "fmove%.l %1,%0")
+
+(define_expand "addxf3"
+ [(set (match_operand:XF 0 "general_operand" "")
+ (plus:XF (match_operand:XF 1 "general_operand" "")
+ (match_operand:XF 2 "general_operand" "")))]
+ "TARGET_68881"
+ "
+{
+ if (CONSTANT_P (operands[1]))
+ operands[1] = force_const_mem (XFmode, operands[1]);
+ if (CONSTANT_P (operands[2]))
+ operands[2] = force_const_mem (XFmode, operands[2]);
+}")
+
+(define_insn ""
+ [(set (match_operand:XF 0 "general_operand" "=f")
+ (plus:XF (match_operand:XF 1 "nonimmediate_operand" "%0")
+ (match_operand:XF 2 "nonimmediate_operand" "fmG")))]
+ "TARGET_68881"
+ "*
+{
+ if (REG_P (operands[2]))
+ return \"fadd%.x %2,%0\";
+ return \"fadd%.x %f2,%0\";
+}")
+
+(define_expand "subxf3"
+ [(set (match_operand:XF 0 "general_operand" "")
+ (minus:XF (match_operand:XF 1 "general_operand" "")
+ (match_operand:XF 2 "general_operand" "")))]
+ "TARGET_68881"
+ "
+{
+ if (CONSTANT_P (operands[1]))
+ operands[1] = force_const_mem (XFmode, operands[1]);
+ if (CONSTANT_P (operands[2]))
+ operands[2] = force_const_mem (XFmode, operands[2]);
+}")
+
+(define_insn ""
+ [(set (match_operand:XF 0 "general_operand" "=f")
+ (minus:XF (match_operand:XF 1 "nonimmediate_operand" "0")
+ (match_operand:XF 2 "nonimmediate_operand" "fmG")))]
+ "TARGET_68881"
+ "*
+{
+ if (REG_P (operands[2]))
+ return \"fsub%.x %2,%0\";
+ return \"fsub%.x %f2,%0\";
+}")
+
+(define_expand "mulxf3"
+ [(set (match_operand:XF 0 "general_operand" "")
+ (mult:XF (match_operand:XF 1 "general_operand" "")
+ (match_operand:XF 2 "general_operand" "")))]
+ "TARGET_68881"
+ "
+{
+ if (CONSTANT_P (operands[1]))
+ operands[1] = force_const_mem (XFmode, operands[1]);
+ if (CONSTANT_P (operands[2]))
+ operands[2] = force_const_mem (XFmode, operands[2]);
+}")
+
+(define_insn ""
+ [(set (match_operand:XF 0 "general_operand" "=f")
+ (mult:XF (match_operand:XF 1 "nonimmediate_operand" "%0")
+ (match_operand:XF 2 "nonimmediate_operand" "fmG")))]
+ "TARGET_68881"
+ "*
+{
+ if (REG_P (operands[2]))
+ return \"fmul%.x %2,%0\";
+ return \"fmul%.x %f2,%0\";
+}")
+
+(define_expand "divxf3"
+ [(set (match_operand:XF 0 "general_operand" "")
+ (div:XF (match_operand:XF 1 "general_operand" "")
+ (match_operand:XF 2 "general_operand" "")))]
+ "TARGET_68881"
+ "
+{
+ if (CONSTANT_P (operands[1]))
+ operands[1] = force_const_mem (XFmode, operands[1]);
+ if (CONSTANT_P (operands[2]))
+ operands[2] = force_const_mem (XFmode, operands[2]);
+}")
+
+(define_insn ""
+ [(set (match_operand:XF 0 "general_operand" "=f")
+ (div:XF (match_operand:XF 1 "nonimmediate_operand" "0")
+ (match_operand:XF 2 "nonimmediate_operand" "fmG")))]
+ "TARGET_68881"
+ "*
+{
+ if (REG_P (operands[2]))
+ return \"fdiv%.x %2,%0\";
+ return \"fdiv%.x %f2,%0\";
+}")
+
+(define_insn "negxf2"
+ [(set (match_operand:XF 0 "general_operand" "=f")
+ (neg:XF (match_operand:XF 1 "nonimmediate_operand" "fmF")))]
+ "TARGET_68881"
+ "*
+{
+ if (REG_P (operands[1]) && ! DATA_REG_P (operands[1]))
+ return \"fneg%.x %1,%0\";
+ return \"fneg%.x %f1,%0\";
+}")
+
+(define_insn "absxf2"
+ [(set (match_operand:XF 0 "general_operand" "=f")
+ (abs:XF (match_operand:XF 1 "nonimmediate_operand" "fmF")))]
+ "TARGET_68881"
+ "*
+{
+ if (REG_P (operands[1]) && ! DATA_REG_P (operands[1]))
+ return \"fabs%.x %1,%0\";
+ return \"fabs%.x %f1,%0\";
+}")
+
+(define_insn "sqrtxf2"
+ [(set (match_operand:XF 0 "general_operand" "=f")
+ (sqrt:XF (match_operand:DF 1 "nonimmediate_operand" "fm")))]
+ "TARGET_68881"
+ "*
+{
+ return \"fsqrt%.x %1,%0\";
+}")