(tstdi): Use tst/subx #0 instead of neg/negx.
authorRichard Kenner <kenner@gcc.gnu.org>
Tue, 30 May 1995 12:17:18 +0000 (08:17 -0400)
committerRichard Kenner <kenner@gcc.gnu.org>
Tue, 30 May 1995 12:17:18 +0000 (08:17 -0400)
Allow "a" and ">" for operand 0.

From-SVN: r9841

gcc/config/m68k/m68k.md

index 672278a..032b25e 100644 (file)
 
 (define_insn "tstdi"
   [(set (cc0)
-       (match_operand:DI 0 "nonimmediate_operand" "do"))]
+       (match_operand:DI 0 "nonimmediate_operand" "oa>,d"))
+   (clobber (match_scratch:SI 1 "=d,d"))
+   (clobber (match_scratch:SI 2 "=d,"))]
   ""
   "*
 {
   if (GET_CODE (operands[0]) == REG)
-    operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
+    operands[3] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
+  else if (GET_CODE (operands[0]) == MEM
+          && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
+    operands[3] = operands[0];
   else
-    operands[1] = adj_offsettable_operand (operands[0], 4);
-  /* Just in case we come here. I hope all tst:DI are combined !!! */
-  return \"neg%.l %1\;negx%.l %0\;neg%.l %1\;negx%.l %0\";
+    operands[3] = adj_offsettable_operand (operands[0], 4);
+  if (DATA_REG_P (operands[0]))
+    operands[2] = operands[0];
+  else
+    output_asm_insn (\"move%.l %0,%2\", operands);
+  /*
+  ** 'sub' clears %1, and also clears the X cc bit
+  ** 'tst' sets the Z cc bit according to the low part of the DImode operand
+  ** 'subx %1' (i.e. subx #0) acts as a (non-existent) tstx on the high part
+  */
+  return \"sub%.l %1,%1\;tst%.l %3\;subx%.l %1,%2\";
 }")
 
 (define_insn "tstsi"