OSDN Git Service

* mn10200.md (abssf2, negsf2): New expanders.
[pf3gnuchains/gcc-fork.git] / gcc / config / mn10200 / mn10200.md
index 1549fa4..0bfdca4 100644 (file)
   [(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"