This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

improving fneg & fabs



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"


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]