From 141e454b1e21d8a832fe55f731f5f516278b54df Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sat, 28 Apr 2001 21:16:30 +0200 Subject: [PATCH] rtl.h (simplify_gen_relational): Add cmp_mode parameter. * 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 | 20 ++++ gcc/config/i386/i386.h | 3 +- gcc/config/i386/i386.md | 213 +++++++++++++++++++++++++++++++--------- gcc/rtl.h | 1 + gcc/simplify-rtx.c | 36 ++++++- 5 files changed, 224 insertions(+), 49 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3c4711381ef..c15c7ffd139 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +Sat Apr 28 21:02:58 CEST 2001 Jan Hubicka + + * 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 diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 10a0edb1d0d..626ca2777e7 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -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 \ diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 2233c1464af..7b55859c7b8 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -1733,13 +1733,18 @@ (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}\"; @@ -1753,16 +1758,17 @@ } }" [(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 @@ -2463,16 +2469,20 @@ (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" "") @@ -2491,8 +2501,8 @@ "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" "* @@ -2500,8 +2510,12 @@ 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: @@ -2529,9 +2543,9 @@ (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 @@ -9337,11 +9351,17 @@ /* 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; } @@ -9355,11 +9375,14 @@ "#") (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 @@ -9457,7 +9480,7 @@ (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) @@ -9469,12 +9492,19 @@ 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; } @@ -9488,11 +9518,25 @@ "#") (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 @@ -9510,11 +9554,25 @@ (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" ""))) @@ -9542,7 +9600,20 @@ [(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 @@ -9558,7 +9629,8 @@ [(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)); @@ -9606,7 +9678,8 @@ [(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 @@ -9635,7 +9708,8 @@ [(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. @@ -9744,8 +9818,17 @@ /* 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; } @@ -9759,11 +9842,14 @@ "#") (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 @@ -9861,12 +9947,19 @@ 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; } @@ -9880,11 +9973,25 @@ "#") (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 @@ -9925,7 +10032,20 @@ [(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 @@ -9941,7 +10061,8 @@ [(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)); @@ -9988,8 +10109,9 @@ "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") @@ -10014,8 +10136,9 @@ "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") diff --git a/gcc/rtl.h b/gcc/rtl.h index fad47cf31fb..4b1051c0b53 100644 --- 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)); diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index af8b708977c..a5e09a75f9a 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -177,17 +177,20 @@ simplify_gen_ternary (code, mode, op0_mode, op0, op1, op2) return gen_rtx_fmt_eee (code, mode, op0, op1, op2); } -/* 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; } /* Try to simplify a unary operation CODE whose output mode is to be -- 2.30.2