;;- Machine description for HP PA-RISC architecture for GCC compiler
;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-;; 2002, 2003 Free Software Foundation, Inc.
+;; 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
;; Contributed by the Center for Software Science at the University
;; of Utah.
;; You should have received a copy of the GNU General Public License
;; along with GCC; see the file COPYING. If not, write to
-;; the Free Software Foundation, 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
;; This gcc Version 2 machine description is inspired by sparc.md and
;; mips.md.
;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
+;; Uses of UNSPEC in this file:
+
+(define_constants
+ [(UNSPEC_CFFC 0) ; canonicalize_funcptr_for_compare
+ (UNSPEC_GOTO 1) ; indirect_goto
+ (UNSPEC_DLTIND14R 2) ;
+ (UNSPEC_TP 3)
+ (UNSPEC_TLSGD 4)
+ (UNSPEC_TLSLDM 5)
+ (UNSPEC_TLSLDO 6)
+ (UNSPEC_TLSLDBASE 7)
+ (UNSPEC_TLSIE 8)
+ (UNSPEC_TLSLE 9)
+ (UNSPEC_TLSGD_PIC 10)
+ (UNSPEC_TLSLDM_PIC 11)
+ (UNSPEC_TLSIE_PIC 12)
+ ])
+
+;; UNSPEC_VOLATILE:
+
+(define_constants
+ [(UNSPECV_BLOCKAGE 0) ; blockage
+ (UNSPECV_DCACHE 1) ; dcacheflush
+ (UNSPECV_ICACHE 2) ; icacheflush
+ (UNSPECV_OPC 3) ; outline_prologue_call
+ (UNSPECV_OEC 4) ; outline_epilogue_call
+ (UNSPECV_LONGJMP 5) ; builtin_longjmp
+ ])
+
+;; Maximum pc-relative branch offsets.
+
+;; These numbers are a bit smaller than the maximum allowable offsets
+;; so that a few instructions may be inserted before the actual branch.
+
+(define_constants
+ [(MAX_12BIT_OFFSET 8184) ; 12-bit branch
+ (MAX_17BIT_OFFSET 262100) ; 17-bit branch
+ ])
+
;; Insn type. Used to default other attribute values.
;; type "unary" insns have one input operand (1) and one output operand (0)
;; type "binary" insns have two input operands (1,2) and one output (0)
(define_attr "type"
- "move,unary,binary,shift,nullshift,compare,load,store,uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,fpload,fpstore,fpalu,fpcc,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,multi,milli,parallel_branch"
+ "move,unary,binary,shift,nullshift,compare,load,store,uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,fpload,fpstore,fpalu,fpcc,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,multi,milli,parallel_branch,fpstore_load,store_fpload"
(const_string "binary"))
(define_attr "pa_combine_type"
(define_delay (eq_attr "type" "btable_branch,branch,parallel_branch")
[(eq_attr "in_branch_delay" "true") (nil) (nil)])
-;; Floating point conditional branch delay slot description and
+;; Floating point conditional branch delay slot description.
(define_delay (eq_attr "type" "fbranch")
[(eq_attr "in_branch_delay" "true")
(eq_attr "in_nullified_branch_delay" "true")
(eq_attr "cpu" "700"))
"mem_700*3")
-(define_insn_reservation "W11" 1
- (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,load,fpload,store,fpstore")
+(define_insn_reservation "W11" 5
+ (and (eq_attr "type" "fpstore_load")
+ (eq_attr "cpu" "700"))
+ "mem_700*5")
+
+(define_insn_reservation "W12" 6
+ (and (eq_attr "type" "store_fpload")
+ (eq_attr "cpu" "700"))
+ "mem_700*6")
+
+(define_insn_reservation "W13" 1
+ (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,load,fpload,store,fpstore,fpstore_load,store_fpload")
(eq_attr "cpu" "700"))
"dummy_700")
;; We have a bypass for all computations in the FP unit which feed an
;; FP store as long as the sizes are the same.
-(define_bypass 2 "W1,W2" "W10" "hppa_fpstore_bypass_p")
-(define_bypass 9 "W3" "W10" "hppa_fpstore_bypass_p")
-(define_bypass 11 "W4" "W10" "hppa_fpstore_bypass_p")
-(define_bypass 13 "W5" "W10" "hppa_fpstore_bypass_p")
-(define_bypass 17 "W6" "W10" "hppa_fpstore_bypass_p")
+(define_bypass 2 "W1,W2" "W10,W11" "hppa_fpstore_bypass_p")
+(define_bypass 9 "W3" "W10,W11" "hppa_fpstore_bypass_p")
+(define_bypass 11 "W4" "W10,W11" "hppa_fpstore_bypass_p")
+(define_bypass 13 "W5" "W10,W11" "hppa_fpstore_bypass_p")
+(define_bypass 17 "W6" "W10,W11" "hppa_fpstore_bypass_p")
;; We have an "anti-bypass" for FP loads which feed an FP store.
-(define_bypass 4 "W8" "W10" "hppa_fpstore_bypass_p")
+(define_bypass 4 "W8,W12" "W10,W11" "hppa_fpstore_bypass_p")
;; Function units for the 7100 and 7150. The 7100/7150 can dual-issue
;; floating point computations with non-floating point computations (fp loads
(eq_attr "cpu" "7100"))
"i_7100+mem_7100,mem_7100")
-(define_insn_reservation "X7" 1
- (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore")
+(define_insn_reservation "X7" 4
+ (and (eq_attr "type" "fpstore_load")
+ (eq_attr "cpu" "7100"))
+ "i_7100+mem_7100,mem_7100*3")
+
+(define_insn_reservation "X8" 4
+ (and (eq_attr "type" "store_fpload")
+ (eq_attr "cpu" "7100"))
+ "i_7100+mem_7100,mem_7100*3")
+
+(define_insn_reservation "X9" 1
+ (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,fpstore_load,store_fpload")
(eq_attr "cpu" "7100"))
"i_7100")
;; We have a bypass for all computations in the FP unit which feed an
;; FP store as long as the sizes are the same.
-(define_bypass 1 "X0" "X6" "hppa_fpstore_bypass_p")
-(define_bypass 7 "X1" "X6" "hppa_fpstore_bypass_p")
-(define_bypass 14 "X2" "X6" "hppa_fpstore_bypass_p")
+(define_bypass 1 "X0" "X6,X7" "hppa_fpstore_bypass_p")
+(define_bypass 7 "X1" "X6,X7" "hppa_fpstore_bypass_p")
+(define_bypass 14 "X2" "X6,X7" "hppa_fpstore_bypass_p")
;; We have an "anti-bypass" for FP loads which feed an FP store.
-(define_bypass 3 "X4" "X6" "hppa_fpstore_bypass_p")
+(define_bypass 3 "X4,X8" "X6,X7" "hppa_fpstore_bypass_p")
;; The 7100LC has three floating-point units: ALU, MUL, and DIV.
;; There's no value in modeling the ALU and MUL separately though
(eq_attr "cpu" "7100LC"))
"i1_7100lc+mem_7100lc,mem_7100lc")
-(define_insn_reservation "Y6" 1
+(define_insn_reservation "Y6" 4
+ (and (eq_attr "type" "fpstore_load")
+ (eq_attr "cpu" "7100LC"))
+ "i1_7100lc+mem_7100lc,mem_7100lc*3")
+
+(define_insn_reservation "Y7" 4
+ (and (eq_attr "type" "store_fpload")
+ (eq_attr "cpu" "7100LC"))
+ "i1_7100lc+mem_7100lc,mem_7100lc*3")
+
+(define_insn_reservation "Y8" 1
(and (eq_attr "type" "shift,nullshift")
(eq_attr "cpu" "7100LC,7200,7300"))
"i1_7100lc")
-(define_insn_reservation "Y7" 1
+(define_insn_reservation "Y9" 1
(and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,shift,nullshift")
(eq_attr "cpu" "7100LC,7200,7300"))
"(i0_7100lc|i1_7100lc)")
;; The 7200 has a store-load penalty
-(define_insn_reservation "Y8" 2
+(define_insn_reservation "Y10" 2
(and (eq_attr "type" "store")
(eq_attr "cpu" "7200"))
"i1_7100lc,mem_7100lc")
-(define_insn_reservation "Y9" 2
+(define_insn_reservation "Y11" 2
(and (eq_attr "type" "fpstore")
(eq_attr "cpu" "7200"))
"i1_7100lc,mem_7100lc")
+(define_insn_reservation "Y12" 4
+ (and (eq_attr "type" "fpstore_load")
+ (eq_attr "cpu" "7200"))
+ "i1_7100lc,mem_7100lc,i1_7100lc+mem_7100lc")
+
+(define_insn_reservation "Y13" 4
+ (and (eq_attr "type" "store_fpload")
+ (eq_attr "cpu" "7200"))
+ "i1_7100lc,mem_7100lc,i1_7100lc+mem_7100lc")
+
;; The 7300 has no penalty for store-store or store-load
-(define_insn_reservation "Y10" 2
+(define_insn_reservation "Y14" 2
(and (eq_attr "type" "store")
(eq_attr "cpu" "7300"))
"i1_7100lc")
-(define_insn_reservation "Y11" 2
+(define_insn_reservation "Y15" 2
(and (eq_attr "type" "fpstore")
(eq_attr "cpu" "7300"))
"i1_7100lc")
+(define_insn_reservation "Y16" 4
+ (and (eq_attr "type" "fpstore_load")
+ (eq_attr "cpu" "7300"))
+ "i1_7100lc,i1_7100lc+mem_7100lc")
+
+(define_insn_reservation "Y17" 4
+ (and (eq_attr "type" "store_fpload")
+ (eq_attr "cpu" "7300"))
+ "i1_7100lc,i1_7100lc+mem_7100lc")
+
;; We have an "anti-bypass" for FP loads which feed an FP store.
-(define_bypass 3 "Y3" "Y5,Y9,Y11" "hppa_fpstore_bypass_p")
+(define_bypass 3 "Y3,Y7,Y13,Y17" "Y5,Y6,Y11,Y12,Y15,Y16" "hppa_fpstore_bypass_p")
;; Scheduling for the PA8000 is somewhat different than scheduling for a
;; traditional architecture.
(eq_attr "cpu" "8000"))
"im_8000,rm_8000+store_8000")
+(define_insn_reservation "Z2" 0
+ (and (eq_attr "type" "fpstore_load,store_fpload")
+ (eq_attr "cpu" "8000"))
+ "im_8000,rm_8000+store_8000,im_8000,rm_8000")
+
;; We can issue and retire two non-memory operations per cycle with
;; a few exceptions (branches). This group catches those we want
;; to assume have zero latency.
-(define_insn_reservation "Z2" 0
+(define_insn_reservation "Z3" 0
(and
- (eq_attr "type" "!load,fpload,store,fpstore,uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch,fpcc,fpalu,fpmulsgl,fpmuldbl,fpsqrtsgl,fpsqrtdbl,fpdivsgl,fpdivdbl")
+ (eq_attr "type" "!load,fpload,store,fpstore,uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch,fpcc,fpalu,fpmulsgl,fpmuldbl,fpsqrtsgl,fpsqrtdbl,fpdivsgl,fpdivdbl,fpstore_load,store_fpload")
(eq_attr "cpu" "8000"))
"inm_8000,rnm_8000")
;; Branches use both slots in the non-memory issue and
;; retirement unit.
-(define_insn_reservation "Z3" 0
+(define_insn_reservation "Z4" 0
(and
(eq_attr "type" "uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch")
(eq_attr "cpu" "8000"))
;; They can issue/retire two at a time in the non-memory
;; units. We fix their latency at 2 cycles and they
;; are fully pipelined.
-(define_insn_reservation "Z4" 1
+(define_insn_reservation "Z5" 1
(and
(eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
(eq_attr "cpu" "8000"))
;; The fdivsqrt units are not pipelined and have a very long latency.
;; To keep the DFA from exploding, we do not show all the
;; reservations for the divsqrt unit.
-(define_insn_reservation "Z5" 17
+(define_insn_reservation "Z6" 17
(and
(eq_attr "type" "fpdivsgl,fpsqrtsgl")
(eq_attr "cpu" "8000"))
"inm_8000,fdivsqrt_8000*6,rnm_8000")
-(define_insn_reservation "Z6" 31
+(define_insn_reservation "Z7" 31
(and
(eq_attr "type" "fpdivdbl,fpsqrtdbl")
(eq_attr "cpu" "8000"))
"inm_8000,fdivsqrt_8000*6,rnm_8000")
+;; Operand and operator predicates and constraints
+(include "predicates.md")
+(include "constraints.md")
\f
;; Compare instructions.
;; This controls RTL generation and register allocation.
""
"*
{
- return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 0, insn);
+ return output_cbranch (operands, 0, insn);
}"
[(set_attr "type" "cbranch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 24)
(eq (symbol_ref "flag_pic") (const_int 0))
(const_int 20)]
(const_int 28)))])
""
"*
{
- return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 1, insn);
+ return output_cbranch (operands, 1, insn);
}"
[(set_attr "type" "cbranch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 24)
(eq (symbol_ref "flag_pic") (const_int 0))
(const_int 20)]
(const_int 28)))])
"TARGET_64BIT"
"*
{
- return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 0, insn);
+ return output_cbranch (operands, 0, insn);
}"
[(set_attr "type" "cbranch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 24)
(eq (symbol_ref "flag_pic") (const_int 0))
(const_int 20)]
(const_int 28)))])
"TARGET_64BIT"
"*
{
- return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 1, insn);
+ return output_cbranch (operands, 1, insn);
}"
[(set_attr "type" "cbranch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 24)
(eq (symbol_ref "flag_pic") (const_int 0))
(const_int 20)]
(const_int 28)))])
"TARGET_64BIT"
"*
{
- return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 0, insn);
+ return output_cbranch (operands, 0, insn);
}"
[(set_attr "type" "cbranch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 24)
(eq (symbol_ref "flag_pic") (const_int 0))
(const_int 20)]
(const_int 28)))])
"TARGET_64BIT"
"*
{
- return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 1, insn);
+ return output_cbranch (operands, 1, insn);
}"
[(set_attr "type" "cbranch")
(set (attr "length")
(cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 8184))
+ (const_int MAX_12BIT_OFFSET))
(const_int 4)
(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 262100))
+ (const_int MAX_17BIT_OFFSET))
(const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 24)
(eq (symbol_ref "flag_pic") (const_int 0))
(const_int 20)]
(const_int 28)))])
""
"*
{
- return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 0, insn, 0);
+ return output_bb (operands, 0, insn, 0);
}"
[(set_attr "type" "cbranch")
(set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
+ (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 4)
+ (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 24)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc)
"TARGET_64BIT"
"*
{
- return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 0, insn, 0);
+ return output_bb (operands, 0, insn, 0);
}"
[(set_attr "type" "cbranch")
(set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
+ (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 4)
+ (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 24)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc)
""
"*
{
- return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 1, insn, 0);
+ return output_bb (operands, 1, insn, 0);
}"
[(set_attr "type" "cbranch")
(set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
+ (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 4)
+ (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 24)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc)
"TARGET_64BIT"
"*
{
- return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 1, insn, 0);
+ return output_bb (operands, 1, insn, 0);
}"
[(set_attr "type" "cbranch")
(set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
+ (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 4)
+ (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 24)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc)
""
"*
{
- return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 0, insn, 1);
+ return output_bb (operands, 0, insn, 1);
}"
[(set_attr "type" "cbranch")
(set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
+ (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 4)
+ (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 24)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc)
"TARGET_64BIT"
"*
{
- return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 0, insn, 1);
+ return output_bb (operands, 0, insn, 1);
}"
[(set_attr "type" "cbranch")
(set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
+ (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 4)
+ (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 24)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc)
""
"*
{
- return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 1, insn, 1);
+ return output_bb (operands, 1, insn, 1);
}"
[(set_attr "type" "cbranch")
(set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
+ (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 4)
+ (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 24)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc)
"TARGET_64BIT"
"*
{
- return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 1, insn, 1);
+ return output_bb (operands, 1, insn, 1);
}"
[(set_attr "type" "cbranch")
(set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
+ (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 4)
+ (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 24)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 20)]
+ (const_int 28)))])
;; Branch on Variable Bit patterns.
(define_insn ""
""
"*
{
- return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 0, insn, 0);
+ return output_bvb (operands, 0, insn, 0);
}"
[(set_attr "type" "cbranch")
(set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
+ (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 4)
+ (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 24)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc)
"TARGET_64BIT"
"*
{
- return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 0, insn, 0);
+ return output_bvb (operands, 0, insn, 0);
}"
[(set_attr "type" "cbranch")
(set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
+ (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 4)
+ (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 24)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc)
""
"*
{
- return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 1, insn, 0);
+ return output_bvb (operands, 1, insn, 0);
}"
[(set_attr "type" "cbranch")
(set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
+ (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 4)
+ (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 24)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc)
"TARGET_64BIT"
"*
{
- return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 1, insn, 0);
+ return output_bvb (operands, 1, insn, 0);
}"
[(set_attr "type" "cbranch")
(set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
+ (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 4)
+ (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 24)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc)
""
"*
{
- return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 0, insn, 1);
+ return output_bvb (operands, 0, insn, 1);
}"
[(set_attr "type" "cbranch")
(set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
+ (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 4)
+ (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 24)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc)
"TARGET_64BIT"
"*
{
- return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 0, insn, 1);
+ return output_bvb (operands, 0, insn, 1);
}"
[(set_attr "type" "cbranch")
(set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
+ (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 4)
+ (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 24)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc)
""
"*
{
- return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 1, insn, 1);
+ return output_bvb (operands, 1, insn, 1);
}"
[(set_attr "type" "cbranch")
(set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
+ (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 4)
+ (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 24)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc)
"TARGET_64BIT"
"*
{
- return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 1, insn, 1);
+ return output_bvb (operands, 1, insn, 1);
}"
[(set_attr "type" "cbranch")
(set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
+ (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 4)
+ (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 24)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 20)]
+ (const_int 28)))])
;; Floating point branches
+
+;; ??? Nullification is handled differently from other branches.
+;; If nullification is specified, the delay slot is nullified on any
+;; taken branch regardless of branch direction.
(define_insn ""
[(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
- "! TARGET_SOFT_FLOAT"
+ "!TARGET_SOFT_FLOAT"
"*
{
- if (INSN_ANNULLED_BRANCH_P (insn))
- return \"ftest\;b,n %0\";
+ int length = get_attr_length (insn);
+ rtx xoperands[1];
+ int nullify, xdelay;
+
+ if (length < 16)
+ return \"ftest\;b%* %l0\";
+
+ if (dbr_sequence_length () == 0 || INSN_ANNULLED_BRANCH_P (insn))
+ {
+ nullify = 1;
+ xdelay = 0;
+ xoperands[0] = GEN_INT (length - 8);
+ }
+ else
+ {
+ nullify = 0;
+ xdelay = 1;
+ xoperands[0] = GEN_INT (length - 4);
+ }
+
+ if (nullify)
+ output_asm_insn (\"ftest\;add,tr %%r0,%%r0,%%r0\;b,n .+%0\", xoperands);
else
- return \"ftest\;b%* %0\";
+ output_asm_insn (\"ftest\;add,tr %%r0,%%r0,%%r0\;b .+%0\", xoperands);
+ return output_lbranch (operands[0], insn, xdelay);
}"
- [(set_attr "type" "fbranch")
- (set_attr "length" "8")])
+[(set_attr "type" "fbranch")
+ (set (attr "length")
+ (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 32)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 28)]
+ (const_int 36)))])
(define_insn ""
[(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))]
- "! TARGET_SOFT_FLOAT"
+ "!TARGET_SOFT_FLOAT"
"*
{
- if (INSN_ANNULLED_BRANCH_P (insn))
- return \"ftest\;add,tr %%r0,%%r0,%%r0\;b,n %0\";
- else
+ int length = get_attr_length (insn);
+ rtx xoperands[1];
+ int nullify, xdelay;
+
+ if (length < 16)
return \"ftest\;add,tr %%r0,%%r0,%%r0\;b%* %0\";
+
+ if (dbr_sequence_length () == 0 || INSN_ANNULLED_BRANCH_P (insn))
+ {
+ nullify = 1;
+ xdelay = 0;
+ xoperands[0] = GEN_INT (length - 4);
+ }
+ else
+ {
+ nullify = 0;
+ xdelay = 1;
+ xoperands[0] = GEN_INT (length);
+ }
+
+ if (nullify)
+ output_asm_insn (\"ftest\;b,n .+%0\", xoperands);
+ else
+ output_asm_insn (\"ftest\;b .+%0\", xoperands);
+ return output_lbranch (operands[0], insn, xdelay);
}"
- [(set_attr "type" "fbranch")
- (set_attr "length" "12")])
+[(set_attr "type" "fbranch")
+ (set (attr "length")
+ (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 12)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 28)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 24)]
+ (const_int 32)))])
;; Move instructions
DONE;
}")
-;; Reloading an SImode or DImode value requires a scratch register if
-;; going in to or out of float point registers.
+;; Handle SImode input reloads requiring %r1 as a scratch register.
+(define_expand "reload_insi_r1"
+ [(set (match_operand:SI 0 "register_operand" "=Z")
+ (match_operand:SI 1 "non_hard_reg_operand" ""))
+ (clobber (match_operand:SI 2 "register_operand" "=&a"))]
+ ""
+ "
+{
+ if (emit_move_sequence (operands, SImode, operands[2]))
+ DONE;
+
+ /* We don't want the clobber emitted, so handle this ourselves. */
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
+ DONE;
+}")
+;; Handle SImode input reloads requiring a general register as a
+;; scratch register.
(define_expand "reload_insi"
[(set (match_operand:SI 0 "register_operand" "=Z")
(match_operand:SI 1 "non_hard_reg_operand" ""))
DONE;
}")
+;; Handle SImode output reloads requiring a general register as a
+;; scratch register.
(define_expand "reload_outsi"
[(set (match_operand:SI 0 "non_hard_reg_operand" "")
(match_operand:SI 1 "register_operand" "Z"))
(define_insn ""
[(set (match_operand:SI 0 "move_dest_operand"
- "=r,r,r,r,r,r,Q,!*q,!*f,*f,T")
+ "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T,?r,?*f")
(match_operand:SI 1 "move_src_operand"
- "A,r,J,N,K,RQ,rM,!rM,!*fM,RT,*f"))]
+ "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f,*f,r"))]
"(register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode))
- && !TARGET_SOFT_FLOAT"
+ && !TARGET_SOFT_FLOAT
+ && !TARGET_64BIT"
+ "@
+ ldw RT'%A1,%0
+ copy %1,%0
+ ldi %1,%0
+ ldil L'%1,%0
+ {zdepi|depwi,z} %Z1,%0
+ ldw%M1 %1,%0
+ stw%M0 %r1,%0
+ mtsar %r1
+ {mfctl|mfctl,w} %%sar,%0
+ fcpy,sgl %f1,%0
+ fldw%F1 %1,%0
+ fstw%F0 %1,%0
+ {fstws|fstw} %1,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0
+ {stws|stw} %1,-16(%%sp)\n\t{fldws|fldw} -16(%%sp),%0"
+ [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore,fpstore_load,store_fpload")
+ (set_attr "pa_combine_type" "addmove")
+ (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,8,8")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "move_dest_operand"
+ "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T")
+ (match_operand:SI 1 "move_src_operand"
+ "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f"))]
+ "(register_operand (operands[0], SImode)
+ || reg_or_0_operand (operands[1], SImode))
+ && !TARGET_SOFT_FLOAT
+ && TARGET_64BIT"
"@
ldw RT'%A1,%0
copy %1,%0
ldw%M1 %1,%0
stw%M0 %r1,%0
mtsar %r1
+ {mfctl|mfctl,w} %%sar,%0
fcpy,sgl %f1,%0
fldw%F1 %1,%0
fstw%F0 %1,%0"
- [(set_attr "type" "load,move,move,move,shift,load,store,move,fpalu,fpload,fpstore")
+ [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore")
(set_attr "pa_combine_type" "addmove")
- (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4")])
+ (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4")])
(define_insn ""
[(set (match_operand:SI 0 "indexed_memory_operand" "=R")
(const_int 4))
(match_operand:SI 2 "register_operand" "")))
(set (mem:SI (match_dup 0))
- (match_operand:SI 3 "reg_or_0_operand" ""))]
+ (match_operand:SI 3 "register_operand" ""))]
"!TARGET_SOFT_FLOAT
+ && !TARGET_DISABLE_INDEXING
&& REG_OK_FOR_BASE_P (operands[2])
&& FP_REGNO_P (REGNO (operands[3]))"
[(set (mem:SI (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
(set (mem:SI (match_dup 0))
(match_operand:SI 3 "register_operand" ""))]
"!TARGET_SOFT_FLOAT
+ && !TARGET_DISABLE_INDEXING
&& REG_OK_FOR_BASE_P (operands[2])
&& FP_REGNO_P (REGNO (operands[3]))"
[(set (mem:SI (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
(set (mem:SI (match_dup 0))
(match_operand:SI 3 "register_operand" ""))]
"!TARGET_SOFT_FLOAT
+ && !TARGET_DISABLE_INDEXING
&& TARGET_64BIT
&& REG_OK_FOR_BASE_P (operands[2])
&& FP_REGNO_P (REGNO (operands[3]))"
(set (mem:SI (match_dup 0))
(match_operand:SI 3 "register_operand" ""))]
"!TARGET_SOFT_FLOAT
+ && !TARGET_DISABLE_INDEXING
&& TARGET_64BIT
&& REG_OK_FOR_BASE_P (operands[2])
&& FP_REGNO_P (REGNO (operands[3]))"
(set (mem:SI (match_dup 0))
(match_operand:SI 3 "register_operand" ""))]
"!TARGET_SOFT_FLOAT
- && REG_OK_FOR_BASE_P (operands[1])
- && (TARGET_NO_SPACE_REGS
- || (!REG_POINTER (operands[1]) && REG_POINTER (operands[2])))
+ && !TARGET_DISABLE_INDEXING
+ && TARGET_NO_SPACE_REGS
+ && REG_OK_FOR_INDEX_P (operands[1])
+ && REG_OK_FOR_BASE_P (operands[2])
&& FP_REGNO_P (REGNO (operands[3]))"
[(set (mem:SI (plus:SI (match_dup 1) (match_dup 2)))
(match_dup 3))
(set (mem:SI (match_dup 0))
(match_operand:SI 3 "register_operand" ""))]
"!TARGET_SOFT_FLOAT
- && REG_OK_FOR_BASE_P (operands[2])
- && (TARGET_NO_SPACE_REGS
- || (REG_POINTER (operands[1]) && !REG_POINTER (operands[2])))
+ && !TARGET_DISABLE_INDEXING
+ && TARGET_NO_SPACE_REGS
+ && REG_OK_FOR_BASE_P (operands[1])
+ && REG_OK_FOR_INDEX_P (operands[2])
&& FP_REGNO_P (REGNO (operands[3]))"
[(set (mem:SI (plus:SI (match_dup 2) (match_dup 1)))
(match_dup 3))
(set (mem:SI (match_dup 0))
(match_operand:SI 3 "register_operand" ""))]
"!TARGET_SOFT_FLOAT
+ && !TARGET_DISABLE_INDEXING
&& TARGET_64BIT
- && REG_OK_FOR_BASE_P (operands[1])
- && (TARGET_NO_SPACE_REGS
- || (!REG_POINTER (operands[1]) && REG_POINTER (operands[2])))
+ && TARGET_NO_SPACE_REGS
+ && REG_OK_FOR_INDEX_P (operands[1])
+ && REG_OK_FOR_BASE_P (operands[2])
&& FP_REGNO_P (REGNO (operands[3]))"
[(set (mem:SI (plus:DI (match_dup 1) (match_dup 2)))
(match_dup 3))
(set (mem:SI (match_dup 0))
(match_operand:SI 3 "register_operand" ""))]
"!TARGET_SOFT_FLOAT
+ && !TARGET_DISABLE_INDEXING
&& TARGET_64BIT
- && REG_OK_FOR_BASE_P (operands[2])
- && (TARGET_NO_SPACE_REGS
- || (REG_POINTER (operands[1]) && !REG_POINTER (operands[2])))
+ && TARGET_NO_SPACE_REGS
+ && REG_OK_FOR_BASE_P (operands[1])
+ && REG_OK_FOR_INDEX_P (operands[2])
&& FP_REGNO_P (REGNO (operands[3]))"
[(set (mem:SI (plus:DI (match_dup 2) (match_dup 1)))
(match_dup 3))
(define_insn ""
[(set (match_operand:SI 0 "move_dest_operand"
- "=r,r,r,r,r,r,Q,!*q")
+ "=r,r,r,r,r,r,Q,!*q,!r")
(match_operand:SI 1 "move_src_operand"
- "A,r,J,N,K,RQ,rM,!rM"))]
+ "A,r,J,N,K,RQ,rM,!rM,!*q"))]
"(register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode))
&& TARGET_SOFT_FLOAT"
{zdepi|depwi,z} %Z1,%0
ldw%M1 %1,%0
stw%M0 %r1,%0
- mtsar %r1"
- [(set_attr "type" "load,move,move,move,move,load,store,move")
+ mtsar %r1
+ {mfctl|mfctl,w} %%sar,%0"
+ [(set_attr "type" "load,move,move,move,move,load,store,move,move")
(set_attr "pa_combine_type" "addmove")
- (set_attr "length" "4,4,4,4,4,4,4,4")])
+ (set_attr "length" "4,4,4,4,4,4,4,4,4")])
;; Load or store with base-register modification.
(define_insn ""
;; Note since this pattern can be created at reload time (via movsi), all
;; the same rules for movsi apply here. (no new pseudos, no temporaries).
(define_insn ""
- [(set (match_operand 0 "pmode_register_operand" "=r")
+ [(set (match_operand 0 "pmode_register_operand" "=a")
(match_operand 1 "pic_label_operand" ""))]
"TARGET_PA_20"
"*
{
rtx xoperands[3];
- extern FILE *asm_out_file;
xoperands[0] = operands[0];
xoperands[1] = operands[1];
/* If we're trying to load the address of a label that happens to be
close, then we can use a shorter sequence. */
if (GET_CODE (operands[1]) == LABEL_REF
+ && !LABEL_REF_NONLOCAL_P (operands[1])
&& INSN_ADDRESSES_SET_P ()
&& abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
- INSN_ADDRESSES (INSN_UID (insn))) < 8100)
"*
{
rtx xoperands[3];
- extern FILE *asm_out_file;
xoperands[0] = operands[0];
xoperands[1] = operands[1];
/* If we're trying to load the address of a label that happens to be
close, then we can use a shorter sequence. */
if (GET_CODE (operands[1]) == LABEL_REF
+ && !LABEL_REF_NONLOCAL_P (operands[1])
&& INSN_ADDRESSES_SET_P ()
&& abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
- INSN_ADDRESSES (INSN_UID (insn))) < 8100)
"!is_function_label_plus_const (operands[2])"
"*
{
- if (flag_pic && symbolic_operand (operands[2], Pmode))
- abort ();
- else if (symbolic_operand (operands[2], Pmode))
+ gcc_assert (!flag_pic || !symbolic_operand (operands[2], Pmode));
+
+ if (symbolic_operand (operands[2], Pmode))
return \"ldo RR'%G2(%1),%0\";
else
return \"ldo R'%G2(%1),%0\";
(define_insn ""
[(set (match_operand:HI 0 "move_dest_operand"
- "=r,r,r,r,r,Q,!*q,!*f")
+ "=r,r,r,r,r,Q,!*q,!r,!*f,?r,?*f")
+ (match_operand:HI 1 "move_src_operand"
+ "r,J,N,K,RQ,rM,!rM,!*q,!*fM,*f,r"))]
+ "(register_operand (operands[0], HImode)
+ || reg_or_0_operand (operands[1], HImode))
+ && !TARGET_SOFT_FLOAT
+ && !TARGET_64BIT"
+ "@
+ copy %1,%0
+ ldi %1,%0
+ ldil L'%1,%0
+ {zdepi|depwi,z} %Z1,%0
+ ldh%M1 %1,%0
+ sth%M0 %r1,%0
+ mtsar %r1
+ {mfctl|mfctl,w} %sar,%0
+ fcpy,sgl %f1,%0
+ {fstws|fstw} %1,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0
+ {stws|stw} %1,-16(%%sp)\n\t{fldws|fldw} -16(%%sp),%0"
+ [(set_attr "type" "move,move,move,shift,load,store,move,move,move,fpstore_load,store_fpload")
+ (set_attr "pa_combine_type" "addmove")
+ (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "move_dest_operand"
+ "=r,r,r,r,r,Q,!*q,!r,!*f")
(match_operand:HI 1 "move_src_operand"
- "r,J,N,K,RQ,rM,!rM,!*fM"))]
- "register_operand (operands[0], HImode)
- || reg_or_0_operand (operands[1], HImode)"
+ "r,J,N,K,RQ,rM,!rM,!*q,!*fM"))]
+ "(register_operand (operands[0], HImode)
+ || reg_or_0_operand (operands[1], HImode))
+ && !TARGET_SOFT_FLOAT
+ && TARGET_64BIT"
"@
copy %1,%0
ldi %1,%0
ldh%M1 %1,%0
sth%M0 %r1,%0
mtsar %r1
+ {mfctl|mfctl,w} %sar,%0
fcpy,sgl %f1,%0"
- [(set_attr "type" "move,move,move,shift,load,store,move,fpalu")
+ [(set_attr "type" "move,move,move,shift,load,store,move,move,move")
+ (set_attr "pa_combine_type" "addmove")
+ (set_attr "length" "4,4,4,4,4,4,4,4,4")])
+
+(define_insn ""
+ [(set (match_operand:HI 0 "move_dest_operand"
+ "=r,r,r,r,r,Q,!*q,!r")
+ (match_operand:HI 1 "move_src_operand"
+ "r,J,N,K,RQ,rM,!rM,!*q"))]
+ "(register_operand (operands[0], HImode)
+ || reg_or_0_operand (operands[1], HImode))
+ && TARGET_SOFT_FLOAT"
+ "@
+ copy %1,%0
+ ldi %1,%0
+ ldil L'%1,%0
+ {zdepi|depwi,z} %Z1,%0
+ ldh%M1 %1,%0
+ sth%M0 %r1,%0
+ mtsar %r1
+ {mfctl|mfctl,w} %sar,%0"
+ [(set_attr "type" "move,move,move,shift,load,store,move,move")
(set_attr "pa_combine_type" "addmove")
(set_attr "length" "4,4,4,4,4,4,4,4")])
(define_insn ""
[(set (match_operand:QI 0 "move_dest_operand"
- "=r,r,r,r,r,Q,!*q,!*f")
+ "=r,r,r,r,r,Q,!*q,!r,!*f,?r,?*f")
(match_operand:QI 1 "move_src_operand"
- "r,J,N,K,RQ,rM,!rM,!*fM"))]
- "register_operand (operands[0], QImode)
- || reg_or_0_operand (operands[1], QImode)"
+ "r,J,N,K,RQ,rM,!rM,!*q,!*fM,*f,r"))]
+ "(register_operand (operands[0], QImode)
+ || reg_or_0_operand (operands[1], QImode))
+ && !TARGET_SOFT_FLOAT
+ && !TARGET_64BIT"
"@
copy %1,%0
ldi %1,%0
ldb%M1 %1,%0
stb%M0 %r1,%0
mtsar %r1
+ {mfctl|mfctl,w} %%sar,%0
+ fcpy,sgl %f1,%0
+ {fstws|fstw} %1,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0
+ {stws|stw} %1,-16(%%sp)\n\t{fldws|fldw} -16(%%sp),%0"
+ [(set_attr "type" "move,move,move,shift,load,store,move,move,move,fpstore_load,store_fpload")
+ (set_attr "pa_combine_type" "addmove")
+ (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8")])
+
+(define_insn ""
+ [(set (match_operand:QI 0 "move_dest_operand"
+ "=r,r,r,r,r,Q,!*q,!r,!*f")
+ (match_operand:QI 1 "move_src_operand"
+ "r,J,N,K,RQ,rM,!rM,!*q,!*fM"))]
+ "(register_operand (operands[0], QImode)
+ || reg_or_0_operand (operands[1], QImode))
+ && !TARGET_SOFT_FLOAT
+ && TARGET_64BIT"
+ "@
+ copy %1,%0
+ ldi %1,%0
+ ldil L'%1,%0
+ {zdepi|depwi,z} %Z1,%0
+ ldb%M1 %1,%0
+ stb%M0 %r1,%0
+ mtsar %r1
+ {mfctl|mfctl,w} %%sar,%0
fcpy,sgl %f1,%0"
- [(set_attr "type" "move,move,move,shift,load,store,move,fpalu")
+ [(set_attr "type" "move,move,move,shift,load,store,move,move,move")
+ (set_attr "pa_combine_type" "addmove")
+ (set_attr "length" "4,4,4,4,4,4,4,4,4")])
+
+(define_insn ""
+ [(set (match_operand:QI 0 "move_dest_operand"
+ "=r,r,r,r,r,Q,!*q,!r")
+ (match_operand:QI 1 "move_src_operand"
+ "r,J,N,K,RQ,rM,!rM,!*q"))]
+ "(register_operand (operands[0], QImode)
+ || reg_or_0_operand (operands[1], QImode))
+ && TARGET_SOFT_FLOAT"
+ "@
+ copy %1,%0
+ ldi %1,%0
+ ldil L'%1,%0
+ {zdepi|depwi,z} %Z1,%0
+ ldb%M1 %1,%0
+ stb%M0 %r1,%0
+ mtsar %r1
+ {mfctl|mfctl,w} %%sar,%0"
+ [(set_attr "type" "move,move,move,shift,load,store,move,move")
(set_attr "pa_combine_type" "addmove")
(set_attr "length" "4,4,4,4,4,4,4,4")])
;; The definition of this insn does not really explain what it does,
;; but it should suffice that anything generated as this insn will be
-;; recognized as a movstrsi operation, and that it will not successfully
+;; recognized as a movmemsi operation, and that it will not successfully
;; combine with anything.
-(define_expand "movstrsi"
+(define_expand "movmemsi"
[(parallel [(set (match_operand:BLK 0 "" "")
(match_operand:BLK 1 "" ""))
(clobber (match_dup 4))
;; operands 0 and 1 are both equivalent to symbolic MEMs. Thus, we are
;; forced to internally copy operands 0 and 1 to operands 7 and 8,
;; respectively. We then split or peephole optimize after reload.
-(define_insn "movstrsi_prereload"
+(define_insn "movmemsi_prereload"
[(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r"))
(mem:BLK (match_operand:SI 1 "register_operand" "r,r")))
- (clobber (match_operand:SI 2 "register_operand" "=r,r")) ;loop cnt/tmp
+ (clobber (match_operand:SI 2 "register_operand" "=&r,&r")) ;loop cnt/tmp
(clobber (match_operand:SI 3 "register_operand" "=&r,&r")) ;item tmp1
(clobber (match_operand:SI 6 "register_operand" "=&r,&r")) ;item tmp2
(clobber (match_operand:SI 7 "register_operand" "=&r,&r")) ;item tmp3
[(set_attr "type" "multi,multi")])
(define_split
- [(parallel [(set (mem:BLK (match_operand:SI 0 "register_operand" ""))
- (mem:BLK (match_operand:SI 1 "register_operand" "")))
+ [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
+ (match_operand:BLK 1 "memory_operand" ""))
(clobber (match_operand:SI 2 "register_operand" ""))
(clobber (match_operand:SI 3 "register_operand" ""))
(clobber (match_operand:SI 6 "register_operand" ""))
(clobber (match_operand:SI 8 "register_operand" ""))
(use (match_operand:SI 4 "arith_operand" ""))
(use (match_operand:SI 5 "const_int_operand" ""))])]
- "!TARGET_64BIT && reload_completed && !flag_peephole2"
- [(set (match_dup 7) (match_dup 0))
- (set (match_dup 8) (match_dup 1))
- (parallel [(set (mem:BLK (match_dup 7)) (mem:BLK (match_dup 8)))
+ "!TARGET_64BIT && reload_completed && !flag_peephole2
+ && GET_CODE (operands[0]) == MEM
+ && register_operand (XEXP (operands[0], 0), SImode)
+ && GET_CODE (operands[1]) == MEM
+ && register_operand (XEXP (operands[1], 0), SImode)"
+ [(set (match_dup 7) (match_dup 9))
+ (set (match_dup 8) (match_dup 10))
+ (parallel [(set (match_dup 0) (match_dup 1))
(clobber (match_dup 2))
(clobber (match_dup 3))
(clobber (match_dup 6))
(use (match_dup 4))
(use (match_dup 5))
(const_int 0)])]
- "")
+ "
+{
+ operands[9] = XEXP (operands[0], 0);
+ operands[10] = XEXP (operands[1], 0);
+ operands[0] = replace_equiv_address (operands[0], operands[7]);
+ operands[1] = replace_equiv_address (operands[1], operands[8]);
+}")
(define_peephole2
- [(parallel [(set (mem:BLK (match_operand:SI 0 "register_operand" ""))
- (mem:BLK (match_operand:SI 1 "register_operand" "")))
+ [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
+ (match_operand:BLK 1 "memory_operand" ""))
(clobber (match_operand:SI 2 "register_operand" ""))
(clobber (match_operand:SI 3 "register_operand" ""))
(clobber (match_operand:SI 6 "register_operand" ""))
(clobber (match_operand:SI 8 "register_operand" ""))
(use (match_operand:SI 4 "arith_operand" ""))
(use (match_operand:SI 5 "const_int_operand" ""))])]
- "!TARGET_64BIT"
- [(parallel [(set (mem:BLK (match_dup 7)) (mem:BLK (match_dup 8)))
+ "!TARGET_64BIT
+ && GET_CODE (operands[0]) == MEM
+ && register_operand (XEXP (operands[0], 0), SImode)
+ && GET_CODE (operands[1]) == MEM
+ && register_operand (XEXP (operands[1], 0), SImode)"
+ [(parallel [(set (match_dup 0) (match_dup 1))
(clobber (match_dup 2))
(clobber (match_dup 3))
(clobber (match_dup 6))
(const_int 0)])]
"
{
- if (dead_or_set_p (curr_insn, operands[0]))
- operands[7] = operands[0];
+ rtx addr = XEXP (operands[0], 0);
+ if (dead_or_set_p (curr_insn, addr))
+ operands[7] = addr;
else
- emit_insn (gen_rtx_SET (VOIDmode, operands[7], operands[0]));
+ {
+ emit_insn (gen_rtx_SET (VOIDmode, operands[7], addr));
+ operands[0] = replace_equiv_address (operands[0], operands[7]);
+ }
- if (dead_or_set_p (curr_insn, operands[1]))
- operands[8] = operands[1];
+ addr = XEXP (operands[1], 0);
+ if (dead_or_set_p (curr_insn, addr))
+ operands[8] = addr;
else
- emit_insn (gen_rtx_SET (VOIDmode, operands[8], operands[1]));
+ {
+ emit_insn (gen_rtx_SET (VOIDmode, operands[8], addr));
+ operands[1] = replace_equiv_address (operands[1], operands[8]);
+ }
}")
-(define_insn "movstrsi_postreload"
- [(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r"))
- (mem:BLK (match_operand:SI 1 "register_operand" "r,r")))
- (clobber (match_operand:SI 2 "register_operand" "=r,r")) ;loop cnt/tmp
+(define_insn "movmemsi_postreload"
+ [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
+ (mem:BLK (match_operand:SI 1 "register_operand" "+r,r")))
+ (clobber (match_operand:SI 2 "register_operand" "=&r,&r")) ;loop cnt/tmp
(clobber (match_operand:SI 3 "register_operand" "=&r,&r")) ;item tmp1
(clobber (match_operand:SI 6 "register_operand" "=&r,&r")) ;item tmp2
(clobber (match_dup 0))
"* return output_block_move (operands, !which_alternative);"
[(set_attr "type" "multi,multi")])
-(define_expand "movstrdi"
+(define_expand "movmemdi"
[(parallel [(set (match_operand:BLK 0 "" "")
(match_operand:BLK 1 "" ""))
(clobber (match_dup 4))
;; operands 0 and 1 are both equivalent to symbolic MEMs. Thus, we are
;; forced to internally copy operands 0 and 1 to operands 7 and 8,
;; respectively. We then split or peephole optimize after reload.
-(define_insn "movstrdi_prereload"
+(define_insn "movmemdi_prereload"
[(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r"))
(mem:BLK (match_operand:DI 1 "register_operand" "r,r")))
- (clobber (match_operand:DI 2 "register_operand" "=r,r")) ;loop cnt/tmp
+ (clobber (match_operand:DI 2 "register_operand" "=&r,&r")) ;loop cnt/tmp
(clobber (match_operand:DI 3 "register_operand" "=&r,&r")) ;item tmp1
(clobber (match_operand:DI 6 "register_operand" "=&r,&r")) ;item tmp2
(clobber (match_operand:DI 7 "register_operand" "=&r,&r")) ;item tmp3
[(set_attr "type" "multi,multi")])
(define_split
- [(parallel [(set (mem:BLK (match_operand:DI 0 "register_operand" ""))
- (mem:BLK (match_operand:DI 1 "register_operand" "")))
+ [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
+ (match_operand:BLK 1 "memory_operand" ""))
(clobber (match_operand:DI 2 "register_operand" ""))
(clobber (match_operand:DI 3 "register_operand" ""))
(clobber (match_operand:DI 6 "register_operand" ""))
(clobber (match_operand:DI 8 "register_operand" ""))
(use (match_operand:DI 4 "arith_operand" ""))
(use (match_operand:DI 5 "const_int_operand" ""))])]
- "TARGET_64BIT && reload_completed && !flag_peephole2"
- [(set (match_dup 7) (match_dup 0))
- (set (match_dup 8) (match_dup 1))
- (parallel [(set (mem:BLK (match_dup 7)) (mem:BLK (match_dup 8)))
+ "TARGET_64BIT && reload_completed && !flag_peephole2
+ && GET_CODE (operands[0]) == MEM
+ && register_operand (XEXP (operands[0], 0), DImode)
+ && GET_CODE (operands[1]) == MEM
+ && register_operand (XEXP (operands[1], 0), DImode)"
+ [(set (match_dup 7) (match_dup 9))
+ (set (match_dup 8) (match_dup 10))
+ (parallel [(set (match_dup 0) (match_dup 1))
(clobber (match_dup 2))
(clobber (match_dup 3))
(clobber (match_dup 6))
(use (match_dup 4))
(use (match_dup 5))
(const_int 0)])]
- "")
+ "
+{
+ operands[9] = XEXP (operands[0], 0);
+ operands[10] = XEXP (operands[1], 0);
+ operands[0] = replace_equiv_address (operands[0], operands[7]);
+ operands[1] = replace_equiv_address (operands[1], operands[8]);
+}")
(define_peephole2
- [(parallel [(set (mem:BLK (match_operand:DI 0 "register_operand" ""))
- (mem:BLK (match_operand:DI 1 "register_operand" "")))
+ [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
+ (match_operand:BLK 1 "memory_operand" ""))
(clobber (match_operand:DI 2 "register_operand" ""))
(clobber (match_operand:DI 3 "register_operand" ""))
(clobber (match_operand:DI 6 "register_operand" ""))
(clobber (match_operand:DI 8 "register_operand" ""))
(use (match_operand:DI 4 "arith_operand" ""))
(use (match_operand:DI 5 "const_int_operand" ""))])]
- "TARGET_64BIT"
- [(parallel [(set (mem:BLK (match_dup 7)) (mem:BLK (match_dup 8)))
+ "TARGET_64BIT
+ && GET_CODE (operands[0]) == MEM
+ && register_operand (XEXP (operands[0], 0), DImode)
+ && GET_CODE (operands[1]) == MEM
+ && register_operand (XEXP (operands[1], 0), DImode)"
+ [(parallel [(set (match_dup 0) (match_dup 1))
(clobber (match_dup 2))
(clobber (match_dup 3))
(clobber (match_dup 6))
(const_int 0)])]
"
{
- if (dead_or_set_p (curr_insn, operands[0]))
- operands[7] = operands[0];
+ rtx addr = XEXP (operands[0], 0);
+ if (dead_or_set_p (curr_insn, addr))
+ operands[7] = addr;
else
- emit_insn (gen_rtx_SET (VOIDmode, operands[7], operands[0]));
+ {
+ emit_insn (gen_rtx_SET (VOIDmode, operands[7], addr));
+ operands[0] = replace_equiv_address (operands[0], operands[7]);
+ }
- if (dead_or_set_p (curr_insn, operands[1]))
- operands[8] = operands[1];
+ addr = XEXP (operands[1], 0);
+ if (dead_or_set_p (curr_insn, addr))
+ operands[8] = addr;
else
- emit_insn (gen_rtx_SET (VOIDmode, operands[8], operands[1]));
+ {
+ emit_insn (gen_rtx_SET (VOIDmode, operands[8], addr));
+ operands[1] = replace_equiv_address (operands[1], operands[8]);
+ }
}")
-(define_insn "movstrdi_postreload"
- [(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r"))
- (mem:BLK (match_operand:DI 1 "register_operand" "r,r")))
- (clobber (match_operand:DI 2 "register_operand" "=r,r")) ;loop cnt/tmp
+(define_insn "movmemdi_postreload"
+ [(set (mem:BLK (match_operand:DI 0 "register_operand" "+r,r"))
+ (mem:BLK (match_operand:DI 1 "register_operand" "+r,r")))
+ (clobber (match_operand:DI 2 "register_operand" "=&r,&r")) ;loop cnt/tmp
(clobber (match_operand:DI 3 "register_operand" "=&r,&r")) ;item tmp1
(clobber (match_operand:DI 6 "register_operand" "=&r,&r")) ;item tmp2
(clobber (match_dup 0))
"* return output_block_move (operands, !which_alternative);"
[(set_attr "type" "multi,multi")])
-(define_expand "clrstrsi"
+(define_expand "setmemsi"
[(parallel [(set (match_operand:BLK 0 "" "")
- (const_int 0))
- (clobber (match_dup 3))
+ (match_operand 2 "const_int_operand" ""))
(clobber (match_dup 4))
+ (clobber (match_dup 5))
(use (match_operand:SI 1 "arith_operand" ""))
- (use (match_operand:SI 2 "const_int_operand" ""))])]
+ (use (match_operand:SI 3 "const_int_operand" ""))])]
"!TARGET_64BIT && optimize > 0"
"
{
int size, align;
+ /* If value to set is not zero, use the library routine. */
+ if (operands[2] != const0_rtx)
+ FAIL;
+
/* Undetermined size, use the library routine. */
if (GET_CODE (operands[1]) != CONST_INT)
FAIL;
size = INTVAL (operands[1]);
- align = INTVAL (operands[2]);
+ align = INTVAL (operands[3]);
align = align > 4 ? 4 : align;
/* If size/alignment is large, then use the library routines. */
operands[0]
= replace_equiv_address (operands[0],
copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
- operands[3] = gen_reg_rtx (SImode);
operands[4] = gen_reg_rtx (SImode);
+ operands[5] = gen_reg_rtx (SImode);
}")
-(define_insn "clrstrsi_prereload"
+(define_insn "clrmemsi_prereload"
[(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r"))
(const_int 0))
- (clobber (match_operand:SI 1 "register_operand" "=r,r")) ;loop cnt/tmp
+ (clobber (match_operand:SI 1 "register_operand" "=&r,&r")) ;loop cnt/tmp
(clobber (match_operand:SI 4 "register_operand" "=&r,&r")) ;tmp1
(use (match_operand:SI 2 "arith_operand" "J,1")) ;byte count
(use (match_operand:SI 3 "const_int_operand" "n,n"))] ;alignment
[(set_attr "type" "multi,multi")])
(define_split
- [(parallel [(set (mem:BLK (match_operand:SI 0 "register_operand" ""))
+ [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
(const_int 0))
(clobber (match_operand:SI 1 "register_operand" ""))
(clobber (match_operand:SI 4 "register_operand" ""))
(use (match_operand:SI 2 "arith_operand" ""))
(use (match_operand:SI 3 "const_int_operand" ""))])]
- "!TARGET_64BIT && reload_completed && !flag_peephole2"
- [(set (match_dup 4) (match_dup 0))
- (parallel [(set (mem:BLK (match_dup 4)) (const_int 0))
+ "!TARGET_64BIT && reload_completed && !flag_peephole2
+ && GET_CODE (operands[0]) == MEM
+ && register_operand (XEXP (operands[0], 0), SImode)"
+ [(set (match_dup 4) (match_dup 5))
+ (parallel [(set (match_dup 0) (const_int 0))
(clobber (match_dup 1))
(clobber (match_dup 4))
(use (match_dup 2))
(use (match_dup 3))
(const_int 0)])]
- "")
+ "
+{
+ operands[5] = XEXP (operands[0], 0);
+ operands[0] = replace_equiv_address (operands[0], operands[4]);
+}")
(define_peephole2
- [(parallel [(set (mem:BLK (match_operand:SI 0 "register_operand" ""))
+ [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
(const_int 0))
(clobber (match_operand:SI 1 "register_operand" ""))
(clobber (match_operand:SI 4 "register_operand" ""))
(use (match_operand:SI 2 "arith_operand" ""))
(use (match_operand:SI 3 "const_int_operand" ""))])]
- "!TARGET_64BIT"
- [(parallel [(set (mem:BLK (match_dup 4)) (const_int 0))
+ "!TARGET_64BIT
+ && GET_CODE (operands[0]) == MEM
+ && register_operand (XEXP (operands[0], 0), SImode)"
+ [(parallel [(set (match_dup 0) (const_int 0))
(clobber (match_dup 1))
(clobber (match_dup 4))
(use (match_dup 2))
(const_int 0)])]
"
{
- if (dead_or_set_p (curr_insn, operands[0]))
- operands[4] = operands[0];
+ rtx addr = XEXP (operands[0], 0);
+ if (dead_or_set_p (curr_insn, addr))
+ operands[4] = addr;
else
- emit_insn (gen_rtx_SET (VOIDmode, operands[4], operands[0]));
+ {
+ emit_insn (gen_rtx_SET (VOIDmode, operands[4], addr));
+ operands[0] = replace_equiv_address (operands[0], operands[4]);
+ }
}")
-(define_insn "clrstrsi_postreload"
- [(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r"))
+(define_insn "clrmemsi_postreload"
+ [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
(const_int 0))
- (clobber (match_operand:SI 1 "register_operand" "=r,r")) ;loop cnt/tmp
+ (clobber (match_operand:SI 1 "register_operand" "=&r,&r")) ;loop cnt/tmp
(clobber (match_dup 0))
(use (match_operand:SI 2 "arith_operand" "J,1")) ;byte count
(use (match_operand:SI 3 "const_int_operand" "n,n")) ;alignment
"* return output_block_clear (operands, !which_alternative);"
[(set_attr "type" "multi,multi")])
-(define_expand "clrstrdi"
+(define_expand "setmemdi"
[(parallel [(set (match_operand:BLK 0 "" "")
- (const_int 0))
- (clobber (match_dup 3))
+ (match_operand 2 "const_int_operand" ""))
(clobber (match_dup 4))
+ (clobber (match_dup 5))
(use (match_operand:DI 1 "arith_operand" ""))
- (use (match_operand:DI 2 "const_int_operand" ""))])]
+ (use (match_operand:DI 3 "const_int_operand" ""))])]
"TARGET_64BIT && optimize > 0"
"
{
int size, align;
+ /* If value to set is not zero, use the library routine. */
+ if (operands[2] != const0_rtx)
+ FAIL;
+
/* Undetermined size, use the library routine. */
if (GET_CODE (operands[1]) != CONST_INT)
FAIL;
size = INTVAL (operands[1]);
- align = INTVAL (operands[2]);
+ align = INTVAL (operands[3]);
align = align > 8 ? 8 : align;
/* If size/alignment is large, then use the library routines. */
operands[0]
= replace_equiv_address (operands[0],
copy_to_mode_reg (DImode, XEXP (operands[0], 0)));
- operands[3] = gen_reg_rtx (DImode);
operands[4] = gen_reg_rtx (DImode);
+ operands[5] = gen_reg_rtx (DImode);
}")
-(define_insn "clrstrdi_prereload"
+(define_insn "clrmemdi_prereload"
[(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r"))
(const_int 0))
- (clobber (match_operand:DI 1 "register_operand" "=r,r")) ;loop cnt/tmp
+ (clobber (match_operand:DI 1 "register_operand" "=&r,&r")) ;loop cnt/tmp
(clobber (match_operand:DI 4 "register_operand" "=&r,&r")) ;item tmp1
(use (match_operand:DI 2 "arith_operand" "J,1")) ;byte count
(use (match_operand:DI 3 "const_int_operand" "n,n"))] ;alignment
[(set_attr "type" "multi,multi")])
(define_split
- [(parallel [(set (mem:BLK (match_operand:DI 0 "register_operand" ""))
+ [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
(const_int 0))
(clobber (match_operand:DI 1 "register_operand" ""))
(clobber (match_operand:DI 4 "register_operand" ""))
(use (match_operand:DI 2 "arith_operand" ""))
(use (match_operand:DI 3 "const_int_operand" ""))])]
- "TARGET_64BIT && reload_completed && !flag_peephole2"
- [(set (match_dup 4) (match_dup 0))
- (parallel [(set (mem:BLK (match_dup 4)) (const_int 0))
+ "TARGET_64BIT && reload_completed && !flag_peephole2
+ && GET_CODE (operands[0]) == MEM
+ && register_operand (XEXP (operands[0], 0), DImode)"
+ [(set (match_dup 4) (match_dup 5))
+ (parallel [(set (match_dup 0) (const_int 0))
(clobber (match_dup 1))
(clobber (match_dup 4))
(use (match_dup 2))
(use (match_dup 3))
(const_int 0)])]
- "")
+ "
+{
+ operands[5] = XEXP (operands[0], 0);
+ operands[0] = replace_equiv_address (operands[0], operands[4]);
+}")
(define_peephole2
- [(parallel [(set (mem:BLK (match_operand:DI 0 "register_operand" ""))
+ [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
(const_int 0))
(clobber (match_operand:DI 1 "register_operand" ""))
(clobber (match_operand:DI 4 "register_operand" ""))
(use (match_operand:DI 2 "arith_operand" ""))
(use (match_operand:DI 3 "const_int_operand" ""))])]
- "TARGET_64BIT"
- [(parallel [(set (mem:BLK (match_dup 4)) (const_int 0))
+ "TARGET_64BIT
+ && GET_CODE (operands[0]) == MEM
+ && register_operand (XEXP (operands[0], 0), DImode)"
+ [(parallel [(set (match_dup 0) (const_int 0))
(clobber (match_dup 1))
(clobber (match_dup 4))
(use (match_dup 2))
(const_int 0)])]
"
{
- if (dead_or_set_p (curr_insn, operands[0]))
- operands[4] = operands[0];
+ rtx addr = XEXP (operands[0], 0);
+ if (dead_or_set_p (curr_insn, addr))
+ operands[4] = addr;
else
- emit_insn (gen_rtx_SET (VOIDmode, operands[4], operands[0]));
+ {
+ emit_insn (gen_rtx_SET (VOIDmode, operands[4], addr));
+ operands[0] = replace_equiv_address (operands[0], operands[4]);
+ }
}")
-(define_insn "clrstrdi_postreload"
- [(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r"))
+(define_insn "clrmemdi_postreload"
+ [(set (mem:BLK (match_operand:DI 0 "register_operand" "+r,r"))
(const_int 0))
- (clobber (match_operand:DI 1 "register_operand" "=r,r")) ;loop cnt/tmp
+ (clobber (match_operand:DI 1 "register_operand" "=&r,&r")) ;loop cnt/tmp
(clobber (match_dup 0))
(use (match_operand:DI 2 "arith_operand" "J,1")) ;byte count
(use (match_operand:DI 3 "const_int_operand" "n,n")) ;alignment
""
"
{
- if (GET_CODE (operands[1]) == CONST_DOUBLE && TARGET_64BIT)
- operands[1] = force_const_mem (DFmode, operands[1]);
+ if (GET_CODE (operands[1]) == CONST_DOUBLE
+ && operands[1] != CONST0_RTX (DFmode))
+ {
+ /* Reject CONST_DOUBLE loads to all hard registers when
+ generating 64-bit code and to floating point registers
+ when generating 32-bit code. */
+ if (REG_P (operands[0])
+ && HARD_REGISTER_P (operands[0])
+ && (TARGET_64BIT || REGNO (operands[0]) >= 32))
+ FAIL;
+
+ if (TARGET_64BIT)
+ operands[1] = force_const_mem (DFmode, operands[1]);
+ }
if (emit_move_sequence (operands, DFmode, 0))
DONE;
}")
-;; Reloading an SImode or DImode value requires a scratch register if
-;; going in to or out of float point registers.
-
+;; Handle DFmode input reloads requiring a general register as a
+;; scratch register.
(define_expand "reload_indf"
[(set (match_operand:DF 0 "register_operand" "=Z")
(match_operand:DF 1 "non_hard_reg_operand" ""))
DONE;
}")
+;; Handle DFmode output reloads requiring a general register as a
+;; scratch register.
(define_expand "reload_outdf"
[(set (match_operand:DF 0 "non_hard_reg_operand" "")
(match_operand:DF 1 "register_operand" "Z"))
(define_insn ""
[(set (match_operand:DF 0 "move_dest_operand"
- "=f,*r,Q,?o,?Q,f,*r,*r")
+ "=f,*r,Q,?o,?Q,f,*r,*r,?*r,?f")
(match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
- "fG,*rG,f,*r,*r,RQ,o,RQ"))]
+ "fG,*rG,f,*r,*r,RQ,o,RQ,f,*r"))]
"(register_operand (operands[0], DFmode)
|| reg_or_0_operand (operands[1], DFmode))
&& !(GET_CODE (operands[1]) == CONST_DOUBLE
&& !TARGET_SOFT_FLOAT"
"*
{
- if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])
- || operands[1] == CONST0_RTX (DFmode))
+ if ((FP_REG_P (operands[0]) || FP_REG_P (operands[1])
+ || operands[1] == CONST0_RTX (DFmode))
+ && !(REG_P (operands[0]) && REG_P (operands[1])
+ && FP_REG_P (operands[0]) ^ FP_REG_P (operands[1])))
return output_fp_move_double (operands);
return output_move_double (operands);
}"
- [(set_attr "type" "fpalu,move,fpstore,store,store,fpload,load,load")
- (set_attr "length" "4,8,4,8,16,4,8,16")])
+ [(set_attr "type" "fpalu,move,fpstore,store,store,fpload,load,load,fpstore_load,store_fpload")
+ (set_attr "length" "4,8,4,8,16,4,8,16,12,12")])
(define_insn ""
[(set (match_operand:DF 0 "indexed_memory_operand" "=R")
(set (mem:DF (match_dup 0))
(match_operand:DF 3 "register_operand" ""))]
"!TARGET_SOFT_FLOAT
+ && !TARGET_DISABLE_INDEXING
&& REG_OK_FOR_BASE_P (operands[2])
&& FP_REGNO_P (REGNO (operands[3]))"
[(set (mem:DF (plus:SI (mult:SI (match_dup 1) (const_int 8)) (match_dup 2)))
(set (mem:DF (match_dup 0))
(match_operand:DF 3 "register_operand" ""))]
"!TARGET_SOFT_FLOAT
+ && !TARGET_DISABLE_INDEXING
&& REG_OK_FOR_BASE_P (operands[2])
&& FP_REGNO_P (REGNO (operands[3]))"
[(set (mem:DF (plus:SI (mult:SI (match_dup 1) (const_int 8)) (match_dup 2)))
(set (mem:DF (match_dup 0))
(match_operand:DF 3 "register_operand" ""))]
"!TARGET_SOFT_FLOAT
+ && !TARGET_DISABLE_INDEXING
&& TARGET_64BIT
&& REG_OK_FOR_BASE_P (operands[2])
&& FP_REGNO_P (REGNO (operands[3]))"
(set (mem:DF (match_dup 0))
(match_operand:DF 3 "register_operand" ""))]
"!TARGET_SOFT_FLOAT
+ && !TARGET_DISABLE_INDEXING
&& TARGET_64BIT
&& REG_OK_FOR_BASE_P (operands[2])
&& FP_REGNO_P (REGNO (operands[3]))"
(set (mem:DF (match_dup 0))
(match_operand:DF 3 "register_operand" ""))]
"!TARGET_SOFT_FLOAT
- && REG_OK_FOR_BASE_P (operands[1])
- && (TARGET_NO_SPACE_REGS
- || (!REG_POINTER (operands[1]) && REG_POINTER (operands[2])))
+ && !TARGET_DISABLE_INDEXING
+ && TARGET_NO_SPACE_REGS
+ && REG_OK_FOR_INDEX_P (operands[1])
+ && REG_OK_FOR_BASE_P (operands[2])
&& FP_REGNO_P (REGNO (operands[3]))"
[(set (mem:DF (plus:SI (match_dup 1) (match_dup 2)))
(match_dup 3))
(set (mem:DF (match_dup 0))
(match_operand:DF 3 "register_operand" ""))]
"!TARGET_SOFT_FLOAT
- && REG_OK_FOR_BASE_P (operands[2])
- && (TARGET_NO_SPACE_REGS
- || (REG_POINTER (operands[1]) && !REG_POINTER (operands[2])))
+ && !TARGET_DISABLE_INDEXING
+ && TARGET_NO_SPACE_REGS
+ && REG_OK_FOR_BASE_P (operands[1])
+ && REG_OK_FOR_INDEX_P (operands[2])
&& FP_REGNO_P (REGNO (operands[3]))"
[(set (mem:DF (plus:SI (match_dup 2) (match_dup 1)))
(match_dup 3))
(set (mem:DF (match_dup 0))
(match_operand:DF 3 "register_operand" ""))]
"!TARGET_SOFT_FLOAT
+ && !TARGET_DISABLE_INDEXING
&& TARGET_64BIT
- && REG_OK_FOR_BASE_P (operands[1])
- && (TARGET_NO_SPACE_REGS
- || (!REG_POINTER (operands[1]) && REG_POINTER (operands[2])))
+ && TARGET_NO_SPACE_REGS
+ && REG_OK_FOR_INDEX_P (operands[1])
+ && REG_OK_FOR_BASE_P (operands[2])
&& FP_REGNO_P (REGNO (operands[3]))"
[(set (mem:DF (plus:DI (match_dup 1) (match_dup 2)))
(match_dup 3))
(set (mem:DF (match_dup 0))
(match_operand:DF 3 "register_operand" ""))]
"!TARGET_SOFT_FLOAT
+ && !TARGET_DISABLE_INDEXING
&& TARGET_64BIT
- && REG_OK_FOR_BASE_P (operands[2])
- && (TARGET_NO_SPACE_REGS
- || (REG_POINTER (operands[1]) && !REG_POINTER (operands[2])))
+ && TARGET_NO_SPACE_REGS
+ && REG_OK_FOR_BASE_P (operands[1])
+ && REG_OK_FOR_INDEX_P (operands[2])
&& FP_REGNO_P (REGNO (operands[3]))"
[(set (mem:DF (plus:DI (match_dup 2) (match_dup 1)))
(match_dup 3))
(define_insn ""
[(set (match_operand:DF 0 "move_dest_operand"
- "=!*r,*r,*r,*r,*r,Q,!*q,f,f,T")
+ "=!*r,*r,*r,*r,*r,Q,f,f,T")
(match_operand:DF 1 "move_src_operand"
- "!*r,J,N,K,RQ,*rM,!*rM,fM,RT,f"))]
+ "!*r,J,N,K,RQ,*rG,fG,RT,f"))]
"(register_operand (operands[0], DFmode)
|| reg_or_0_operand (operands[1], DFmode))
&& !TARGET_SOFT_FLOAT && TARGET_64BIT"
depdi,z %z1,%0
ldd%M1 %1,%0
std%M0 %r1,%0
- mtsar %r1
fcpy,dbl %f1,%0
fldd%F1 %1,%0
fstd%F0 %1,%0"
- [(set_attr "type" "move,move,move,shift,load,store,move,fpalu,fpload,fpstore")
+ [(set_attr "type" "move,move,move,shift,load,store,fpalu,fpload,fpstore")
(set_attr "pa_combine_type" "addmove")
- (set_attr "length" "4,4,4,4,4,4,4,4,4,4")])
+ (set_attr "length" "4,4,4,4,4,4,4,4,4")])
\f
(define_expand "movdi"
""
"
{
- if (GET_CODE (operands[1]) == CONST_DOUBLE && TARGET_64BIT)
- operands[1] = force_const_mem (DImode, operands[1]);
+ /* Except for zero, we don't support loading a CONST_INT directly
+ to a hard floating-point register since a scratch register is
+ needed for the operation. While the operation could be handled
+ before register allocation, the simplest solution is to fail. */
+ if (TARGET_64BIT
+ && GET_CODE (operands[1]) == CONST_INT
+ && operands[1] != CONST0_RTX (DImode)
+ && REG_P (operands[0])
+ && HARD_REGISTER_P (operands[0])
+ && REGNO (operands[0]) >= 32)
+ FAIL;
if (emit_move_sequence (operands, DImode, 0))
DONE;
}")
+;; Handle DImode input reloads requiring %r1 as a scratch register.
+(define_expand "reload_indi_r1"
+ [(set (match_operand:DI 0 "register_operand" "=Z")
+ (match_operand:DI 1 "non_hard_reg_operand" ""))
+ (clobber (match_operand:SI 2 "register_operand" "=&a"))]
+ ""
+ "
+{
+ if (emit_move_sequence (operands, DImode, operands[2]))
+ DONE;
+
+ /* We don't want the clobber emitted, so handle this ourselves. */
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
+ DONE;
+}")
+
+;; Handle DImode input reloads requiring a general register as a
+;; scratch register.
(define_expand "reload_indi"
[(set (match_operand:DI 0 "register_operand" "=Z")
(match_operand:DI 1 "non_hard_reg_operand" ""))
DONE;
}")
+;; Handle DImode output reloads requiring a general register as a
+;; scratch register.
(define_expand "reload_outdi"
[(set (match_operand:DI 0 "non_hard_reg_operand" "")
(match_operand:DI 1 "register_operand" "Z"))
rtx op0 = operands[0];
rtx op1 = operands[1];
- if (GET_CODE (op1) == CONST_INT)
+ switch (GET_CODE (op1))
{
+ case CONST_INT:
+#if HOST_BITS_PER_WIDE_INT <= 32
operands[0] = operand_subword (op0, 1, 0, DImode);
output_asm_insn (\"ldil L'%1,%0\", operands);
output_asm_insn (\"ldi -1,%0\", operands);
else
output_asm_insn (\"ldi 0,%0\", operands);
- return \"\";
- }
- else if (GET_CODE (op1) == CONST_DOUBLE)
- {
+#else
+ operands[0] = operand_subword (op0, 1, 0, DImode);
+ operands[1] = GEN_INT (INTVAL (op1) & 0xffffffff);
+ output_asm_insn (\"ldil L'%1,%0\", operands);
+
+ operands[0] = operand_subword (op0, 0, 0, DImode);
+ operands[1] = GEN_INT (INTVAL (op1) >> 32);
+ output_asm_insn (singlemove_string (operands), operands);
+#endif
+ break;
+
+ case CONST_DOUBLE:
operands[0] = operand_subword (op0, 1, 0, DImode);
operands[1] = GEN_INT (CONST_DOUBLE_LOW (op1));
output_asm_insn (\"ldil L'%1,%0\", operands);
operands[0] = operand_subword (op0, 0, 0, DImode);
operands[1] = GEN_INT (CONST_DOUBLE_HIGH (op1));
output_asm_insn (singlemove_string (operands), operands);
- return \"\";
+ break;
+
+ default:
+ gcc_unreachable ();
}
- else
- abort ();
+ return \"\";
}"
[(set_attr "type" "move")
- (set_attr "length" "8")])
+ (set_attr "length" "12")])
(define_insn ""
[(set (match_operand:DI 0 "move_dest_operand"
- "=r,o,Q,r,r,r,*f,*f,T")
+ "=r,o,Q,r,r,r,*f,*f,T,?r,?*f")
(match_operand:DI 1 "general_operand"
- "rM,r,r,o*R,Q,i,*fM,RT,*f"))]
+ "rM,r,r,o*R,Q,i,*fM,RT,*f,*f,r"))]
"(register_operand (operands[0], DImode)
|| reg_or_0_operand (operands[1], DImode))
&& !TARGET_64BIT
&& !TARGET_SOFT_FLOAT"
"*
{
- if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])
- || (operands[1] == CONST0_RTX (DImode)))
+ if ((FP_REG_P (operands[0]) || FP_REG_P (operands[1])
+ || operands[1] == CONST0_RTX (DFmode))
+ && !(REG_P (operands[0]) && REG_P (operands[1])
+ && FP_REG_P (operands[0]) ^ FP_REG_P (operands[1])))
return output_fp_move_double (operands);
return output_move_double (operands);
}"
- [(set_attr "type" "move,store,store,load,load,multi,fpalu,fpload,fpstore")
- (set_attr "length" "8,8,16,8,16,16,4,4,4")])
+ [(set_attr "type"
+ "move,store,store,load,load,multi,fpalu,fpload,fpstore,fpstore_load,store_fpload")
+ (set_attr "length" "8,8,16,8,16,16,4,4,4,12,12")])
(define_insn ""
[(set (match_operand:DI 0 "move_dest_operand"
- "=r,r,r,r,r,r,Q,!*q,!*f,*f,T")
+ "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T")
(match_operand:DI 1 "move_src_operand"
- "A,r,J,N,K,RQ,rM,!rM,!*fM,RT,*f"))]
+ "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f"))]
"(register_operand (operands[0], DImode)
|| reg_or_0_operand (operands[1], DImode))
&& !TARGET_SOFT_FLOAT && TARGET_64BIT"
ldd%M1 %1,%0
std%M0 %r1,%0
mtsar %r1
+ {mfctl|mfctl,w} %%sar,%0
fcpy,dbl %f1,%0
fldd%F1 %1,%0
fstd%F0 %1,%0"
- [(set_attr "type" "load,move,move,move,shift,load,store,move,fpalu,fpload,fpstore")
+ [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore")
(set_attr "pa_combine_type" "addmove")
- (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4")])
+ (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4")])
(define_insn ""
[(set (match_operand:DI 0 "indexed_memory_operand" "=R")
(set (mem:DI (match_dup 0))
(match_operand:DI 3 "register_operand" ""))]
"!TARGET_SOFT_FLOAT
+ && !TARGET_DISABLE_INDEXING
&& TARGET_64BIT
&& REG_OK_FOR_BASE_P (operands[2])
&& FP_REGNO_P (REGNO (operands[3]))"
(set (mem:DI (match_dup 0))
(match_operand:DI 3 "register_operand" ""))]
"!TARGET_SOFT_FLOAT
+ && !TARGET_DISABLE_INDEXING
&& TARGET_64BIT
&& REG_OK_FOR_BASE_P (operands[2])
&& FP_REGNO_P (REGNO (operands[3]))"
(set (mem:DI (match_dup 0))
(match_operand:DI 3 "register_operand" ""))]
"!TARGET_SOFT_FLOAT
+ && !TARGET_DISABLE_INDEXING
&& TARGET_64BIT
- && REG_OK_FOR_BASE_P (operands[1])
- && (TARGET_NO_SPACE_REGS
- || (!REG_POINTER (operands[1]) && REG_POINTER (operands[2])))
+ && TARGET_NO_SPACE_REGS
+ && REG_OK_FOR_INDEX_P (operands[1])
+ && REG_OK_FOR_BASE_P (operands[2])
&& FP_REGNO_P (REGNO (operands[3]))"
[(set (mem:DI (plus:DI (match_dup 1) (match_dup 2)))
(match_dup 3))
(set (mem:DI (match_dup 0))
(match_operand:DI 3 "register_operand" ""))]
"!TARGET_SOFT_FLOAT
+ && !TARGET_DISABLE_INDEXING
&& TARGET_64BIT
- && REG_OK_FOR_BASE_P (operands[2])
- && (TARGET_NO_SPACE_REGS
- || (REG_POINTER (operands[1]) && !REG_POINTER (operands[2])))
+ && TARGET_NO_SPACE_REGS
+ && REG_OK_FOR_BASE_P (operands[1])
+ && REG_OK_FOR_INDEX_P (operands[2])
&& FP_REGNO_P (REGNO (operands[3]))"
[(set (mem:DI (plus:DI (match_dup 2) (match_dup 1)))
(match_dup 3))
"!TARGET_64BIT"
"*
{
- /* Don't output a 64 bit constant, since we can't trust the assembler to
+ /* Don't output a 64-bit constant, since we can't trust the assembler to
handle it correctly. */
if (GET_CODE (operands[2]) == CONST_DOUBLE)
operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[2]));
+ else if (HOST_BITS_PER_WIDE_INT > 32
+ && GET_CODE (operands[2]) == CONST_INT)
+ operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffffffff);
if (which_alternative == 1)
output_asm_insn (\"copy %1,%0\", operands);
return \"ldo R'%G2(%R1),%R0\";
""
"
{
+ /* Reject CONST_DOUBLE loads to floating point registers. */
+ if (GET_CODE (operands[1]) == CONST_DOUBLE
+ && operands[1] != CONST0_RTX (SFmode)
+ && REG_P (operands[0])
+ && HARD_REGISTER_P (operands[0])
+ && REGNO (operands[0]) >= 32)
+ FAIL;
+
if (emit_move_sequence (operands, SFmode, 0))
DONE;
}")
-;; Reloading an SImode or DImode value requires a scratch register if
-;; going in to or out of float point registers.
-
+;; Handle SFmode input reloads requiring a general register as a
+;; scratch register.
(define_expand "reload_insf"
[(set (match_operand:SF 0 "register_operand" "=Z")
(match_operand:SF 1 "non_hard_reg_operand" ""))
DONE;
}")
+;; Handle SFmode output reloads requiring a general register as a
+;; scratch register.
(define_expand "reload_outsf"
[(set (match_operand:SF 0 "non_hard_reg_operand" "")
(match_operand:SF 1 "register_operand" "Z"))
(define_insn ""
[(set (match_operand:SF 0 "move_dest_operand"
+ "=f,!*r,f,*r,Q,Q,?*r,?f")
+ (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
+ "fG,!*rG,RQ,RQ,f,*rG,f,*r"))]
+ "(register_operand (operands[0], SFmode)
+ || reg_or_0_operand (operands[1], SFmode))
+ && !TARGET_SOFT_FLOAT
+ && !TARGET_64BIT"
+ "@
+ fcpy,sgl %f1,%0
+ copy %r1,%0
+ fldw%F1 %1,%0
+ ldw%M1 %1,%0
+ fstw%F0 %1,%0
+ stw%M0 %r1,%0
+ {fstws|fstw} %1,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0
+ {stws|stw} %1,-16(%%sp)\n\t{fldws|fldw} -16(%%sp),%0"
+ [(set_attr "type" "fpalu,move,fpload,load,fpstore,store,fpstore_load,store_fpload")
+ (set_attr "pa_combine_type" "addmove")
+ (set_attr "length" "4,4,4,4,4,4,8,8")])
+
+(define_insn ""
+ [(set (match_operand:SF 0 "move_dest_operand"
"=f,!*r,f,*r,Q,Q")
(match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
"fG,!*rG,RQ,RQ,f,*rG"))]
"(register_operand (operands[0], SFmode)
|| reg_or_0_operand (operands[1], SFmode))
- && !TARGET_SOFT_FLOAT"
+ && !TARGET_SOFT_FLOAT
+ && TARGET_64BIT"
"@
fcpy,sgl %f1,%0
copy %r1,%0
(set (mem:SF (match_dup 0))
(match_operand:SF 3 "register_operand" ""))]
"!TARGET_SOFT_FLOAT
+ && !TARGET_DISABLE_INDEXING
&& REG_OK_FOR_BASE_P (operands[2])
&& FP_REGNO_P (REGNO (operands[3]))"
[(set (mem:SF (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
(set (mem:SF (match_dup 0))
(match_operand:SF 3 "register_operand" ""))]
"!TARGET_SOFT_FLOAT
+ && !TARGET_DISABLE_INDEXING
&& REG_OK_FOR_BASE_P (operands[2])
&& FP_REGNO_P (REGNO (operands[3]))"
[(set (mem:SF (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
(set (mem:SF (match_dup 0))
(match_operand:SF 3 "register_operand" ""))]
"!TARGET_SOFT_FLOAT
+ && !TARGET_DISABLE_INDEXING
&& TARGET_64BIT
&& REG_OK_FOR_BASE_P (operands[2])
&& FP_REGNO_P (REGNO (operands[3]))"
(set (mem:SF (match_dup 0))
(match_operand:SF 3 "register_operand" ""))]
"!TARGET_SOFT_FLOAT
+ && !TARGET_DISABLE_INDEXING
&& TARGET_64BIT
&& REG_OK_FOR_BASE_P (operands[2])
&& FP_REGNO_P (REGNO (operands[3]))"
(set (mem:SF (match_dup 0))
(match_operand:SF 3 "register_operand" ""))]
"!TARGET_SOFT_FLOAT
- && REG_OK_FOR_BASE_P (operands[1])
- && (TARGET_NO_SPACE_REGS
- || (!REG_POINTER (operands[1]) && REG_POINTER (operands[2])))
+ && !TARGET_DISABLE_INDEXING
+ && TARGET_NO_SPACE_REGS
+ && REG_OK_FOR_INDEX_P (operands[1])
+ && REG_OK_FOR_BASE_P (operands[2])
&& FP_REGNO_P (REGNO (operands[3]))"
[(set (mem:SF (plus:SI (match_dup 1) (match_dup 2)))
(match_dup 3))
(set (mem:SF (match_dup 0))
(match_operand:SF 3 "register_operand" ""))]
"!TARGET_SOFT_FLOAT
- && REG_OK_FOR_BASE_P (operands[2])
- && (TARGET_NO_SPACE_REGS
- || (REG_POINTER (operands[1]) && !REG_POINTER (operands[2])))
+ && !TARGET_DISABLE_INDEXING
+ && TARGET_NO_SPACE_REGS
+ && REG_OK_FOR_BASE_P (operands[1])
+ && REG_OK_FOR_INDEX_P (operands[2])
&& FP_REGNO_P (REGNO (operands[3]))"
[(set (mem:SF (plus:SI (match_dup 2) (match_dup 1)))
(match_dup 3))
(set (mem:SF (match_dup 0))
(match_operand:SF 3 "register_operand" ""))]
"!TARGET_SOFT_FLOAT
+ && !TARGET_DISABLE_INDEXING
&& TARGET_64BIT
- && REG_OK_FOR_BASE_P (operands[1])
- && (TARGET_NO_SPACE_REGS
- || (!REG_POINTER (operands[1]) && REG_POINTER (operands[2])))
+ && TARGET_NO_SPACE_REGS
+ && REG_OK_FOR_INDEX_P (operands[1])
+ && REG_OK_FOR_BASE_P (operands[2])
&& FP_REGNO_P (REGNO (operands[3]))"
[(set (mem:SF (plus:DI (match_dup 1) (match_dup 2)))
(match_dup 3))
(set (mem:SF (match_dup 0))
(match_operand:SF 3 "register_operand" ""))]
"!TARGET_SOFT_FLOAT
+ && !TARGET_DISABLE_INDEXING
&& TARGET_64BIT
- && REG_OK_FOR_BASE_P (operands[2])
- && (TARGET_NO_SPACE_REGS
- || (REG_POINTER (operands[1]) && !REG_POINTER (operands[2])))
+ && TARGET_NO_SPACE_REGS
+ && REG_OK_FOR_BASE_P (operands[1])
+ && REG_OK_FOR_INDEX_P (operands[2])
&& FP_REGNO_P (REGNO (operands[3]))"
[(set (mem:SF (plus:DI (match_dup 2) (match_dup 1)))
(match_dup 3))
[(set_attr "type" "binary")
(set_attr "length" "4")])
+(define_expand "addvdi3"
+ [(parallel [(set (match_operand:DI 0 "register_operand" "")
+ (plus:DI (match_operand:DI 1 "reg_or_0_operand" "")
+ (match_operand:DI 2 "arith11_operand" "")))
+ (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
+ (sign_extend:TI (match_dup 2)))
+ (sign_extend:TI (plus:DI (match_dup 1)
+ (match_dup 2))))
+ (const_int 0))])]
+ ""
+ "")
+
+(define_insn ""
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+ (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rM,rM")
+ (match_operand:DI 2 "arith11_operand" "r,I")))
+ (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
+ (sign_extend:TI (match_dup 2)))
+ (sign_extend:TI (plus:DI (match_dup 1)
+ (match_dup 2))))
+ (const_int 0))]
+ "TARGET_64BIT"
+ "@
+ add,tsv,* %2,%1,%0
+ addi,tsv,* %2,%1,%0"
+ [(set_attr "type" "binary,binary")
+ (set_attr "length" "4,4")])
+
+(define_insn ""
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rM")
+ (match_operand:DI 2 "arith11_operand" "rI")))
+ (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
+ (sign_extend:TI (match_dup 2)))
+ (sign_extend:TI (plus:DI (match_dup 1)
+ (match_dup 2))))
+ (const_int 0))]
+ "!TARGET_64BIT"
+ "*
+{
+ if (GET_CODE (operands[2]) == CONST_INT)
+ {
+ if (INTVAL (operands[2]) >= 0)
+ return \"addi %2,%R1,%R0\;{addco|add,c,tsv} %1,%%r0,%0\";
+ else
+ return \"addi %2,%R1,%R0\;{subbo|sub,b,tsv} %1,%%r0,%0\";
+ }
+ else
+ return \"add %R2,%R1,%R0\;{addco|add,c,tsv} %2,%1,%0\";
+}"
+ [(set_attr "type" "binary")
+ (set_attr "length" "8")])
+
;; define_splits to optimize cases of adding a constant integer
;; to a register when the constant does not fit in 14 bits. */
(define_split
if (intval % 2 == 0 && cint_ok_for_move (intval / 2))
{
operands[2] = GEN_INT (intval / 2);
- operands[3] = GEN_INT (2);
+ operands[3] = const2_rtx;
}
else if (intval % 4 == 0 && cint_ok_for_move (intval / 4))
{
(set_attr "pa_combine_type" "addmove")
(set_attr "length" "4,4")])
+(define_insn "addvsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rM,rM")
+ (match_operand:SI 2 "arith11_operand" "r,I")))
+ (trap_if (ne (plus:DI (sign_extend:DI (match_dup 1))
+ (sign_extend:DI (match_dup 2)))
+ (sign_extend:DI (plus:SI (match_dup 1)
+ (match_dup 2))))
+ (const_int 0))]
+ ""
+ "@
+ {addo|add,tsv} %2,%1,%0
+ {addio|addi,tsv} %2,%1,%0"
+ [(set_attr "type" "binary,binary")
+ (set_attr "length" "4,4")])
+
(define_expand "subdi3"
[(set (match_operand:DI 0 "register_operand" "")
- (minus:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "register_operand" "")))]
+ (minus:DI (match_operand:DI 1 "arith11_operand" "")
+ (match_operand:DI 2 "reg_or_0_operand" "")))]
""
"")
(define_insn ""
- [(set (match_operand:DI 0 "register_operand" "=r")
- (minus:DI (match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "register_operand" "r")))]
- "!TARGET_64BIT"
- "sub %R1,%R2,%R0\;{subb|sub,b} %1,%2,%0"
- [(set_attr "type" "binary")
- (set_attr "length" "8")])
-
-(define_insn ""
[(set (match_operand:DI 0 "register_operand" "=r,r,!q")
(minus:DI (match_operand:DI 1 "arith11_operand" "r,I,!U")
- (match_operand:DI 2 "register_operand" "r,r,!r")))]
+ (match_operand:DI 2 "reg_or_0_operand" "rM,rM,!rM")))]
"TARGET_64BIT"
"@
sub %1,%2,%0
[(set_attr "type" "binary,binary,move")
(set_attr "length" "4,4,4")])
+(define_insn ""
+ [(set (match_operand:DI 0 "register_operand" "=r,&r")
+ (minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
+ (match_operand:DI 2 "reg_or_0_operand" "rM,rM")))]
+ "!TARGET_64BIT"
+ "*
+{
+ if (GET_CODE (operands[1]) == CONST_INT)
+ {
+ if (INTVAL (operands[1]) >= 0)
+ return \"subi %1,%R2,%R0\;{subb|sub,b} %%r0,%2,%0\";
+ else
+ return \"ldi -1,%0\;subi %1,%R2,%R0\;{subb|sub,b} %0,%2,%0\";
+ }
+ else
+ return \"sub %R1,%R2,%R0\;{subb|sub,b} %1,%2,%0\";
+}"
+ [(set_attr "type" "binary")
+ (set (attr "length")
+ (if_then_else (eq_attr "alternative" "0")
+ (const_int 8)
+ (if_then_else (ge (symbol_ref "INTVAL (operands[1])")
+ (const_int 0))
+ (const_int 8)
+ (const_int 12))))])
+
+(define_expand "subvdi3"
+ [(parallel [(set (match_operand:DI 0 "register_operand" "")
+ (minus:DI (match_operand:DI 1 "arith11_operand" "")
+ (match_operand:DI 2 "reg_or_0_operand" "")))
+ (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
+ (sign_extend:TI (match_dup 2)))
+ (sign_extend:TI (minus:DI (match_dup 1)
+ (match_dup 2))))
+ (const_int 0))])]
+ ""
+ "")
+
+(define_insn ""
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+ (minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
+ (match_operand:DI 2 "reg_or_0_operand" "rM,rM")))
+ (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
+ (sign_extend:TI (match_dup 2)))
+ (sign_extend:TI (minus:DI (match_dup 1)
+ (match_dup 2))))
+ (const_int 0))]
+ "TARGET_64BIT"
+ "@
+ {subo|sub,tsv} %1,%2,%0
+ {subio|subi,tsv} %1,%2,%0"
+ [(set_attr "type" "binary,binary")
+ (set_attr "length" "4,4")])
+
+(define_insn ""
+ [(set (match_operand:DI 0 "register_operand" "=r,&r")
+ (minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
+ (match_operand:DI 2 "reg_or_0_operand" "rM,rM")))
+ (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
+ (sign_extend:TI (match_dup 2)))
+ (sign_extend:TI (minus:DI (match_dup 1)
+ (match_dup 2))))
+ (const_int 0))]
+ "!TARGET_64BIT"
+ "*
+{
+ if (GET_CODE (operands[1]) == CONST_INT)
+ {
+ if (INTVAL (operands[1]) >= 0)
+ return \"subi %1,%R2,%R0\;{subbo|sub,b,tsv} %%r0,%2,%0\";
+ else
+ return \"ldi -1,%0\;subi %1,%R2,%R0\;{subbo|sub,b,tsv} %0,%2,%0\";
+ }
+ else
+ return \"sub %R1,%R2,%R0\;{subbo|sub,b,tsv} %1,%2,%0\";
+}"
+ [(set_attr "type" "binary,binary")
+ (set (attr "length")
+ (if_then_else (eq_attr "alternative" "0")
+ (const_int 8)
+ (if_then_else (ge (symbol_ref "INTVAL (operands[1])")
+ (const_int 0))
+ (const_int 8)
+ (const_int 12))))])
+
(define_expand "subsi3"
[(set (match_operand:SI 0 "register_operand" "")
(minus:SI (match_operand:SI 1 "arith11_operand" "")
[(set_attr "type" "binary,binary,move")
(set_attr "length" "4,4,4")])
+(define_insn "subvsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (minus:SI (match_operand:SI 1 "arith11_operand" "rM,I")
+ (match_operand:SI 2 "reg_or_0_operand" "rM,rM")))
+ (trap_if (ne (minus:DI (sign_extend:DI (match_dup 1))
+ (sign_extend:DI (match_dup 2)))
+ (sign_extend:DI (minus:SI (match_dup 1)
+ (match_dup 2))))
+ (const_int 0))]
+ ""
+ "@
+ {subo|sub,tsv} %1,%2,%0
+ {subio|subi,tsv} %1,%2,%0"
+ [(set_attr "type" "binary,binary")
+ (set_attr "length" "4,4")])
+
;; Clobbering a "register_operand" instead of a match_scratch
;; in operand3 of millicode calls avoids spilling %r1 and
;; produces better code.
(clobber (reg:SI 26))
(clobber (reg:SI 25))
(clobber (match_dup 4))])
- (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
+ (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
""
"
{
GEN_INT (32)));
emit_move_insn (op2shifted, gen_rtx_LSHIFTRT (DImode, operands[2],
GEN_INT (32)));
- op1r = gen_rtx_SUBREG (SImode, operands[1], 4);
- op2r = gen_rtx_SUBREG (SImode, operands[2], 4);
- op1l = gen_rtx_SUBREG (SImode, op1shifted, 4);
- op2l = gen_rtx_SUBREG (SImode, op2shifted, 4);
+ op1r = force_reg (SImode, gen_rtx_SUBREG (SImode, operands[1], 4));
+ op2r = force_reg (SImode, gen_rtx_SUBREG (SImode, operands[2], 4));
+ op1l = force_reg (SImode, gen_rtx_SUBREG (SImode, op1shifted, 4));
+ op2l = force_reg (SImode, gen_rtx_SUBREG (SImode, op2shifted, 4));
/* Emit multiplies for the cross products. */
emit_insn (gen_umulsidi3 (cross_product1, op2r, op1l));
(clobber (reg:SI 26))
(clobber (reg:SI 25))
(clobber (match_dup 5))])
- (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
+ (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
""
"
{
(clobber (reg:SI 26))
(clobber (reg:SI 25))
(clobber (match_dup 5))])
- (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
+ (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
""
"
{
(clobber (reg:SI 26))
(clobber (reg:SI 25))
(clobber (match_dup 5))])
- (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
+ (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
""
"
{
(clobber (reg:SI 26))
(clobber (reg:SI 25))
(clobber (match_dup 5))])
- (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
+ (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
""
"
{
(define_expand "anddi3"
[(set (match_operand:DI 0 "register_operand" "")
- (and:DI (match_operand:DI 1 "arith_double_operand" "")
- (match_operand:DI 2 "arith_double_operand" "")))]
+ (and:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:DI 2 "and_operand" "")))]
""
"
{
- if (! register_operand (operands[1], DImode)
- || ! register_operand (operands[2], DImode))
- /* Let GCC break this into word-at-a-time operations. */
+ /* Both operands must be register operands. */
+ if (!TARGET_64BIT && !register_operand (operands[2], DImode))
FAIL;
}")
(define_expand "iordi3"
[(set (match_operand:DI 0 "register_operand" "")
- (ior:DI (match_operand:DI 1 "arith_double_operand" "")
- (match_operand:DI 2 "arith_double_operand" "")))]
+ (ior:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:DI 2 "ior_operand" "")))]
""
"
{
- if (! register_operand (operands[1], DImode)
- || ! register_operand (operands[2], DImode))
- /* Let GCC break this into word-at-a-time operations. */
+ /* Both operands must be register operands. */
+ if (!TARGET_64BIT && !register_operand (operands[2], DImode))
FAIL;
}")
(define_expand "xordi3"
[(set (match_operand:DI 0 "register_operand" "")
- (xor:DI (match_operand:DI 1 "arith_double_operand" "")
- (match_operand:DI 2 "arith_double_operand" "")))]
+ (xor:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:DI 2 "register_operand" "")))]
""
"
{
- if (! register_operand (operands[1], DImode)
- || ! register_operand (operands[2], DImode))
- /* Let GCC break this into word-at-a-time operations. */
- FAIL;
}")
(define_insn ""
[(set_attr "type" "binary")
(set_attr "length" "4")])
-(define_expand "negdi2"
- [(set (match_operand:DI 0 "register_operand" "")
- (neg:DI (match_operand:DI 1 "register_operand" "")))]
+(define_expand "negdi2"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (neg:DI (match_operand:DI 1 "register_operand" "")))]
+ ""
+ "")
+
+(define_insn ""
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (neg:DI (match_operand:DI 1 "register_operand" "r")))]
+ "!TARGET_64BIT"
+ "sub %%r0,%R1,%R0\;{subb|sub,b} %%r0,%1,%0"
+ [(set_attr "type" "unary")
+ (set_attr "length" "8")])
+
+(define_insn ""
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (neg:DI (match_operand:DI 1 "register_operand" "r")))]
+ "TARGET_64BIT"
+ "sub %%r0,%1,%0"
+ [(set_attr "type" "unary")
+ (set_attr "length" "4")])
+
+(define_expand "negvdi2"
+ [(parallel [(set (match_operand:DI 0 "register_operand" "")
+ (neg:DI (match_operand:DI 1 "register_operand" "")))
+ (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
+ (sign_extend:TI (neg:DI (match_dup 1))))
+ (const_int 0))])]
""
"")
(define_insn ""
[(set (match_operand:DI 0 "register_operand" "=r")
- (neg:DI (match_operand:DI 1 "register_operand" "r")))]
+ (neg:DI (match_operand:DI 1 "register_operand" "r")))
+ (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
+ (sign_extend:TI (neg:DI (match_dup 1))))
+ (const_int 0))]
"!TARGET_64BIT"
- "sub %%r0,%R1,%R0\;{subb|sub,b} %%r0,%1,%0"
+ "sub %%r0,%R1,%R0\;{subbo|sub,b,tsv} %%r0,%1,%0"
[(set_attr "type" "unary")
(set_attr "length" "8")])
(define_insn ""
[(set (match_operand:DI 0 "register_operand" "=r")
- (neg:DI (match_operand:DI 1 "register_operand" "r")))]
+ (neg:DI (match_operand:DI 1 "register_operand" "r")))
+ (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
+ (sign_extend:TI (neg:DI (match_dup 1))))
+ (const_int 0))]
"TARGET_64BIT"
- "sub %%r0,%1,%0"
+ "sub,tsv %%r0,%1,%0"
[(set_attr "type" "unary")
(set_attr "length" "4")])
[(set_attr "type" "unary")
(set_attr "length" "4")])
+(define_insn "negvsi2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (neg:SI (match_operand:SI 1 "register_operand" "r")))
+ (trap_if (ne (neg:DI (sign_extend:DI (match_dup 1)))
+ (sign_extend:DI (neg:SI (match_dup 1))))
+ (const_int 0))]
+ ""
+ "{subo|sub,tsv} %%r0,%1,%0"
+ [(set_attr "type" "unary")
+ (set_attr "length" "4")])
+
(define_expand "one_cmpldi2"
[(set (match_operand:DI 0 "register_operand" "")
- (not:DI (match_operand:DI 1 "arith_double_operand" "")))]
+ (not:DI (match_operand:DI 1 "register_operand" "")))]
""
"
{
- if (! register_operand (operands[1], DImode))
- FAIL;
}")
(define_insn ""
(match_operand:SI 2 "register_operand" "q")))
(match_operand:SI 3 "register_operand" "0")))]
; accept ...0001...1, can this be generalized?
- "exact_log2 (INTVAL (operands[1]) + 1) >= 0"
+ "exact_log2 (INTVAL (operands[1]) + 1) > 0"
"*
{
int x = INTVAL (operands[1]);
(match_operand:DI 2 "register_operand" "q")))
(match_operand:DI 3 "register_operand" "0")))]
; accept ...0001...1, can this be generalized?
- "TARGET_64BIT && exact_log2 (INTVAL (operands[1]) + 1) >= 0"
+ "TARGET_64BIT && exact_log2 (INTVAL (operands[1]) + 1) > 0"
"*
{
int x = INTVAL (operands[1]);
(and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "const_int_operand" ""))
(match_operand:SI 3 "const_int_operand" "")))]
- "exact_log2 (1 + (INTVAL (operands[3]) >> (INTVAL (operands[2]) & 31))) >= 0"
+ "exact_log2 (1 + (INTVAL (operands[3]) >> (INTVAL (operands[2]) & 31))) > 0"
"*
{
int cnt = INTVAL (operands[2]) & 31;
\f
;; Unconditional and other jump instructions.
-;; This can only be used in a leaf function, so we do
-;; not need to use the PIC register when generating PIC code.
-(define_insn "return"
- [(return)
- (use (reg:SI 2))
- (const_int 0)]
- "hppa_can_use_return_insn_p ()"
- "*
-{
- if (TARGET_PA_20)
- return \"bve%* (%%r2)\";
- return \"bv%* %%r0(%%r2)\";
-}"
- [(set_attr "type" "branch")
- (set_attr "length" "4")])
-
-;; Emit a different pattern for functions which have non-trivial
-;; epilogues so as not to confuse jump and reorg.
+;; This is used for most returns.
(define_insn "return_internal"
[(return)
- (use (reg:SI 2))
- (const_int 1)]
+ (use (reg:SI 2))]
""
"*
{
""
"
{
- /* Try to use the trivial return first. Else use the full
- epilogue. */
- if (hppa_can_use_return_insn_p ())
- emit_jump_insn (gen_return ());
+ rtx x;
+
+ /* Try to use the trivial return first. Else use the full epilogue. */
+ if (reload_completed
+ && !frame_pointer_needed
+ && !df_regs_ever_live_p (2)
+ && (compute_frame_size (get_frame_size (), 0) ? 0 : 1))
+ x = gen_return_internal ();
else
{
- rtx x;
-
hppa_expand_epilogue ();
/* EH returns bypass the normal return stub. Thus, we must do an
x = gen_return_external_pic ();
else
x = gen_return_internal ();
-
- emit_jump_insn (x);
}
+ emit_jump_insn (x);
DONE;
}")
(set_attr "length" "4")])
(define_insn "blockage"
- [(unspec_volatile [(const_int 2)] 0)]
+ [(unspec_volatile [(const_int 2)] UNSPECV_BLOCKAGE)]
""
""
[(set_attr "length" "0")])
"*
{
/* An unconditional branch which can reach its target. */
- if (get_attr_length (insn) != 24
- && get_attr_length (insn) != 16)
+ if (get_attr_length (insn) < 16)
return \"b%* %l0\";
- return output_lbranch (operands[0], insn);
+ return output_lbranch (operands[0], insn, 1);
}"
[(set_attr "type" "uncond_branch")
(set_attr "pa_combine_type" "uncond_branch")
(cond [(eq (symbol_ref "jump_in_call_delay (insn)") (const_int 1))
(if_then_else (lt (abs (minus (match_dup 0)
(plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8))
- (ge (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 262100))
- (if_then_else (eq (symbol_ref "flag_pic") (const_int 0))
- (const_int 16)
- (const_int 24))]
- (const_int 4)))])
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 4)
+ (const_int 8))
+ (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 4)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 20)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 16)]
+ (const_int 24)))])
;;; Hope this is only within a function...
(define_insn "indirect_jump"
[(set_attr "type" "branch")
(set_attr "length" "4")])
+;;; An indirect jump can be optimized to a direct jump. GAS for the
+;;; SOM target doesn't allow branching to a label inside a function.
+;;; We also don't correctly compute branch distances for labels
+;;; outside the current function. Thus, we use an indirect jump can't
+;;; be optimized to a direct jump for all targets. We assume that
+;;; the branch target is in the same space (i.e., nested function
+;;; jumping to a label in an outer function in the same translation
+;;; unit).
+(define_expand "nonlocal_goto"
+ [(use (match_operand 0 "general_operand" ""))
+ (use (match_operand 1 "general_operand" ""))
+ (use (match_operand 2 "general_operand" ""))
+ (use (match_operand 3 "general_operand" ""))]
+ ""
+{
+ rtx lab = operands[1];
+ rtx stack = operands[2];
+ rtx fp = operands[3];
+
+ lab = copy_to_reg (lab);
+
+ emit_insn (gen_rtx_CLOBBER (VOIDmode,
+ gen_rtx_MEM (BLKmode,
+ gen_rtx_SCRATCH (VOIDmode))));
+ emit_insn (gen_rtx_CLOBBER (VOIDmode,
+ gen_rtx_MEM (BLKmode,
+ hard_frame_pointer_rtx)));
+
+ /* Restore the frame pointer. The virtual_stack_vars_rtx is saved
+ instead of the hard_frame_pointer_rtx in the save area. As a
+ result, an extra instruction is needed to adjust for the offset
+ of the virtual stack variables and the frame pointer. */
+ if (GET_CODE (fp) != REG)
+ fp = force_reg (Pmode, fp);
+ emit_move_insn (virtual_stack_vars_rtx, fp);
+
+ emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
+
+ emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
+ emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
+
+ /* Nonlocal goto jumps are only used between functions in the same
+ translation unit. Thus, we can avoid the extra overhead of an
+ interspace jump. */
+ emit_jump_insn (gen_indirect_goto (lab));
+ emit_barrier ();
+ DONE;
+})
+
+(define_insn "indirect_goto"
+ [(unspec [(match_operand 0 "register_operand" "=r")] UNSPEC_GOTO)]
+ "GET_MODE (operands[0]) == word_mode"
+ "bv%* %%r0(%0)"
+ [(set_attr "type" "branch")
+ (set_attr "length" "4")])
+
;;; This jump is used in branch tables where the insn length is fixed.
;;; The length of this insn is adjusted if the delay slot is not filled.
(define_insn "short_jump"
the only method that we have for doing DImode multiplication
is with a libcall. This could be trouble if we haven't
allocated enough space for the outgoing arguments. */
- if (INTVAL (nb) > current_function_outgoing_args_size)
- abort ();
+ gcc_assert (INTVAL (nb) <= current_function_outgoing_args_size);
emit_move_insn (arg_pointer_rtx,
gen_rtx_PLUS (word_mode, stack_pointer_rtx,
the only method that we have for doing DImode multiplication
is with a libcall. This could be trouble if we haven't
allocated enough space for the outgoing arguments. */
- if (INTVAL (nb) > current_function_outgoing_args_size)
- abort ();
+ gcc_assert (INTVAL (nb) <= current_function_outgoing_args_size);
emit_move_insn (arg_pointer_rtx,
gen_rtx_PLUS (word_mode, stack_pointer_rtx,
the only method that we have for doing DImode multiplication
is with a libcall. This could be trouble if we haven't
allocated enough space for the outgoing arguments. */
- if (INTVAL (nb) > current_function_outgoing_args_size)
- abort ();
+ gcc_assert (INTVAL (nb) <= current_function_outgoing_args_size);
emit_move_insn (arg_pointer_rtx,
gen_rtx_PLUS (word_mode, stack_pointer_rtx,
the only method that we have for doing DImode multiplication
is with a libcall. This could be trouble if we haven't
allocated enough space for the outgoing arguments. */
- if (INTVAL (nb) > current_function_outgoing_args_size)
- abort ();
+ gcc_assert (INTVAL (nb) <= current_function_outgoing_args_size);
emit_move_insn (arg_pointer_rtx,
gen_rtx_PLUS (word_mode, stack_pointer_rtx,
[(set (pc) (match_operand 0 "pmode_register_operand" "a"))
(clobber (reg:SI 2))]
"!TARGET_64BIT"
- "ldsid (%%sr0,%0),%%r2\; mtsp %%r2,%%sr0\; be%* 0(%%sr0,%0)"
+ "ldsid (%%sr0,%0),%%r2\;mtsp %%r2,%%sr0\;be%* 0(%%sr0,%0)"
[(set_attr "type" "branch")
(set_attr "length" "12")])
(set_attr "length" "4")])
(define_expand "builtin_longjmp"
- [(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)]
+ [(unspec_volatile [(match_operand 0 "register_operand" "r")] UNSPECV_LONGJMP)]
""
"
{
(POINTER_SIZE * 2) / BITS_PER_UNIT));
rtx pv = gen_rtx_REG (Pmode, 1);
+ emit_insn (gen_rtx_CLOBBER (VOIDmode,
+ gen_rtx_MEM (BLKmode,
+ gen_rtx_SCRATCH (VOIDmode))));
+ emit_insn (gen_rtx_CLOBBER (VOIDmode,
+ gen_rtx_MEM (BLKmode,
+ hard_frame_pointer_rtx)));
+
+ /* Restore the frame pointer. The virtual_stack_vars_rtx is saved
+ instead of the hard_frame_pointer_rtx in the save area. We need
+ to adjust for the offset between these two values when we have
+ a nonlocal_goto pattern. When we don't have a nonlocal_goto
+ pattern, the receiver performs the adjustment. */
+#ifdef HAVE_nonlocal_goto
+ if (HAVE_nonlocal_goto)
+ emit_move_insn (virtual_stack_vars_rtx, force_reg (Pmode, fp));
+ else
+#endif
+ emit_move_insn (hard_frame_pointer_rtx, fp);
+
/* This bit is the same as expand_builtin_longjmp. */
- emit_move_insn (hard_frame_pointer_rtx, fp);
emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
(if_then_else (eq_attr "alternative" "0")
;; Loop counter in register case
;; Short branch has length of 4
-;; Long branch has length of 8
- (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8))
+;; Long branch has length of 8, 20, 24 or 28
+ (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 4)
+ (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 24)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 20)]
+ (const_int 28))
;; Loop counter in FP reg case.
;; Extra goo to deal with additional reload insns.
(if_then_else (eq_attr "alternative" "1")
(if_then_else (lt (match_dup 3) (pc))
- (if_then_else
- (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
- (const_int 8184))
- (const_int 24)
- (const_int 28))
- (if_then_else
- (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 24)
- (const_int 28)))
+ (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 24)
+ (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 28)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 44)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 40)]
+ (const_int 48))
+ (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 24)
+ (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 28)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 44)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 40)]
+ (const_int 48)))
+
;; Loop counter in memory case.
;; Extra goo to deal with additional reload insns.
(if_then_else (lt (match_dup 3) (pc))
- (if_then_else
- (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
- (const_int 8184))
- (const_int 12)
- (const_int 16))
- (if_then_else
- (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 12)
- (const_int 16))))))])
+ (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 12)
+ (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 16)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 32)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 28)]
+ (const_int 36))
+ (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 12)
+ (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 16)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 32)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 28)]
+ (const_int 36))))))])
(define_insn ""
[(set (pc)
(if_then_else (eq_attr "alternative" "0")
;; Loop counter in register case
;; Short branch has length of 4
-;; Long branch has length of 8
- (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8))
+;; Long branch has length of 8, 20, 24 or 28
+ (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 4)
+ (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 24)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 20)]
+ (const_int 28))
;; Loop counter in FP reg case.
;; Extra goo to deal with additional reload insns.
(if_then_else (eq_attr "alternative" "1")
(if_then_else (lt (match_dup 3) (pc))
- (if_then_else
- (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
- (const_int 8184))
- (const_int 12)
- (const_int 16))
- (if_then_else
- (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 12)
- (const_int 16)))
+ (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 12)
+ (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 16)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 32)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 28)]
+ (const_int 36))
+ (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 12)
+ (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 16)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 32)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 28)]
+ (const_int 36)))
+
;; Loop counter in memory or sar case.
;; Extra goo to deal with additional reload insns.
- (if_then_else
- (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 8)
- (const_int 12)))))])
+ (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 8)
+ (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 12)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 28)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 24)]
+ (const_int 32)))))])
;; Handle negated branch.
(define_insn ""
;; Loop counter in register case
;; Short branch has length of 4
;; Long branch has length of 8
- (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8))
+ (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 4)
+ (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 24)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 20)]
+ (const_int 28))
;; Loop counter in FP reg case.
;; Extra goo to deal with additional reload insns.
(if_then_else (eq_attr "alternative" "1")
(if_then_else (lt (match_dup 3) (pc))
- (if_then_else
- (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
- (const_int 8184))
- (const_int 12)
- (const_int 16))
- (if_then_else
- (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 12)
- (const_int 16)))
+ (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 12)
+ (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 16)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 32)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 28)]
+ (const_int 36))
+ (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 12)
+ (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 16)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 32)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 28)]
+ (const_int 36)))
+
;; Loop counter in memory or SAR case.
;; Extra goo to deal with additional reload insns.
- (if_then_else
- (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 8)
- (const_int 12)))))])
+ (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 8)
+ (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 12)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 28)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 24)]
+ (const_int 32)))))])
(define_insn ""
[(set (pc) (label_ref (match_operand 3 "" "" )))
"(reload_completed && operands[0] == operands[1]) || operands[0] == operands[2]"
"*
{
- return output_parallel_addb (operands, get_attr_length (insn));
+ return output_parallel_addb (operands, insn);
}"
- [(set_attr "type" "parallel_branch")
- (set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
+[(set_attr "type" "parallel_branch")
+ (set (attr "length")
+ (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 4)
+ (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 24)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc) (label_ref (match_operand 2 "" "" )))
"reload_completed"
"*
{
- return output_parallel_movb (operands, get_attr_length (insn));
+ return output_parallel_movb (operands, insn);
}"
- [(set_attr "type" "parallel_branch")
- (set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
+[(set_attr "type" "parallel_branch")
+ (set (attr "length")
+ (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 4)
+ (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 24)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc) (label_ref (match_operand 2 "" "" )))
"reload_completed"
"*
{
- return output_parallel_movb (operands, get_attr_length (insn));
+ return output_parallel_movb (operands, insn);
}"
- [(set_attr "type" "parallel_branch")
- (set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
+[(set_attr "type" "parallel_branch")
+ (set (attr "length")
+ (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 4)
+ (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 24)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc) (label_ref (match_operand 2 "" "" )))
"reload_completed"
"*
{
- return output_parallel_movb (operands, get_attr_length (insn));
+ return output_parallel_movb (operands, insn);
}"
- [(set_attr "type" "parallel_branch")
- (set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
+[(set_attr "type" "parallel_branch")
+ (set (attr "length")
+ (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 4)
+ (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 24)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (pc) (label_ref (match_operand 2 "" "" )))
"reload_completed"
"*
{
- return output_parallel_movb (operands, get_attr_length (insn));
+ return output_parallel_movb (operands, insn);
}"
- [(set_attr "type" "parallel_branch")
- (set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
+[(set_attr "type" "parallel_branch")
+ (set (attr "length")
+ (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_12BIT_OFFSET))
+ (const_int 4)
+ (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
+ (const_int MAX_17BIT_OFFSET))
+ (const_int 8)
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
+ (const_int 24)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 20)]
+ (const_int 28)))])
(define_insn ""
[(set (match_operand 0 "register_operand" "=f")
[(set_attr "type" "fpalu")
(set_attr "length" "4")])
-;; Clean up turds left by reload.
-(define_peephole
- [(set (match_operand 0 "move_dest_operand" "")
- (match_operand 1 "register_operand" "fr"))
- (set (match_operand 2 "register_operand" "fr")
- (match_dup 0))]
- "!TARGET_SOFT_FLOAT
- && GET_CODE (operands[0]) == MEM
- && ! MEM_VOLATILE_P (operands[0])
- && GET_MODE (operands[0]) == GET_MODE (operands[1])
- && GET_MODE (operands[0]) == GET_MODE (operands[2])
- && GET_MODE (operands[0]) == DFmode
- && GET_CODE (operands[1]) == REG
- && GET_CODE (operands[2]) == REG
- && ! side_effects_p (XEXP (operands[0], 0))
- && REGNO_REG_CLASS (REGNO (operands[1]))
- == REGNO_REG_CLASS (REGNO (operands[2]))"
- "*
-{
- rtx xoperands[2];
-
- if (FP_REG_P (operands[1]))
- output_asm_insn (output_fp_move_double (operands), operands);
- else
- output_asm_insn (output_move_double (operands), operands);
-
- if (rtx_equal_p (operands[1], operands[2]))
- return \"\";
-
- xoperands[0] = operands[2];
- xoperands[1] = operands[1];
-
- if (FP_REG_P (xoperands[1]))
- output_asm_insn (output_fp_move_double (xoperands), xoperands);
- else
- output_asm_insn (output_move_double (xoperands), xoperands);
-
- return \"\";
-}")
-
-(define_peephole
- [(set (match_operand 0 "register_operand" "fr")
- (match_operand 1 "move_src_operand" ""))
- (set (match_operand 2 "register_operand" "fr")
- (match_dup 1))]
- "!TARGET_SOFT_FLOAT
- && GET_CODE (operands[1]) == MEM
- && ! MEM_VOLATILE_P (operands[1])
- && GET_MODE (operands[0]) == GET_MODE (operands[1])
- && GET_MODE (operands[0]) == GET_MODE (operands[2])
- && GET_MODE (operands[0]) == DFmode
- && GET_CODE (operands[0]) == REG
- && GET_CODE (operands[2]) == REG
- && ! side_effects_p (XEXP (operands[1], 0))
- && REGNO_REG_CLASS (REGNO (operands[0]))
- == REGNO_REG_CLASS (REGNO (operands[2]))"
- "*
-{
- rtx xoperands[2];
-
- if (FP_REG_P (operands[0]))
- output_asm_insn (output_fp_move_double (operands), operands);
- else
- output_asm_insn (output_move_double (operands), operands);
-
- xoperands[0] = operands[2];
- xoperands[1] = operands[0];
-
- if (FP_REG_P (xoperands[1]))
- output_asm_insn (output_fp_move_double (xoperands), xoperands);
- else
- output_asm_insn (output_move_double (xoperands), xoperands);
-
- return \"\";
-}")
-
-;; Flush the I and D cache line found at the address in operand 0.
+;; Flush the I and D cache lines from the start address (operand0)
+;; to the end address (operand1). No lines are flushed if the end
+;; address is less than the start address (unsigned).
+;;
+;; Because the range of memory flushed is variable and the size of
+;; a MEM can only be a CONST_INT, the patterns specify that they
+;; perform an unspecified volatile operation on all memory.
+;;
+;; The address range for an icache flush must lie within a single
+;; space on targets with non-equivalent space registers.
+;;
;; This is used by the trampoline code for nested functions.
-;; So long as the trampoline itself is less than 32 bytes this
-;; is sufficient.
-
+;;
+;; Operand 0 contains the start address.
+;; Operand 1 contains the end address.
+;; Operand 2 contains the line length to use.
+;; Operands 3 and 4 (icacheflush) are clobbered scratch registers.
(define_insn "dcacheflush"
- [(unspec_volatile [(const_int 1)] 0)
- (use (mem:SI (match_operand 0 "pmode_register_operand" "r")))
- (use (mem:SI (match_operand 1 "pmode_register_operand" "r")))]
+ [(const_int 1)
+ (unspec_volatile [(mem:BLK (scratch))] UNSPECV_DCACHE)
+ (use (match_operand 0 "pmode_register_operand" "r"))
+ (use (match_operand 1 "pmode_register_operand" "r"))
+ (use (match_operand 2 "pmode_register_operand" "r"))
+ (clobber (match_scratch 3 "=&0"))]
""
- "fdc 0(%0)\;fdc 0(%1)\;sync"
+ "*
+{
+ if (TARGET_64BIT)
+ return \"cmpb,*<<=,n %3,%1,.\;fdc,m %2(%3)\;sync\";
+ else
+ return \"cmpb,<<=,n %3,%1,.\;fdc,m %2(%3)\;sync\";
+}"
[(set_attr "type" "multi")
(set_attr "length" "12")])
(define_insn "icacheflush"
- [(unspec_volatile [(const_int 2)] 0)
- (use (mem:SI (match_operand 0 "pmode_register_operand" "r")))
- (use (mem:SI (match_operand 1 "pmode_register_operand" "r")))
+ [(const_int 2)
+ (unspec_volatile [(mem:BLK (scratch))] UNSPECV_ICACHE)
+ (use (match_operand 0 "pmode_register_operand" "r"))
+ (use (match_operand 1 "pmode_register_operand" "r"))
(use (match_operand 2 "pmode_register_operand" "r"))
(clobber (match_operand 3 "pmode_register_operand" "=&r"))
- (clobber (match_operand 4 "pmode_register_operand" "=&r"))]
+ (clobber (match_operand 4 "pmode_register_operand" "=&r"))
+ (clobber (match_scratch 5 "=&0"))]
""
- "mfsp %%sr0,%4\;ldsid (%2),%3\;mtsp %3,%%sr0\;fic 0(%%sr0,%0)\;fic 0(%%sr0,%1)\;sync\;mtsp %4,%%sr0\;nop\;nop\;nop\;nop\;nop\;nop"
+ "*
+{
+ if (TARGET_64BIT)
+ return \"mfsp %%sr0,%4\;ldsid (%5),%3\;mtsp %3,%%sr0\;cmpb,*<<=,n %5,%1,.\;fic,m %2(%%sr0,%5)\;sync\;mtsp %4,%%sr0\;nop\;nop\;nop\;nop\;nop\;nop\";
+ else
+ return \"mfsp %%sr0,%4\;ldsid (%5),%3\;mtsp %3,%%sr0\;cmpb,<<=,n %5,%1,.\;fic,m %2(%%sr0,%5)\;sync\;mtsp %4,%%sr0\;nop\;nop\;nop\;nop\;nop\;nop\";
+}"
[(set_attr "type" "multi")
(set_attr "length" "52")])
;; An out-of-line prologue.
(define_insn "outline_prologue_call"
- [(unspec_volatile [(const_int 0)] 0)
+ [(unspec_volatile [(const_int 0)] UNSPECV_OPC)
(clobber (reg:SI 31))
(clobber (reg:SI 22))
(clobber (reg:SI 21))
;; An out-of-line epilogue.
(define_insn "outline_epilogue_call"
- [(unspec_volatile [(const_int 1)] 0)
+ [(unspec_volatile [(const_int 1)] UNSPECV_OEC)
(use (reg:SI 29))
(use (reg:SI 28))
(clobber (reg:SI 31))
;; reliably compared to another function pointer. */
(define_expand "canonicalize_funcptr_for_compare"
[(set (reg:SI 26) (match_operand:SI 1 "register_operand" ""))
- (parallel [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] 0))
+ (parallel [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] UNSPEC_CFFC))
(clobber (match_dup 2))
(clobber (reg:SI 26))
(clobber (reg:SI 22))
}
}")
-(define_insn ""
- [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] 0))
+(define_insn "*$$sh_func_adrs"
+ [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] UNSPEC_CFFC))
(clobber (match_operand:SI 0 "register_operand" "=a"))
(clobber (reg:SI 26))
(clobber (reg:SI 22))
}
DONE;
}")
+
+(define_expand "prefetch"
+ [(match_operand 0 "address_operand" "")
+ (match_operand 1 "const_int_operand" "")
+ (match_operand 2 "const_int_operand" "")]
+ "TARGET_PA_20"
+{
+ int locality = INTVAL (operands[2]);
+
+ gcc_assert (locality >= 0 && locality <= 3);
+
+ /* Change operand[0] to a MEM as we don't have the infrastructure
+ to output all the supported address modes for ldw/ldd when we use
+ the address directly. However, we do have it for MEMs. */
+ operands[0] = gen_rtx_MEM (QImode, operands[0]);
+
+ /* If the address isn't valid for the prefetch, replace it. */
+ if (locality)
+ {
+ if (!prefetch_nocc_operand (operands[0], QImode))
+ operands[0]
+ = replace_equiv_address (operands[0],
+ copy_to_mode_reg (Pmode,
+ XEXP (operands[0], 0)));
+ emit_insn (gen_prefetch_nocc (operands[0], operands[1], operands[2]));
+ }
+ else
+ {
+ if (!prefetch_cc_operand (operands[0], QImode))
+ operands[0]
+ = replace_equiv_address (operands[0],
+ copy_to_mode_reg (Pmode,
+ XEXP (operands[0], 0)));
+ emit_insn (gen_prefetch_cc (operands[0], operands[1], operands[2]));
+ }
+ DONE;
+})
+
+(define_insn "prefetch_cc"
+ [(prefetch (match_operand:QI 0 "prefetch_cc_operand" "RW")
+ (match_operand:SI 1 "const_int_operand" "n")
+ (match_operand:SI 2 "const_int_operand" "n"))]
+ "TARGET_PA_20 && operands[2] == const0_rtx"
+{
+ /* The SL cache-control completor indicates good spatial locality but
+ poor temporal locality. The ldw instruction with a target of general
+ register 0 prefetches a cache line for a read. The ldd instruction
+ prefetches a cache line for a write. */
+ static const char * const instr[2] = {
+ "ldw%M0,sl %0,%%r0",
+ "ldd%M0,sl %0,%%r0"
+ };
+ int read_or_write = INTVAL (operands[1]);
+
+ gcc_assert (read_or_write >= 0 && read_or_write <= 1);
+
+ return instr [read_or_write];
+}
+ [(set_attr "type" "load")
+ (set_attr "length" "4")])
+
+(define_insn "prefetch_nocc"
+ [(prefetch (match_operand:QI 0 "prefetch_nocc_operand" "A,RQ")
+ (match_operand:SI 1 "const_int_operand" "n,n")
+ (match_operand:SI 2 "const_int_operand" "n,n"))]
+ "TARGET_PA_20 && operands[2] != const0_rtx"
+{
+ /* The ldw instruction with a target of general register 0 prefetches
+ a cache line for a read. The ldd instruction prefetches a cache line
+ for a write. */
+ static const char * const instr[2][2] = {
+ {
+ "ldw RT'%A0,%%r0",
+ "ldd RT'%A0,%%r0",
+ },
+ {
+ "ldw%M0 %0,%%r0",
+ "ldd%M0 %0,%%r0",
+ }
+ };
+ int read_or_write = INTVAL (operands[1]);
+
+ gcc_assert (which_alternative == 0 || which_alternative == 1);
+ gcc_assert (read_or_write >= 0 && read_or_write <= 1);
+
+ return instr [which_alternative][read_or_write];
+}
+ [(set_attr "type" "load")
+ (set_attr "length" "4")])
+
+
+;; TLS Support
+(define_insn "tgd_load"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD))
+ (clobber (reg:SI 1))
+ (use (reg:SI 27))]
+ ""
+ "*
+{
+ return \"addil LR'%1-$tls_gdidx$,%%r27\;ldo RR'%1-$tls_gdidx$(%%r1),%0\";
+}"
+ [(set_attr "type" "multi")
+ (set_attr "length" "8")])
+
+(define_insn "tgd_load_pic"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD_PIC))
+ (clobber (reg:SI 1))
+ (use (reg:SI 19))]
+ ""
+ "*
+{
+ return \"addil LT'%1-$tls_gdidx$,%%r19\;ldo RT'%1-$tls_gdidx$(%%r1),%0\";
+}"
+ [(set_attr "type" "multi")
+ (set_attr "length" "8")])
+
+(define_insn "tld_load"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM))
+ (clobber (reg:SI 1))
+ (use (reg:SI 27))]
+ ""
+ "*
+{
+ return \"addil LR'%1-$tls_ldidx$,%%r27\;ldo RR'%1-$tls_ldidx$(%%r1),%0\";
+}"
+ [(set_attr "type" "multi")
+ (set_attr "length" "8")])
+
+(define_insn "tld_load_pic"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM_PIC))
+ (clobber (reg:SI 1))
+ (use (reg:SI 19))]
+ ""
+ "*
+{
+ return \"addil LT'%1-$tls_ldidx$,%%r19\;ldo RT'%1-$tls_ldidx$(%%r1),%0\";
+}"
+ [(set_attr "type" "multi")
+ (set_attr "length" "8")])
+
+(define_insn "tld_offset_load"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:SI 2 "register_operand" "r")))
+ (clobber (reg:SI 1))]
+ ""
+ "*
+{
+ return \"addil LR'%1-$tls_dtpoff$,%2\;ldo RR'%1-$tls_dtpoff$(%%r1),%0\";
+}"
+ [(set_attr "type" "multi")
+ (set_attr "length" "8")])
+
+(define_insn "tp_load"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(const_int 0)] UNSPEC_TP))]
+ ""
+ "mfctl %%cr27,%0"
+ [(set_attr "type" "multi")
+ (set_attr "length" "4")])
+
+(define_insn "tie_load"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE))
+ (clobber (reg:SI 1))
+ (use (reg:SI 27))]
+ ""
+ "*
+{
+ return \"addil LR'%1-$tls_ieoff$,%%r27\;ldw RR'%1-$tls_ieoff$(%%r1),%0\";
+}"
+ [(set_attr "type" "multi")
+ (set_attr "length" "8")])
+
+(define_insn "tie_load_pic"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE_PIC))
+ (clobber (reg:SI 1))
+ (use (reg:SI 19))]
+ ""
+ "*
+{
+ return \"addil LT'%1-$tls_ieoff$,%%r19\;ldw RT'%1-$tls_ieoff$(%%r1),%0\";
+}"
+ [(set_attr "type" "multi")
+ (set_attr "length" "8")])
+
+(define_insn "tle_load"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
+ UNSPEC_TLSLE)
+ (match_operand:SI 2 "register_operand" "r")))
+ (clobber (reg:SI 1))]
+ ""
+ "addil LR'%1-$tls_leoff$,%2\;ldo RR'%1-$tls_leoff$(%%r1),%0"
+ [(set_attr "type" "multi")
+ (set_attr "length" "8")])