aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDoug Evans <dje@gnu.org>1994-12-05 18:53:20 +0000
committerDoug Evans <dje@gnu.org>1994-12-05 18:53:20 +0000
commit5120098826508feefce4783726adac89fdf5f653 (patch)
treef470b001b7f84c0a7e0f1383bc69bab8a7210320 /gcc
parentd537c24df239d35f32f5fb473b70607278c81e82 (diff)
downloadgcc-5120098826508feefce4783726adac89fdf5f653.zip
gcc-5120098826508feefce4783726adac89fdf5f653.tar.gz
gcc-5120098826508feefce4783726adac89fdf5f653.tar.bz2
(negsf2): Flip sign bit if software floating point.
(negdf2,negxf2): Likewise. (abssf2): Zero sign bit if software floating point. (absdf2,absxf2): Likewise. From-SVN: r8608
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/m68k/m68k.md197
1 files changed, 187 insertions, 10 deletions
diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index 10d444f..bd826e1 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -3292,11 +3292,34 @@
""
"neg%.b %0")
+;; If using software floating point, just flip the sign bit.
+
(define_expand "negsf2"
[(set (match_operand:SF 0 "general_operand" "")
(neg:SF (match_operand:SF 1 "general_operand" "")))]
- "TARGET_68881 || TARGET_FPA"
- "")
+ ""
+ "
+{
+ if (!TARGET_FPA && !TARGET_68881)
+ {
+ 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;
+ }
+}")
(define_insn ""
[(set (match_operand:SF 0 "general_operand" "=x,y")
@@ -3323,8 +3346,36 @@
(define_expand "negdf2"
[(set (match_operand:DF 0 "general_operand" "")
(neg:DF (match_operand:DF 1 "general_operand" "")))]
- "TARGET_68881 || TARGET_FPA"
- "")
+ ""
+ "
+{
+ if (!TARGET_FPA && !TARGET_68881)
+ {
+ rtx result;
+ rtx target;
+ rtx 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_insn ""
[(set (match_operand:DF 0 "general_operand" "=x,y")
@@ -3363,12 +3414,34 @@
}")
;; Absolute value instructions
+;; If using software floating point, just zero the sign bit.
(define_expand "abssf2"
[(set (match_operand:SF 0 "general_operand" "")
(abs:SF (match_operand:SF 1 "general_operand" "")))]
- "TARGET_68881 || TARGET_FPA"
- "")
+ ""
+ "
+{
+ if (!TARGET_FPA && !TARGET_68881)
+ {
+ 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_insn ""
[(set (match_operand:SF 0 "general_operand" "=x,y")
@@ -3390,8 +3463,36 @@
(define_expand "absdf2"
[(set (match_operand:DF 0 "general_operand" "")
(abs:DF (match_operand:DF 1 "general_operand" "")))]
- "TARGET_68881 || TARGET_FPA"
- "")
+ ""
+ "
+{
+ if (!TARGET_FPA && !TARGET_68881)
+ {
+ rtx result;
+ rtx target;
+ rtx 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_insn ""
[(set (match_operand:DF 0 "general_operand" "=x,y")
@@ -5606,7 +5707,45 @@
return \"fdiv%.x %f2,%0\";
}")
-(define_insn "negxf2"
+(define_expand "negxf2"
+ [(set (match_operand:XF 0 "general_operand" "")
+ (neg:XF (match_operand:XF 1 "general_operand" "")))]
+ ""
+ "
+{
+ /* ??? There isn't an FPA define_insn so we could handle it here too.
+ For now we don't (paranoia). */
+ if (!TARGET_FPA && !TARGET_68881)
+ {
+ rtx result;
+ rtx target;
+ rtx insns;
+
+ start_sequence ();
+ target = operand_subword (operands[0], 0, 1, XFmode);
+ result = expand_binop (SImode, xor_optab,
+ operand_subword_force (operands[1], 0, XFmode),
+ 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, XFmode),
+ operand_subword_force (operands[1], 1, XFmode));
+ emit_move_insn (operand_subword (operands[0], 2, 1, XFmode),
+ operand_subword_force (operands[1], 2, XFmode));
+
+ insns = get_insns ();
+ end_sequence ();
+
+ emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
+ DONE;
+ }
+}")
+
+(define_insn "negxf2_68881"
[(set (match_operand:XF 0 "general_operand" "=f")
(neg:XF (match_operand:XF 1 "nonimmediate_operand" "fmF")))]
"TARGET_68881"
@@ -5617,7 +5756,45 @@
return \"fneg%.x %f1,%0\";
}")
-(define_insn "absxf2"
+(define_expand "absxf2"
+ [(set (match_operand:XF 0 "general_operand" "")
+ (abs:XF (match_operand:XF 1 "general_operand" "")))]
+ ""
+ "
+{
+ /* ??? There isn't an FPA define_insn so we could handle it here too.
+ For now we don't (paranoia). */
+ if (!TARGET_FPA && !TARGET_68881)
+ {
+ rtx result;
+ rtx target;
+ rtx insns;
+
+ start_sequence ();
+ target = operand_subword (operands[0], 0, 1, XFmode);
+ result = expand_binop (SImode, and_optab,
+ operand_subword_force (operands[1], 0, XFmode),
+ 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, XFmode),
+ operand_subword_force (operands[1], 1, XFmode));
+ emit_move_insn (operand_subword (operands[0], 2, 1, XFmode),
+ operand_subword_force (operands[1], 2, XFmode));
+
+ insns = get_insns ();
+ end_sequence ();
+
+ emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
+ DONE;
+ }
+}")
+
+(define_insn "absxf2_68881"
[(set (match_operand:XF 0 "general_operand" "=f")
(abs:XF (match_operand:XF 1 "nonimmediate_operand" "fmF")))]
"TARGET_68881"