This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Patch RFC IA64] Fixing predication & autoinc interaction
- From: Steve Ellcey <sje at cup dot hp dot com>
- To: gcc-patches at gcc dot gnu dot org, wilson at codesourcery dot com
- Cc: abel at ispras dot ru, amonakov at ispras dot ru, maxim at codesourcery dot com
- Date: Thu, 24 Sep 2009 13:46:46 -0700 (PDT)
- Subject: [Patch RFC IA64] Fixing predication & autoinc interaction
- Reply-to: sje at cup dot hp dot com
I would like to get some feedback on this proposed patch to fix an IA64
bug that is caused by the interaction of predication and autoincrement.
The problem is that GCC is generating predicated instructions that
use autoincrement but if the predicated instruction is not executed
then the autoincrement does not happen and we get incorrect results.
My fix is to break the instructions that allow both predication and
autoincrement modes into two insructions, one that does not allow
autoincrement (but is otherwise identical) and one that allows
autoincrement but has the "predicable" attibute set to "no" so that
it won't be used as a predicated instruction. This seems to be working
but I thought I would see if anyone had any comments on my approach
or ideas on a better way to do this.
I haven't yet addressed the speculative and advanced loads but I think
I need to do those too. Can they be used as predicated instructions?
And I did not create predicated versions of the spill and restore
instructions used by the function prologue and epilogue since I didn't
think those would ever be used in a situation where they would be predicated.
I did explicitly set 'predicable' to no for them though just to be sure they
wouldn't get used this way.
Comments?
Steve Ellcey
sje@cup.hp.com
2009-09-24 Steve Ellcey <sje@cup.hp.com>
PR target/41365
* config/ia64/predicates.md (not_postinc_destination_operand): New.
(not_postinc_general_operand): New.
(not_postinc_move_operand): New.
(not_postinc_gr_nonimmediate_operand): New.
(not_postinc_grfr_nonimmediate_operand): New.
* config/ia64/vect.md (*mov<mode>_internal): Disallow autoinc.
(*movv2sf_internal): Ditto.
(*mov<mode>_internal_2): New.
(*movv2sf_internal_2): New.
* config/ia64/ia64.md (movbi, movqi_internal, movhi_internal,
movsi_internal, movdi_internal, movti_internal, movsf_internal,
movdf_internal, movxf_internal, movrf_internal, zero_extendqidi2,
zero_extendhidi2, zero_extendsidi2, *cmovdi_internal,
*cmovsi_internal, gr_spill_internal, gr_restore, fr_spill,
fr_restore): Disallow autoincrement.
(movbi_2, movqi_internal_2, movhi_internal_2, movsi_internal_2,
movdi_internal_2, movti_internal_2, movsf_internal_2, movdf_internal_2,
movxf_internal_2, movrf_internal_2, zero_extendqidi2_2,
zero_extendhidi2_2, zero_extendsidi2_2): New.
Index: config/ia64/predicates.md
===================================================================
--- config/ia64/predicates.md (revision 152088)
+++ config/ia64/predicates.md (working copy)
@@ -281,11 +281,23 @@ (define_predicate "destination_operand"
|| GET_CODE (XEXP (op, 0)) != POST_MODIFY
|| GET_CODE (XEXP (XEXP (XEXP (op, 0), 1), 1)) != REG")))
+;; Like destination_operand, but don't allow any post-increments.
+(define_predicate "not_postinc_destination_operand"
+ (and (match_operand 0 "nonimmediate_operand")
+ (match_test "GET_CODE (op) != MEM
+ || GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) != RTX_AUTOINC")))
+
;; Like memory_operand, but don't allow post-increments.
(define_predicate "not_postinc_memory_operand"
(and (match_operand 0 "memory_operand")
(match_test "GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) != RTX_AUTOINC")))
+;; Like general_operand but don't allow post-increments.
+(define_predicate "not_postinc_general_operand"
+ (and (match_operand 0 "general_operand")
+ (match_test "GET_CODE (op) != MEM
+ || GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) != RTX_AUTOINC")))
+
;; True if OP is a general operand, with some restrictions on symbols.
(define_predicate "move_operand"
(match_operand 0 "general_operand")
@@ -332,6 +344,12 @@ (define_predicate "move_operand"
}
})
+;; Like move_operand but don't allow post-increments.
+(define_predicate "not_postinc_move_operand"
+ (and (match_operand 0 "move_operand")
+ (match_test "GET_CODE (op) != MEM
+ || GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) != RTX_AUTOINC")))
+
;; True if OP is a register operand that is (or could be) a GR reg.
(define_predicate "gr_register_operand"
(match_operand 0 "register_operand")
@@ -385,6 +403,12 @@ (define_predicate "gr_nonimmediate_opera
return (regno >= FIRST_PSEUDO_REGISTER || GENERAL_REGNO_P (regno));
})
+;; Like gr_nonimmediate_operand, but don't allow any post-increments.
+(define_predicate "not_postinc_gr_nonimmediate_operand"
+ (and (match_operand 0 "gr_nonimmediate_operand")
+ (match_test "GET_CODE (op) != MEM
+ || GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) != RTX_AUTOINC")))
+
;; True if OP is a nonimmediate operand that is (or could be) a FR reg.
(define_predicate "fr_nonimmediate_operand"
(match_operand 0 "nonimmediate_operand")
@@ -417,6 +441,12 @@ (define_predicate "grfr_nonimmediate_ope
|| FR_REGNO_P (regno));
})
+;; Like grfr_nonimmediate_operand, but don't allow any post-increments.
+(define_predicate "not_postinc_grfr_nonimmediate_operand"
+ (and (match_operand 0 "grfr_nonimmediate_operand")
+ (match_test "GET_CODE (op) != MEM
+ || GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) != RTX_AUTOINC")))
+
;; True if OP is a GR register operand, or zero.
(define_predicate "gr_reg_or_0_operand"
(ior (match_operand 0 "gr_register_operand")
Index: config/ia64/vect.md
===================================================================
--- config/ia64/vect.md (revision 152088)
+++ config/ia64/vect.md (working copy)
@@ -37,24 +37,38 @@ (define_expand "mov<mode>"
})
(define_insn "*mov<mode>_internal"
- [(set (match_operand:VECINT 0 "destination_operand"
+ [(set (match_operand:VECINT 0 "not_postinc_destination_operand"
"=r,r,r,r,m ,*f ,*f,Q ,r ,*f")
- (match_operand:VECINT 1 "move_operand"
+ (match_operand:VECINT 1 "not_postinc_move_operand"
"rU,W,i,m,rU,U*f,Q ,*f,*f,r "))]
"ia64_move_ok (operands[0], operands[1])"
"@
mov %0 = %r1
addl %0 = %v1, r0
movl %0 = %v1
- ld8%O1 %0 = %1%P1
- st8%Q0 %0 = %r1%P0
+ ld8%O1 %0 = %1
+ st8%Q0 %0 = %r1
mov %0 = %F1
- ldf8 %0 = %1%P1
- stf8 %0 = %1%P0
+ ldf8 %0 = %1
+ stf8 %0 = %1
getf.sig %0 = %1
setf.sig %0 = %1"
[(set_attr "itanium_class" "ialu,ialu,long_i,ld,st,fmisc,fld,stf,frfr,tofr")])
+(define_insn "*mov<mode>_internal_2"
+ [(set (match_operand:VECINT 0 "destination_operand"
+ "=r,m ,*f,Q")
+ (match_operand:VECINT 1 "move_operand"
+ "m,rU,Q ,*f"))]
+ "ia64_move_ok (operands[0], operands[1])"
+ "@
+ ld8%O1 %0 = %1%P1
+ st8%Q0 %0 = %r1%P0
+ ldf8 %0 = %1%P1
+ stf8 %0 = %1%P0"
+ [(set_attr "itanium_class" "ld,st,fld,stf")
+ (set_attr "predicable" "no")])
+
(define_insn "one_cmpl<mode>2"
[(set (match_operand:VECINT 0 "gr_register_operand" "=r")
(not:VECINT (match_operand:VECINT 1 "gr_register_operand" "r")))]
@@ -851,22 +865,22 @@ (define_expand "movv2sf"
})
(define_insn "*movv2sf_internal"
- [(set (match_operand:V2SF 0 "destination_operand"
+ [(set (match_operand:V2SF 0 "not_postinc_destination_operand"
"=f,f,f,Q,*r ,*r,*r,*r,m ,f ,*r")
- (match_operand:V2SF 1 "move_operand"
+ (match_operand:V2SF 1 "not_postinc_move_operand"
"fU,Y,Q,f,U*r,W ,i ,m ,*r,*r,f "))]
"ia64_move_ok (operands[0], operands[1])"
{
static const char * const alt[] = {
"%,mov %0 = %F1",
"%,fpack %0 = %F2, %F1",
- "%,ldf8 %0 = %1%P1",
- "%,stf8 %0 = %1%P0",
+ "%,ldf8 %0 = %1%",
+ "%,stf8 %0 = %1%",
"%,mov %0 = %r1",
"%,addl %0 = %v1, r0",
"%,movl %0 = %v1",
- "%,ld8%O1 %0 = %1%P1",
- "%,st8%Q0 %0 = %r1%P0",
+ "%,ld8%O1 %0 = %1%",
+ "%,st8%Q0 %0 = %r1%",
"%,setf.sig %0 = %1",
"%,getf.sig %0 = %1"
};
@@ -881,6 +895,31 @@ (define_insn "*movv2sf_internal"
}
[(set_attr "itanium_class" "fmisc,fmisc,fld,stf,ialu,ialu,long_i,ld,st,tofr,frfr")])
+(define_insn "*movv2sf_internal_2"
+ [(set (match_operand:V2SF 0 "destination_operand"
+ "=f,Q,*r, m")
+ (match_operand:V2SF 1 "move_operand"
+ "Q,f, m,*r"))]
+ "ia64_move_ok (operands[0], operands[1])"
+{
+ static const char * const alt[] = {
+ "%,ldf8 %0 = %1%P1",
+ "%,stf8 %0 = %1%P0",
+ "%,ld8%O1 %0 = %1%P1",
+ "%,st8%Q0 %0 = %r1%P0",
+ };
+
+ if (which_alternative == 1)
+ {
+ operands[2] = XVECEXP (operands[1], 0, TARGET_BIG_ENDIAN ? 0 : 1);
+ operands[1] = XVECEXP (operands[1], 0, TARGET_BIG_ENDIAN ? 1 : 0);
+ }
+
+ return alt[which_alternative];
+}
+ [(set_attr "itanium_class" "fld,stf,ld,st")
+ (set_attr "predicable" "no")])
+
(define_insn "absv2sf2"
[(set (match_operand:V2SF 0 "fr_register_operand" "=f")
(abs:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")))]
Index: config/ia64/ia64.md
===================================================================
--- config/ia64/ia64.md (revision 152088)
+++ config/ia64/ia64.md (working copy)
@@ -230,8 +230,8 @@ (define_insn "*movcci"
(set_attr "predicable" "no")])
(define_insn "movbi"
- [(set (match_operand:BI 0 "destination_operand" "=c,c,?c,?*r, c,*r,*r,*m,*r")
- (match_operand:BI 1 "move_operand" " O,n, c, c,*r, n,*m,*r,*r"))]
+ [(set (match_operand:BI 0 "not_postinc_destination_operand" "=c,c,?c,?*r, c,*r,*r,*m,*r")
+ (match_operand:BI 1 "not_postinc_move_operand" " O,n, c, c,*r, n,*m,*r,*r"))]
""
"@
cmp.ne %0, %I0 = r0, r0
@@ -240,13 +240,25 @@ (define_insn "movbi"
#
tbit.nz %0, %I0 = %1, 0
adds %0 = %1, r0
- ld1%O1 %0 = %1%P1
- st1%Q0 %0 = %1%P0
+ ld1%O1 %0 = %1
+ st1%Q0 %0 = %1
mov %0 = %1"
[(set_attr "itanium_class" "icmp,icmp,unknown,unknown,tbit,ialu,ld,st,ialu")
(set_attr "speculable1" "yes")
(set_attr "speculable2" "no, no, no, no, no, no, yes,no,no")])
+(define_insn "movbi_2"
+ [(set (match_operand:BI 0 "destination_operand" "=*r,*m")
+ (match_operand:BI 1 "move_operand" "*m, *r"))]
+ ""
+ "@
+ ld1%O1 %0 = %1%P1
+ st1%Q0 %0 = %1%P0"
+ [(set_attr "itanium_class" "ld, st")
+ (set_attr "speculable1" "yes")
+ (set_attr "speculable2" "yes,no")
+ (set_attr "predicable" "no")])
+
(define_split
[(set (match_operand:BI 0 "register_operand" "")
(match_operand:BI 1 "register_operand" ""))]
@@ -285,14 +297,14 @@ (define_expand "movqi"
})
(define_insn "movqi_internal"
- [(set (match_operand:QI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
- (match_operand:QI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))]
+ [(set (match_operand:QI 0 "not_postinc_destination_operand" "=r,r,r, m, r,*f,*f")
+ (match_operand:QI 1 "not_postinc_move_operand" "rO,J,m,rO,*f,rO,*f"))]
"ia64_move_ok (operands[0], operands[1])"
"@
mov %0 = %r1
addl %0 = %1, r0
- ld1%O1 %0 = %1%P1
- st1%Q0 %0 = %r1%P0
+ ld1%O1 %0 = %1
+ st1%Q0 %0 = %r1
getf.sig %0 = %1
setf.sig %0 = %r1
mov %0 = %1"
@@ -300,6 +312,18 @@ (define_insn "movqi_internal"
(set_attr "speculable1" "yes")
(set_attr "speculable2" "no, no, yes,no,no, no, no")])
+(define_insn "movqi_internal_2"
+ [(set (match_operand:QI 0 "destination_operand" "=r,m")
+ (match_operand:QI 1 "move_operand" "m, rO"))]
+ "ia64_move_ok (operands[0], operands[1])"
+ "@
+ ld1%O1 %0 = %1%P1
+ st1%Q0 %0 = %r1%P0"
+ [(set_attr "itanium_class" "ld, st")
+ (set_attr "speculable1" "yes")
+ (set_attr "speculable2" "yes,no")
+ (set_attr "predicable" "no")])
+
(define_expand "movhi"
[(set (match_operand:HI 0 "general_operand" "")
(match_operand:HI 1 "general_operand" ""))]
@@ -312,14 +336,14 @@ (define_expand "movhi"
})
(define_insn "movhi_internal"
- [(set (match_operand:HI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
- (match_operand:HI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))]
+ [(set (match_operand:HI 0 "not_postinc_destination_operand" "=r,r,r, m, r,*f,*f")
+ (match_operand:HI 1 "not_postinc_move_operand" "rO,J,m,rO,*f,rO,*f"))]
"ia64_move_ok (operands[0], operands[1])"
"@
mov %0 = %r1
addl %0 = %1, r0
- ld2%O1 %0 = %1%P1
- st2%Q0 %0 = %r1%P0
+ ld2%O1 %0 = %1
+ st2%Q0 %0 = %r1
getf.sig %0 = %1
setf.sig %0 = %r1
mov %0 = %1"
@@ -327,6 +351,18 @@ (define_insn "movhi_internal"
(set_attr "speculable1" "yes")
(set_attr "speculable2" "no, no, yes,no,no, no, no")])
+(define_insn "movhi_internal_2"
+ [(set (match_operand:HI 0 "destination_operand" "=r,m")
+ (match_operand:HI 1 "move_operand" "m,rO"))]
+ "ia64_move_ok (operands[0], operands[1])"
+ "@
+ ld2%O1 %0 = %1%P1
+ st2%Q0 %0 = %r1%P0"
+ [(set_attr "itanium_class" "ld,st")
+ (set_attr "speculable1" "yes")
+ (set_attr "speculable2" "yes,no")
+ (set_attr "predicable" "no")])
+
(define_expand "movsi"
[(set (match_operand:SI 0 "general_operand" "")
(match_operand:SI 1 "general_operand" ""))]
@@ -339,16 +375,16 @@ (define_expand "movsi"
})
(define_insn "movsi_internal"
- [(set (match_operand:SI 0 "destination_operand" "=r,r,r,r,r, m, r,*f,*f, r,*d")
- (match_operand:SI 1 "move_operand" "rO,J,j,i,m,rO,*f,rO,*f,*d,rK"))]
+ [(set (match_operand:SI 0 "not_postinc_destination_operand" "=r,r,r,r,r, m, r,*f,*f, r,*d")
+ (match_operand:SI 1 "not_postinc_move_operand" "rO,J,j,i,m,rO,*f,rO,*f,*d,rK"))]
"ia64_move_ok (operands[0], operands[1])"
"@
mov %0 = %r1
addl %0 = %1, r0
addp4 %0 = %1 - 0x100000000, r0
movl %0 = %1
- ld4%O1 %0 = %1%P1
- st4%Q0 %0 = %r1%P0
+ ld4%O1 %0 = %1
+ st4%Q0 %0 = %r1
getf.sig %0 = %1
setf.sig %0 = %r1
mov %0 = %1
@@ -359,6 +395,18 @@ (define_insn "movsi_internal"
(set_attr "speculable1" "yes")
(set_attr "speculable2" "no, no, no, no, yes,no,no, no, no, no, no")])
+(define_insn "movsi_internal_2"
+ [(set (match_operand:SI 0 "destination_operand" "=r, m")
+ (match_operand:SI 1 "move_operand" " m,rO"))]
+ "ia64_move_ok (operands[0], operands[1])"
+ "@
+ ld4%O1 %0 = %1%P1
+ st4%Q0 %0 = %r1%P0"
+ [(set_attr "itanium_class" "ld,st")
+ (set_attr "speculable1" "yes")
+ (set_attr "speculable2" "yes,no")
+ (set_attr "predicable" "no")])
+
(define_expand "movdi"
[(set (match_operand:DI 0 "general_operand" "")
(match_operand:DI 1 "general_operand" ""))]
@@ -371,9 +419,9 @@ (define_expand "movdi"
})
(define_insn "movdi_internal"
- [(set (match_operand:DI 0 "destination_operand"
+ [(set (match_operand:DI 0 "not_postinc_destination_operand"
"=r,r,r,r,r, m, r,*f,*f,*f, Q, r,*b, r,*e, r,*d, r,*c")
- (match_operand:DI 1 "move_operand"
+ (match_operand:DI 1 "not_postinc_move_operand"
"rO,JT,j,i,m,rO,*f,rO,*f, Q,*f,*b,rO,*e,rK,*d,rK,*c,rO"))]
"ia64_move_ok (operands[0], operands[1])"
{
@@ -382,13 +430,13 @@ (define_insn "movdi_internal"
"%,addl %0 = %1, r0",
"%,addp4 %0 = %1 - 0x100000000, r0",
"%,movl %0 = %1",
- "%,ld8%O1 %0 = %1%P1",
- "%,st8%Q0 %0 = %r1%P0",
+ "%,ld8%O1 %0 = %1",
+ "%,st8%Q0 %0 = %r1",
"%,getf.sig %0 = %1",
"%,setf.sig %0 = %r1",
"%,mov %0 = %1",
- "%,ldf8 %0 = %1%P1",
- "%,stf8 %0 = %1%P0",
+ "%,ldf8 %0 = %1",
+ "%,stf8 %0 = %1",
"%,mov %0 = %1",
"%,mov %0 = %r1",
"%,mov %0 = %1",
@@ -408,6 +456,26 @@ (define_insn "movdi_internal"
(set_attr "speculable1" "yes")
(set_attr "speculable2" "no, no, no, no, yes,no,no, no, no, yes,no, no, no, no, no, no, no, no, no")])
+(define_insn "movdi_internal_2"
+ [(set (match_operand:DI 0 "destination_operand"
+ "=r, m, *f, Q")
+ (match_operand:DI 1 "move_operand"
+ "m,rO, Q,*f"))]
+ "ia64_move_ok (operands[0], operands[1])"
+{
+ static const char * const alt[] = {
+ "ld8%O1 %0 = %1%P1",
+ "st8%Q0 %0 = %r1%P0",
+ "ldf8 %0 = %1%P1",
+ "stf8 %0 = %1%P0",
+ };
+ return alt[which_alternative];
+}
+ [(set_attr "itanium_class" "ld, st,fld,stf")
+ (set_attr "speculable1" "yes")
+ (set_attr "speculable2" "yes,no,yes,no")
+ (set_attr "predicable" "no")])
+
(define_mode_iterator MODE [BI QI HI SI DI SF DF XF TI])
(define_mode_iterator MODE_FOR_CMP [BI SI DI SF DF XF (TF "TARGET_HPUX")])
(define_mode_iterator MODE_FOR_EXTEND [QI HI SI])
@@ -951,13 +1019,13 @@ (define_expand "movti"
})
(define_insn_and_split "movti_internal"
- [(set (match_operand:TI 0 "destination_operand" "=r, *fm,*x,*f, Q")
- (match_operand:TI 1 "general_operand" "r*fim,r, Q, *fOQ,*f"))]
+ [(set (match_operand:TI 0 "not_postinc_destination_operand" "=r, *fm,*x,*f, Q")
+ (match_operand:TI 1 "not_postinc_general_operand" "r*fim,r, Q, *fOQ,*f"))]
"ia64_move_ok (operands[0], operands[1])"
"@
#
#
- ldfp8 %X0 = %1%P1
+ ldfp8 %X0 = %1
#
#"
"reload_completed && !ia64_load_pair_ok(operands[0], operands[1])"
@@ -970,6 +1038,23 @@ (define_insn_and_split "movti_internal"
(set_attr "speculable1" "yes")
(set_attr "speculable2" "no, no, yes, no, no")])
+(define_insn_and_split "movti_internal_2"
+ [(set (match_operand:TI 0 "destination_operand" "=*x")
+ (match_operand:TI 1 "general_operand" "Q"))]
+ "ia64_move_ok (operands[0], operands[1])"
+ "@
+ ldfp8 %X0 = %1%P1"
+ "reload_completed && !ia64_load_pair_ok(operands[0], operands[1])"
+ [(const_int 0)]
+{
+ ia64_split_tmode_move (operands);
+ DONE;
+}
+ [(set_attr "itanium_class" "fldp")
+ (set_attr "speculable1" "yes")
+ (set_attr "speculable2" "yes")
+ (set_attr "predicable" "no")])
+
;; Floating Point Moves
;;
;; Note - Patterns for SF mode moves are compulsory, but
@@ -987,23 +1072,36 @@ (define_expand "movsf"
})
(define_insn "movsf_internal"
- [(set (match_operand:SF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m,*r")
- (match_operand:SF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r, F"))]
+ [(set (match_operand:SF 0 "not_postinc_destination_operand" "=f,f, Q,*r, f,*r,*r, m,*r")
+ (match_operand:SF 1 "not_postinc_general_operand" "fG,Q,fG,fG,*r,*r, m,*r, F"))]
"ia64_move_ok (operands[0], operands[1])"
"@
mov %0 = %F1
- ldfs %0 = %1%P1
- stfs %0 = %F1%P0
+ ldfs %0 = %1
+ stfs %0 = %F1
getf.s %0 = %F1
setf.s %0 = %1
mov %0 = %1
- ld4%O1 %0 = %1%P1
- st4%Q0 %0 = %1%P0
+ ld4%O1 %0 = %1
+ st4%Q0 %0 = %1
movl %0 = %G1"
[(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st,long_i")
(set_attr "speculable1" "yes")
(set_attr "speculable2" "no, yes,no, no, no, no, yes,no,no")])
+(define_insn "movsf_internal_2"
+ [(set (match_operand:SF 0 "destination_operand" "=f, Q,*r, m")
+ (match_operand:SF 1 "general_operand" "Q, fG, m,*r"))]
+ "ia64_move_ok (operands[0], operands[1])"
+ "@
+ ldfs %0 = %1%P1
+ stfs %0 = %F1%P0
+ ld4%O1 %0 = %1%P1
+ st4%Q0 %0 = %1%P0"
+ [(set_attr "itanium_class" "fld,stf,ld, st")
+ (set_attr "speculable1" "yes")
+ (set_attr "speculable2" "yes,no, yes,no")])
+
(define_expand "movdf"
[(set (match_operand:DF 0 "general_operand" "")
(match_operand:DF 1 "general_operand" ""))]
@@ -1016,23 +1114,37 @@ (define_expand "movdf"
})
(define_insn "movdf_internal"
- [(set (match_operand:DF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m,*r")
- (match_operand:DF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r, F"))]
+ [(set (match_operand:DF 0 "not_postinc_destination_operand" "=f,f, Q,*r, f,*r,*r, m,*r")
+ (match_operand:DF 1 "not_postinc_general_operand" "fG,Q,fG,fG,*r,*r, m,*r, F"))]
"ia64_move_ok (operands[0], operands[1])"
"@
mov %0 = %F1
- ldfd %0 = %1%P1
- stfd %0 = %F1%P0
+ ldfd %0 = %1
+ stfd %0 = %F1
getf.d %0 = %F1
setf.d %0 = %1
mov %0 = %1
- ld8%O1 %0 = %1%P1
- st8%Q0 %0 = %1%P0
+ ld8%O1 %0 = %1
+ st8%Q0 %0 = %1
movl %0 = %G1"
[(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st,long_i")
(set_attr "speculable1" "yes")
(set_attr "speculable2" "no, yes,no, no, no, no, yes,no,no")])
+(define_insn "movdf_internal_2"
+ [(set (match_operand:DF 0 "destination_operand" "=f,Q,*r, m")
+ (match_operand:DF 1 "general_operand" "Q, fG,m,*r"))]
+ "ia64_move_ok (operands[0], operands[1])"
+ "@
+ ldfd %0 = %1%P1
+ stfd %0 = %F1%P0
+ ld8%O1 %0 = %1%P1
+ st8%Q0 %0 = %1%P0"
+ [(set_attr "itanium_class" "fld,stf,ld,st")
+ (set_attr "speculable1" "yes")
+ (set_attr "speculable2" "yes,no, yes,no")
+ (set_attr "predicable" "no")])
+
;; With no offsettable memory references, we've got to have a scratch
;; around to play with the second word if the variable winds up in GRs.
(define_expand "movxf"
@@ -1047,17 +1159,29 @@ (define_expand "movxf"
;; ??? There's no easy way to mind volatile acquire/release semantics.
(define_insn "movxf_internal"
- [(set (match_operand:XF 0 "destination_operand" "=f,f, m")
- (match_operand:XF 1 "general_operand" "fG,m,fG"))]
+ [(set (match_operand:XF 0 "not_postinc_destination_operand" "=f,f, m")
+ (match_operand:XF 1 "not_postinc_general_operand" "fG,m,fG"))]
"ia64_move_ok (operands[0], operands[1])"
"@
mov %0 = %F1
- ldfe %0 = %1%P1
- stfe %0 = %F1%P0"
+ ldfe %0 = %1
+ stfe %0 = %F1"
[(set_attr "itanium_class" "fmisc,fld,stf")
(set_attr "speculable1" "yes")
(set_attr "speculable2" "no, yes,no")])
+(define_insn "movxf_internal_2"
+ [(set (match_operand:XF 0 "destination_operand" "=f, m")
+ (match_operand:XF 1 "general_operand" "m,fG"))]
+ "ia64_move_ok (operands[0], operands[1])"
+ "@
+ ldfe %0 = %1%P1
+ stfe %0 = %F1%P0"
+ [(set_attr "itanium_class" "fld,stf")
+ (set_attr "speculable1" "yes")
+ (set_attr "speculable2" "yes,no")
+ (set_attr "predicable" "no")])
+
;; Same as for movxf, but for RFmode.
(define_expand "movrf"
[(set (match_operand:RF 0 "general_operand" "")
@@ -1069,14 +1193,24 @@ (define_expand "movrf"
})
(define_insn "*movrf_internal"
- [(set (match_operand:RF 0 "destination_operand" "=f,f, m")
- (match_operand:RF 1 "general_operand" "fG,m,fG"))]
+ [(set (match_operand:RF 0 "not_postinc_destination_operand" "=f,f, m")
+ (match_operand:RF 1 "not_postinc_general_operand" "fG,m,fG"))]
"ia64_move_ok (operands[0], operands[1])"
"@
mov %0 = %F1
+ ldf.fill %0 = %1
+ stf.spill %0 = %F1"
+ [(set_attr "itanium_class" "fmisc,fld,stf")])
+
+(define_insn "*movrf_internal_2"
+ [(set (match_operand:RF 0 "destination_operand" "=f, m")
+ (match_operand:RF 1 "general_operand" "m,fG"))]
+ "ia64_move_ok (operands[0], operands[1])"
+ "@
ldf.fill %0 = %1%P1
stf.spill %0 = %F1%P0"
- [(set_attr "itanium_class" "fmisc,fld,stf")])
+ [(set_attr "itanium_class" "fld,stf")
+ (set_attr "predicable" "no")])
;; Better code generation via insns that deal with TFmode register pairs
;; directly. Same concerns apply as for TImode.
@@ -1141,39 +1275,73 @@ (define_insn "extendsidi2"
(define_insn "zero_extendqidi2"
[(set (match_operand:DI 0 "gr_register_operand" "=r,r")
- (zero_extend:DI (match_operand:QI 1 "gr_nonimmediate_operand" "r,m")))]
+ (zero_extend:DI (match_operand:QI 1 "not_postinc_gr_nonimmediate_operand" "r,m")))]
""
"@
zxt1 %0 = %1
- ld1%O1 %0 = %1%P1"
+ ld1%O1 %0 = %1"
[(set_attr "itanium_class" "xtd,ld")
(set_attr "speculable1" "yes")
(set_attr "speculable2" "no, yes")])
+(define_insn "zero_extendqidi2_2"
+ [(set (match_operand:DI 0 "gr_register_operand" "=r")
+ (zero_extend:DI (match_operand:QI 1 "gr_nonimmediate_operand" "m")))]
+ ""
+ "@
+ ld1%O1 %0 = %1%P1"
+ [(set_attr "itanium_class" "ld")
+ (set_attr "speculable1" "yes")
+ (set_attr "speculable2" "yes")
+ (set_attr "predicable" "no")])
+
(define_insn "zero_extendhidi2"
[(set (match_operand:DI 0 "gr_register_operand" "=r,r")
- (zero_extend:DI (match_operand:HI 1 "gr_nonimmediate_operand" "r,m")))]
+ (zero_extend:DI (match_operand:HI 1 "not_postinc_gr_nonimmediate_operand" "r,m")))]
""
"@
zxt2 %0 = %1
- ld2%O1 %0 = %1%P1"
+ ld2%O1 %0 = %1"
[(set_attr "itanium_class" "xtd,ld")
(set_attr "speculable1" "yes")
(set_attr "speculable2" "no, yes")])
+(define_insn "zero_extendhidi2_2"
+ [(set (match_operand:DI 0 "gr_register_operand" "=r")
+ (zero_extend:DI (match_operand:HI 1 "gr_nonimmediate_operand" "m")))]
+ ""
+ "@
+ ld2%O1 %0 = %1%P1"
+ [(set_attr "itanium_class" "ld")
+ (set_attr "speculable1" "yes")
+ (set_attr "speculable2" "yes")
+ (set_attr "predicable" "no")])
+
(define_insn "zero_extendsidi2"
[(set (match_operand:DI 0 "grfr_register_operand" "=r,r,?f")
(zero_extend:DI
- (match_operand:SI 1 "grfr_nonimmediate_operand" "r,m,f")))]
+ (match_operand:SI 1 "not_postinc_grfr_nonimmediate_operand" "r,m,f")))]
""
"@
addp4 %0 = %1, r0
- ld4%O1 %0 = %1%P1
+ ld4%O1 %0 = %1
fmix.r %0 = f0, %1"
[(set_attr "itanium_class" "ialu,ld,fmisc")
(set_attr "speculable1" "yes")
(set_attr "speculable2" "no, yes,no")])
+(define_insn "zero_extendsidi2_2"
+ [(set (match_operand:DI 0 "grfr_register_operand" "=r")
+ (zero_extend:DI
+ (match_operand:SI 1 "grfr_nonimmediate_operand" "m")))]
+ ""
+ "@
+ ld4%O1 %0 = %1%P1"
+ [(set_attr "itanium_class" "ld")
+ (set_attr "speculable1" "yes")
+ (set_attr "speculable2" "yes")
+ (set_attr "predicable" "no")])
+
;; Convert between floating point types of different sizes.
;; At first glance, it would appear that emitting fnorm for an extending
@@ -4083,16 +4251,16 @@ (define_insn_and_split "*seq_internal"
;;
(define_insn "*cmovdi_internal"
- [(set (match_operand:DI 0 "destination_operand"
+ [(set (match_operand:DI 0 "not_postinc_destination_operand"
"= r, r, r, r, r, r, r, r, r, r, m, Q, *f,*b,*d*e")
(if_then_else:DI
(match_operator 4 "predicate_operator"
[(match_operand:BI 1 "register_operand"
"c,c,c,c,c,c,c,c,c,c,c,c,c,c,c")
(const_int 0)])
- (match_operand:DI 2 "move_operand"
+ (match_operand:DI 2 "not_postinc_move_operand"
"rim, *f, *b,*d*e,rim,rim, rim,*f,*b,*d*e,rO,*f,rOQ,rO, rK")
- (match_operand:DI 3 "move_operand"
+ (match_operand:DI 3 "not_postinc_move_operand"
"rim,rim,rim, rim, *f, *b,*d*e,*f,*b,*d*e,rO,*f,rOQ,rO, rK")))]
"ia64_move_ok (operands[0], operands[2])
&& ia64_move_ok (operands[0], operands[3])"
@@ -4100,13 +4268,13 @@ (define_insn "*cmovdi_internal"
[(set_attr "predicable" "no")])
(define_split
- [(set (match_operand 0 "destination_operand" "")
+ [(set (match_operand 0 "not_postinc_destination_operand" "")
(if_then_else
(match_operator 4 "predicate_operator"
[(match_operand:BI 1 "register_operand" "")
(const_int 0)])
- (match_operand 2 "move_operand" "")
- (match_operand 3 "move_operand" "")))]
+ (match_operand 2 "not_postinc_move_operand" "")
+ (match_operand 3 "not_postinc_move_operand" "")))]
"reload_completed"
[(const_int 0)]
{
@@ -4188,14 +4356,14 @@ (define_split
;;
(define_insn "*cmovsi_internal"
- [(set (match_operand:SI 0 "destination_operand" "=r,m,*f,r,m,*f,r,m,*f")
+ [(set (match_operand:SI 0 "not_postinc_destination_operand" "=r,m,*f,r,m,*f,r,m,*f")
(if_then_else:SI
(match_operator 4 "predicate_operator"
[(match_operand:BI 1 "register_operand" "c,c,c,c,c,c,c,c,c")
(const_int 0)])
- (match_operand:SI 2 "move_operand"
+ (match_operand:SI 2 "not_postinc_move_operand"
"0,0,0,rim*f,rO,rO,rim*f,rO,rO")
- (match_operand:SI 3 "move_operand"
+ (match_operand:SI 3 "not_postinc_move_operand"
"rim*f,rO,rO,0,0,0,rim*f,rO,rO")))]
"ia64_move_ok (operands[0], operands[2])
&& ia64_move_ok (operands[0], operands[3])"
@@ -4724,7 +4892,8 @@ (define_insn "gr_spill_internal"
being automatically added before the .mem.offset directive. */
return ".mem.offset %2, 0\;%,st8.spill %0 = %1%P0";
}
- [(set_attr "itanium_class" "st")])
+ [(set_attr "itanium_class" "st")
+ (set_attr "predicable" "no")])
;; Reads ar.unat
(define_expand "gr_restore"
@@ -4744,7 +4913,8 @@ (define_insn "gr_restore_internal"
(use (match_operand:DI 3 "register_operand" ""))]
""
{ return ".mem.offset %2, 0\;%,ld8.fill %0 = %1%P1"; }
- [(set_attr "itanium_class" "ld")])
+ [(set_attr "itanium_class" "ld")
+ (set_attr "predicable" "no")])
(define_insn "fr_spill"
[(set (match_operand:XF 0 "destination_operand" "=m")
@@ -4752,7 +4922,8 @@ (define_insn "fr_spill"
UNSPEC_FR_SPILL))]
""
"stf.spill %0 = %1%P0"
- [(set_attr "itanium_class" "stf")])
+ [(set_attr "itanium_class" "stf")
+ (set_attr "predicable" "no")])
(define_insn "fr_restore"
[(set (match_operand:XF 0 "register_operand" "=f")
@@ -4760,7 +4931,8 @@ (define_insn "fr_restore"
UNSPEC_FR_RESTORE))]
""
"ldf.fill %0 = %1%P1"
- [(set_attr "itanium_class" "fld")])
+ [(set_attr "itanium_class" "fld")
+ (set_attr "predicable" "no")])
;; ??? The explicit stop is not ideal. It would be better if
;; rtx_needs_barrier took care of this, but this is something that can be