[PATCH] Unordered SPARC fixes

Jakub Jelinek jakub@redhat.com
Wed Jan 26 10:12:00 GMT 2000


> > +    case ORDERED:
> > +    case UNORDERED:
> > +      emit_cmp_insn (result, GEN_INT(3), NE,
> > +		     NULL_RTX, mode, 0, 0);
> 
> This can't be right.  They can't both be identical comparisons. 
> Surely it's
> 
> 	ORDERED:	result != 3
> 	UNORDERED:	result == 3
> 
> > +    case UNGT:
> > +    case UNGE:
> > +      emit_cmp_insn (result, const1_rtx, NE,
> > +		     NULL_RTX, mode, 0, 0);
> 
> 	UNGT:		result > 1
> 	UNGE:		result != 1

Yep, but I think the comparison argument did not matter on SPARC, as before
we were passing comparison itself (e.g. GT, LT etc. eventhough we meant NE)
and it worked. The actual branch is generated in .md.
Anyway, attached is an updated patch.
BTW: Have you had time to look at the LONG_DOUBLE_TYPE_SIZE patch I've
posted yesterday?

2000-01-26  Jakub Jelinek  <jakub@redhat.com>

	* config/sparc/sparc.c (sparc_emit_float_lib_cmp): Handle
	TARGET_ARCH32 again. Handle ORDERED, UN* and LTGT comparisons
	using _Qp_cmp/_Q_cmp and testing the return value.
	(print_operand): Call reverse_condition_maybe_unordered if
	we are handling CCFPmode or CCFPEmode.
	Handle ORDERED, UN* and LTGT comparisons.
	* config/sparc/sparc.md (cmptf): Use even on TARGET_ARCH32
	if not TARGET_HARD_QUAD.
	(seq, sne, sgt, slt, sge, sle, beq, bne, bgt, blt, bge, ble,
	bunordered, bordered, bungt, bunlt, buneq, bunge, bunle, bltgt):
	Call sparc_emit_float_lib_cmp even on TARGET_ARCH32.
	Adjust gen_b* calls so that they reflect return comparison of
	sparc_emit_float_lib_cmp.

--- gcc/config/sparc/sparc.c.jj	Wed Jan 26 08:38:26 2000
+++ gcc/config/sparc/sparc.c	Wed Jan 26 19:01:05 2000
@@ -4822,33 +4822,46 @@ sparc_emit_float_lib_cmp (x, y, comparis
      rtx x, y;
      enum rtx_code comparison;
 {
-  const char *qpfunc;
-  rtx slot0, slot1, result;
+  char *qpfunc;
+  rtx cmp = const0_rtx;
+  rtx slot0, slot1, result, tem, tem2;
+  enum machine_mode mode;
 
   switch (comparison)
     {
     case EQ:
-      qpfunc = "_Qp_feq";
+      qpfunc = (TARGET_ARCH64) ? "_Qp_feq" : "_Q_feq";
       break;
 
     case NE:
-      qpfunc = "_Qp_fne";
+      qpfunc = (TARGET_ARCH64) ? "_Qp_fne" : "_Q_fne";
       break;
 
     case GT:
-      qpfunc = "_Qp_fgt";
+      qpfunc = (TARGET_ARCH64) ? "_Qp_fgt" : "_Q_fgt";
       break;
 
     case GE:
-      qpfunc = "_Qp_fge";
+      qpfunc = (TARGET_ARCH64) ? "_Qp_fge" : "_Q_fge";
       break;
 
     case LT:
-      qpfunc = "_Qp_flt";
+      qpfunc = (TARGET_ARCH64) ? "_Qp_flt" : "_Q_flt";
       break;
 
     case LE:
-      qpfunc = "_Qp_fle";
+      qpfunc = (TARGET_ARCH64) ? "_Qp_fle" : "_Q_fle";
+      break;
+
+    case ORDERED:
+    case UNORDERED:
+    case UNGT:
+    case UNLT:
+    case UNEQ:
+    case UNGE:
+    case UNLE:
+    case LTGT:
+      qpfunc = (TARGET_ARCH64) ? "_Qp_cmp" : "_Q_cmp";
       break;
 
     default:
@@ -4856,33 +4869,97 @@ sparc_emit_float_lib_cmp (x, y, comparis
       break;
     }
 
-  if (GET_CODE (x) != MEM)
+  if (TARGET_ARCH64)
     {
-      slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
-      emit_insn (gen_rtx_SET (VOIDmode, slot0, x));
-    }
+      if (GET_CODE (x) != MEM)
+	{
+	  slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
+	  emit_insn (gen_rtx_SET (VOIDmode, slot0, x));
+	}
+      else
+	slot0 = x;
 
-  if (GET_CODE (y) != MEM)
+      if (GET_CODE (y) != MEM)
+	{
+	  slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
+	  emit_insn (gen_rtx_SET (VOIDmode, slot1, y));
+	}
+      else
+	slot1 = y;
+
+      emit_library_call (gen_rtx_SYMBOL_REF (Pmode, qpfunc), 1,
+			 DImode, 2,
+			 XEXP (slot0, 0), Pmode,
+			 XEXP (slot1, 0), Pmode);
+
+      mode = DImode;
+    }
+  else
     {
-      slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
-      emit_insn (gen_rtx_SET (VOIDmode, slot1, y));
+      emit_library_call (gen_rtx_SYMBOL_REF (Pmode, qpfunc), 1,
+			 SImode, 2,
+			 x, TFmode, y, TFmode);
+
+      mode = SImode;
     }
 
-  emit_library_call (gen_rtx (SYMBOL_REF, Pmode, qpfunc), 1,
-                     DImode, 2,
-                     XEXP (slot0, 0), Pmode,
-                     XEXP (slot1, 0), Pmode);
 
   /* Immediately move the result of the libcall into a pseudo
      register so reload doesn't clobber the value if it needs
      the return register for a spill reg.  */
-  result = gen_reg_rtx (DImode);
-  emit_move_insn (result, hard_libcall_value (DImode));
+  result = gen_reg_rtx (mode);
+  emit_move_insn (result, hard_libcall_value (mode));
 
-  emit_cmp_insn (result, const0_rtx, comparison,
-                 NULL_RTX, DImode, 0, 0);
+  switch (comparison)
+    {
+    default:
+      emit_cmp_insn (result, const0_rtx, NE,
+		     NULL_RTX, mode, 0, 0);
+      break;
+    case ORDERED:
+    case UNORDERED:
+      emit_cmp_insn (result, GEN_INT(3),
+		     (comparison == UNORDERED) ? EQ : NE,
+		     NULL_RTX, mode, 0, 0);
+      break;
+    case UNGT:
+    case UNGE:
+      emit_cmp_insn (result, const1_rtx,
+		     (comparison == UNGT) ? GT : NE,
+		     NULL_RTX, mode, 0, 0);
+      break;
+    case UNLE:
+      emit_cmp_insn (result, const2_rtx, NE,
+		     NULL_RTX, mode, 0, 0);
+      break;
+    case UNLT:
+      tem = gen_reg_rtx (mode);
+      if (TARGET_ARCH32)
+	emit_insn (gen_andsi3 (tem, result, const1_rtx));
+      else
+	emit_insn (gen_anddi3 (tem, result, const1_rtx));
+      emit_cmp_insn (tem, const0_rtx, NE,
+		     NULL_RTX, mode, 0, 0);
+      break;
+    case UNEQ:
+    case LTGT:
+      tem = gen_reg_rtx (mode);
+      if (TARGET_ARCH32)
+	emit_insn (gen_addsi3 (tem, result, const1_rtx));
+      else
+	emit_insn (gen_adddi3 (tem, result, const1_rtx));
+      tem2 = gen_reg_rtx (mode);
+      if (TARGET_ARCH32)
+	emit_insn (gen_andsi3 (tem2, tem, const2_rtx));
+      else
+	emit_insn (gen_anddi3 (tem2, tem, const2_rtx));
+      emit_cmp_insn (tem2, const0_rtx,
+		     (comparison == UNEQ) ? EQ : NE,
+		     NULL_RTX, mode, 0, 0);
+      break;
+    }
 }
-          
+
 /* Return the string to output a conditional branch to LABEL, testing
    register REG.  LABEL is the operand number of the label; REG is the
    operand number of the reg.  OP is the conditional expression.  The mode
@@ -5449,9 +5526,16 @@ print_operand (file, x, code)
     case 'c' :
     case 'C':
       {
-	enum rtx_code rc = (code == 'c'
-			    ? reverse_condition (GET_CODE (x))
-			    : GET_CODE (x));
+	enum rtx_code rc = GET_CODE (x);
+	
+	if (code == 'c')
+	  {
+	    enum machine_mode mode = GET_MODE (XEXP (x, 0));
+	    if (mode == CCFPmode || mode == CCFPEmode)
+	      rc = reverse_condition_maybe_unordered (GET_CODE (x));
+	    else
+	      rc = reverse_condition (GET_CODE (x));
+	  }
 	switch (rc)
 	  {
 	  case NE: fputs ("ne", file); break;
@@ -5464,6 +5548,14 @@ print_operand (file, x, code)
 	  case GTU: fputs ("gu", file); break;
 	  case LEU: fputs ("leu", file); break;
 	  case LTU: fputs ("lu", file); break;
+	  case LTGT: fputs ("lg", file); break;
+	  case UNORDERED: fputs ("u", file); break;
+	  case ORDERED: fputs ("o", file); break;
+	  case UNLT: fputs ("ul", file); break;
+	  case UNLE: fputs ("ule", file); break;
+	  case UNGT: fputs ("ug", file); break;
+	  case UNGE: fputs ("uge", file); break;
+	  case UNEQ: fputs ("ue", file); break;
 	  default: output_operand_lossage (code == 'c'
 					   ? "Invalid %%c operand"
 					   : "Invalid %%C operand");
--- gcc/config/sparc/sparc.md.jj	Wed Jan 26 08:38:26 2000
+++ gcc/config/sparc/sparc.md	Wed Jan 26 16:41:07 2000
@@ -627,7 +627,7 @@
   [(set (reg:CCFP 96)
 	(compare:CCFP (match_operand:TF 0 "register_operand" "")
 		      (match_operand:TF 1 "register_operand" "")))]
-  "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
+  "TARGET_FPU"
   "
 {
   sparc_compare_op0 = operands[0];
@@ -855,7 +855,7 @@
       emit_insn (pat);
       DONE;
     }
-  else if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
+  else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
       emit_jump_insn (gen_sne (operands[0]));
@@ -908,7 +908,7 @@
       emit_insn (pat);
       DONE;
     }
-  else if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
+  else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
       emit_jump_insn (gen_sne (operands[0]));
@@ -929,7 +929,7 @@
   "! TARGET_LIVE_G0"
   "
 {
-  if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
+  if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
       emit_jump_insn (gen_sne (operands[0]));
@@ -950,7 +950,7 @@
   "! TARGET_LIVE_G0"
   "
 {
-  if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
+  if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
       emit_jump_insn (gen_sne (operands[0]));
@@ -971,7 +971,7 @@
   "! TARGET_LIVE_G0"
   "
 {
-  if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
+  if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
       emit_jump_insn (gen_sne (operands[0]));
@@ -992,7 +992,7 @@
   "! TARGET_LIVE_G0"
   "
 {
-  if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
+  if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
       emit_jump_insn (gen_sne (operands[0]));
@@ -1626,7 +1626,7 @@
       emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
       DONE;
     }
-  else if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
+  else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
       emit_jump_insn (gen_bne (operands[0]));
@@ -1650,7 +1650,7 @@
       emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
       DONE;
     }
-  else if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
+  else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
       emit_jump_insn (gen_bne (operands[0]));
@@ -1674,7 +1674,7 @@
       emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
       DONE;
     }
-  else if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
+  else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
       emit_jump_insn (gen_bne (operands[0]));
@@ -1708,7 +1708,7 @@
       emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
       DONE;
     }
-  else if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
+  else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
       emit_jump_insn (gen_bne (operands[0]));
@@ -1742,7 +1742,7 @@
       emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
       DONE;
     }
-  else if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
+  else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
       emit_jump_insn (gen_bne (operands[0]));
@@ -1776,7 +1776,7 @@
       emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
       DONE;
     }
-  else if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
+  else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
       emit_jump_insn (gen_bne (operands[0]));
@@ -1803,12 +1803,11 @@
   ""
   "
 {
-  if (GET_MODE (sparc_compare_op0) == TFmode
-      && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
+  if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
 				UNORDERED);
-      emit_jump_insn (gen_bne (operands[0]));
+      emit_jump_insn (gen_beq (operands[0]));
       DONE;
     }
   operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
@@ -1823,8 +1822,7 @@
   ""
   "
 {
-  if (GET_MODE (sparc_compare_op0) == TFmode
-      && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
+  if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
       emit_jump_insn (gen_bne (operands[0]));
@@ -1842,11 +1840,10 @@
   ""
   "
 {
-  if (GET_MODE (sparc_compare_op0) == TFmode
-      && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
+  if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
-      emit_jump_insn (gen_bne (operands[0]));
+      emit_jump_insn (gen_bgt (operands[0]));
       DONE;
     }
   operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
@@ -1860,8 +1857,7 @@
   ""
   "
 {
-  if (GET_MODE (sparc_compare_op0) == TFmode
-      && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
+  if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
       emit_jump_insn (gen_bne (operands[0]));
@@ -1878,11 +1874,10 @@
   ""
   "
 {
-  if (GET_MODE (sparc_compare_op0) == TFmode
-      && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
+  if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
-      emit_jump_insn (gen_bne (operands[0]));
+      emit_jump_insn (gen_beq (operands[0]));
       DONE;
     }
   operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
@@ -1896,8 +1891,7 @@
   ""
   "
 {
-  if (GET_MODE (sparc_compare_op0) == TFmode
-      && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
+  if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
       emit_jump_insn (gen_bne (operands[0]));
@@ -1914,8 +1908,7 @@
   ""
   "
 {
-  if (GET_MODE (sparc_compare_op0) == TFmode
-      && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
+  if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
       emit_jump_insn (gen_bne (operands[0]));
@@ -1932,8 +1925,7 @@
   ""
   "
 {
-  if (GET_MODE (sparc_compare_op0) == TFmode
-      && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
+  if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
       emit_jump_insn (gen_bne (operands[0]));


Cheers,
    Jakub
___________________________________________________________________
Jakub Jelinek | jakub@redhat.com | http://sunsite.mff.cuni.cz/~jj
Linux version 2.3.41 on a sparc64 machine (1343.49 BogoMips)
___________________________________________________________________


More information about the Gcc-patches mailing list