aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2001-04-28 21:16:30 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2001-04-28 19:16:30 +0000
commit141e454b1e21d8a832fe55f731f5f516278b54df (patch)
tree600f80e03a22ccdb9bfcc58f1635f187b941c104 /gcc
parent5bb86bf23de91f8495c4c9d578cf702a81624633 (diff)
downloadgcc-141e454b1e21d8a832fe55f731f5f516278b54df.zip
gcc-141e454b1e21d8a832fe55f731f5f516278b54df.tar.gz
gcc-141e454b1e21d8a832fe55f731f5f516278b54df.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog20
-rw-r--r--gcc/config/i386/i386.h3
-rw-r--r--gcc/config/i386/i386.md213
-rw-r--r--gcc/rtl.h1
-rw-r--r--gcc/simplify-rtx.c36
5 files changed, 224 insertions, 49 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3c47113..c15c7ff 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 10a0edb..626ca27 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 2233c14..7b55859 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,7 +9554,8 @@
(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))])])
@@ -9518,6 +9563,19 @@
(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" "")))
(use (match_operand:DF 2 "register_operand" ""))
(clobber (reg:CC 17))]
"reload_completed && SSE_REG_P (operands[0])"
@@ -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 fad47cf..4b1051c 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1318,6 +1318,7 @@ extern rtx simplify_gen_ternary PARAMS ((enum rtx_code,
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));
extern rtx simplify_rtx PARAMS ((rtx));
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index af8b708..a5e09a7 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