SSE fix 16 - comparisons

Jan Hubicka jh@suse.cz
Sat Oct 19 13:41:00 GMT 2002


Hi,
comparsions are more or less broken.  The comi comparisons are defined
by Intel to compare in the "intelish sense", not in IEEE sense.
We also used bogus mode and thus comparison codes.

Sat Oct 19 22:27:11 CEST 2002  Jan Hubicka  <jh@suse.cz>
	* i386.c (bdesc_comi): Fix to match specification.
	(ix86_expand_sse_comi): Emit the comparison properly.
	* i386.md (sse_comi, sse2_comi, sse_ucomi, sse2_ucomi):
	Do not use comparison operator.
	(vnmaskcmp): Fix template.
Index: i386.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.c,v
retrieving revision 1.474
diff -c -3 -p -r1.474 i386.c
*** i386.c	18 Oct 2002 23:35:29 -0000	1.474
--- i386.c	19 Oct 2002 20:32:52 -0000
*************** struct builtin_description
*** 11755,11784 ****
  
  static const struct builtin_description bdesc_comi[] =
  {
!   { MASK_SSE1, CODE_FOR_sse_comi, "__builtin_ia32_comieq", IX86_BUILTIN_COMIEQSS, EQ, 0 },
!   { MASK_SSE1, CODE_FOR_sse_comi, "__builtin_ia32_comilt", IX86_BUILTIN_COMILTSS, LT, 0 },
!   { MASK_SSE1, CODE_FOR_sse_comi, "__builtin_ia32_comile", IX86_BUILTIN_COMILESS, LE, 0 },
!   { MASK_SSE1, CODE_FOR_sse_comi, "__builtin_ia32_comigt", IX86_BUILTIN_COMIGTSS, LT, 1 },
!   { MASK_SSE1, CODE_FOR_sse_comi, "__builtin_ia32_comige", IX86_BUILTIN_COMIGESS, LE, 1 },
!   { MASK_SSE1, CODE_FOR_sse_comi, "__builtin_ia32_comineq", IX86_BUILTIN_COMINEQSS, NE, 0 },
!   { MASK_SSE1, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomieq", IX86_BUILTIN_UCOMIEQSS, EQ, 0 },
!   { MASK_SSE1, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomilt", IX86_BUILTIN_UCOMILTSS, LT, 0 },
!   { MASK_SSE1, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomile", IX86_BUILTIN_UCOMILESS, LE, 0 },
!   { MASK_SSE1, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomigt", IX86_BUILTIN_UCOMIGTSS, LT, 1 },
!   { MASK_SSE1, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomige", IX86_BUILTIN_UCOMIGESS, LE, 1 },
!   { MASK_SSE1, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomineq", IX86_BUILTIN_UCOMINEQSS, NE, 0 },
!   { MASK_SSE2, CODE_FOR_sse2_comi, "__builtin_ia32_comisdeq", IX86_BUILTIN_COMIEQSD, EQ, 0 },
!   { MASK_SSE2, CODE_FOR_sse2_comi, "__builtin_ia32_comisdlt", IX86_BUILTIN_COMILTSD, LT, 0 },
!   { MASK_SSE2, CODE_FOR_sse2_comi, "__builtin_ia32_comisdle", IX86_BUILTIN_COMILESD, LE, 0 },
!   { MASK_SSE2, CODE_FOR_sse2_comi, "__builtin_ia32_comisdgt", IX86_BUILTIN_COMIGTSD, LT, 1 },
!   { MASK_SSE2, CODE_FOR_sse2_comi, "__builtin_ia32_comisdge", IX86_BUILTIN_COMIGESD, LE, 1 },
!   { MASK_SSE2, CODE_FOR_sse2_comi, "__builtin_ia32_comisdneq", IX86_BUILTIN_COMINEQSD, NE, 0 },
!   { MASK_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdeq", IX86_BUILTIN_UCOMIEQSD, EQ, 0 },
!   { MASK_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdlt", IX86_BUILTIN_UCOMILTSD, LT, 0 },
!   { MASK_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdle", IX86_BUILTIN_UCOMILESD, LE, 0 },
!   { MASK_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdgt", IX86_BUILTIN_UCOMIGTSD, LT, 1 },
!   { MASK_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdge", IX86_BUILTIN_UCOMIGESD, LE, 1 },
!   { MASK_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdneq", IX86_BUILTIN_UCOMINEQSD, NE, 0 },
  };
  
  static const struct builtin_description bdesc_2arg[] =
--- 11754,11783 ----
  
  static const struct builtin_description bdesc_comi[] =
  {
!   { MASK_SSE1, CODE_FOR_sse_comi, "__builtin_ia32_comieq", IX86_BUILTIN_COMIEQSS, UNEQ, 0 },
!   { MASK_SSE1, CODE_FOR_sse_comi, "__builtin_ia32_comilt", IX86_BUILTIN_COMILTSS, UNLT, 0 },
!   { MASK_SSE1, CODE_FOR_sse_comi, "__builtin_ia32_comile", IX86_BUILTIN_COMILESS, UNLE, 0 },
!   { MASK_SSE1, CODE_FOR_sse_comi, "__builtin_ia32_comigt", IX86_BUILTIN_COMIGTSS, GT, 0 },
!   { MASK_SSE1, CODE_FOR_sse_comi, "__builtin_ia32_comige", IX86_BUILTIN_COMIGESS, GE, 0 },
!   { MASK_SSE1, CODE_FOR_sse_comi, "__builtin_ia32_comineq", IX86_BUILTIN_COMINEQSS, LTGT, 0 },
!   { MASK_SSE1, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomieq", IX86_BUILTIN_UCOMIEQSS, UNEQ, 0 },
!   { MASK_SSE1, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomilt", IX86_BUILTIN_UCOMILTSS, UNLT, 0 },
!   { MASK_SSE1, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomile", IX86_BUILTIN_UCOMILESS, UNLE, 0 },
!   { MASK_SSE1, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomigt", IX86_BUILTIN_UCOMIGTSS, GT, 0 },
!   { MASK_SSE1, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomige", IX86_BUILTIN_UCOMIGESS, GE, 0 },
!   { MASK_SSE1, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomineq", IX86_BUILTIN_UCOMINEQSS, LTGT, 0 },
!   { MASK_SSE2, CODE_FOR_sse2_comi, "__builtin_ia32_comisdeq", IX86_BUILTIN_COMIEQSD, UNEQ, 0 },
!   { MASK_SSE2, CODE_FOR_sse2_comi, "__builtin_ia32_comisdlt", IX86_BUILTIN_COMILTSD, UNLT, 0 },
!   { MASK_SSE2, CODE_FOR_sse2_comi, "__builtin_ia32_comisdle", IX86_BUILTIN_COMILESD, UNLE, 0 },
!   { MASK_SSE2, CODE_FOR_sse2_comi, "__builtin_ia32_comisdgt", IX86_BUILTIN_COMIGTSD, GT, 0 },
!   { MASK_SSE2, CODE_FOR_sse2_comi, "__builtin_ia32_comisdge", IX86_BUILTIN_COMIGESD, GE, 0 },
!   { MASK_SSE2, CODE_FOR_sse2_comi, "__builtin_ia32_comisdneq", IX86_BUILTIN_COMINEQSD, LTGT, 0 },
!   { MASK_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdeq", IX86_BUILTIN_UCOMIEQSD, UNEQ, 0 },
!   { MASK_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdlt", IX86_BUILTIN_UCOMILTSD, UNLT, 0 },
!   { MASK_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdle", IX86_BUILTIN_UCOMILESD, UNLE, 0 },
!   { MASK_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdgt", IX86_BUILTIN_UCOMIGTSD, GT, 0 },
!   { MASK_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdge", IX86_BUILTIN_UCOMIGESD, GE, 0 },
!   { MASK_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdneq", IX86_BUILTIN_UCOMINEQSD, LTGT, 0 },
  };
  
  static const struct builtin_description bdesc_2arg[] =
*************** ix86_expand_sse_comi (d, arglist, target
*** 12881,12894 ****
      op1 = copy_to_mode_reg (mode1, op1);
  
    op2 = gen_rtx_fmt_ee (comparison, mode0, op0, op1);
!   pat = GEN_FCN (d->icode) (op0, op1, op2);
    if (! pat)
      return 0;
    emit_insn (pat);
    emit_insn (gen_rtx_SET (VOIDmode,
  			  gen_rtx_STRICT_LOW_PART (VOIDmode, target),
  			  gen_rtx_fmt_ee (comparison, QImode,
! 					  gen_rtx_REG (CCmode, FLAGS_REG),
  					  const0_rtx)));
  
    return SUBREG_REG (target);
--- 12880,12893 ----
      op1 = copy_to_mode_reg (mode1, op1);
  
    op2 = gen_rtx_fmt_ee (comparison, mode0, op0, op1);
!   pat = GEN_FCN (d->icode) (op0, op1);
    if (! pat)
      return 0;
    emit_insn (pat);
    emit_insn (gen_rtx_SET (VOIDmode,
  			  gen_rtx_STRICT_LOW_PART (VOIDmode, target),
  			  gen_rtx_fmt_ee (comparison, QImode,
! 					  SET_DEST (pat),
  					  const0_rtx)));
  
    return SUBREG_REG (target);
Index: i386.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.md,v
retrieving revision 1.391
diff -c -3 -p -r1.391 i386.md
*** i386.md	17 Oct 2002 17:09:16 -0000	1.391
--- i386.md	19 Oct 2002 20:32:58 -0000
***************
*** 18883,18895 ****
  
  (define_insn "sse_comi"
    [(set (reg:CCFP 17)
!         (match_operator:CCFP 2 "sse_comparison_operator"
! 			[(vec_select:SF
! 			  (match_operand:V4SF 0 "register_operand" "x")
! 			  (parallel [(const_int 0)]))
! 			 (vec_select:SF
! 			  (match_operand:V4SF 1 "register_operand" "x")
! 			  (parallel [(const_int 0)]))]))]
    "TARGET_SSE"
    "comiss\t{%1, %0|%0, %1}"
    [(set_attr "type" "ssecmp")
--- 18884,18895 ----
  
  (define_insn "sse_comi"
    [(set (reg:CCFP 17)
!         (compare:CCFP (vec_select:SF
! 		       (match_operand:V4SF 0 "register_operand" "x")
! 		       (parallel [(const_int 0)]))
! 		      (vec_select:SF
! 		       (match_operand:V4SF 1 "register_operand" "x")
! 		       (parallel [(const_int 0)]))))]
    "TARGET_SSE"
    "comiss\t{%1, %0|%0, %1}"
    [(set_attr "type" "ssecmp")
***************
*** 18897,18909 ****
  
  (define_insn "sse_ucomi"
    [(set (reg:CCFPU 17)
! 	(match_operator:CCFPU 2 "sse_comparison_operator"
! 			[(vec_select:SF
! 			  (match_operand:V4SF 0 "register_operand" "x")
! 			  (parallel [(const_int 0)]))
! 			 (vec_select:SF
! 			  (match_operand:V4SF 1 "register_operand" "x")
! 			  (parallel [(const_int 0)]))]))]
    "TARGET_SSE"
    "ucomiss\t{%1, %0|%0, %1}"
    [(set_attr "type" "ssecmp")
--- 18897,18908 ----
  
  (define_insn "sse_ucomi"
    [(set (reg:CCFPU 17)
! 	(compare:CCFPU (vec_select:SF
! 			(match_operand:V4SF 0 "register_operand" "x")
! 			(parallel [(const_int 0)]))
! 		       (vec_select:SF
! 			(match_operand:V4SF 1 "register_operand" "x")
! 			(parallel [(const_int 0)]))))]
    "TARGET_SSE"
    "ucomiss\t{%1, %0|%0, %1}"
    [(set_attr "type" "ssecmp")
***************
*** 20409,20415 ****
  			      [(match_operand:V2DF 1 "register_operand" "0")
  			       (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
    "TARGET_SSE2"
!   "cmpn%D3pd\t{%2, %0|%0, %2}"
    [(set_attr "type" "ssecmp")
     (set_attr "mode" "V2DF")])
  
--- 20408,20419 ----
  			      [(match_operand:V2DF 1 "register_operand" "0")
  			       (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
    "TARGET_SSE2"
! {
!   if (GET_CODE (operands[3]) == UNORDERED)
!     return "cmpordps\t{%2, %0|%0, %2}";
!   else
!     return "cmpn%D3pd\t{%2, %0|%0, %2}";
! }
    [(set_attr "type" "ssecmp")
     (set_attr "mode" "V2DF")])
  
***************
*** 20436,20454 ****
  	 (subreg:V2DI (match_dup 1) 0)
  	 (const_int 1)))]
    "TARGET_SSE2"
!   "cmp%D3sd\t{%2, %0|%0, %2}"
    [(set_attr "type" "ssecmp")
     (set_attr "mode" "DF")])
  
  (define_insn "sse2_comi"
    [(set (reg:CCFP 17)
!         (match_operator:CCFP 2 "sse_comparison_operator"
! 			[(vec_select:DF
! 			  (match_operand:V2DF 0 "register_operand" "x")
! 			  (parallel [(const_int 0)]))
! 			 (vec_select:DF
! 			  (match_operand:V2DF 1 "register_operand" "x")
! 			  (parallel [(const_int 0)]))]))]
    "TARGET_SSE2"
    "comisd\t{%1, %0|%0, %1}"
    [(set_attr "type" "ssecmp")
--- 20440,20462 ----
  	 (subreg:V2DI (match_dup 1) 0)
  	 (const_int 1)))]
    "TARGET_SSE2"
! {
!   if (GET_CODE (operands[3]) == UNORDERED)
!     return "cmpordsd\t{%2, %0|%0, %2}";
!   else
!     return "cmpn%D3sd\t{%2, %0|%0, %2}";
! }
    [(set_attr "type" "ssecmp")
     (set_attr "mode" "DF")])
  
  (define_insn "sse2_comi"
    [(set (reg:CCFP 17)
!         (compare:CCFP (vec_select:DF
! 		       (match_operand:V2DF 0 "register_operand" "x")
! 		       (parallel [(const_int 0)]))
! 		      (vec_select:DF
! 		       (match_operand:V2DF 1 "register_operand" "x")
! 		       (parallel [(const_int 0)]))))]
    "TARGET_SSE2"
    "comisd\t{%1, %0|%0, %1}"
    [(set_attr "type" "ssecmp")
***************
*** 20456,20468 ****
  
  (define_insn "sse2_ucomi"
    [(set (reg:CCFPU 17)
! 	(match_operator:CCFPU 2 "sse_comparison_operator"
! 			[(vec_select:DF
! 			  (match_operand:V2DF 0 "register_operand" "x")
! 			  (parallel [(const_int 0)]))
! 			 (vec_select:DF
! 			  (match_operand:V2DF 1 "register_operand" "x")
! 			  (parallel [(const_int 0)]))]))]
    "TARGET_SSE2"
    "ucomisd\t{%1, %0|%0, %1}"
    [(set_attr "type" "ssecmp")
--- 20464,20475 ----
  
  (define_insn "sse2_ucomi"
    [(set (reg:CCFPU 17)
! 	(compare:CCFPU (vec_select:DF
! 			 (match_operand:V2DF 0 "register_operand" "x")
! 			 (parallel [(const_int 0)]))
! 			(vec_select:DF
! 			 (match_operand:V2DF 1 "register_operand" "x")
! 			 (parallel [(const_int 0)]))))]
    "TARGET_SSE2"
    "ucomisd\t{%1, %0|%0, %1}"
    [(set_attr "type" "ssecmp")



More information about the Gcc-patches mailing list