aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/mn10300/mn10300.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/mn10300/mn10300.md')
-rw-r--r--gcc/config/mn10300/mn10300.md129
1 files changed, 125 insertions, 4 deletions
diff --git a/gcc/config/mn10300/mn10300.md b/gcc/config/mn10300/mn10300.md
index d3061ad54b8..8e090a3395d 100644
--- a/gcc/config/mn10300/mn10300.md
+++ b/gcc/config/mn10300/mn10300.md
@@ -155,7 +155,6 @@
{
if (XEXP (operands[1], 0) == stack_pointer_rtx)
{
- emit_move_insn (operands[0], XEXP (operands[1], 0));
if (GET_CODE (XEXP (operands[1], 1)) == SUBREG
&& (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 1)))
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 1))))))
@@ -164,10 +163,10 @@
SUBREG_REG (XEXP (operands[1], 1))));
else
emit_move_insn (operands[2], XEXP (operands[1], 1));
+ emit_move_insn (operands[0], XEXP (operands[1], 0));
}
else
{
- emit_move_insn (operands[0], XEXP (operands[1], 1));
if (GET_CODE (XEXP (operands[1], 0)) == SUBREG
&& (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 0)))
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 0))))))
@@ -176,6 +175,7 @@
SUBREG_REG (XEXP (operands[1], 0))));
else
emit_move_insn (operands[2], XEXP (operands[1], 0));
+ emit_move_insn (operands[0], XEXP (operands[1], 1));
}
emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
DONE;
@@ -849,7 +849,7 @@
[(set_attr "cc" "clobber,none_0hit")])
(define_insn ""
- [(set (match_operand:QI 0 "general_operand" "=R,d")
+ [(set (match_operand:QI 0 "general_operand" "+R,d")
(subreg:QI
(and:SI (subreg:SI (match_dup 0) 0)
(match_operand:SI 1 "const_int_operand" "i,i")) 0))]
@@ -860,7 +860,7 @@
[(set_attr "cc" "clobber,set_znv")])
(define_insn ""
- [(set (match_operand:QI 0 "general_operand" "=R,d")
+ [(set (match_operand:QI 0 "general_operand" "+R,d")
(subreg:QI
(ior:SI (subreg:SI (match_dup 0) 0)
(match_operand:SI 1 "const_int_operand" "i,i")) 0))]
@@ -1339,6 +1339,127 @@
[(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], 1, 1, DFmode);
+ result = expand_binop (SImode, and_optab,
+ operand_subword_force (operands[1], 1, 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], 0, 1, DFmode),
+ operand_subword_force (operands[1], 0, 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], 1, 1, DFmode);
+ result = expand_binop (SImode, xor_optab,
+ operand_subword_force (operands[1], 1, 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], 0, 1, DFmode),
+ operand_subword_force (operands[1], 0, 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"