rtl.h (simplify_gen_relational): Add cmp_mode parameter.
authorJan Hubicka <jh@suse.cz>
Sat, 28 Apr 2001 19:16:30 +0000 (21:16 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sat, 28 Apr 2001 19:16:30 +0000 (19:16 +0000)
* rtl.h (simplify_gen_relational): Add cmp_mode parameter.
* simplify-rtx.c (simplify_gen_relational): Likewise.

* simplify-rtx.c (simplify_replace_rtx): Handle relationals and MEMs.

* i386.h (VALID_SSE_REG_MODE): Accept MMX modes if SSE2
* i386.md (movsi_1, movdi2, movdi_1_rex64): Handle SSE2 moves.

* i386.md (negsf2, negdf2, abssf2, absdf2): Force operands to
registers in SSE case; fix handling of the immediates.
(negsf2_ifs, abssf2_ifs): Tweak constraints; require
operands to be in regsiters before reload.
(negdf2_ifs, absdf2_ifs): Likewise; disable for 64bit
(negdf2_ifs_rex64, absdf2_ifs_rtx64): New.
(abstf,absxf,negtf,negxf splitters): Compute
properly the regnum for x86_64.
(avsdf2_if_rex64): New.

From-SVN: r41664

gcc/ChangeLog
gcc/config/i386/i386.h
gcc/config/i386/i386.md
gcc/rtl.h
gcc/simplify-rtx.c

index 3c4711381ef25a364c2c859d78a13b8fe7bff3ab..c15c7ffd13948e9b3cd4297160731ec6d8e10ad6 100644 (file)
@@ -1,3 +1,23 @@
+Sat Apr 28 21:02:58 CEST 2001  Jan Hubicka  <jh@suse.cz>
+
+       * rtl.h (simplify_gen_relational): Add cmp_mode parameter.
+       * simplify-rtx.c (simplify_gen_relational): Likewise.
+
+       * simplify-rtx.c (simplify_replace_rtx): Handle relationals and MEMs.
+
+       * i386.h (VALID_SSE_REG_MODE): Accept MMX modes if SSE2
+       * i386.md (movsi_1, movdi2, movdi_1_rex64): Handle SSE2 moves.
+
+       * i386.md (negsf2, negdf2, abssf2, absdf2): Force operands to
+       registers in SSE case; fix handling of the immediates.
+       (negsf2_ifs, abssf2_ifs): Tweak constraints; require
+       operands to be in regsiters before reload.
+       (negdf2_ifs, absdf2_ifs): Likewise; disable for 64bit
+       (negdf2_ifs_rex64, absdf2_ifs_rtx64): New.
+       (abstf,absxf,negtf,negxf splitters): Compute
+       properly the regnum for x86_64.
+       (avsdf2_if_rex64): New.
+
 Sat Apr 28 10:36:23 2001  Jeffrey A Law  (law@cygnus.com)
 
        * flow.c (propagate_block_delete_insn): Handle deletion of ADDR_VEC
index 10a0edb1d0d36aaa26bbe8243754d218083a44a7..626ca2777e702bc4b19631b7dd7cf66c76fc05f1 100644 (file)
@@ -861,7 +861,8 @@ extern int ix86_arch;
 
 #define VALID_SSE_REG_MODE(MODE) \
     ((MODE) == TImode || (MODE) == V4SFmode || (MODE) == V4SImode \
-     || (MODE) == SFmode || (TARGET_SSE2 && (MODE) == DFmode))
+     || (MODE) == SFmode \
+     || (TARGET_SSE2 && ((MODE) == DFmode || VALID_MMX_REG_MODE (MODE))))
 
 #define VALID_MMX_REG_MODE(MODE) \
     ((MODE) == DImode || (MODE) == V8QImode || (MODE) == V4HImode \
index 2233c1464afabfd20b3aebb177011e9fb17666c5..7b55859c7b891a0a72ad402df200a6e8c04a6097 100644 (file)
    (set_attr "length_immediate" "1")])
 
 (define_insn "*movsi_1"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=*a,r,*a,m,!*y,!r")
-       (match_operand:SI 1 "general_operand" "im,rinm,rinm,rin,r,*y"))]
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=*a,r,*a,m,!*y,!rm,!*Y,!rm,!*Y")
+       (match_operand:SI 1 "general_operand" "im,rinm,rinm,rin,rm,*y,rm,*Y,*Y"))]
   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
   "*
 {
   switch (get_attr_type (insn))
     {
+    case TYPE_SSE:
+      if (get_attr_mode (insn) == TImode)
+        return \"movdqa\\t{%1, %0|%0, %1}\";
+      return \"movd\\t{%1, %0|%0, %1}\";
+
     case TYPE_MMX:
       return \"movd\\t{%1, %0|%0, %1}\";
 
     }
 }"
   [(set (attr "type")
-     (cond [(ior (match_operand:SI 0 "mmx_reg_operand" "")
-                (match_operand:SI 1 "mmx_reg_operand" ""))
+     (cond [(eq_attr "alternative" "4,5")
              (const_string "mmx")
+           (eq_attr "alternative" "6,7,8")
+             (const_string "sse")
            (and (ne (symbol_ref "flag_pic") (const_int 0))
                 (match_operand:SI 1 "symbolic_operand" ""))
              (const_string "lea")
           ]
           (const_string "imov")))
-   (set_attr "modrm" "0,*,0,*,*,*")
-   (set_attr "mode" "SI")])
+   (set_attr "modrm" "0,*,0,*,*,*,*,*,*")
+   (set_attr "mode" "SI,SI,SI,SI,SI,SI,TI,SI,SI")])
 
 ;; Stores and loads of ax to arbitary constant address.
 ;; We fake an second form of instruction to force reload to load address
    (set_attr "length_immediate" "1")])
 
 (define_insn "*movdi_2"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y")
-       (match_operand:DI 1 "general_operand" "riFo,riF,*y,m"))]
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,*Y,!*Y")
+       (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
   "!TARGET_64BIT
    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
   "@
    #
    #
    movq\\t{%1, %0|%0, %1}
+   movq\\t{%1, %0|%0, %1}
+   movq\\t{%1, %0|%0, %1}
+   movdqa\\t{%1, %0|%0, %1}
    movq\\t{%1, %0|%0, %1}"
-  [(set_attr "type" "*,*,mmx,mmx")])
+  [(set_attr "type" "*,*,mmx,mmx,sse,sse,sse")
+   (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
 
 (define_split
   [(set (match_operand:DI 0 "push_operand" "")
   "ix86_split_long_move (operands); DONE;")
 
 (define_insn "*movdi_1_rex64"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!m*y,!*y,m*Y,*Y")
-       (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,m,*Y,*m"))]
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!m*y,!*y,!*Y,!m,!*Y")
+       (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,m,*Y,*Y,*m"))]
   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
    && TARGET_64BIT"
   "*
   switch (get_attr_type (insn))
     {
     case TYPE_SSE:
+      if (register_operand (operands[0], DImode)
+         && register_operand (operands[1], DImode))
+         return \"movdqa\\t{%1, %0|%0, %1}\";
+      /* FALLTHRU */
     case TYPE_MMX:
-      return \"movd\\t{%1, %0|%0, %1}\";
+      return \"movq\\t{%1, %0|%0, %1}\";
     case TYPE_MULTI:
       return \"#\";
     case TYPE_LEA:
              (const_string "lea")
           ]
           (const_string "imov")))
-   (set_attr "modrm" "*,0,0,*,*,*,*,*,*")
-   (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*")
-   (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI")])
+   (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*")
+   (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*")
+   (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI")])
 
 ;; Stores and loads of ax to arbitary constant address.
 ;; We fake an second form of instruction to force reload to load address
          /* Using SSE is tricky, since we need bitwise negation of -0
             in register.  */
          rtx reg = gen_reg_rtx (SFmode);
+         rtx dest = operands[0];
+
+         operands[1] = force_reg (SFmode, operands[1]);
+         operands[0] = force_reg (SFmode, operands[0]);
          emit_move_insn (reg,
                          gen_lowpart (SFmode,
-                                      trunc_int_for_mode (0x80000000,
-                                                          SImode)));
+                                      GEN_INT (trunc_int_for_mode (0x80000000,
+                                                                   SImode))));
          emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
+         if (dest != operands[0])
+           emit_move_insn (dest, operands[0]);
        }
        DONE;
      }
   "#")
 
 (define_insn "negsf2_ifs"
-  [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,r#xf")
+  [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
        (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
-   (use (match_operand:SF 2 "nonmemory_operand" "x#x,0#x,*X#x,*X#x"))
+   (use (match_operand:SF 2 "nonmemory_operand" "x,0#x,*g#x,*g#x"))
    (clobber (reg:CC 17))]
-  "TARGET_SSE"
+  "TARGET_SSE
+   && (reload_in_progress || reload_completed
+       || (register_operand (operands[0], VOIDmode)
+          && register_operand (operands[1], VOIDmode)))"
   "#")
 
 (define_split
                   (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
              (clobber (reg:CC 17))])]
   "TARGET_80387"
-  "if (TARGET_SSE)
+  "if (TARGET_SSE2)
      {
        /* In case operand is in memory,  we will not use SSE.  */
        if (memory_operand (operands[0], VOIDmode)
             in register.  */
          rtx reg = gen_reg_rtx (DFmode);
 #if HOST_BITS_PER_WIDE_INT >= 64
-         rtx imm = GEN_INT (0x80000000);
+         rtx imm = GEN_INT (trunc_int_for_mode(((HOST_WIDE_INT)1) << 63,
+                                               DImode));
 #else
          rtx imm = immed_double_const (0, 0x80000000, DImode);
 #endif
+         rtx dest = operands[0];
+
+         operands[1] = force_reg (DFmode, operands[1]);
+         operands[0] = force_reg (DFmode, operands[0]);
          emit_move_insn (reg, gen_lowpart (DFmode, imm));
          emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
+         if (dest != operands[0])
+           emit_move_insn (dest, operands[0]);
        }
        DONE;
      }
   "#")
 
 (define_insn "negdf2_ifs"
-  [(set (match_operand:DF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,r#xf")
-       (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,x#fr,0,0")))
-   (use (match_operand:DF 2 "nonmemory_operand" "x#x,0#x,*X#x,*X#x"))
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
+       (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
+   (use (match_operand:DF 2 "nonmemory_operand" "Y,0,*g#Y,*g#Y"))
    (clobber (reg:CC 17))]
-  "TARGET_SSE"
+  "TARGET_SSE2 && !TARGET_64BIT
+   && (reload_in_progress || reload_completed
+       || (register_operand (operands[0], VOIDmode)
+          && register_operand (operands[1], VOIDmode)))"
+  "#")
+
+(define_insn "*negdf2_ifs_rex64"
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,fm#Yr,r#Yf")
+       (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
+   (use (match_operand:DF 2 "general_operand" "Y,0,*g#Yr,*rm"))
+   (clobber (reg:CC 17))]
+  "TARGET_SSE2 && TARGET_64BIT
+   && (reload_in_progress || reload_completed
+       || (register_operand (operands[0], VOIDmode)
+          && register_operand (operands[1], VOIDmode)))"
   "#")
 
 (define_split
        (neg:DF (match_operand:DF 1 "register_operand" "")))
    (use (match_operand:DF 2 "" ""))
    (clobber (reg:CC 17))]
-  "reload_completed && !SSE_REG_P (operands[0])"
+  "reload_completed && !SSE_REG_P (operands[0])
+   && (!TARGET_64BIT || FP_REG_P (operands[0]))"
   [(parallel [(set (match_dup 0)
                   (neg:DF (match_dup 1)))
              (clobber (reg:CC 17))])])
 
+(define_split
+  [(set (match_operand:DF 0 "register_operand" "")
+       (neg:DF (match_operand:DF 1 "register_operand" "")))
+   (use (match_operand:DF 2 "" ""))
+   (clobber (reg:CC 17))]
+  "reload_completed && GENERAL_REG_P (operands[0]) && TARGET_64BIT"
+  [(parallel [(set (match_dup 0)
+                  (xor:DI (match_dup 1) (match_dup 2)))
+             (clobber (reg:CC 17))])]
+   "operands[0] = gen_lowpart (DImode, operands[0]);
+    operands[1] = gen_lowpart (DImode, operands[1]);
+    operands[2] = gen_lowpart (DImode, operands[2]);")
+
 (define_split
   [(set (match_operand:DF 0 "register_operand" "")
        (neg:DF (match_operand:DF 1 "register_operand" "")))
   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
        (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
    (clobber (reg:CC 17))]
-  "TARGET_80387 && ix86_unary_operator_ok (NEG, DFmode, operands)"
+  "TARGET_80387 && !TARGET_64BIT
+   && ix86_unary_operator_ok (NEG, DFmode, operands)"
+  "#")
+
+;; FIXME: We should to allow integer registers here.  Problem is that
+;; we need another scratch register to get constant from.
+;; Forcing constant to mem if no register available in peep2 should be
+;; safe even for PIC mode, because of RIP relative addressing.
+(define_insn "*negdf2_if_rex64"
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
+       (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
+   (clobber (reg:CC 17))]
+  "TARGET_80387 && TARGET_64BIT
+   && ix86_unary_operator_ok (NEG, DFmode, operands)"
   "#")
 
 (define_split
   [(set (match_operand:DF 0 "register_operand" "")
        (neg:DF (match_operand:DF 1 "register_operand" "")))
    (clobber (reg:CC 17))]
-  "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
+  "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))
+   && !TARGET_64BIT"
   [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
              (clobber (reg:CC 17))])]
   "operands[4] = GEN_INT (trunc_int_for_mode (0x80000000, SImode));
   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
              (clobber (reg:CC 17))])]
   "operands[1] = GEN_INT (0x8000);
-   operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
+   operands[0] = gen_rtx_REG (SImode,
+                             true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
 
 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
              (clobber (reg:CC 17))])]
   "operands[1] = GEN_INT (0x8000);
-   operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
+   operands[0] = gen_rtx_REG (SImode,
+                             true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
 
 ;; Conditionize these after reload. If they matches before reload, we 
 ;; lose the clobber and ability to use integer instructions.
          /* Using SSE is tricky, since we need bitwise negation of -0
             in register.  */
          rtx reg = gen_reg_rtx (SFmode);
-         emit_move_insn (reg, gen_lowpart (SFmode, GEN_INT (0x80000000)));
+         rtx dest = operands[0];
+
+         operands[1] = force_reg (SFmode, operands[1]);
+         operands[0] = force_reg (SFmode, operands[0]);
+         emit_move_insn (reg,
+                         gen_lowpart (SFmode,
+                                      GEN_INT (trunc_int_for_mode (0x80000000,
+                                                                   SImode))));
          emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
+         if (dest != operands[0])
+           emit_move_insn (dest, operands[0]);
        }
        DONE;
      }
   "#")
 
 (define_insn "abssf2_ifs"
-  [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,f#xr,r#xf")
+  [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,f#xr,rm#xf")
        (abs:SF (match_operand:SF 1 "nonimmediate_operand" "x,0,0")))
-   (use (match_operand:SF 2 "nonmemory_operand" "*0#x,*X#x,*X#x"))
+   (use (match_operand:SF 2 "nonmemory_operand" "*0#x,*g#x,*g#x"))
    (clobber (reg:CC 17))]
-  "TARGET_SSE"
+  "TARGET_SSE
+   && (reload_in_progress || reload_completed
+       || (register_operand (operands[0], VOIDmode)
+          && register_operand (operands[1], VOIDmode)))"
   "#")
 
 (define_split
             in register.  */
          rtx reg = gen_reg_rtx (DFmode);
 #if HOST_BITS_PER_WIDE_INT >= 64
-         rtx imm = GEN_INT (0x80000000);
+         rtx imm = GEN_INT (trunc_int_for_mode(((HOST_WIDE_INT)1) << 63,
+                                               DImode));
 #else
          rtx imm = immed_double_const (0, 0x80000000, DImode);
 #endif
+         rtx dest = operands[0];
+
+         operands[1] = force_reg (DFmode, operands[1]);
+         operands[0] = force_reg (DFmode, operands[0]);
          emit_move_insn (reg, gen_lowpart (DFmode, imm));
          emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
+         if (dest != operands[0])
+           emit_move_insn (dest, operands[0]);
        }
        DONE;
      }
   "#")
 
 (define_insn "absdf2_ifs"
-  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,f#Yr,r#Yf")
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,mf#Yr,mr#Yf")
        (abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0,0")))
-   (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*X#Y,*X#Y"))
+   (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*g#Y,*g#Y"))
    (clobber (reg:CC 17))]
-  "TARGET_SSE2"
+  "TARGET_SSE2 && !TARGET_64BIT
+   && (reload_in_progress || reload_completed
+       || (register_operand (operands[0], VOIDmode)
+          && register_operand (operands[1], VOIDmode)))"
+  "#")
+
+(define_insn "*absdf2_ifs_rex64"
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,mf#Yr")
+       (abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0")))
+   (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*g#Y"))
+   (clobber (reg:CC 17))]
+  "TARGET_SSE2 && TARGET_64BIT
+   && (reload_in_progress || reload_completed
+       || (register_operand (operands[0], VOIDmode)
+          && register_operand (operands[1], VOIDmode)))"
   "#")
 
 (define_split
   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
        (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
    (clobber (reg:CC 17))]
-  "TARGET_80387 && ix86_unary_operator_ok (ABS, DFmode, operands)"
+  "TARGET_80387 && !TARGET_64BIT
+   && ix86_unary_operator_ok (ABS, DFmode, operands)"
+  "#")
+
+;; FIXME: We should to allow integer registers here.  Problem is that
+;; we need another scratch register to get constant from.
+;; Forcing constant to mem if no register available in peep2 should be
+;; safe even for PIC mode, because of RIP relative addressing.
+(define_insn "*absdf2_if_rex64"
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
+       (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
+   (clobber (reg:CC 17))]
+  "TARGET_80387 && TARGET_64BIT
+   && ix86_unary_operator_ok (ABS, DFmode, operands)"
   "#")
 
 (define_split
   [(set (match_operand:DF 0 "register_operand" "")
        (abs:DF (match_operand:DF 1 "register_operand" "")))
    (clobber (reg:CC 17))]
-  "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
+  "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))
+   && !TARGET_64BIT"
   [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
              (clobber (reg:CC 17))])]
   "operands[4] = GEN_INT (trunc_int_for_mode (~0x80000000, SImode));
   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
              (clobber (reg:CC 17))])]
-  "operands[1] = GEN_INT (trunc_int_for_mode (~0x8000, SImode));
-   operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
+  "operands[1] = GEN_INT (~0x8000);
+   operands[0] = gen_rtx_REG (SImode,
+                             true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
 
 (define_insn "*abstf2_if"
   [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
   "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
              (clobber (reg:CC 17))])]
-  "operands[1] = GEN_INT (trunc_int_for_mode (~0x8000, SImode));
-   operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
+  "operands[1] = GEN_INT (~0x8000);
+   operands[0] = gen_rtx_REG (SImode,
+                             true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
 
 (define_insn "*abssf2_1"
   [(set (match_operand:SF 0 "register_operand" "=f")
index fad47cf31fb7f968a53d12b774c908ad51ac4707..4b1051c0b53cbe3434f39b9ffb9481fcab3e08cb 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1317,6 +1317,7 @@ extern rtx simplify_gen_ternary           PARAMS ((enum rtx_code,
                                                 enum machine_mode,
                                                 rtx, rtx, rtx));
 extern rtx simplify_gen_relational     PARAMS ((enum rtx_code,
+                                                enum machine_mode,
                                                 enum machine_mode,
                                                 rtx, rtx));
 extern rtx simplify_replace_rtx                PARAMS ((rtx, rtx, rtx));
index af8b708977c3fe014a9fe6dc71d3bb69b9dbb500..a5e09a75f9a9be6a930b662c1bde173dba6b928e 100644 (file)
@@ -177,17 +177,20 @@ simplify_gen_ternary (code, mode, op0_mode, op0, op1, op2)
   return gen_rtx_fmt_eee (code, mode, op0, op1, op2);
 }
 \f
-/* Likewise, for relational operations.  */
+/* Likewise, for relational operations.
+   CMP_MODE specifies mode comparison is done in.
+  */
 
 rtx
-simplify_gen_relational (code, mode, op0, op1)
+simplify_gen_relational (code, mode, cmp_mode, op0, op1)
      enum rtx_code code;
      enum machine_mode mode;
+     enum machine_mode cmp_mode;
      rtx op0, op1;
 {
   rtx tem;
 
-  if ((tem = simplify_relational_operation (code, mode, op0, op1)) != 0)
+  if ((tem = simplify_relational_operation (code, cmp_mode, op0, op1)) != 0)
     return tem;
 
   /* Put complex operands first and constants second.  */
@@ -238,6 +241,14 @@ simplify_replace_rtx (x, old, new)
        simplify_gen_binary (code, mode,
                             simplify_replace_rtx (XEXP (x, 0), old, new),
                             simplify_replace_rtx (XEXP (x, 1), old, new));
+    case '<':
+      return
+       simplify_gen_relational (code, mode,
+                                (GET_MODE (XEXP (x, 0)) != VOIDmode
+                                 ? GET_MODE (XEXP (x, 0))
+                                 : GET_MODE (XEXP (x, 1))),
+                                simplify_replace_rtx (XEXP (x, 0), old, new),
+                                simplify_replace_rtx (XEXP (x, 1), old, new));
 
     case '3':
     case 'b':
@@ -258,8 +269,27 @@ simplify_replace_rtx (x, old, new)
       return x;
 
     default:
+      if (GET_CODE (x) == MEM)
+       {
+         /* We can't use change_address here, since it verifies memory address
+            for corectness.  We don't want such check, since we may handle
+            addresses previously incorect (such as ones in push instructions)
+            and it is caller's work to verify whether resulting insn match.  */
+         rtx addr = simplify_replace_rtx (XEXP (x, 0), old, new);
+         rtx mem;
+         if (XEXP (x, 0) != addr)
+           {
+             mem = gen_rtx_MEM (GET_MODE (x), addr);
+             MEM_COPY_ATTRIBUTES (mem, x);
+           }
+         else
+           mem = x;
+         return mem;
+       }
+
       return x;
     }
+  return x;
 }
 \f
 /* Try to simplify a unary operation CODE whose output mode is to be