This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
improving fneg & fabs
- To: egcs-patches at cygnus dot com
- Subject: improving fneg & fabs
- From: Jeffrey A Law <law at cygnus dot com>
- Date: Tue, 15 Dec 1998 13:51:23 -0700
- Reply-To: law at cygnus dot com
This patch improves the generated code for fabs and fneg operations on the
mn10200 and mn10300 chips.
* mn10200.md (abssf2, negsf2): New expanders.
* mn10300.md (absdf2, abssf2, negdf2, negsf2): New expanders.
Index: mn10200/mn10200.md
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/config/mn10200/mn10200.md,v
retrieving revision 1.50
diff -c -3 -p -r1.50 mn10200.md
*** mn10200.md 1998/07/07 21:37:31 1.50
--- mn10200.md 1998/12/15 20:48:52
***************
*** 1639,1644 ****
--- 1639,1715 ----
[(set_attr "cc" "clobber")])
;; ----------------------------------------------------------------------
+ ;; FP INSTRUCTIONS
+ ;; ----------------------------------------------------------------------
+ ;;
+ ;; The mn102 series does not have floating point instructions, but since
+ ;; FP values are held in integer regs, we can clear the high bit easily
+ ;; which gives us an efficient inline floating point absolute value.
+ ;;
+ ;; Similarly for negation of a FP value.
+ ;;
+
+ (define_expand "abssf2"
+ [(set (match_operand:SF 0 "register_operand" "")
+ (abs:SF (match_operand:SF 1 "register_operand" "")))]
+ ""
+ "
+ {
+ rtx target, result, insns;
+
+ start_sequence ();
+ target = operand_subword (operands[0], 0, 1, SFmode);
+ result = expand_binop (HImode, and_optab,
+ operand_subword_force (operands[1], 0, SFmode),
+ GEN_INT(0x7fff), target, 0, OPTAB_WIDEN);
+
+ if (result == 0)
+ abort ();
+
+ if (result != target)
+ emit_move_insn (result, target);
+
+ emit_move_insn (operand_subword (operands[0], 1, 1, SFmode),
+ operand_subword_force (operands[1], 1, SFmode));
+
+ insns = get_insns ();
+ end_sequence ();
+
+ emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
+ DONE;
+ }")
+
+ (define_expand "negsf2"
+ [(set (match_operand:SF 0 "register_operand" "")
+ (neg:SF (match_operand:SF 1 "register_operand" "")))]
+ ""
+ "
+ {
+ rtx target, result, insns;
+
+ start_sequence ();
+ target = operand_subword (operands[0], 0, 1, SFmode);
+ result = expand_binop (HImode, xor_optab,
+ operand_subword_force (operands[1], 0, SFmode),
+ GEN_INT(0x8000), target, 0, OPTAB_WIDEN);
+
+ if (result == 0)
+ abort ();
+
+ if (result != target)
+ emit_move_insn (result, target);
+
+ emit_move_insn (operand_subword (operands[0], 1, 1, SFmode),
+ operand_subword_force (operands[1], 1, SFmode));
+
+ insns = get_insns ();
+ end_sequence ();
+
+ emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
+ DONE;
+ }")
+
+ ;; ----------------------------------------------------------------------
;; PROLOGUE/EPILOGUE
;; ----------------------------------------------------------------------
(define_expand "prologue"
Index: mn10300/mn10300.md
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/config/mn10300/mn10300.md,v
retrieving revision 1.56.2.4
diff -c -3 -p -r1.56.2.4 mn10300.md
*** mn10300.md 1998/08/31 16:16:34 1.56.2.4
--- mn10300.md 1998/12/15 20:48:55
***************
*** 1843,1848 ****
--- 1843,1969 ----
[(set_attr "cc" "set_zn")])
;; ----------------------------------------------------------------------
+ ;; FP INSTRUCTIONS
+ ;; ----------------------------------------------------------------------
+ ;;
+ ;; The mn103 series does not have floating point instructions, but since
+ ;; FP values are held in integer regs, we can clear the high bit easily
+ ;; which gives us an efficient inline floating point absolute value.
+ ;;
+ ;; Similarly for negation of a FP value.
+ ;;
+
+ (define_expand "absdf2"
+ [(set (match_operand:DF 0 "register_operand" "")
+ (abs:DF (match_operand:DF 1 "register_operand" "")))]
+ ""
+ "
+ {
+ rtx target, result, insns;
+
+ start_sequence ();
+ target = operand_subword (operands[0], 0, 1, DFmode);
+ result = expand_binop (SImode, and_optab,
+ operand_subword_force (operands[1], 0, DFmode),
+ GEN_INT(0x7fffffff), target, 0, OPTAB_WIDEN);
+
+ if (result == 0)
+ abort ();
+
+ if (result != target)
+ emit_move_insn (result, target);
+
+ emit_move_insn (operand_subword (operands[0], 1, 1, DFmode),
+ operand_subword_force (operands[1], 1, DFmode));
+
+ insns = get_insns ();
+ end_sequence ();
+
+ emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
+ DONE;
+ }")
+
+ (define_expand "abssf2"
+ [(set (match_operand:SF 0 "register_operand" "")
+ (abs:SF (match_operand:SF 1 "register_operand" "")))]
+ ""
+ "
+ {
+ rtx result;
+ rtx target;
+
+ target = operand_subword_force (operands[0], 0, SFmode);
+ result = expand_binop (SImode, and_optab,
+ operand_subword_force (operands[1], 0, SFmode),
+ GEN_INT(0x7fffffff), target, 0, OPTAB_WIDEN);
+ if (result == 0)
+ abort ();
+
+ if (result != target)
+ emit_move_insn (result, target);
+
+ /* Make a place for REG_EQUAL. */
+ emit_move_insn (operands[0], operands[0]);
+ DONE;
+ }")
+
+
+ (define_expand "negdf2"
+ [(set (match_operand:DF 0 "register_operand" "")
+ (neg:DF (match_operand:DF 1 "register_operand" "")))]
+ ""
+ "
+ {
+ rtx target, result, insns;
+
+ start_sequence ();
+ target = operand_subword (operands[0], 0, 1, DFmode);
+ result = expand_binop (SImode, xor_optab,
+ operand_subword_force (operands[1], 0, DFmode),
+ GEN_INT(0x80000000), target, 0, OPTAB_WIDEN);
+
+ if (result == 0)
+ abort ();
+
+ if (result != target)
+ emit_move_insn (result, target);
+
+ emit_move_insn (operand_subword (operands[0], 1, 1, DFmode),
+ operand_subword_force (operands[1], 1, DFmode));
+
+ insns = get_insns ();
+ end_sequence ();
+
+ emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
+ DONE;
+ }")
+
+ (define_expand "negsf2"
+ [(set (match_operand:SF 0 "register_operand" "")
+ (neg:SF (match_operand:SF 1 "register_operand" "")))]
+ ""
+ "
+ {
+ rtx result;
+ rtx target;
+
+ target = operand_subword_force (operands[0], 0, SFmode);
+ result = expand_binop (SImode, xor_optab,
+ operand_subword_force (operands[1], 0, SFmode),
+ GEN_INT(0x80000000), target, 0, OPTAB_WIDEN);
+ if (result == 0)
+ abort ();
+
+ if (result != target)
+ emit_move_insn (result, target);
+
+ /* Make a place for REG_EQUAL. */
+ emit_move_insn (operands[0], operands[0]);
+ DONE;
+ }")
+
+
+ ;; ----------------------------------------------------------------------
;; PROLOGUE/EPILOGUE
;; ----------------------------------------------------------------------
(define_expand "prologue"