;;- Machine description for HP PA-RISC architecture for GCC compiler
|
;;- Machine description for HP PA-RISC architecture for GCC compiler
|
;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
|
;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
|
;; 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010
|
;; 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010
|
;; Free Software Foundation, Inc.
|
;; Free Software Foundation, Inc.
|
;; Contributed by the Center for Software Science at the University
|
;; Contributed by the Center for Software Science at the University
|
;; of Utah.
|
;; of Utah.
|
|
|
;; This file is part of GCC.
|
;; This file is part of GCC.
|
|
|
;; GCC is free software; you can redistribute it and/or modify
|
;; GCC is free software; you can redistribute it and/or modify
|
;; it under the terms of the GNU General Public License as published by
|
;; it under the terms of the GNU General Public License as published by
|
;; the Free Software Foundation; either version 3, or (at your option)
|
;; the Free Software Foundation; either version 3, or (at your option)
|
;; any later version.
|
;; any later version.
|
|
|
;; GCC is distributed in the hope that it will be useful,
|
;; GCC is distributed in the hope that it will be useful,
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
;; GNU General Public License for more details.
|
;; GNU General Public License for more details.
|
|
|
;; You should have received a copy of the GNU General Public License
|
;; You should have received a copy of the GNU General Public License
|
;; along with GCC; see the file COPYING3. If not see
|
;; along with GCC; see the file COPYING3. If not see
|
;; .
|
;; .
|
|
|
;; This gcc Version 2 machine description is inspired by sparc.md and
|
;; This gcc Version 2 machine description is inspired by sparc.md and
|
;; mips.md.
|
;; mips.md.
|
|
|
;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
|
;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
|
|
|
;; Uses of UNSPEC in this file:
|
;; Uses of UNSPEC in this file:
|
|
|
(define_constants
|
(define_constants
|
[(UNSPEC_CFFC 0) ; canonicalize_funcptr_for_compare
|
[(UNSPEC_CFFC 0) ; canonicalize_funcptr_for_compare
|
(UNSPEC_GOTO 1) ; indirect_goto
|
(UNSPEC_GOTO 1) ; indirect_goto
|
(UNSPEC_DLTIND14R 2) ;
|
(UNSPEC_DLTIND14R 2) ;
|
(UNSPEC_TP 3)
|
(UNSPEC_TP 3)
|
(UNSPEC_TLSGD 4)
|
(UNSPEC_TLSGD 4)
|
(UNSPEC_TLSLDM 5)
|
(UNSPEC_TLSLDM 5)
|
(UNSPEC_TLSLDO 6)
|
(UNSPEC_TLSLDO 6)
|
(UNSPEC_TLSLDBASE 7)
|
(UNSPEC_TLSLDBASE 7)
|
(UNSPEC_TLSIE 8)
|
(UNSPEC_TLSIE 8)
|
(UNSPEC_TLSLE 9)
|
(UNSPEC_TLSLE 9)
|
(UNSPEC_TLSGD_PIC 10)
|
(UNSPEC_TLSGD_PIC 10)
|
(UNSPEC_TLSLDM_PIC 11)
|
(UNSPEC_TLSLDM_PIC 11)
|
(UNSPEC_TLSIE_PIC 12)
|
(UNSPEC_TLSIE_PIC 12)
|
])
|
])
|
|
|
;; UNSPEC_VOLATILE:
|
;; UNSPEC_VOLATILE:
|
|
|
(define_constants
|
(define_constants
|
[(UNSPECV_BLOCKAGE 0) ; blockage
|
[(UNSPECV_BLOCKAGE 0) ; blockage
|
(UNSPECV_DCACHE 1) ; dcacheflush
|
(UNSPECV_DCACHE 1) ; dcacheflush
|
(UNSPECV_ICACHE 2) ; icacheflush
|
(UNSPECV_ICACHE 2) ; icacheflush
|
(UNSPECV_OPC 3) ; outline_prologue_call
|
(UNSPECV_OPC 3) ; outline_prologue_call
|
(UNSPECV_OEC 4) ; outline_epilogue_call
|
(UNSPECV_OEC 4) ; outline_epilogue_call
|
(UNSPECV_LONGJMP 5) ; builtin_longjmp
|
(UNSPECV_LONGJMP 5) ; builtin_longjmp
|
])
|
])
|
|
|
;; Maximum pc-relative branch offsets.
|
;; Maximum pc-relative branch offsets.
|
|
|
;; These numbers are a bit smaller than the maximum allowable offsets
|
;; These numbers are a bit smaller than the maximum allowable offsets
|
;; so that a few instructions may be inserted before the actual branch.
|
;; so that a few instructions may be inserted before the actual branch.
|
|
|
(define_constants
|
(define_constants
|
[(MAX_12BIT_OFFSET 8184) ; 12-bit branch
|
[(MAX_12BIT_OFFSET 8184) ; 12-bit branch
|
(MAX_17BIT_OFFSET 262100) ; 17-bit branch
|
(MAX_17BIT_OFFSET 262100) ; 17-bit branch
|
])
|
])
|
|
|
;; Mode and code iterators
|
;; Mode and code iterators
|
|
|
;; This mode iterator allows :P to be used for patterns that operate on
|
;; This mode iterator allows :P to be used for patterns that operate on
|
;; pointer-sized quantities. Exactly one of the two alternatives will match.
|
;; pointer-sized quantities. Exactly one of the two alternatives will match.
|
(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
|
(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
|
|
|
;; This attribute defines the condition prefix for word and double word
|
;; This attribute defines the condition prefix for word and double word
|
;; add, compare, subtract and logical instructions.
|
;; add, compare, subtract and logical instructions.
|
(define_mode_attr dwc [(SI "") (DI "*")])
|
(define_mode_attr dwc [(SI "") (DI "*")])
|
|
|
;; Insn type. Used to default other attribute values.
|
;; Insn type. Used to default other attribute values.
|
|
|
;; type "unary" insns have one input operand (1) and one output operand (0)
|
;; 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)
|
;; type "binary" insns have two input operands (1,2) and one output (0)
|
|
|
(define_attr "type"
|
(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,fpstore_load,store_fpload"
|
"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"))
|
(const_string "binary"))
|
|
|
(define_attr "pa_combine_type"
|
(define_attr "pa_combine_type"
|
"fmpy,faddsub,uncond_branch,addmove,none"
|
"fmpy,faddsub,uncond_branch,addmove,none"
|
(const_string "none"))
|
(const_string "none"))
|
|
|
;; Processor type (for scheduling, not code generation) -- this attribute
|
;; Processor type (for scheduling, not code generation) -- this attribute
|
;; must exactly match the processor_type enumeration in pa.h.
|
;; must exactly match the processor_type enumeration in pa.h.
|
;;
|
;;
|
;; FIXME: Add 800 scheduling for completeness?
|
;; FIXME: Add 800 scheduling for completeness?
|
|
|
(define_attr "cpu" "700,7100,7100LC,7200,7300,8000" (const (symbol_ref "pa_cpu_attr")))
|
(define_attr "cpu" "700,7100,7100LC,7200,7300,8000" (const (symbol_ref "pa_cpu_attr")))
|
|
|
;; Length (in # of bytes).
|
;; Length (in # of bytes).
|
(define_attr "length" ""
|
(define_attr "length" ""
|
(cond [(eq_attr "type" "load,fpload")
|
(cond [(eq_attr "type" "load,fpload")
|
(if_then_else (match_operand 1 "symbolic_memory_operand" "")
|
(if_then_else (match_operand 1 "symbolic_memory_operand" "")
|
(const_int 8) (const_int 4))
|
(const_int 8) (const_int 4))
|
|
|
(eq_attr "type" "store,fpstore")
|
(eq_attr "type" "store,fpstore")
|
(if_then_else (match_operand 0 "symbolic_memory_operand" "")
|
(if_then_else (match_operand 0 "symbolic_memory_operand" "")
|
(const_int 8) (const_int 4))
|
(const_int 8) (const_int 4))
|
|
|
(eq_attr "type" "binary,shift,nullshift")
|
(eq_attr "type" "binary,shift,nullshift")
|
(if_then_else (match_operand 2 "arith_operand" "")
|
(if_then_else (match_operand 2 "arith_operand" "")
|
(const_int 4) (const_int 12))
|
(const_int 4) (const_int 12))
|
|
|
(eq_attr "type" "move,unary,shift,nullshift")
|
(eq_attr "type" "move,unary,shift,nullshift")
|
(if_then_else (match_operand 1 "arith_operand" "")
|
(if_then_else (match_operand 1 "arith_operand" "")
|
(const_int 4) (const_int 8))]
|
(const_int 4) (const_int 8))]
|
|
|
(const_int 4)))
|
(const_int 4)))
|
|
|
(define_asm_attributes
|
(define_asm_attributes
|
[(set_attr "length" "4")
|
[(set_attr "length" "4")
|
(set_attr "type" "multi")])
|
(set_attr "type" "multi")])
|
|
|
;; Attributes for instruction and branch scheduling
|
;; Attributes for instruction and branch scheduling
|
|
|
;; For conditional branches.
|
;; For conditional branches.
|
(define_attr "in_branch_delay" "false,true"
|
(define_attr "in_branch_delay" "false,true"
|
(if_then_else (and (eq_attr "type" "!uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch")
|
(if_then_else (and (eq_attr "type" "!uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch")
|
(eq_attr "length" "4"))
|
(eq_attr "length" "4"))
|
(const_string "true")
|
(const_string "true")
|
(const_string "false")))
|
(const_string "false")))
|
|
|
;; Disallow instructions which use the FPU since they will tie up the FPU
|
;; Disallow instructions which use the FPU since they will tie up the FPU
|
;; even if the instruction is nullified.
|
;; even if the instruction is nullified.
|
(define_attr "in_nullified_branch_delay" "false,true"
|
(define_attr "in_nullified_branch_delay" "false,true"
|
(if_then_else (and (eq_attr "type" "!uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,parallel_branch")
|
(if_then_else (and (eq_attr "type" "!uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,parallel_branch")
|
(eq_attr "length" "4"))
|
(eq_attr "length" "4"))
|
(const_string "true")
|
(const_string "true")
|
(const_string "false")))
|
(const_string "false")))
|
|
|
;; For calls and millicode calls. Allow unconditional branches in the
|
;; For calls and millicode calls. Allow unconditional branches in the
|
;; delay slot.
|
;; delay slot.
|
(define_attr "in_call_delay" "false,true"
|
(define_attr "in_call_delay" "false,true"
|
(cond [(and (eq_attr "type" "!uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch")
|
(cond [(and (eq_attr "type" "!uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch")
|
(eq_attr "length" "4"))
|
(eq_attr "length" "4"))
|
(const_string "true")
|
(const_string "true")
|
(eq_attr "type" "uncond_branch")
|
(eq_attr "type" "uncond_branch")
|
(if_then_else (ne (symbol_ref "TARGET_JUMP_IN_DELAY")
|
(if_then_else (ne (symbol_ref "TARGET_JUMP_IN_DELAY")
|
(const_int 0))
|
(const_int 0))
|
(const_string "true")
|
(const_string "true")
|
(const_string "false"))]
|
(const_string "false"))]
|
(const_string "false")))
|
(const_string "false")))
|
|
|
|
|
;; Call delay slot description.
|
;; Call delay slot description.
|
(define_delay (eq_attr "type" "call")
|
(define_delay (eq_attr "type" "call")
|
[(eq_attr "in_call_delay" "true") (nil) (nil)])
|
[(eq_attr "in_call_delay" "true") (nil) (nil)])
|
|
|
;; Millicode call delay slot description.
|
;; Millicode call delay slot description.
|
(define_delay (eq_attr "type" "milli")
|
(define_delay (eq_attr "type" "milli")
|
[(eq_attr "in_call_delay" "true") (nil) (nil)])
|
[(eq_attr "in_call_delay" "true") (nil) (nil)])
|
|
|
;; Return and other similar instructions.
|
;; Return and other similar instructions.
|
(define_delay (eq_attr "type" "btable_branch,branch,parallel_branch")
|
(define_delay (eq_attr "type" "btable_branch,branch,parallel_branch")
|
[(eq_attr "in_branch_delay" "true") (nil) (nil)])
|
[(eq_attr "in_branch_delay" "true") (nil) (nil)])
|
|
|
;; Floating point conditional branch delay slot description.
|
;; Floating point conditional branch delay slot description.
|
(define_delay (eq_attr "type" "fbranch")
|
(define_delay (eq_attr "type" "fbranch")
|
[(eq_attr "in_branch_delay" "true")
|
[(eq_attr "in_branch_delay" "true")
|
(eq_attr "in_nullified_branch_delay" "true")
|
(eq_attr "in_nullified_branch_delay" "true")
|
(nil)])
|
(nil)])
|
|
|
;; Integer conditional branch delay slot description.
|
;; Integer conditional branch delay slot description.
|
;; Nullification of conditional branches on the PA is dependent on the
|
;; Nullification of conditional branches on the PA is dependent on the
|
;; direction of the branch. Forward branches nullify true and
|
;; direction of the branch. Forward branches nullify true and
|
;; backward branches nullify false. If the direction is unknown
|
;; backward branches nullify false. If the direction is unknown
|
;; then nullification is not allowed.
|
;; then nullification is not allowed.
|
(define_delay (eq_attr "type" "cbranch")
|
(define_delay (eq_attr "type" "cbranch")
|
[(eq_attr "in_branch_delay" "true")
|
[(eq_attr "in_branch_delay" "true")
|
(and (eq_attr "in_nullified_branch_delay" "true")
|
(and (eq_attr "in_nullified_branch_delay" "true")
|
(attr_flag "forward"))
|
(attr_flag "forward"))
|
(and (eq_attr "in_nullified_branch_delay" "true")
|
(and (eq_attr "in_nullified_branch_delay" "true")
|
(attr_flag "backward"))])
|
(attr_flag "backward"))])
|
|
|
(define_delay (and (eq_attr "type" "uncond_branch")
|
(define_delay (and (eq_attr "type" "uncond_branch")
|
(eq (symbol_ref "following_call (insn)")
|
(eq (symbol_ref "following_call (insn)")
|
(const_int 0)))
|
(const_int 0)))
|
[(eq_attr "in_branch_delay" "true") (nil) (nil)])
|
[(eq_attr "in_branch_delay" "true") (nil) (nil)])
|
|
|
;; Memory. Disregarding Cache misses, the Mustang memory times are:
|
;; Memory. Disregarding Cache misses, the Mustang memory times are:
|
;; load: 2, fpload: 3
|
;; load: 2, fpload: 3
|
;; store, fpstore: 3, no D-cache operations should be scheduled.
|
;; store, fpstore: 3, no D-cache operations should be scheduled.
|
|
|
;; The Timex (aka 700) has two floating-point units: ALU, and MUL/DIV/SQRT.
|
;; The Timex (aka 700) has two floating-point units: ALU, and MUL/DIV/SQRT.
|
;; Timings:
|
;; Timings:
|
;; Instruction Time Unit Minimum Distance (unit contention)
|
;; Instruction Time Unit Minimum Distance (unit contention)
|
;; fcpy 3 ALU 2
|
;; fcpy 3 ALU 2
|
;; fabs 3 ALU 2
|
;; fabs 3 ALU 2
|
;; fadd 3 ALU 2
|
;; fadd 3 ALU 2
|
;; fsub 3 ALU 2
|
;; fsub 3 ALU 2
|
;; fcmp 3 ALU 2
|
;; fcmp 3 ALU 2
|
;; fcnv 3 ALU 2
|
;; fcnv 3 ALU 2
|
;; fmpyadd 3 ALU,MPY 2
|
;; fmpyadd 3 ALU,MPY 2
|
;; fmpysub 3 ALU,MPY 2
|
;; fmpysub 3 ALU,MPY 2
|
;; fmpycfxt 3 ALU,MPY 2
|
;; fmpycfxt 3 ALU,MPY 2
|
;; fmpy 3 MPY 2
|
;; fmpy 3 MPY 2
|
;; fmpyi 3 MPY 2
|
;; fmpyi 3 MPY 2
|
;; fdiv,sgl 10 MPY 10
|
;; fdiv,sgl 10 MPY 10
|
;; fdiv,dbl 12 MPY 12
|
;; fdiv,dbl 12 MPY 12
|
;; fsqrt,sgl 14 MPY 14
|
;; fsqrt,sgl 14 MPY 14
|
;; fsqrt,dbl 18 MPY 18
|
;; fsqrt,dbl 18 MPY 18
|
;;
|
;;
|
;; We don't model fmpyadd/fmpysub properly as those instructions
|
;; We don't model fmpyadd/fmpysub properly as those instructions
|
;; keep both the FP ALU and MPY units busy. Given that these
|
;; keep both the FP ALU and MPY units busy. Given that these
|
;; processors are obsolete, I'm not going to spend the time to
|
;; processors are obsolete, I'm not going to spend the time to
|
;; model those instructions correctly.
|
;; model those instructions correctly.
|
|
|
(define_automaton "pa700")
|
(define_automaton "pa700")
|
(define_cpu_unit "dummy_700,mem_700,fpalu_700,fpmpy_700" "pa700")
|
(define_cpu_unit "dummy_700,mem_700,fpalu_700,fpmpy_700" "pa700")
|
|
|
(define_insn_reservation "W0" 4
|
(define_insn_reservation "W0" 4
|
(and (eq_attr "type" "fpcc")
|
(and (eq_attr "type" "fpcc")
|
(eq_attr "cpu" "700"))
|
(eq_attr "cpu" "700"))
|
"fpalu_700*2")
|
"fpalu_700*2")
|
|
|
(define_insn_reservation "W1" 3
|
(define_insn_reservation "W1" 3
|
(and (eq_attr "type" "fpalu")
|
(and (eq_attr "type" "fpalu")
|
(eq_attr "cpu" "700"))
|
(eq_attr "cpu" "700"))
|
"fpalu_700*2")
|
"fpalu_700*2")
|
|
|
(define_insn_reservation "W2" 3
|
(define_insn_reservation "W2" 3
|
(and (eq_attr "type" "fpmulsgl,fpmuldbl")
|
(and (eq_attr "type" "fpmulsgl,fpmuldbl")
|
(eq_attr "cpu" "700"))
|
(eq_attr "cpu" "700"))
|
"fpmpy_700*2")
|
"fpmpy_700*2")
|
|
|
(define_insn_reservation "W3" 10
|
(define_insn_reservation "W3" 10
|
(and (eq_attr "type" "fpdivsgl")
|
(and (eq_attr "type" "fpdivsgl")
|
(eq_attr "cpu" "700"))
|
(eq_attr "cpu" "700"))
|
"fpmpy_700*10")
|
"fpmpy_700*10")
|
|
|
(define_insn_reservation "W4" 12
|
(define_insn_reservation "W4" 12
|
(and (eq_attr "type" "fpdivdbl")
|
(and (eq_attr "type" "fpdivdbl")
|
(eq_attr "cpu" "700"))
|
(eq_attr "cpu" "700"))
|
"fpmpy_700*12")
|
"fpmpy_700*12")
|
|
|
(define_insn_reservation "W5" 14
|
(define_insn_reservation "W5" 14
|
(and (eq_attr "type" "fpsqrtsgl")
|
(and (eq_attr "type" "fpsqrtsgl")
|
(eq_attr "cpu" "700"))
|
(eq_attr "cpu" "700"))
|
"fpmpy_700*14")
|
"fpmpy_700*14")
|
|
|
(define_insn_reservation "W6" 18
|
(define_insn_reservation "W6" 18
|
(and (eq_attr "type" "fpsqrtdbl")
|
(and (eq_attr "type" "fpsqrtdbl")
|
(eq_attr "cpu" "700"))
|
(eq_attr "cpu" "700"))
|
"fpmpy_700*18")
|
"fpmpy_700*18")
|
|
|
(define_insn_reservation "W7" 2
|
(define_insn_reservation "W7" 2
|
(and (eq_attr "type" "load")
|
(and (eq_attr "type" "load")
|
(eq_attr "cpu" "700"))
|
(eq_attr "cpu" "700"))
|
"mem_700")
|
"mem_700")
|
|
|
(define_insn_reservation "W8" 2
|
(define_insn_reservation "W8" 2
|
(and (eq_attr "type" "fpload")
|
(and (eq_attr "type" "fpload")
|
(eq_attr "cpu" "700"))
|
(eq_attr "cpu" "700"))
|
"mem_700")
|
"mem_700")
|
|
|
(define_insn_reservation "W9" 3
|
(define_insn_reservation "W9" 3
|
(and (eq_attr "type" "store")
|
(and (eq_attr "type" "store")
|
(eq_attr "cpu" "700"))
|
(eq_attr "cpu" "700"))
|
"mem_700*3")
|
"mem_700*3")
|
|
|
(define_insn_reservation "W10" 3
|
(define_insn_reservation "W10" 3
|
(and (eq_attr "type" "fpstore")
|
(and (eq_attr "type" "fpstore")
|
(eq_attr "cpu" "700"))
|
(eq_attr "cpu" "700"))
|
"mem_700*3")
|
"mem_700*3")
|
|
|
(define_insn_reservation "W11" 5
|
(define_insn_reservation "W11" 5
|
(and (eq_attr "type" "fpstore_load")
|
(and (eq_attr "type" "fpstore_load")
|
(eq_attr "cpu" "700"))
|
(eq_attr "cpu" "700"))
|
"mem_700*5")
|
"mem_700*5")
|
|
|
(define_insn_reservation "W12" 6
|
(define_insn_reservation "W12" 6
|
(and (eq_attr "type" "store_fpload")
|
(and (eq_attr "type" "store_fpload")
|
(eq_attr "cpu" "700"))
|
(eq_attr "cpu" "700"))
|
"mem_700*6")
|
"mem_700*6")
|
|
|
(define_insn_reservation "W13" 1
|
(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")
|
(and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,load,fpload,store,fpstore,fpstore_load,store_fpload")
|
(eq_attr "cpu" "700"))
|
(eq_attr "cpu" "700"))
|
"dummy_700")
|
"dummy_700")
|
|
|
;; We have a bypass for all computations in the FP unit which feed an
|
;; We have a bypass for all computations in the FP unit which feed an
|
;; FP store as long as the sizes are the same.
|
;; FP store as long as the sizes are the same.
|
(define_bypass 2 "W1,W2" "W10,W11" "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 9 "W3" "W10,W11" "hppa_fpstore_bypass_p")
|
(define_bypass 11 "W4" "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 13 "W5" "W10,W11" "hppa_fpstore_bypass_p")
|
(define_bypass 17 "W6" "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.
|
;; We have an "anti-bypass" for FP loads which feed an FP store.
|
(define_bypass 4 "W8,W12" "W10,W11" "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
|
;; Function units for the 7100 and 7150. The 7100/7150 can dual-issue
|
;; floating point computations with non-floating point computations (fp loads
|
;; floating point computations with non-floating point computations (fp loads
|
;; and stores are not fp computations).
|
;; and stores are not fp computations).
|
;;
|
;;
|
;; Memory. Disregarding Cache misses, memory loads take two cycles; stores also
|
;; Memory. Disregarding Cache misses, memory loads take two cycles; stores also
|
;; take two cycles, during which no Dcache operations should be scheduled.
|
;; take two cycles, during which no Dcache operations should be scheduled.
|
;; Any special cases are handled in pa_adjust_cost. The 7100, 7150 and 7100LC
|
;; Any special cases are handled in pa_adjust_cost. The 7100, 7150 and 7100LC
|
;; all have the same memory characteristics if one disregards cache misses.
|
;; all have the same memory characteristics if one disregards cache misses.
|
;;
|
;;
|
;; The 7100/7150 has three floating-point units: ALU, MUL, and DIV.
|
;; The 7100/7150 has three floating-point units: ALU, MUL, and DIV.
|
;; There's no value in modeling the ALU and MUL separately though
|
;; There's no value in modeling the ALU and MUL separately though
|
;; since there can never be a functional unit conflict given the
|
;; since there can never be a functional unit conflict given the
|
;; latency and issue rates for those units.
|
;; latency and issue rates for those units.
|
;;
|
;;
|
;; Timings:
|
;; Timings:
|
;; Instruction Time Unit Minimum Distance (unit contention)
|
;; Instruction Time Unit Minimum Distance (unit contention)
|
;; fcpy 2 ALU 1
|
;; fcpy 2 ALU 1
|
;; fabs 2 ALU 1
|
;; fabs 2 ALU 1
|
;; fadd 2 ALU 1
|
;; fadd 2 ALU 1
|
;; fsub 2 ALU 1
|
;; fsub 2 ALU 1
|
;; fcmp 2 ALU 1
|
;; fcmp 2 ALU 1
|
;; fcnv 2 ALU 1
|
;; fcnv 2 ALU 1
|
;; fmpyadd 2 ALU,MPY 1
|
;; fmpyadd 2 ALU,MPY 1
|
;; fmpysub 2 ALU,MPY 1
|
;; fmpysub 2 ALU,MPY 1
|
;; fmpycfxt 2 ALU,MPY 1
|
;; fmpycfxt 2 ALU,MPY 1
|
;; fmpy 2 MPY 1
|
;; fmpy 2 MPY 1
|
;; fmpyi 2 MPY 1
|
;; fmpyi 2 MPY 1
|
;; fdiv,sgl 8 DIV 8
|
;; fdiv,sgl 8 DIV 8
|
;; fdiv,dbl 15 DIV 15
|
;; fdiv,dbl 15 DIV 15
|
;; fsqrt,sgl 8 DIV 8
|
;; fsqrt,sgl 8 DIV 8
|
;; fsqrt,dbl 15 DIV 15
|
;; fsqrt,dbl 15 DIV 15
|
|
|
(define_automaton "pa7100")
|
(define_automaton "pa7100")
|
(define_cpu_unit "i_7100, f_7100,fpmac_7100,fpdivsqrt_7100,mem_7100" "pa7100")
|
(define_cpu_unit "i_7100, f_7100,fpmac_7100,fpdivsqrt_7100,mem_7100" "pa7100")
|
|
|
(define_insn_reservation "X0" 2
|
(define_insn_reservation "X0" 2
|
(and (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
|
(and (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
|
(eq_attr "cpu" "7100"))
|
(eq_attr "cpu" "7100"))
|
"f_7100,fpmac_7100")
|
"f_7100,fpmac_7100")
|
|
|
(define_insn_reservation "X1" 8
|
(define_insn_reservation "X1" 8
|
(and (eq_attr "type" "fpdivsgl,fpsqrtsgl")
|
(and (eq_attr "type" "fpdivsgl,fpsqrtsgl")
|
(eq_attr "cpu" "7100"))
|
(eq_attr "cpu" "7100"))
|
"f_7100+fpdivsqrt_7100,fpdivsqrt_7100*7")
|
"f_7100+fpdivsqrt_7100,fpdivsqrt_7100*7")
|
|
|
(define_insn_reservation "X2" 15
|
(define_insn_reservation "X2" 15
|
(and (eq_attr "type" "fpdivdbl,fpsqrtdbl")
|
(and (eq_attr "type" "fpdivdbl,fpsqrtdbl")
|
(eq_attr "cpu" "7100"))
|
(eq_attr "cpu" "7100"))
|
"f_7100+fpdivsqrt_7100,fpdivsqrt_7100*14")
|
"f_7100+fpdivsqrt_7100,fpdivsqrt_7100*14")
|
|
|
(define_insn_reservation "X3" 2
|
(define_insn_reservation "X3" 2
|
(and (eq_attr "type" "load")
|
(and (eq_attr "type" "load")
|
(eq_attr "cpu" "7100"))
|
(eq_attr "cpu" "7100"))
|
"i_7100+mem_7100")
|
"i_7100+mem_7100")
|
|
|
(define_insn_reservation "X4" 2
|
(define_insn_reservation "X4" 2
|
(and (eq_attr "type" "fpload")
|
(and (eq_attr "type" "fpload")
|
(eq_attr "cpu" "7100"))
|
(eq_attr "cpu" "7100"))
|
"i_7100+mem_7100")
|
"i_7100+mem_7100")
|
|
|
(define_insn_reservation "X5" 2
|
(define_insn_reservation "X5" 2
|
(and (eq_attr "type" "store")
|
(and (eq_attr "type" "store")
|
(eq_attr "cpu" "7100"))
|
(eq_attr "cpu" "7100"))
|
"i_7100+mem_7100,mem_7100")
|
"i_7100+mem_7100,mem_7100")
|
|
|
(define_insn_reservation "X6" 2
|
(define_insn_reservation "X6" 2
|
(and (eq_attr "type" "fpstore")
|
(and (eq_attr "type" "fpstore")
|
(eq_attr "cpu" "7100"))
|
(eq_attr "cpu" "7100"))
|
"i_7100+mem_7100,mem_7100")
|
"i_7100+mem_7100,mem_7100")
|
|
|
(define_insn_reservation "X7" 4
|
(define_insn_reservation "X7" 4
|
(and (eq_attr "type" "fpstore_load")
|
(and (eq_attr "type" "fpstore_load")
|
(eq_attr "cpu" "7100"))
|
(eq_attr "cpu" "7100"))
|
"i_7100+mem_7100,mem_7100*3")
|
"i_7100+mem_7100,mem_7100*3")
|
|
|
(define_insn_reservation "X8" 4
|
(define_insn_reservation "X8" 4
|
(and (eq_attr "type" "store_fpload")
|
(and (eq_attr "type" "store_fpload")
|
(eq_attr "cpu" "7100"))
|
(eq_attr "cpu" "7100"))
|
"i_7100+mem_7100,mem_7100*3")
|
"i_7100+mem_7100,mem_7100*3")
|
|
|
(define_insn_reservation "X9" 1
|
(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")
|
(and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,fpstore_load,store_fpload")
|
(eq_attr "cpu" "7100"))
|
(eq_attr "cpu" "7100"))
|
"i_7100")
|
"i_7100")
|
|
|
;; We have a bypass for all computations in the FP unit which feed an
|
;; We have a bypass for all computations in the FP unit which feed an
|
;; FP store as long as the sizes are the same.
|
;; FP store as long as the sizes are the same.
|
(define_bypass 1 "X0" "X6,X7" "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 7 "X1" "X6,X7" "hppa_fpstore_bypass_p")
|
(define_bypass 14 "X2" "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.
|
;; We have an "anti-bypass" for FP loads which feed an FP store.
|
(define_bypass 3 "X4,X8" "X6,X7" "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.
|
;; The 7100LC has three floating-point units: ALU, MUL, and DIV.
|
;; There's no value in modeling the ALU and MUL separately though
|
;; There's no value in modeling the ALU and MUL separately though
|
;; since there can never be a functional unit conflict that
|
;; since there can never be a functional unit conflict that
|
;; can be avoided given the latency, issue rates and mandatory
|
;; can be avoided given the latency, issue rates and mandatory
|
;; one cycle cpu-wide lock for a double precision fp multiply.
|
;; one cycle cpu-wide lock for a double precision fp multiply.
|
;;
|
;;
|
;; Timings:
|
;; Timings:
|
;; Instruction Time Unit Minimum Distance (unit contention)
|
;; Instruction Time Unit Minimum Distance (unit contention)
|
;; fcpy 2 ALU 1
|
;; fcpy 2 ALU 1
|
;; fabs 2 ALU 1
|
;; fabs 2 ALU 1
|
;; fadd 2 ALU 1
|
;; fadd 2 ALU 1
|
;; fsub 2 ALU 1
|
;; fsub 2 ALU 1
|
;; fcmp 2 ALU 1
|
;; fcmp 2 ALU 1
|
;; fcnv 2 ALU 1
|
;; fcnv 2 ALU 1
|
;; fmpyadd,sgl 2 ALU,MPY 1
|
;; fmpyadd,sgl 2 ALU,MPY 1
|
;; fmpyadd,dbl 3 ALU,MPY 2
|
;; fmpyadd,dbl 3 ALU,MPY 2
|
;; fmpysub,sgl 2 ALU,MPY 1
|
;; fmpysub,sgl 2 ALU,MPY 1
|
;; fmpysub,dbl 3 ALU,MPY 2
|
;; fmpysub,dbl 3 ALU,MPY 2
|
;; fmpycfxt,sgl 2 ALU,MPY 1
|
;; fmpycfxt,sgl 2 ALU,MPY 1
|
;; fmpycfxt,dbl 3 ALU,MPY 2
|
;; fmpycfxt,dbl 3 ALU,MPY 2
|
;; fmpy,sgl 2 MPY 1
|
;; fmpy,sgl 2 MPY 1
|
;; fmpy,dbl 3 MPY 2
|
;; fmpy,dbl 3 MPY 2
|
;; fmpyi 3 MPY 2
|
;; fmpyi 3 MPY 2
|
;; fdiv,sgl 8 DIV 8
|
;; fdiv,sgl 8 DIV 8
|
;; fdiv,dbl 15 DIV 15
|
;; fdiv,dbl 15 DIV 15
|
;; fsqrt,sgl 8 DIV 8
|
;; fsqrt,sgl 8 DIV 8
|
;; fsqrt,dbl 15 DIV 15
|
;; fsqrt,dbl 15 DIV 15
|
;;
|
;;
|
;; The PA7200 is just like the PA7100LC except that there is
|
;; The PA7200 is just like the PA7100LC except that there is
|
;; no store-store penalty.
|
;; no store-store penalty.
|
;;
|
;;
|
;; The PA7300 is just like the PA7200 except that there is
|
;; The PA7300 is just like the PA7200 except that there is
|
;; no store-load penalty.
|
;; no store-load penalty.
|
;;
|
;;
|
;; Note there are some aspects of the 7100LC we are not modeling
|
;; Note there are some aspects of the 7100LC we are not modeling
|
;; at the moment. I'll be reviewing the 7100LC scheduling info
|
;; at the moment. I'll be reviewing the 7100LC scheduling info
|
;; shortly and updating this description.
|
;; shortly and updating this description.
|
;;
|
;;
|
;; load-load pairs
|
;; load-load pairs
|
;; store-store pairs
|
;; store-store pairs
|
;; other issue modeling
|
;; other issue modeling
|
|
|
(define_automaton "pa7100lc")
|
(define_automaton "pa7100lc")
|
(define_cpu_unit "i0_7100lc, i1_7100lc, f_7100lc" "pa7100lc")
|
(define_cpu_unit "i0_7100lc, i1_7100lc, f_7100lc" "pa7100lc")
|
(define_cpu_unit "fpmac_7100lc" "pa7100lc")
|
(define_cpu_unit "fpmac_7100lc" "pa7100lc")
|
(define_cpu_unit "mem_7100lc" "pa7100lc")
|
(define_cpu_unit "mem_7100lc" "pa7100lc")
|
|
|
;; Double precision multiplies lock the entire CPU for one
|
;; Double precision multiplies lock the entire CPU for one
|
;; cycle. There is no way to avoid this lock and trying to
|
;; cycle. There is no way to avoid this lock and trying to
|
;; schedule around the lock is pointless and thus there is no
|
;; schedule around the lock is pointless and thus there is no
|
;; value in trying to model this lock.
|
;; value in trying to model this lock.
|
;;
|
;;
|
;; Not modeling the lock allows us to treat fp multiplies just
|
;; Not modeling the lock allows us to treat fp multiplies just
|
;; like any other FP alu instruction. It allows for a smaller
|
;; like any other FP alu instruction. It allows for a smaller
|
;; DFA and may reduce register pressure.
|
;; DFA and may reduce register pressure.
|
(define_insn_reservation "Y0" 2
|
(define_insn_reservation "Y0" 2
|
(and (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
|
(and (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
|
(eq_attr "cpu" "7100LC,7200,7300"))
|
(eq_attr "cpu" "7100LC,7200,7300"))
|
"f_7100lc,fpmac_7100lc")
|
"f_7100lc,fpmac_7100lc")
|
|
|
;; fp division and sqrt instructions lock the entire CPU for
|
;; fp division and sqrt instructions lock the entire CPU for
|
;; 7 cycles (single precision) or 14 cycles (double precision).
|
;; 7 cycles (single precision) or 14 cycles (double precision).
|
;; There is no way to avoid this lock and trying to schedule
|
;; There is no way to avoid this lock and trying to schedule
|
;; around the lock is pointless and thus there is no value in
|
;; around the lock is pointless and thus there is no value in
|
;; trying to model this lock. Not modeling the lock allows
|
;; trying to model this lock. Not modeling the lock allows
|
;; for a smaller DFA and may reduce register pressure.
|
;; for a smaller DFA and may reduce register pressure.
|
(define_insn_reservation "Y1" 1
|
(define_insn_reservation "Y1" 1
|
(and (eq_attr "type" "fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
|
(and (eq_attr "type" "fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
|
(eq_attr "cpu" "7100LC,7200,7300"))
|
(eq_attr "cpu" "7100LC,7200,7300"))
|
"f_7100lc")
|
"f_7100lc")
|
|
|
(define_insn_reservation "Y2" 2
|
(define_insn_reservation "Y2" 2
|
(and (eq_attr "type" "load")
|
(and (eq_attr "type" "load")
|
(eq_attr "cpu" "7100LC,7200,7300"))
|
(eq_attr "cpu" "7100LC,7200,7300"))
|
"i1_7100lc+mem_7100lc")
|
"i1_7100lc+mem_7100lc")
|
|
|
(define_insn_reservation "Y3" 2
|
(define_insn_reservation "Y3" 2
|
(and (eq_attr "type" "fpload")
|
(and (eq_attr "type" "fpload")
|
(eq_attr "cpu" "7100LC,7200,7300"))
|
(eq_attr "cpu" "7100LC,7200,7300"))
|
"i1_7100lc+mem_7100lc")
|
"i1_7100lc+mem_7100lc")
|
|
|
(define_insn_reservation "Y4" 2
|
(define_insn_reservation "Y4" 2
|
(and (eq_attr "type" "store")
|
(and (eq_attr "type" "store")
|
(eq_attr "cpu" "7100LC"))
|
(eq_attr "cpu" "7100LC"))
|
"i1_7100lc+mem_7100lc,mem_7100lc")
|
"i1_7100lc+mem_7100lc,mem_7100lc")
|
|
|
(define_insn_reservation "Y5" 2
|
(define_insn_reservation "Y5" 2
|
(and (eq_attr "type" "fpstore")
|
(and (eq_attr "type" "fpstore")
|
(eq_attr "cpu" "7100LC"))
|
(eq_attr "cpu" "7100LC"))
|
"i1_7100lc+mem_7100lc,mem_7100lc")
|
"i1_7100lc+mem_7100lc,mem_7100lc")
|
|
|
(define_insn_reservation "Y6" 4
|
(define_insn_reservation "Y6" 4
|
(and (eq_attr "type" "fpstore_load")
|
(and (eq_attr "type" "fpstore_load")
|
(eq_attr "cpu" "7100LC"))
|
(eq_attr "cpu" "7100LC"))
|
"i1_7100lc+mem_7100lc,mem_7100lc*3")
|
"i1_7100lc+mem_7100lc,mem_7100lc*3")
|
|
|
(define_insn_reservation "Y7" 4
|
(define_insn_reservation "Y7" 4
|
(and (eq_attr "type" "store_fpload")
|
(and (eq_attr "type" "store_fpload")
|
(eq_attr "cpu" "7100LC"))
|
(eq_attr "cpu" "7100LC"))
|
"i1_7100lc+mem_7100lc,mem_7100lc*3")
|
"i1_7100lc+mem_7100lc,mem_7100lc*3")
|
|
|
(define_insn_reservation "Y8" 1
|
(define_insn_reservation "Y8" 1
|
(and (eq_attr "type" "shift,nullshift")
|
(and (eq_attr "type" "shift,nullshift")
|
(eq_attr "cpu" "7100LC,7200,7300"))
|
(eq_attr "cpu" "7100LC,7200,7300"))
|
"i1_7100lc")
|
"i1_7100lc")
|
|
|
(define_insn_reservation "Y9" 1
|
(define_insn_reservation "Y9" 1
|
(and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,shift,nullshift")
|
(and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,shift,nullshift")
|
(eq_attr "cpu" "7100LC,7200,7300"))
|
(eq_attr "cpu" "7100LC,7200,7300"))
|
"(i0_7100lc|i1_7100lc)")
|
"(i0_7100lc|i1_7100lc)")
|
|
|
;; The 7200 has a store-load penalty
|
;; The 7200 has a store-load penalty
|
(define_insn_reservation "Y10" 2
|
(define_insn_reservation "Y10" 2
|
(and (eq_attr "type" "store")
|
(and (eq_attr "type" "store")
|
(eq_attr "cpu" "7200"))
|
(eq_attr "cpu" "7200"))
|
"i1_7100lc,mem_7100lc")
|
"i1_7100lc,mem_7100lc")
|
|
|
(define_insn_reservation "Y11" 2
|
(define_insn_reservation "Y11" 2
|
(and (eq_attr "type" "fpstore")
|
(and (eq_attr "type" "fpstore")
|
(eq_attr "cpu" "7200"))
|
(eq_attr "cpu" "7200"))
|
"i1_7100lc,mem_7100lc")
|
"i1_7100lc,mem_7100lc")
|
|
|
(define_insn_reservation "Y12" 4
|
(define_insn_reservation "Y12" 4
|
(and (eq_attr "type" "fpstore_load")
|
(and (eq_attr "type" "fpstore_load")
|
(eq_attr "cpu" "7200"))
|
(eq_attr "cpu" "7200"))
|
"i1_7100lc,mem_7100lc,i1_7100lc+mem_7100lc")
|
"i1_7100lc,mem_7100lc,i1_7100lc+mem_7100lc")
|
|
|
(define_insn_reservation "Y13" 4
|
(define_insn_reservation "Y13" 4
|
(and (eq_attr "type" "store_fpload")
|
(and (eq_attr "type" "store_fpload")
|
(eq_attr "cpu" "7200"))
|
(eq_attr "cpu" "7200"))
|
"i1_7100lc,mem_7100lc,i1_7100lc+mem_7100lc")
|
"i1_7100lc,mem_7100lc,i1_7100lc+mem_7100lc")
|
|
|
;; The 7300 has no penalty for store-store or store-load
|
;; The 7300 has no penalty for store-store or store-load
|
(define_insn_reservation "Y14" 2
|
(define_insn_reservation "Y14" 2
|
(and (eq_attr "type" "store")
|
(and (eq_attr "type" "store")
|
(eq_attr "cpu" "7300"))
|
(eq_attr "cpu" "7300"))
|
"i1_7100lc")
|
"i1_7100lc")
|
|
|
(define_insn_reservation "Y15" 2
|
(define_insn_reservation "Y15" 2
|
(and (eq_attr "type" "fpstore")
|
(and (eq_attr "type" "fpstore")
|
(eq_attr "cpu" "7300"))
|
(eq_attr "cpu" "7300"))
|
"i1_7100lc")
|
"i1_7100lc")
|
|
|
(define_insn_reservation "Y16" 4
|
(define_insn_reservation "Y16" 4
|
(and (eq_attr "type" "fpstore_load")
|
(and (eq_attr "type" "fpstore_load")
|
(eq_attr "cpu" "7300"))
|
(eq_attr "cpu" "7300"))
|
"i1_7100lc,i1_7100lc+mem_7100lc")
|
"i1_7100lc,i1_7100lc+mem_7100lc")
|
|
|
(define_insn_reservation "Y17" 4
|
(define_insn_reservation "Y17" 4
|
(and (eq_attr "type" "store_fpload")
|
(and (eq_attr "type" "store_fpload")
|
(eq_attr "cpu" "7300"))
|
(eq_attr "cpu" "7300"))
|
"i1_7100lc,i1_7100lc+mem_7100lc")
|
"i1_7100lc,i1_7100lc+mem_7100lc")
|
|
|
;; We have an "anti-bypass" for FP loads which feed an FP store.
|
;; We have an "anti-bypass" for FP loads which feed an FP store.
|
(define_bypass 3 "Y3,Y7,Y13,Y17" "Y5,Y6,Y11,Y12,Y15,Y16" "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
|
;; Scheduling for the PA8000 is somewhat different than scheduling for a
|
;; traditional architecture.
|
;; traditional architecture.
|
;;
|
;;
|
;; The PA8000 has a large (56) entry reorder buffer that is split between
|
;; The PA8000 has a large (56) entry reorder buffer that is split between
|
;; memory and non-memory operations.
|
;; memory and non-memory operations.
|
;;
|
;;
|
;; The PA8000 can issue two memory and two non-memory operations per cycle to
|
;; The PA8000 can issue two memory and two non-memory operations per cycle to
|
;; the function units, with the exception of branches and multi-output
|
;; the function units, with the exception of branches and multi-output
|
;; instructions. The PA8000 can retire two non-memory operations per cycle
|
;; instructions. The PA8000 can retire two non-memory operations per cycle
|
;; and two memory operations per cycle, only one of which may be a store.
|
;; and two memory operations per cycle, only one of which may be a store.
|
;;
|
;;
|
;; Given the large reorder buffer, the processor can hide most latencies.
|
;; Given the large reorder buffer, the processor can hide most latencies.
|
;; According to HP, they've got the best results by scheduling for retirement
|
;; According to HP, they've got the best results by scheduling for retirement
|
;; bandwidth with limited latency scheduling for floating point operations.
|
;; bandwidth with limited latency scheduling for floating point operations.
|
;; Latency for integer operations and memory references is ignored.
|
;; Latency for integer operations and memory references is ignored.
|
;;
|
;;
|
;;
|
;;
|
;; We claim floating point operations have a 2 cycle latency and are
|
;; We claim floating point operations have a 2 cycle latency and are
|
;; fully pipelined, except for div and sqrt which are not pipelined and
|
;; fully pipelined, except for div and sqrt which are not pipelined and
|
;; take from 17 to 31 cycles to complete.
|
;; take from 17 to 31 cycles to complete.
|
;;
|
;;
|
;; It's worth noting that there is no way to saturate all the functional
|
;; It's worth noting that there is no way to saturate all the functional
|
;; units on the PA8000 as there is not enough issue bandwidth.
|
;; units on the PA8000 as there is not enough issue bandwidth.
|
|
|
(define_automaton "pa8000")
|
(define_automaton "pa8000")
|
(define_cpu_unit "inm0_8000, inm1_8000, im0_8000, im1_8000" "pa8000")
|
(define_cpu_unit "inm0_8000, inm1_8000, im0_8000, im1_8000" "pa8000")
|
(define_cpu_unit "rnm0_8000, rnm1_8000, rm0_8000, rm1_8000" "pa8000")
|
(define_cpu_unit "rnm0_8000, rnm1_8000, rm0_8000, rm1_8000" "pa8000")
|
(define_cpu_unit "store_8000" "pa8000")
|
(define_cpu_unit "store_8000" "pa8000")
|
(define_cpu_unit "f0_8000, f1_8000" "pa8000")
|
(define_cpu_unit "f0_8000, f1_8000" "pa8000")
|
(define_cpu_unit "fdivsqrt0_8000, fdivsqrt1_8000" "pa8000")
|
(define_cpu_unit "fdivsqrt0_8000, fdivsqrt1_8000" "pa8000")
|
(define_reservation "inm_8000" "inm0_8000 | inm1_8000")
|
(define_reservation "inm_8000" "inm0_8000 | inm1_8000")
|
(define_reservation "im_8000" "im0_8000 | im1_8000")
|
(define_reservation "im_8000" "im0_8000 | im1_8000")
|
(define_reservation "rnm_8000" "rnm0_8000 | rnm1_8000")
|
(define_reservation "rnm_8000" "rnm0_8000 | rnm1_8000")
|
(define_reservation "rm_8000" "rm0_8000 | rm1_8000")
|
(define_reservation "rm_8000" "rm0_8000 | rm1_8000")
|
(define_reservation "f_8000" "f0_8000 | f1_8000")
|
(define_reservation "f_8000" "f0_8000 | f1_8000")
|
(define_reservation "fdivsqrt_8000" "fdivsqrt0_8000 | fdivsqrt1_8000")
|
(define_reservation "fdivsqrt_8000" "fdivsqrt0_8000 | fdivsqrt1_8000")
|
|
|
;; We can issue any two memops per cycle, but we can only retire
|
;; We can issue any two memops per cycle, but we can only retire
|
;; one memory store per cycle. We assume that the reorder buffer
|
;; one memory store per cycle. We assume that the reorder buffer
|
;; will hide any memory latencies per HP's recommendation.
|
;; will hide any memory latencies per HP's recommendation.
|
(define_insn_reservation "Z0" 0
|
(define_insn_reservation "Z0" 0
|
(and
|
(and
|
(eq_attr "type" "load,fpload")
|
(eq_attr "type" "load,fpload")
|
(eq_attr "cpu" "8000"))
|
(eq_attr "cpu" "8000"))
|
"im_8000,rm_8000")
|
"im_8000,rm_8000")
|
|
|
(define_insn_reservation "Z1" 0
|
(define_insn_reservation "Z1" 0
|
(and
|
(and
|
(eq_attr "type" "store,fpstore")
|
(eq_attr "type" "store,fpstore")
|
(eq_attr "cpu" "8000"))
|
(eq_attr "cpu" "8000"))
|
"im_8000,rm_8000+store_8000")
|
"im_8000,rm_8000+store_8000")
|
|
|
(define_insn_reservation "Z2" 0
|
(define_insn_reservation "Z2" 0
|
(and (eq_attr "type" "fpstore_load,store_fpload")
|
(and (eq_attr "type" "fpstore_load,store_fpload")
|
(eq_attr "cpu" "8000"))
|
(eq_attr "cpu" "8000"))
|
"im_8000,rm_8000+store_8000,im_8000,rm_8000")
|
"im_8000,rm_8000+store_8000,im_8000,rm_8000")
|
|
|
;; We can issue and retire two non-memory operations per cycle with
|
;; We can issue and retire two non-memory operations per cycle with
|
;; a few exceptions (branches). This group catches those we want
|
;; a few exceptions (branches). This group catches those we want
|
;; to assume have zero latency.
|
;; to assume have zero latency.
|
(define_insn_reservation "Z3" 0
|
(define_insn_reservation "Z3" 0
|
(and
|
(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,fpstore_load,store_fpload")
|
(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"))
|
(eq_attr "cpu" "8000"))
|
"inm_8000,rnm_8000")
|
"inm_8000,rnm_8000")
|
|
|
;; Branches use both slots in the non-memory issue and
|
;; Branches use both slots in the non-memory issue and
|
;; retirement unit.
|
;; retirement unit.
|
(define_insn_reservation "Z4" 0
|
(define_insn_reservation "Z4" 0
|
(and
|
(and
|
(eq_attr "type" "uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch")
|
(eq_attr "type" "uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch")
|
(eq_attr "cpu" "8000"))
|
(eq_attr "cpu" "8000"))
|
"inm0_8000+inm1_8000,rnm0_8000+rnm1_8000")
|
"inm0_8000+inm1_8000,rnm0_8000+rnm1_8000")
|
|
|
;; We partial latency schedule the floating point units.
|
;; We partial latency schedule the floating point units.
|
;; They can issue/retire two at a time in the non-memory
|
;; They can issue/retire two at a time in the non-memory
|
;; units. We fix their latency at 2 cycles and they
|
;; units. We fix their latency at 2 cycles and they
|
;; are fully pipelined.
|
;; are fully pipelined.
|
(define_insn_reservation "Z5" 1
|
(define_insn_reservation "Z5" 1
|
(and
|
(and
|
(eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
|
(eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
|
(eq_attr "cpu" "8000"))
|
(eq_attr "cpu" "8000"))
|
"inm_8000,f_8000,rnm_8000")
|
"inm_8000,f_8000,rnm_8000")
|
|
|
;; The fdivsqrt units are not pipelined and have a very long latency.
|
;; The fdivsqrt units are not pipelined and have a very long latency.
|
;; To keep the DFA from exploding, we do not show all the
|
;; To keep the DFA from exploding, we do not show all the
|
;; reservations for the divsqrt unit.
|
;; reservations for the divsqrt unit.
|
(define_insn_reservation "Z6" 17
|
(define_insn_reservation "Z6" 17
|
(and
|
(and
|
(eq_attr "type" "fpdivsgl,fpsqrtsgl")
|
(eq_attr "type" "fpdivsgl,fpsqrtsgl")
|
(eq_attr "cpu" "8000"))
|
(eq_attr "cpu" "8000"))
|
"inm_8000,fdivsqrt_8000*6,rnm_8000")
|
"inm_8000,fdivsqrt_8000*6,rnm_8000")
|
|
|
(define_insn_reservation "Z7" 31
|
(define_insn_reservation "Z7" 31
|
(and
|
(and
|
(eq_attr "type" "fpdivdbl,fpsqrtdbl")
|
(eq_attr "type" "fpdivdbl,fpsqrtdbl")
|
(eq_attr "cpu" "8000"))
|
(eq_attr "cpu" "8000"))
|
"inm_8000,fdivsqrt_8000*6,rnm_8000")
|
"inm_8000,fdivsqrt_8000*6,rnm_8000")
|
|
|
;; Operand and operator predicates and constraints
|
;; Operand and operator predicates and constraints
|
|
|
(include "predicates.md")
|
(include "predicates.md")
|
(include "constraints.md")
|
(include "constraints.md")
|
|
|
;; Compare instructions.
|
;; Compare instructions.
|
;; This controls RTL generation and register allocation.
|
;; This controls RTL generation and register allocation.
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (reg:CCFP 0)
|
[(set (reg:CCFP 0)
|
(match_operator:CCFP 2 "comparison_operator"
|
(match_operator:CCFP 2 "comparison_operator"
|
[(match_operand:SF 0 "reg_or_0_operand" "fG")
|
[(match_operand:SF 0 "reg_or_0_operand" "fG")
|
(match_operand:SF 1 "reg_or_0_operand" "fG")]))]
|
(match_operand:SF 1 "reg_or_0_operand" "fG")]))]
|
"! TARGET_SOFT_FLOAT"
|
"! TARGET_SOFT_FLOAT"
|
"fcmp,sgl,%Y2 %f0,%f1"
|
"fcmp,sgl,%Y2 %f0,%f1"
|
[(set_attr "length" "4")
|
[(set_attr "length" "4")
|
(set_attr "type" "fpcc")])
|
(set_attr "type" "fpcc")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (reg:CCFP 0)
|
[(set (reg:CCFP 0)
|
(match_operator:CCFP 2 "comparison_operator"
|
(match_operator:CCFP 2 "comparison_operator"
|
[(match_operand:DF 0 "reg_or_0_operand" "fG")
|
[(match_operand:DF 0 "reg_or_0_operand" "fG")
|
(match_operand:DF 1 "reg_or_0_operand" "fG")]))]
|
(match_operand:DF 1 "reg_or_0_operand" "fG")]))]
|
"! TARGET_SOFT_FLOAT"
|
"! TARGET_SOFT_FLOAT"
|
"fcmp,dbl,%Y2 %f0,%f1"
|
"fcmp,dbl,%Y2 %f0,%f1"
|
[(set_attr "length" "4")
|
[(set_attr "length" "4")
|
(set_attr "type" "fpcc")])
|
(set_attr "type" "fpcc")])
|
|
|
;; Provide a means to emit the movccfp0 and movccfp1 optimization
|
;; Provide a means to emit the movccfp0 and movccfp1 optimization
|
;; placeholders. This is necessary in rare situations when a
|
;; placeholders. This is necessary in rare situations when a
|
;; placeholder is re-emitted (see PR 8705).
|
;; placeholder is re-emitted (see PR 8705).
|
|
|
(define_expand "movccfp"
|
(define_expand "movccfp"
|
[(set (reg:CCFP 0)
|
[(set (reg:CCFP 0)
|
(match_operand 0 "const_int_operand" ""))]
|
(match_operand 0 "const_int_operand" ""))]
|
"! TARGET_SOFT_FLOAT"
|
"! TARGET_SOFT_FLOAT"
|
"
|
"
|
{
|
{
|
if ((unsigned HOST_WIDE_INT) INTVAL (operands[0]) > 1)
|
if ((unsigned HOST_WIDE_INT) INTVAL (operands[0]) > 1)
|
FAIL;
|
FAIL;
|
}")
|
}")
|
|
|
;; The following patterns are optimization placeholders. In almost
|
;; The following patterns are optimization placeholders. In almost
|
;; all cases, the user of the condition code will be simplified and the
|
;; all cases, the user of the condition code will be simplified and the
|
;; original condition code setting insn should be eliminated.
|
;; original condition code setting insn should be eliminated.
|
|
|
(define_insn "*movccfp0"
|
(define_insn "*movccfp0"
|
[(set (reg:CCFP 0)
|
[(set (reg:CCFP 0)
|
(const_int 0))]
|
(const_int 0))]
|
"! TARGET_SOFT_FLOAT"
|
"! TARGET_SOFT_FLOAT"
|
"fcmp,dbl,= %%fr0,%%fr0"
|
"fcmp,dbl,= %%fr0,%%fr0"
|
[(set_attr "length" "4")
|
[(set_attr "length" "4")
|
(set_attr "type" "fpcc")])
|
(set_attr "type" "fpcc")])
|
|
|
(define_insn "*movccfp1"
|
(define_insn "*movccfp1"
|
[(set (reg:CCFP 0)
|
[(set (reg:CCFP 0)
|
(const_int 1))]
|
(const_int 1))]
|
"! TARGET_SOFT_FLOAT"
|
"! TARGET_SOFT_FLOAT"
|
"fcmp,dbl,!= %%fr0,%%fr0"
|
"fcmp,dbl,!= %%fr0,%%fr0"
|
[(set_attr "length" "4")
|
[(set_attr "length" "4")
|
(set_attr "type" "fpcc")])
|
(set_attr "type" "fpcc")])
|
|
|
;; scc insns.
|
;; scc insns.
|
|
|
(define_expand "cstoresi4"
|
(define_expand "cstoresi4"
|
[(set (match_operand:SI 0 "register_operand")
|
[(set (match_operand:SI 0 "register_operand")
|
(match_operator:SI 1 "ordered_comparison_operator"
|
(match_operator:SI 1 "ordered_comparison_operator"
|
[(match_operand:SI 2 "reg_or_0_operand" "")
|
[(match_operand:SI 2 "reg_or_0_operand" "")
|
(match_operand:SI 3 "arith5_operand" "")]))]
|
(match_operand:SI 3 "arith5_operand" "")]))]
|
"!TARGET_64BIT"
|
"!TARGET_64BIT"
|
"")
|
"")
|
|
|
;; Instruction canonicalization puts immediate operands second, which
|
;; Instruction canonicalization puts immediate operands second, which
|
;; is the reverse of what we want.
|
;; is the reverse of what we want.
|
|
|
(define_insn "scc"
|
(define_insn "scc"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(match_operator:SI 3 "comparison_operator"
|
(match_operator:SI 3 "comparison_operator"
|
[(match_operand:SI 1 "register_operand" "r")
|
[(match_operand:SI 1 "register_operand" "r")
|
(match_operand:SI 2 "arith11_operand" "rI")]))]
|
(match_operand:SI 2 "arith11_operand" "rI")]))]
|
""
|
""
|
"{com%I2clr|cmp%I2clr},%B3 %2,%1,%0\;ldi 1,%0"
|
"{com%I2clr|cmp%I2clr},%B3 %2,%1,%0\;ldi 1,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(match_operator:DI 3 "comparison_operator"
|
(match_operator:DI 3 "comparison_operator"
|
[(match_operand:DI 1 "register_operand" "r")
|
[(match_operand:DI 1 "register_operand" "r")
|
(match_operand:DI 2 "arith11_operand" "rI")]))]
|
(match_operand:DI 2 "arith11_operand" "rI")]))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"cmp%I2clr,*%B3 %2,%1,%0\;ldi 1,%0"
|
"cmp%I2clr,*%B3 %2,%1,%0\;ldi 1,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn "iorscc"
|
(define_insn "iorscc"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(ior:SI (match_operator:SI 3 "comparison_operator"
|
(ior:SI (match_operator:SI 3 "comparison_operator"
|
[(match_operand:SI 1 "register_operand" "r")
|
[(match_operand:SI 1 "register_operand" "r")
|
(match_operand:SI 2 "arith11_operand" "rI")])
|
(match_operand:SI 2 "arith11_operand" "rI")])
|
(match_operator:SI 6 "comparison_operator"
|
(match_operator:SI 6 "comparison_operator"
|
[(match_operand:SI 4 "register_operand" "r")
|
[(match_operand:SI 4 "register_operand" "r")
|
(match_operand:SI 5 "arith11_operand" "rI")])))]
|
(match_operand:SI 5 "arith11_operand" "rI")])))]
|
""
|
""
|
"{com%I2clr|cmp%I2clr},%S3 %2,%1,%%r0\;{com%I5clr|cmp%I5clr},%B6 %5,%4,%0\;ldi 1,%0"
|
"{com%I2clr|cmp%I2clr},%S3 %2,%1,%%r0\;{com%I5clr|cmp%I5clr},%B6 %5,%4,%0\;ldi 1,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "12")])
|
(set_attr "length" "12")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(ior:DI (match_operator:DI 3 "comparison_operator"
|
(ior:DI (match_operator:DI 3 "comparison_operator"
|
[(match_operand:DI 1 "register_operand" "r")
|
[(match_operand:DI 1 "register_operand" "r")
|
(match_operand:DI 2 "arith11_operand" "rI")])
|
(match_operand:DI 2 "arith11_operand" "rI")])
|
(match_operator:DI 6 "comparison_operator"
|
(match_operator:DI 6 "comparison_operator"
|
[(match_operand:DI 4 "register_operand" "r")
|
[(match_operand:DI 4 "register_operand" "r")
|
(match_operand:DI 5 "arith11_operand" "rI")])))]
|
(match_operand:DI 5 "arith11_operand" "rI")])))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"cmp%I2clr,*%S3 %2,%1,%%r0\;cmp%I5clr,*%B6 %5,%4,%0\;ldi 1,%0"
|
"cmp%I2clr,*%S3 %2,%1,%%r0\;cmp%I5clr,*%B6 %5,%4,%0\;ldi 1,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "12")])
|
(set_attr "length" "12")])
|
|
|
;; Combiner patterns for common operations performed with the output
|
;; Combiner patterns for common operations performed with the output
|
;; from an scc insn (negscc and incscc).
|
;; from an scc insn (negscc and incscc).
|
(define_insn "negscc"
|
(define_insn "negscc"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(neg:SI (match_operator:SI 3 "comparison_operator"
|
(neg:SI (match_operator:SI 3 "comparison_operator"
|
[(match_operand:SI 1 "register_operand" "r")
|
[(match_operand:SI 1 "register_operand" "r")
|
(match_operand:SI 2 "arith11_operand" "rI")])))]
|
(match_operand:SI 2 "arith11_operand" "rI")])))]
|
""
|
""
|
"{com%I2clr|cmp%I2clr},%B3 %2,%1,%0\;ldi -1,%0"
|
"{com%I2clr|cmp%I2clr},%B3 %2,%1,%0\;ldi -1,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(neg:DI (match_operator:DI 3 "comparison_operator"
|
(neg:DI (match_operator:DI 3 "comparison_operator"
|
[(match_operand:DI 1 "register_operand" "r")
|
[(match_operand:DI 1 "register_operand" "r")
|
(match_operand:DI 2 "arith11_operand" "rI")])))]
|
(match_operand:DI 2 "arith11_operand" "rI")])))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"cmp%I2clr,*%B3 %2,%1,%0\;ldi -1,%0"
|
"cmp%I2clr,*%B3 %2,%1,%0\;ldi -1,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
;; Patterns for adding/subtracting the result of a boolean expression from
|
;; Patterns for adding/subtracting the result of a boolean expression from
|
;; a register. First we have special patterns that make use of the carry
|
;; a register. First we have special patterns that make use of the carry
|
;; bit, and output only two instructions. For the cases we can't in
|
;; bit, and output only two instructions. For the cases we can't in
|
;; general do in two instructions, the incscc pattern at the end outputs
|
;; general do in two instructions, the incscc pattern at the end outputs
|
;; two or three instructions.
|
;; two or three instructions.
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(plus:SI (leu:SI (match_operand:SI 2 "register_operand" "r")
|
(plus:SI (leu:SI (match_operand:SI 2 "register_operand" "r")
|
(match_operand:SI 3 "arith11_operand" "rI"))
|
(match_operand:SI 3 "arith11_operand" "rI"))
|
(match_operand:SI 1 "register_operand" "r")))]
|
(match_operand:SI 1 "register_operand" "r")))]
|
""
|
""
|
"sub%I3 %3,%2,%%r0\;{addc|add,c} %%r0,%1,%0"
|
"sub%I3 %3,%2,%%r0\;{addc|add,c} %%r0,%1,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(plus:DI (leu:DI (match_operand:DI 2 "register_operand" "r")
|
(plus:DI (leu:DI (match_operand:DI 2 "register_operand" "r")
|
(match_operand:DI 3 "arith11_operand" "rI"))
|
(match_operand:DI 3 "arith11_operand" "rI"))
|
(match_operand:DI 1 "register_operand" "r")))]
|
(match_operand:DI 1 "register_operand" "r")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"sub%I3 %3,%2,%%r0\;add,dc %%r0,%1,%0"
|
"sub%I3 %3,%2,%%r0\;add,dc %%r0,%1,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
; This need only accept registers for op3, since canonicalization
|
; This need only accept registers for op3, since canonicalization
|
; replaces geu with gtu when op3 is an integer.
|
; replaces geu with gtu when op3 is an integer.
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(plus:SI (geu:SI (match_operand:SI 2 "register_operand" "r")
|
(plus:SI (geu:SI (match_operand:SI 2 "register_operand" "r")
|
(match_operand:SI 3 "register_operand" "r"))
|
(match_operand:SI 3 "register_operand" "r"))
|
(match_operand:SI 1 "register_operand" "r")))]
|
(match_operand:SI 1 "register_operand" "r")))]
|
""
|
""
|
"sub %2,%3,%%r0\;{addc|add,c} %%r0,%1,%0"
|
"sub %2,%3,%%r0\;{addc|add,c} %%r0,%1,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(plus:DI (geu:DI (match_operand:DI 2 "register_operand" "r")
|
(plus:DI (geu:DI (match_operand:DI 2 "register_operand" "r")
|
(match_operand:DI 3 "register_operand" "r"))
|
(match_operand:DI 3 "register_operand" "r"))
|
(match_operand:DI 1 "register_operand" "r")))]
|
(match_operand:DI 1 "register_operand" "r")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"sub %2,%3,%%r0\;add,dc %%r0,%1,%0"
|
"sub %2,%3,%%r0\;add,dc %%r0,%1,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
; Match only integers for op3 here. This is used as canonical form of the
|
; Match only integers for op3 here. This is used as canonical form of the
|
; geu pattern when op3 is an integer. Don't match registers since we can't
|
; geu pattern when op3 is an integer. Don't match registers since we can't
|
; make better code than the general incscc pattern.
|
; make better code than the general incscc pattern.
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(plus:SI (gtu:SI (match_operand:SI 2 "register_operand" "r")
|
(plus:SI (gtu:SI (match_operand:SI 2 "register_operand" "r")
|
(match_operand:SI 3 "int11_operand" "I"))
|
(match_operand:SI 3 "int11_operand" "I"))
|
(match_operand:SI 1 "register_operand" "r")))]
|
(match_operand:SI 1 "register_operand" "r")))]
|
""
|
""
|
"addi %k3,%2,%%r0\;{addc|add,c} %%r0,%1,%0"
|
"addi %k3,%2,%%r0\;{addc|add,c} %%r0,%1,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(plus:DI (gtu:DI (match_operand:DI 2 "register_operand" "r")
|
(plus:DI (gtu:DI (match_operand:DI 2 "register_operand" "r")
|
(match_operand:DI 3 "int11_operand" "I"))
|
(match_operand:DI 3 "int11_operand" "I"))
|
(match_operand:DI 1 "register_operand" "r")))]
|
(match_operand:DI 1 "register_operand" "r")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"addi %k3,%2,%%r0\;add,dc %%r0,%1,%0"
|
"addi %k3,%2,%%r0\;add,dc %%r0,%1,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn "incscc"
|
(define_insn "incscc"
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
(plus:SI (match_operator:SI 4 "comparison_operator"
|
(plus:SI (match_operator:SI 4 "comparison_operator"
|
[(match_operand:SI 2 "register_operand" "r,r")
|
[(match_operand:SI 2 "register_operand" "r,r")
|
(match_operand:SI 3 "arith11_operand" "rI,rI")])
|
(match_operand:SI 3 "arith11_operand" "rI,rI")])
|
(match_operand:SI 1 "register_operand" "0,?r")))]
|
(match_operand:SI 1 "register_operand" "0,?r")))]
|
""
|
""
|
"@
|
"@
|
{com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi 1,%0,%0
|
{com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi 1,%0,%0
|
{com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0"
|
{com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0"
|
[(set_attr "type" "binary,binary")
|
[(set_attr "type" "binary,binary")
|
(set_attr "length" "8,12")])
|
(set_attr "length" "8,12")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
(plus:DI (match_operator:DI 4 "comparison_operator"
|
(plus:DI (match_operator:DI 4 "comparison_operator"
|
[(match_operand:DI 2 "register_operand" "r,r")
|
[(match_operand:DI 2 "register_operand" "r,r")
|
(match_operand:DI 3 "arith11_operand" "rI,rI")])
|
(match_operand:DI 3 "arith11_operand" "rI,rI")])
|
(match_operand:DI 1 "register_operand" "0,?r")))]
|
(match_operand:DI 1 "register_operand" "0,?r")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"@
|
"@
|
cmp%I3clr,*%B4 %3,%2,%%r0\;addi 1,%0,%0
|
cmp%I3clr,*%B4 %3,%2,%%r0\;addi 1,%0,%0
|
cmp%I3clr,*%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0"
|
cmp%I3clr,*%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0"
|
[(set_attr "type" "binary,binary")
|
[(set_attr "type" "binary,binary")
|
(set_attr "length" "8,12")])
|
(set_attr "length" "8,12")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(minus:SI (match_operand:SI 1 "register_operand" "r")
|
(minus:SI (match_operand:SI 1 "register_operand" "r")
|
(gtu:SI (match_operand:SI 2 "register_operand" "r")
|
(gtu:SI (match_operand:SI 2 "register_operand" "r")
|
(match_operand:SI 3 "arith11_operand" "rI"))))]
|
(match_operand:SI 3 "arith11_operand" "rI"))))]
|
""
|
""
|
"sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0"
|
"sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(minus:DI (match_operand:DI 1 "register_operand" "r")
|
(minus:DI (match_operand:DI 1 "register_operand" "r")
|
(gtu:DI (match_operand:DI 2 "register_operand" "r")
|
(gtu:DI (match_operand:DI 2 "register_operand" "r")
|
(match_operand:DI 3 "arith11_operand" "rI"))))]
|
(match_operand:DI 3 "arith11_operand" "rI"))))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"sub%I3 %3,%2,%%r0\;sub,db %1,%%r0,%0"
|
"sub%I3 %3,%2,%%r0\;sub,db %1,%%r0,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
|
(minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
|
(gtu:SI (match_operand:SI 2 "register_operand" "r")
|
(gtu:SI (match_operand:SI 2 "register_operand" "r")
|
(match_operand:SI 3 "arith11_operand" "rI")))
|
(match_operand:SI 3 "arith11_operand" "rI")))
|
(match_operand:SI 4 "register_operand" "r")))]
|
(match_operand:SI 4 "register_operand" "r")))]
|
""
|
""
|
"sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%4,%0"
|
"sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%4,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
|
(minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
|
(gtu:DI (match_operand:DI 2 "register_operand" "r")
|
(gtu:DI (match_operand:DI 2 "register_operand" "r")
|
(match_operand:DI 3 "arith11_operand" "rI")))
|
(match_operand:DI 3 "arith11_operand" "rI")))
|
(match_operand:DI 4 "register_operand" "r")))]
|
(match_operand:DI 4 "register_operand" "r")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"sub%I3 %3,%2,%%r0\;sub,db %1,%4,%0"
|
"sub%I3 %3,%2,%%r0\;sub,db %1,%4,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
; This need only accept registers for op3, since canonicalization
|
; This need only accept registers for op3, since canonicalization
|
; replaces ltu with leu when op3 is an integer.
|
; replaces ltu with leu when op3 is an integer.
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(minus:SI (match_operand:SI 1 "register_operand" "r")
|
(minus:SI (match_operand:SI 1 "register_operand" "r")
|
(ltu:SI (match_operand:SI 2 "register_operand" "r")
|
(ltu:SI (match_operand:SI 2 "register_operand" "r")
|
(match_operand:SI 3 "register_operand" "r"))))]
|
(match_operand:SI 3 "register_operand" "r"))))]
|
""
|
""
|
"sub %2,%3,%%r0\;{subb|sub,b} %1,%%r0,%0"
|
"sub %2,%3,%%r0\;{subb|sub,b} %1,%%r0,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(minus:DI (match_operand:DI 1 "register_operand" "r")
|
(minus:DI (match_operand:DI 1 "register_operand" "r")
|
(ltu:DI (match_operand:DI 2 "register_operand" "r")
|
(ltu:DI (match_operand:DI 2 "register_operand" "r")
|
(match_operand:DI 3 "register_operand" "r"))))]
|
(match_operand:DI 3 "register_operand" "r"))))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"sub %2,%3,%%r0\;sub,db %1,%%r0,%0"
|
"sub %2,%3,%%r0\;sub,db %1,%%r0,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
|
(minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
|
(ltu:SI (match_operand:SI 2 "register_operand" "r")
|
(ltu:SI (match_operand:SI 2 "register_operand" "r")
|
(match_operand:SI 3 "register_operand" "r")))
|
(match_operand:SI 3 "register_operand" "r")))
|
(match_operand:SI 4 "register_operand" "r")))]
|
(match_operand:SI 4 "register_operand" "r")))]
|
""
|
""
|
"sub %2,%3,%%r0\;{subb|sub,b} %1,%4,%0"
|
"sub %2,%3,%%r0\;{subb|sub,b} %1,%4,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
|
(minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
|
(ltu:DI (match_operand:DI 2 "register_operand" "r")
|
(ltu:DI (match_operand:DI 2 "register_operand" "r")
|
(match_operand:DI 3 "register_operand" "r")))
|
(match_operand:DI 3 "register_operand" "r")))
|
(match_operand:DI 4 "register_operand" "r")))]
|
(match_operand:DI 4 "register_operand" "r")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"sub %2,%3,%%r0\;sub,db %1,%4,%0"
|
"sub %2,%3,%%r0\;sub,db %1,%4,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
; Match only integers for op3 here. This is used as canonical form of the
|
; Match only integers for op3 here. This is used as canonical form of the
|
; ltu pattern when op3 is an integer. Don't match registers since we can't
|
; ltu pattern when op3 is an integer. Don't match registers since we can't
|
; make better code than the general incscc pattern.
|
; make better code than the general incscc pattern.
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(minus:SI (match_operand:SI 1 "register_operand" "r")
|
(minus:SI (match_operand:SI 1 "register_operand" "r")
|
(leu:SI (match_operand:SI 2 "register_operand" "r")
|
(leu:SI (match_operand:SI 2 "register_operand" "r")
|
(match_operand:SI 3 "int11_operand" "I"))))]
|
(match_operand:SI 3 "int11_operand" "I"))))]
|
""
|
""
|
"addi %k3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0"
|
"addi %k3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(minus:DI (match_operand:DI 1 "register_operand" "r")
|
(minus:DI (match_operand:DI 1 "register_operand" "r")
|
(leu:DI (match_operand:DI 2 "register_operand" "r")
|
(leu:DI (match_operand:DI 2 "register_operand" "r")
|
(match_operand:DI 3 "int11_operand" "I"))))]
|
(match_operand:DI 3 "int11_operand" "I"))))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"addi %k3,%2,%%r0\;sub,db %1,%%r0,%0"
|
"addi %k3,%2,%%r0\;sub,db %1,%%r0,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
|
(minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
|
(leu:SI (match_operand:SI 2 "register_operand" "r")
|
(leu:SI (match_operand:SI 2 "register_operand" "r")
|
(match_operand:SI 3 "int11_operand" "I")))
|
(match_operand:SI 3 "int11_operand" "I")))
|
(match_operand:SI 4 "register_operand" "r")))]
|
(match_operand:SI 4 "register_operand" "r")))]
|
""
|
""
|
"addi %k3,%2,%%r0\;{subb|sub,b} %1,%4,%0"
|
"addi %k3,%2,%%r0\;{subb|sub,b} %1,%4,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
|
(minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
|
(leu:DI (match_operand:DI 2 "register_operand" "r")
|
(leu:DI (match_operand:DI 2 "register_operand" "r")
|
(match_operand:DI 3 "int11_operand" "I")))
|
(match_operand:DI 3 "int11_operand" "I")))
|
(match_operand:DI 4 "register_operand" "r")))]
|
(match_operand:DI 4 "register_operand" "r")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"addi %k3,%2,%%r0\;sub,db %1,%4,%0"
|
"addi %k3,%2,%%r0\;sub,db %1,%4,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn "decscc"
|
(define_insn "decscc"
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
(minus:SI (match_operand:SI 1 "register_operand" "0,?r")
|
(minus:SI (match_operand:SI 1 "register_operand" "0,?r")
|
(match_operator:SI 4 "comparison_operator"
|
(match_operator:SI 4 "comparison_operator"
|
[(match_operand:SI 2 "register_operand" "r,r")
|
[(match_operand:SI 2 "register_operand" "r,r")
|
(match_operand:SI 3 "arith11_operand" "rI,rI")])))]
|
(match_operand:SI 3 "arith11_operand" "rI,rI")])))]
|
""
|
""
|
"@
|
"@
|
{com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi -1,%0,%0
|
{com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi -1,%0,%0
|
{com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0"
|
{com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0"
|
[(set_attr "type" "binary,binary")
|
[(set_attr "type" "binary,binary")
|
(set_attr "length" "8,12")])
|
(set_attr "length" "8,12")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
(minus:DI (match_operand:DI 1 "register_operand" "0,?r")
|
(minus:DI (match_operand:DI 1 "register_operand" "0,?r")
|
(match_operator:DI 4 "comparison_operator"
|
(match_operator:DI 4 "comparison_operator"
|
[(match_operand:DI 2 "register_operand" "r,r")
|
[(match_operand:DI 2 "register_operand" "r,r")
|
(match_operand:DI 3 "arith11_operand" "rI,rI")])))]
|
(match_operand:DI 3 "arith11_operand" "rI,rI")])))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"@
|
"@
|
cmp%I3clr,*%B4 %3,%2,%%r0\;addi -1,%0,%0
|
cmp%I3clr,*%B4 %3,%2,%%r0\;addi -1,%0,%0
|
cmp%I3clr,*%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0"
|
cmp%I3clr,*%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0"
|
[(set_attr "type" "binary,binary")
|
[(set_attr "type" "binary,binary")
|
(set_attr "length" "8,12")])
|
(set_attr "length" "8,12")])
|
|
|
; Patterns for max and min. (There is no need for an earlyclobber in the
|
; Patterns for max and min. (There is no need for an earlyclobber in the
|
; last alternative since the middle alternative will match if op0 == op1.)
|
; last alternative since the middle alternative will match if op0 == op1.)
|
|
|
(define_insn "sminsi3"
|
(define_insn "sminsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
|
(smin:SI (match_operand:SI 1 "register_operand" "%0,0,r")
|
(smin:SI (match_operand:SI 1 "register_operand" "%0,0,r")
|
(match_operand:SI 2 "arith11_operand" "r,I,M")))]
|
(match_operand:SI 2 "arith11_operand" "r,I,M")))]
|
""
|
""
|
"@
|
"@
|
{comclr|cmpclr},> %2,%0,%%r0\;copy %2,%0
|
{comclr|cmpclr},> %2,%0,%%r0\;copy %2,%0
|
{comiclr|cmpiclr},> %2,%0,%%r0\;ldi %2,%0
|
{comiclr|cmpiclr},> %2,%0,%%r0\;ldi %2,%0
|
{comclr|cmpclr},> %1,%r2,%0\;copy %1,%0"
|
{comclr|cmpclr},> %1,%r2,%0\;copy %1,%0"
|
[(set_attr "type" "multi,multi,multi")
|
[(set_attr "type" "multi,multi,multi")
|
(set_attr "length" "8,8,8")])
|
(set_attr "length" "8,8,8")])
|
|
|
(define_insn "smindi3"
|
(define_insn "smindi3"
|
[(set (match_operand:DI 0 "register_operand" "=r,r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r,r")
|
(smin:DI (match_operand:DI 1 "register_operand" "%0,0,r")
|
(smin:DI (match_operand:DI 1 "register_operand" "%0,0,r")
|
(match_operand:DI 2 "arith11_operand" "r,I,M")))]
|
(match_operand:DI 2 "arith11_operand" "r,I,M")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"@
|
"@
|
cmpclr,*> %2,%0,%%r0\;copy %2,%0
|
cmpclr,*> %2,%0,%%r0\;copy %2,%0
|
cmpiclr,*> %2,%0,%%r0\;ldi %2,%0
|
cmpiclr,*> %2,%0,%%r0\;ldi %2,%0
|
cmpclr,*> %1,%r2,%0\;copy %1,%0"
|
cmpclr,*> %1,%r2,%0\;copy %1,%0"
|
[(set_attr "type" "multi,multi,multi")
|
[(set_attr "type" "multi,multi,multi")
|
(set_attr "length" "8,8,8")])
|
(set_attr "length" "8,8,8")])
|
|
|
(define_insn "uminsi3"
|
(define_insn "uminsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
(umin:SI (match_operand:SI 1 "register_operand" "%0,0")
|
(umin:SI (match_operand:SI 1 "register_operand" "%0,0")
|
(match_operand:SI 2 "arith11_operand" "r,I")))]
|
(match_operand:SI 2 "arith11_operand" "r,I")))]
|
""
|
""
|
"@
|
"@
|
{comclr|cmpclr},>> %2,%0,%%r0\;copy %2,%0
|
{comclr|cmpclr},>> %2,%0,%%r0\;copy %2,%0
|
{comiclr|cmpiclr},>> %2,%0,%%r0\;ldi %2,%0"
|
{comiclr|cmpiclr},>> %2,%0,%%r0\;ldi %2,%0"
|
[(set_attr "type" "multi,multi")
|
[(set_attr "type" "multi,multi")
|
(set_attr "length" "8,8")])
|
(set_attr "length" "8,8")])
|
|
|
(define_insn "umindi3"
|
(define_insn "umindi3"
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
(umin:DI (match_operand:DI 1 "register_operand" "%0,0")
|
(umin:DI (match_operand:DI 1 "register_operand" "%0,0")
|
(match_operand:DI 2 "arith11_operand" "r,I")))]
|
(match_operand:DI 2 "arith11_operand" "r,I")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"@
|
"@
|
cmpclr,*>> %2,%0,%%r0\;copy %2,%0
|
cmpclr,*>> %2,%0,%%r0\;copy %2,%0
|
cmpiclr,*>> %2,%0,%%r0\;ldi %2,%0"
|
cmpiclr,*>> %2,%0,%%r0\;ldi %2,%0"
|
[(set_attr "type" "multi,multi")
|
[(set_attr "type" "multi,multi")
|
(set_attr "length" "8,8")])
|
(set_attr "length" "8,8")])
|
|
|
(define_insn "smaxsi3"
|
(define_insn "smaxsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
|
(smax:SI (match_operand:SI 1 "register_operand" "%0,0,r")
|
(smax:SI (match_operand:SI 1 "register_operand" "%0,0,r")
|
(match_operand:SI 2 "arith11_operand" "r,I,M")))]
|
(match_operand:SI 2 "arith11_operand" "r,I,M")))]
|
""
|
""
|
"@
|
"@
|
{comclr|cmpclr},< %2,%0,%%r0\;copy %2,%0
|
{comclr|cmpclr},< %2,%0,%%r0\;copy %2,%0
|
{comiclr|cmpiclr},< %2,%0,%%r0\;ldi %2,%0
|
{comiclr|cmpiclr},< %2,%0,%%r0\;ldi %2,%0
|
{comclr|cmpclr},< %1,%r2,%0\;copy %1,%0"
|
{comclr|cmpclr},< %1,%r2,%0\;copy %1,%0"
|
[(set_attr "type" "multi,multi,multi")
|
[(set_attr "type" "multi,multi,multi")
|
(set_attr "length" "8,8,8")])
|
(set_attr "length" "8,8,8")])
|
|
|
(define_insn "smaxdi3"
|
(define_insn "smaxdi3"
|
[(set (match_operand:DI 0 "register_operand" "=r,r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r,r")
|
(smax:DI (match_operand:DI 1 "register_operand" "%0,0,r")
|
(smax:DI (match_operand:DI 1 "register_operand" "%0,0,r")
|
(match_operand:DI 2 "arith11_operand" "r,I,M")))]
|
(match_operand:DI 2 "arith11_operand" "r,I,M")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"@
|
"@
|
cmpclr,*< %2,%0,%%r0\;copy %2,%0
|
cmpclr,*< %2,%0,%%r0\;copy %2,%0
|
cmpiclr,*< %2,%0,%%r0\;ldi %2,%0
|
cmpiclr,*< %2,%0,%%r0\;ldi %2,%0
|
cmpclr,*< %1,%r2,%0\;copy %1,%0"
|
cmpclr,*< %1,%r2,%0\;copy %1,%0"
|
[(set_attr "type" "multi,multi,multi")
|
[(set_attr "type" "multi,multi,multi")
|
(set_attr "length" "8,8,8")])
|
(set_attr "length" "8,8,8")])
|
|
|
(define_insn "umaxsi3"
|
(define_insn "umaxsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
(umax:SI (match_operand:SI 1 "register_operand" "%0,0")
|
(umax:SI (match_operand:SI 1 "register_operand" "%0,0")
|
(match_operand:SI 2 "arith11_operand" "r,I")))]
|
(match_operand:SI 2 "arith11_operand" "r,I")))]
|
""
|
""
|
"@
|
"@
|
{comclr|cmpclr},<< %2,%0,%%r0\;copy %2,%0
|
{comclr|cmpclr},<< %2,%0,%%r0\;copy %2,%0
|
{comiclr|cmpiclr},<< %2,%0,%%r0\;ldi %2,%0"
|
{comiclr|cmpiclr},<< %2,%0,%%r0\;ldi %2,%0"
|
[(set_attr "type" "multi,multi")
|
[(set_attr "type" "multi,multi")
|
(set_attr "length" "8,8")])
|
(set_attr "length" "8,8")])
|
|
|
(define_insn "umaxdi3"
|
(define_insn "umaxdi3"
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
(umax:DI (match_operand:DI 1 "register_operand" "%0,0")
|
(umax:DI (match_operand:DI 1 "register_operand" "%0,0")
|
(match_operand:DI 2 "arith11_operand" "r,I")))]
|
(match_operand:DI 2 "arith11_operand" "r,I")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"@
|
"@
|
cmpclr,*<< %2,%0,%%r0\;copy %2,%0
|
cmpclr,*<< %2,%0,%%r0\;copy %2,%0
|
cmpiclr,*<< %2,%0,%%r0\;ldi %2,%0"
|
cmpiclr,*<< %2,%0,%%r0\;ldi %2,%0"
|
[(set_attr "type" "multi,multi")
|
[(set_attr "type" "multi,multi")
|
(set_attr "length" "8,8")])
|
(set_attr "length" "8,8")])
|
|
|
(define_insn "abssi2"
|
(define_insn "abssi2"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(abs:SI (match_operand:SI 1 "register_operand" "r")))]
|
(abs:SI (match_operand:SI 1 "register_operand" "r")))]
|
""
|
""
|
"or,>= %%r0,%1,%0\;subi 0,%0,%0"
|
"or,>= %%r0,%1,%0\;subi 0,%0,%0"
|
[(set_attr "type" "multi")
|
[(set_attr "type" "multi")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn "absdi2"
|
(define_insn "absdi2"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(abs:DI (match_operand:DI 1 "register_operand" "r")))]
|
(abs:DI (match_operand:DI 1 "register_operand" "r")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"or,*>= %%r0,%1,%0\;subi 0,%0,%0"
|
"or,*>= %%r0,%1,%0\;subi 0,%0,%0"
|
[(set_attr "type" "multi")
|
[(set_attr "type" "multi")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
;;; Experimental conditional move patterns
|
;;; Experimental conditional move patterns
|
|
|
(define_expand "movsicc"
|
(define_expand "movsicc"
|
[(set (match_operand:SI 0 "register_operand" "")
|
[(set (match_operand:SI 0 "register_operand" "")
|
(if_then_else:SI
|
(if_then_else:SI
|
(match_operand 1 "comparison_operator" "")
|
(match_operand 1 "comparison_operator" "")
|
(match_operand:SI 2 "reg_or_cint_move_operand" "")
|
(match_operand:SI 2 "reg_or_cint_move_operand" "")
|
(match_operand:SI 3 "reg_or_cint_move_operand" "")))]
|
(match_operand:SI 3 "reg_or_cint_move_operand" "")))]
|
""
|
""
|
"
|
"
|
{
|
{
|
if (GET_MODE (XEXP (operands[1], 0)) != SImode
|
if (GET_MODE (XEXP (operands[1], 0)) != SImode
|
|| GET_MODE (XEXP (operands[1], 0)) != GET_MODE (XEXP (operands[1], 1)))
|
|| GET_MODE (XEXP (operands[1], 0)) != GET_MODE (XEXP (operands[1], 1)))
|
FAIL;
|
FAIL;
|
}")
|
}")
|
|
|
;; We used to accept any register for op1.
|
;; We used to accept any register for op1.
|
;;
|
;;
|
;; However, it loses sometimes because the compiler will end up using
|
;; However, it loses sometimes because the compiler will end up using
|
;; different registers for op0 and op1 in some critical cases. local-alloc
|
;; different registers for op0 and op1 in some critical cases. local-alloc
|
;; will not tie op0 and op1 because op0 is used in multiple basic blocks.
|
;; will not tie op0 and op1 because op0 is used in multiple basic blocks.
|
;;
|
;;
|
;; If/when global register allocation supports tying we should allow any
|
;; If/when global register allocation supports tying we should allow any
|
;; register for op1 again.
|
;; register for op1 again.
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
|
(if_then_else:SI
|
(if_then_else:SI
|
(match_operator 2 "comparison_operator"
|
(match_operator 2 "comparison_operator"
|
[(match_operand:SI 3 "register_operand" "r,r,r,r")
|
[(match_operand:SI 3 "register_operand" "r,r,r,r")
|
(match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI")])
|
(match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI")])
|
(match_operand:SI 1 "reg_or_cint_move_operand" "0,J,N,K")
|
(match_operand:SI 1 "reg_or_cint_move_operand" "0,J,N,K")
|
(const_int 0)))]
|
(const_int 0)))]
|
""
|
""
|
"@
|
"@
|
{com%I4clr|cmp%I4clr},%S2 %4,%3,%%r0\;ldi 0,%0
|
{com%I4clr|cmp%I4clr},%S2 %4,%3,%%r0\;ldi 0,%0
|
{com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;ldi %1,%0
|
{com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;ldi %1,%0
|
{com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;ldil L'%1,%0
|
{com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;ldil L'%1,%0
|
{com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;{zdepi|depwi,z} %Z1,%0"
|
{com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;{zdepi|depwi,z} %Z1,%0"
|
[(set_attr "type" "multi,multi,multi,nullshift")
|
[(set_attr "type" "multi,multi,multi,nullshift")
|
(set_attr "length" "8,8,8,8")])
|
(set_attr "length" "8,8,8,8")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r")
|
(if_then_else:SI
|
(if_then_else:SI
|
(match_operator 5 "comparison_operator"
|
(match_operator 5 "comparison_operator"
|
[(match_operand:SI 3 "register_operand" "r,r,r,r,r,r,r,r")
|
[(match_operand:SI 3 "register_operand" "r,r,r,r,r,r,r,r")
|
(match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
|
(match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
|
(match_operand:SI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
|
(match_operand:SI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
|
(match_operand:SI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
|
(match_operand:SI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
|
""
|
""
|
"@
|
"@
|
{com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;copy %2,%0
|
{com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;copy %2,%0
|
{com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldi %2,%0
|
{com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldi %2,%0
|
{com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldil L'%2,%0
|
{com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldil L'%2,%0
|
{com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;{zdepi|depwi,z} %Z2,%0
|
{com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;{zdepi|depwi,z} %Z2,%0
|
{com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;copy %1,%0
|
{com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;copy %1,%0
|
{com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldi %1,%0
|
{com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldi %1,%0
|
{com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldil L'%1,%0
|
{com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldil L'%1,%0
|
{com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;{zdepi|depwi,z} %Z1,%0"
|
{com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;{zdepi|depwi,z} %Z1,%0"
|
[(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
|
[(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
|
(set_attr "length" "8,8,8,8,8,8,8,8")])
|
(set_attr "length" "8,8,8,8,8,8,8,8")])
|
|
|
(define_expand "movdicc"
|
(define_expand "movdicc"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(if_then_else:DI
|
(if_then_else:DI
|
(match_operand 1 "comparison_operator" "")
|
(match_operand 1 "comparison_operator" "")
|
(match_operand:DI 2 "reg_or_cint_move_operand" "")
|
(match_operand:DI 2 "reg_or_cint_move_operand" "")
|
(match_operand:DI 3 "reg_or_cint_move_operand" "")))]
|
(match_operand:DI 3 "reg_or_cint_move_operand" "")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"
|
"
|
{
|
{
|
if (GET_MODE (XEXP (operands[1], 0)) != DImode
|
if (GET_MODE (XEXP (operands[1], 0)) != DImode
|
|| GET_MODE (XEXP (operands[1], 0)) != GET_MODE (XEXP (operands[1], 1)))
|
|| GET_MODE (XEXP (operands[1], 0)) != GET_MODE (XEXP (operands[1], 1)))
|
FAIL;
|
FAIL;
|
}")
|
}")
|
|
|
; We need the first constraint alternative in order to avoid
|
; We need the first constraint alternative in order to avoid
|
; earlyclobbers on all other alternatives.
|
; earlyclobbers on all other alternatives.
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r")
|
(if_then_else:DI
|
(if_then_else:DI
|
(match_operator 2 "comparison_operator"
|
(match_operator 2 "comparison_operator"
|
[(match_operand:DI 3 "register_operand" "r,r,r,r,r")
|
[(match_operand:DI 3 "register_operand" "r,r,r,r,r")
|
(match_operand:DI 4 "arith11_operand" "rI,rI,rI,rI,rI")])
|
(match_operand:DI 4 "arith11_operand" "rI,rI,rI,rI,rI")])
|
(match_operand:DI 1 "reg_or_cint_move_operand" "0,r,J,N,K")
|
(match_operand:DI 1 "reg_or_cint_move_operand" "0,r,J,N,K")
|
(const_int 0)))]
|
(const_int 0)))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"@
|
"@
|
cmp%I4clr,*%S2 %4,%3,%%r0\;ldi 0,%0
|
cmp%I4clr,*%S2 %4,%3,%%r0\;ldi 0,%0
|
cmp%I4clr,*%B2 %4,%3,%0\;copy %1,%0
|
cmp%I4clr,*%B2 %4,%3,%0\;copy %1,%0
|
cmp%I4clr,*%B2 %4,%3,%0\;ldi %1,%0
|
cmp%I4clr,*%B2 %4,%3,%0\;ldi %1,%0
|
cmp%I4clr,*%B2 %4,%3,%0\;ldil L'%1,%0
|
cmp%I4clr,*%B2 %4,%3,%0\;ldil L'%1,%0
|
cmp%I4clr,*%B2 %4,%3,%0\;depdi,z %z1,%0"
|
cmp%I4clr,*%B2 %4,%3,%0\;depdi,z %z1,%0"
|
[(set_attr "type" "multi,multi,multi,multi,nullshift")
|
[(set_attr "type" "multi,multi,multi,multi,nullshift")
|
(set_attr "length" "8,8,8,8,8")])
|
(set_attr "length" "8,8,8,8,8")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r,r")
|
(if_then_else:DI
|
(if_then_else:DI
|
(match_operator 5 "comparison_operator"
|
(match_operator 5 "comparison_operator"
|
[(match_operand:DI 3 "register_operand" "r,r,r,r,r,r,r,r")
|
[(match_operand:DI 3 "register_operand" "r,r,r,r,r,r,r,r")
|
(match_operand:DI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
|
(match_operand:DI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
|
(match_operand:DI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
|
(match_operand:DI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
|
(match_operand:DI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
|
(match_operand:DI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"@
|
"@
|
cmp%I4clr,*%S5 %4,%3,%%r0\;copy %2,%0
|
cmp%I4clr,*%S5 %4,%3,%%r0\;copy %2,%0
|
cmp%I4clr,*%S5 %4,%3,%%r0\;ldi %2,%0
|
cmp%I4clr,*%S5 %4,%3,%%r0\;ldi %2,%0
|
cmp%I4clr,*%S5 %4,%3,%%r0\;ldil L'%2,%0
|
cmp%I4clr,*%S5 %4,%3,%%r0\;ldil L'%2,%0
|
cmp%I4clr,*%S5 %4,%3,%%r0\;depdi,z %z2,%0
|
cmp%I4clr,*%S5 %4,%3,%%r0\;depdi,z %z2,%0
|
cmp%I4clr,*%B5 %4,%3,%%r0\;copy %1,%0
|
cmp%I4clr,*%B5 %4,%3,%%r0\;copy %1,%0
|
cmp%I4clr,*%B5 %4,%3,%%r0\;ldi %1,%0
|
cmp%I4clr,*%B5 %4,%3,%%r0\;ldi %1,%0
|
cmp%I4clr,*%B5 %4,%3,%%r0\;ldil L'%1,%0
|
cmp%I4clr,*%B5 %4,%3,%%r0\;ldil L'%1,%0
|
cmp%I4clr,*%B5 %4,%3,%%r0\;depdi,z %z1,%0"
|
cmp%I4clr,*%B5 %4,%3,%%r0\;depdi,z %z1,%0"
|
[(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
|
[(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
|
(set_attr "length" "8,8,8,8,8,8,8,8")])
|
(set_attr "length" "8,8,8,8,8,8,8,8")])
|
|
|
;; Conditional Branches
|
;; Conditional Branches
|
|
|
(define_expand "cbranchdi4"
|
(define_expand "cbranchdi4"
|
[(set (pc)
|
[(set (pc)
|
(if_then_else (match_operator 0 "ordered_comparison_operator"
|
(if_then_else (match_operator 0 "ordered_comparison_operator"
|
[(match_operand:DI 1 "reg_or_0_operand" "")
|
[(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 2 "register_operand" "")])
|
(match_operand:DI 2 "register_operand" "")])
|
(label_ref (match_operand 3 "" ""))
|
(label_ref (match_operand 3 "" ""))
|
(pc)))]
|
(pc)))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"")
|
"")
|
|
|
(define_expand "cbranchsi4"
|
(define_expand "cbranchsi4"
|
[(set (pc)
|
[(set (pc)
|
(if_then_else (match_operator 0 "ordered_comparison_operator"
|
(if_then_else (match_operator 0 "ordered_comparison_operator"
|
[(match_operand:SI 1 "reg_or_0_operand" "")
|
[(match_operand:SI 1 "reg_or_0_operand" "")
|
(match_operand:SI 2 "arith5_operand" "")])
|
(match_operand:SI 2 "arith5_operand" "")])
|
(label_ref (match_operand 3 "" ""))
|
(label_ref (match_operand 3 "" ""))
|
(pc)))]
|
(pc)))]
|
""
|
""
|
"")
|
"")
|
|
|
(define_expand "cbranchsf4"
|
(define_expand "cbranchsf4"
|
[(set (pc)
|
[(set (pc)
|
(if_then_else (match_operator 0 "comparison_operator"
|
(if_then_else (match_operator 0 "comparison_operator"
|
[(match_operand:SF 1 "reg_or_0_operand" "")
|
[(match_operand:SF 1 "reg_or_0_operand" "")
|
(match_operand:SF 2 "reg_or_0_operand" "")])
|
(match_operand:SF 2 "reg_or_0_operand" "")])
|
(label_ref (match_operand 3 "" ""))
|
(label_ref (match_operand 3 "" ""))
|
(pc)))]
|
(pc)))]
|
""
|
""
|
"
|
"
|
{
|
{
|
emit_bcond_fp (operands);
|
emit_bcond_fp (operands);
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
|
|
(define_expand "cbranchdf4"
|
(define_expand "cbranchdf4"
|
[(set (pc)
|
[(set (pc)
|
(if_then_else (match_operator 0 "comparison_operator"
|
(if_then_else (match_operator 0 "comparison_operator"
|
[(match_operand:DF 1 "reg_or_0_operand" "")
|
[(match_operand:DF 1 "reg_or_0_operand" "")
|
(match_operand:DF 2 "reg_or_0_operand" "")])
|
(match_operand:DF 2 "reg_or_0_operand" "")])
|
(label_ref (match_operand 3 "" ""))
|
(label_ref (match_operand 3 "" ""))
|
(pc)))]
|
(pc)))]
|
""
|
""
|
"
|
"
|
{
|
{
|
emit_bcond_fp (operands);
|
emit_bcond_fp (operands);
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
;; Match the branch patterns.
|
;; Match the branch patterns.
|
|
|
|
|
;; Note a long backward conditional branch with an annulled delay slot
|
;; Note a long backward conditional branch with an annulled delay slot
|
;; has a length of 12.
|
;; has a length of 12.
|
(define_insn ""
|
(define_insn ""
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(match_operator 3 "comparison_operator"
|
(match_operator 3 "comparison_operator"
|
[(match_operand:SI 1 "reg_or_0_operand" "rM")
|
[(match_operand:SI 1 "reg_or_0_operand" "rM")
|
(match_operand:SI 2 "arith5_operand" "rL")])
|
(match_operand:SI 2 "arith5_operand" "rL")])
|
(label_ref (match_operand 0 "" ""))
|
(label_ref (match_operand 0 "" ""))
|
(pc)))]
|
(pc)))]
|
""
|
""
|
"*
|
"*
|
{
|
{
|
return output_cbranch (operands, 0, insn);
|
return output_cbranch (operands, 0, insn);
|
}"
|
}"
|
[(set_attr "type" "cbranch")
|
[(set_attr "type" "cbranch")
|
(set (attr "length")
|
(set (attr "length")
|
(cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 24)
|
(const_int 24)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 20)]
|
(const_int 20)]
|
(const_int 28)))])
|
(const_int 28)))])
|
|
|
;; Match the negated branch.
|
;; Match the negated branch.
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(match_operator 3 "comparison_operator"
|
(match_operator 3 "comparison_operator"
|
[(match_operand:SI 1 "reg_or_0_operand" "rM")
|
[(match_operand:SI 1 "reg_or_0_operand" "rM")
|
(match_operand:SI 2 "arith5_operand" "rL")])
|
(match_operand:SI 2 "arith5_operand" "rL")])
|
(pc)
|
(pc)
|
(label_ref (match_operand 0 "" ""))))]
|
(label_ref (match_operand 0 "" ""))))]
|
""
|
""
|
"*
|
"*
|
{
|
{
|
return output_cbranch (operands, 1, insn);
|
return output_cbranch (operands, 1, insn);
|
}"
|
}"
|
[(set_attr "type" "cbranch")
|
[(set_attr "type" "cbranch")
|
(set (attr "length")
|
(set (attr "length")
|
(cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 24)
|
(const_int 24)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 20)]
|
(const_int 20)]
|
(const_int 28)))])
|
(const_int 28)))])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(match_operator 3 "comparison_operator"
|
(match_operator 3 "comparison_operator"
|
[(match_operand:DI 1 "reg_or_0_operand" "rM")
|
[(match_operand:DI 1 "reg_or_0_operand" "rM")
|
(match_operand:DI 2 "reg_or_0_operand" "rM")])
|
(match_operand:DI 2 "reg_or_0_operand" "rM")])
|
(label_ref (match_operand 0 "" ""))
|
(label_ref (match_operand 0 "" ""))
|
(pc)))]
|
(pc)))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
return output_cbranch (operands, 0, insn);
|
return output_cbranch (operands, 0, insn);
|
}"
|
}"
|
[(set_attr "type" "cbranch")
|
[(set_attr "type" "cbranch")
|
(set (attr "length")
|
(set (attr "length")
|
(cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 24)
|
(const_int 24)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 20)]
|
(const_int 20)]
|
(const_int 28)))])
|
(const_int 28)))])
|
|
|
;; Match the negated branch.
|
;; Match the negated branch.
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(match_operator 3 "comparison_operator"
|
(match_operator 3 "comparison_operator"
|
[(match_operand:DI 1 "reg_or_0_operand" "rM")
|
[(match_operand:DI 1 "reg_or_0_operand" "rM")
|
(match_operand:DI 2 "reg_or_0_operand" "rM")])
|
(match_operand:DI 2 "reg_or_0_operand" "rM")])
|
(pc)
|
(pc)
|
(label_ref (match_operand 0 "" ""))))]
|
(label_ref (match_operand 0 "" ""))))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
return output_cbranch (operands, 1, insn);
|
return output_cbranch (operands, 1, insn);
|
}"
|
}"
|
[(set_attr "type" "cbranch")
|
[(set_attr "type" "cbranch")
|
(set (attr "length")
|
(set (attr "length")
|
(cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 24)
|
(const_int 24)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 20)]
|
(const_int 20)]
|
(const_int 28)))])
|
(const_int 28)))])
|
(define_insn ""
|
(define_insn ""
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(match_operator 3 "cmpib_comparison_operator"
|
(match_operator 3 "cmpib_comparison_operator"
|
[(match_operand:DI 1 "reg_or_0_operand" "rM")
|
[(match_operand:DI 1 "reg_or_0_operand" "rM")
|
(match_operand:DI 2 "arith5_operand" "rL")])
|
(match_operand:DI 2 "arith5_operand" "rL")])
|
(label_ref (match_operand 0 "" ""))
|
(label_ref (match_operand 0 "" ""))
|
(pc)))]
|
(pc)))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
return output_cbranch (operands, 0, insn);
|
return output_cbranch (operands, 0, insn);
|
}"
|
}"
|
[(set_attr "type" "cbranch")
|
[(set_attr "type" "cbranch")
|
(set (attr "length")
|
(set (attr "length")
|
(cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 24)
|
(const_int 24)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 20)]
|
(const_int 20)]
|
(const_int 28)))])
|
(const_int 28)))])
|
|
|
;; Match the negated branch.
|
;; Match the negated branch.
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(match_operator 3 "cmpib_comparison_operator"
|
(match_operator 3 "cmpib_comparison_operator"
|
[(match_operand:DI 1 "reg_or_0_operand" "rM")
|
[(match_operand:DI 1 "reg_or_0_operand" "rM")
|
(match_operand:DI 2 "arith5_operand" "rL")])
|
(match_operand:DI 2 "arith5_operand" "rL")])
|
(pc)
|
(pc)
|
(label_ref (match_operand 0 "" ""))))]
|
(label_ref (match_operand 0 "" ""))))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
return output_cbranch (operands, 1, insn);
|
return output_cbranch (operands, 1, insn);
|
}"
|
}"
|
[(set_attr "type" "cbranch")
|
[(set_attr "type" "cbranch")
|
(set (attr "length")
|
(set (attr "length")
|
(cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 24)
|
(const_int 24)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 20)]
|
(const_int 20)]
|
(const_int 28)))])
|
(const_int 28)))])
|
|
|
;; Branch on Bit patterns.
|
;; Branch on Bit patterns.
|
(define_insn ""
|
(define_insn ""
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
|
(ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
|
(const_int 1)
|
(const_int 1)
|
(match_operand:SI 1 "uint5_operand" ""))
|
(match_operand:SI 1 "uint5_operand" ""))
|
(const_int 0))
|
(const_int 0))
|
(label_ref (match_operand 2 "" ""))
|
(label_ref (match_operand 2 "" ""))
|
(pc)))]
|
(pc)))]
|
""
|
""
|
"*
|
"*
|
{
|
{
|
return output_bb (operands, 0, insn, 0);
|
return output_bb (operands, 0, insn, 0);
|
}"
|
}"
|
[(set_attr "type" "cbranch")
|
[(set_attr "type" "cbranch")
|
(set (attr "length")
|
(set (attr "length")
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 24)
|
(const_int 24)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 20)]
|
(const_int 20)]
|
(const_int 28)))])
|
(const_int 28)))])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
|
(ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
|
(const_int 1)
|
(const_int 1)
|
(match_operand:DI 1 "uint32_operand" ""))
|
(match_operand:DI 1 "uint32_operand" ""))
|
(const_int 0))
|
(const_int 0))
|
(label_ref (match_operand 2 "" ""))
|
(label_ref (match_operand 2 "" ""))
|
(pc)))]
|
(pc)))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
return output_bb (operands, 0, insn, 0);
|
return output_bb (operands, 0, insn, 0);
|
}"
|
}"
|
[(set_attr "type" "cbranch")
|
[(set_attr "type" "cbranch")
|
(set (attr "length")
|
(set (attr "length")
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 24)
|
(const_int 24)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 20)]
|
(const_int 20)]
|
(const_int 28)))])
|
(const_int 28)))])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
|
(ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
|
(const_int 1)
|
(const_int 1)
|
(match_operand:SI 1 "uint5_operand" ""))
|
(match_operand:SI 1 "uint5_operand" ""))
|
(const_int 0))
|
(const_int 0))
|
(pc)
|
(pc)
|
(label_ref (match_operand 2 "" ""))))]
|
(label_ref (match_operand 2 "" ""))))]
|
""
|
""
|
"*
|
"*
|
{
|
{
|
return output_bb (operands, 1, insn, 0);
|
return output_bb (operands, 1, insn, 0);
|
}"
|
}"
|
[(set_attr "type" "cbranch")
|
[(set_attr "type" "cbranch")
|
(set (attr "length")
|
(set (attr "length")
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 24)
|
(const_int 24)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 20)]
|
(const_int 20)]
|
(const_int 28)))])
|
(const_int 28)))])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
|
(ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
|
(const_int 1)
|
(const_int 1)
|
(match_operand:DI 1 "uint32_operand" ""))
|
(match_operand:DI 1 "uint32_operand" ""))
|
(const_int 0))
|
(const_int 0))
|
(pc)
|
(pc)
|
(label_ref (match_operand 2 "" ""))))]
|
(label_ref (match_operand 2 "" ""))))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
return output_bb (operands, 1, insn, 0);
|
return output_bb (operands, 1, insn, 0);
|
}"
|
}"
|
[(set_attr "type" "cbranch")
|
[(set_attr "type" "cbranch")
|
(set (attr "length")
|
(set (attr "length")
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 24)
|
(const_int 24)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 20)]
|
(const_int 20)]
|
(const_int 28)))])
|
(const_int 28)))])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
|
(eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
|
(const_int 1)
|
(const_int 1)
|
(match_operand:SI 1 "uint5_operand" ""))
|
(match_operand:SI 1 "uint5_operand" ""))
|
(const_int 0))
|
(const_int 0))
|
(label_ref (match_operand 2 "" ""))
|
(label_ref (match_operand 2 "" ""))
|
(pc)))]
|
(pc)))]
|
""
|
""
|
"*
|
"*
|
{
|
{
|
return output_bb (operands, 0, insn, 1);
|
return output_bb (operands, 0, insn, 1);
|
}"
|
}"
|
[(set_attr "type" "cbranch")
|
[(set_attr "type" "cbranch")
|
(set (attr "length")
|
(set (attr "length")
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 24)
|
(const_int 24)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 20)]
|
(const_int 20)]
|
(const_int 28)))])
|
(const_int 28)))])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
|
(eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
|
(const_int 1)
|
(const_int 1)
|
(match_operand:DI 1 "uint32_operand" ""))
|
(match_operand:DI 1 "uint32_operand" ""))
|
(const_int 0))
|
(const_int 0))
|
(label_ref (match_operand 2 "" ""))
|
(label_ref (match_operand 2 "" ""))
|
(pc)))]
|
(pc)))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
return output_bb (operands, 0, insn, 1);
|
return output_bb (operands, 0, insn, 1);
|
}"
|
}"
|
[(set_attr "type" "cbranch")
|
[(set_attr "type" "cbranch")
|
(set (attr "length")
|
(set (attr "length")
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 24)
|
(const_int 24)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 20)]
|
(const_int 20)]
|
(const_int 28)))])
|
(const_int 28)))])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
|
(eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
|
(const_int 1)
|
(const_int 1)
|
(match_operand:SI 1 "uint5_operand" ""))
|
(match_operand:SI 1 "uint5_operand" ""))
|
(const_int 0))
|
(const_int 0))
|
(pc)
|
(pc)
|
(label_ref (match_operand 2 "" ""))))]
|
(label_ref (match_operand 2 "" ""))))]
|
""
|
""
|
"*
|
"*
|
{
|
{
|
return output_bb (operands, 1, insn, 1);
|
return output_bb (operands, 1, insn, 1);
|
}"
|
}"
|
[(set_attr "type" "cbranch")
|
[(set_attr "type" "cbranch")
|
(set (attr "length")
|
(set (attr "length")
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 24)
|
(const_int 24)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 20)]
|
(const_int 20)]
|
(const_int 28)))])
|
(const_int 28)))])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
|
(eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
|
(const_int 1)
|
(const_int 1)
|
(match_operand:DI 1 "uint32_operand" ""))
|
(match_operand:DI 1 "uint32_operand" ""))
|
(const_int 0))
|
(const_int 0))
|
(pc)
|
(pc)
|
(label_ref (match_operand 2 "" ""))))]
|
(label_ref (match_operand 2 "" ""))))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
return output_bb (operands, 1, insn, 1);
|
return output_bb (operands, 1, insn, 1);
|
}"
|
}"
|
[(set_attr "type" "cbranch")
|
[(set_attr "type" "cbranch")
|
(set (attr "length")
|
(set (attr "length")
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 24)
|
(const_int 24)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 20)]
|
(const_int 20)]
|
(const_int 28)))])
|
(const_int 28)))])
|
|
|
;; Branch on Variable Bit patterns.
|
;; Branch on Variable Bit patterns.
|
(define_insn ""
|
(define_insn ""
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
|
(ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
|
(const_int 1)
|
(const_int 1)
|
(match_operand:SI 1 "register_operand" "q"))
|
(match_operand:SI 1 "register_operand" "q"))
|
(const_int 0))
|
(const_int 0))
|
(label_ref (match_operand 2 "" ""))
|
(label_ref (match_operand 2 "" ""))
|
(pc)))]
|
(pc)))]
|
""
|
""
|
"*
|
"*
|
{
|
{
|
return output_bvb (operands, 0, insn, 0);
|
return output_bvb (operands, 0, insn, 0);
|
}"
|
}"
|
[(set_attr "type" "cbranch")
|
[(set_attr "type" "cbranch")
|
(set (attr "length")
|
(set (attr "length")
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 24)
|
(const_int 24)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 20)]
|
(const_int 20)]
|
(const_int 28)))])
|
(const_int 28)))])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
|
(ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
|
(const_int 1)
|
(const_int 1)
|
(match_operand:DI 1 "register_operand" "q"))
|
(match_operand:DI 1 "register_operand" "q"))
|
(const_int 0))
|
(const_int 0))
|
(label_ref (match_operand 2 "" ""))
|
(label_ref (match_operand 2 "" ""))
|
(pc)))]
|
(pc)))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
return output_bvb (operands, 0, insn, 0);
|
return output_bvb (operands, 0, insn, 0);
|
}"
|
}"
|
[(set_attr "type" "cbranch")
|
[(set_attr "type" "cbranch")
|
(set (attr "length")
|
(set (attr "length")
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 24)
|
(const_int 24)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 20)]
|
(const_int 20)]
|
(const_int 28)))])
|
(const_int 28)))])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
|
(ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
|
(const_int 1)
|
(const_int 1)
|
(match_operand:SI 1 "register_operand" "q"))
|
(match_operand:SI 1 "register_operand" "q"))
|
(const_int 0))
|
(const_int 0))
|
(pc)
|
(pc)
|
(label_ref (match_operand 2 "" ""))))]
|
(label_ref (match_operand 2 "" ""))))]
|
""
|
""
|
"*
|
"*
|
{
|
{
|
return output_bvb (operands, 1, insn, 0);
|
return output_bvb (operands, 1, insn, 0);
|
}"
|
}"
|
[(set_attr "type" "cbranch")
|
[(set_attr "type" "cbranch")
|
(set (attr "length")
|
(set (attr "length")
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 24)
|
(const_int 24)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 20)]
|
(const_int 20)]
|
(const_int 28)))])
|
(const_int 28)))])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
|
(ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
|
(const_int 1)
|
(const_int 1)
|
(match_operand:DI 1 "register_operand" "q"))
|
(match_operand:DI 1 "register_operand" "q"))
|
(const_int 0))
|
(const_int 0))
|
(pc)
|
(pc)
|
(label_ref (match_operand 2 "" ""))))]
|
(label_ref (match_operand 2 "" ""))))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
return output_bvb (operands, 1, insn, 0);
|
return output_bvb (operands, 1, insn, 0);
|
}"
|
}"
|
[(set_attr "type" "cbranch")
|
[(set_attr "type" "cbranch")
|
(set (attr "length")
|
(set (attr "length")
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 24)
|
(const_int 24)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 20)]
|
(const_int 20)]
|
(const_int 28)))])
|
(const_int 28)))])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
|
(eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
|
(const_int 1)
|
(const_int 1)
|
(match_operand:SI 1 "register_operand" "q"))
|
(match_operand:SI 1 "register_operand" "q"))
|
(const_int 0))
|
(const_int 0))
|
(label_ref (match_operand 2 "" ""))
|
(label_ref (match_operand 2 "" ""))
|
(pc)))]
|
(pc)))]
|
""
|
""
|
"*
|
"*
|
{
|
{
|
return output_bvb (operands, 0, insn, 1);
|
return output_bvb (operands, 0, insn, 1);
|
}"
|
}"
|
[(set_attr "type" "cbranch")
|
[(set_attr "type" "cbranch")
|
(set (attr "length")
|
(set (attr "length")
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 24)
|
(const_int 24)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 20)]
|
(const_int 20)]
|
(const_int 28)))])
|
(const_int 28)))])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
|
(eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
|
(const_int 1)
|
(const_int 1)
|
(match_operand:DI 1 "register_operand" "q"))
|
(match_operand:DI 1 "register_operand" "q"))
|
(const_int 0))
|
(const_int 0))
|
(label_ref (match_operand 2 "" ""))
|
(label_ref (match_operand 2 "" ""))
|
(pc)))]
|
(pc)))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
return output_bvb (operands, 0, insn, 1);
|
return output_bvb (operands, 0, insn, 1);
|
}"
|
}"
|
[(set_attr "type" "cbranch")
|
[(set_attr "type" "cbranch")
|
(set (attr "length")
|
(set (attr "length")
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 24)
|
(const_int 24)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 20)]
|
(const_int 20)]
|
(const_int 28)))])
|
(const_int 28)))])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
|
(eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
|
(const_int 1)
|
(const_int 1)
|
(match_operand:SI 1 "register_operand" "q"))
|
(match_operand:SI 1 "register_operand" "q"))
|
(const_int 0))
|
(const_int 0))
|
(pc)
|
(pc)
|
(label_ref (match_operand 2 "" ""))))]
|
(label_ref (match_operand 2 "" ""))))]
|
""
|
""
|
"*
|
"*
|
{
|
{
|
return output_bvb (operands, 1, insn, 1);
|
return output_bvb (operands, 1, insn, 1);
|
}"
|
}"
|
[(set_attr "type" "cbranch")
|
[(set_attr "type" "cbranch")
|
(set (attr "length")
|
(set (attr "length")
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 24)
|
(const_int 24)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 20)]
|
(const_int 20)]
|
(const_int 28)))])
|
(const_int 28)))])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
|
(eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
|
(const_int 1)
|
(const_int 1)
|
(match_operand:DI 1 "register_operand" "q"))
|
(match_operand:DI 1 "register_operand" "q"))
|
(const_int 0))
|
(const_int 0))
|
(pc)
|
(pc)
|
(label_ref (match_operand 2 "" ""))))]
|
(label_ref (match_operand 2 "" ""))))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
return output_bvb (operands, 1, insn, 1);
|
return output_bvb (operands, 1, insn, 1);
|
}"
|
}"
|
[(set_attr "type" "cbranch")
|
[(set_attr "type" "cbranch")
|
(set (attr "length")
|
(set (attr "length")
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 24)
|
(const_int 24)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 20)]
|
(const_int 20)]
|
(const_int 28)))])
|
(const_int 28)))])
|
|
|
;; Floating point branches
|
;; Floating point branches
|
|
|
;; ??? Nullification is handled differently from other branches.
|
;; ??? Nullification is handled differently from other branches.
|
;; If nullification is specified, the delay slot is nullified on any
|
;; If nullification is specified, the delay slot is nullified on any
|
;; taken branch regardless of branch direction.
|
;; taken branch regardless of branch direction.
|
(define_insn ""
|
(define_insn ""
|
[(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
|
[(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
|
(label_ref (match_operand 0 "" ""))
|
(label_ref (match_operand 0 "" ""))
|
(pc)))]
|
(pc)))]
|
"!TARGET_SOFT_FLOAT"
|
"!TARGET_SOFT_FLOAT"
|
"*
|
"*
|
{
|
{
|
int length = get_attr_length (insn);
|
int length = get_attr_length (insn);
|
rtx xoperands[1];
|
rtx xoperands[1];
|
int nullify, xdelay;
|
int nullify, xdelay;
|
|
|
if (length < 16)
|
if (length < 16)
|
return \"ftest\;b%* %l0\";
|
return \"ftest\;b%* %l0\";
|
|
|
if (dbr_sequence_length () == 0 || INSN_ANNULLED_BRANCH_P (insn))
|
if (dbr_sequence_length () == 0 || INSN_ANNULLED_BRANCH_P (insn))
|
{
|
{
|
nullify = 1;
|
nullify = 1;
|
xdelay = 0;
|
xdelay = 0;
|
xoperands[0] = GEN_INT (length - 8);
|
xoperands[0] = GEN_INT (length - 8);
|
}
|
}
|
else
|
else
|
{
|
{
|
nullify = 0;
|
nullify = 0;
|
xdelay = 1;
|
xdelay = 1;
|
xoperands[0] = GEN_INT (length - 4);
|
xoperands[0] = GEN_INT (length - 4);
|
}
|
}
|
|
|
if (nullify)
|
if (nullify)
|
output_asm_insn (\"ftest\;add,tr %%r0,%%r0,%%r0\;b,n .+%0\", xoperands);
|
output_asm_insn (\"ftest\;add,tr %%r0,%%r0,%%r0\;b,n .+%0\", xoperands);
|
else
|
else
|
output_asm_insn (\"ftest\;add,tr %%r0,%%r0,%%r0\;b .+%0\", xoperands);
|
output_asm_insn (\"ftest\;add,tr %%r0,%%r0,%%r0\;b .+%0\", xoperands);
|
return output_lbranch (operands[0], insn, xdelay);
|
return output_lbranch (operands[0], insn, xdelay);
|
}"
|
}"
|
[(set_attr "type" "fbranch")
|
[(set_attr "type" "fbranch")
|
(set (attr "length")
|
(set (attr "length")
|
(cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 32)
|
(const_int 32)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 28)]
|
(const_int 28)]
|
(const_int 36)))])
|
(const_int 36)))])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
|
[(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
|
(pc)
|
(pc)
|
(label_ref (match_operand 0 "" ""))))]
|
(label_ref (match_operand 0 "" ""))))]
|
"!TARGET_SOFT_FLOAT"
|
"!TARGET_SOFT_FLOAT"
|
"*
|
"*
|
{
|
{
|
int length = get_attr_length (insn);
|
int length = get_attr_length (insn);
|
rtx xoperands[1];
|
rtx xoperands[1];
|
int nullify, xdelay;
|
int nullify, xdelay;
|
|
|
if (length < 16)
|
if (length < 16)
|
return \"ftest\;add,tr %%r0,%%r0,%%r0\;b%* %0\";
|
return \"ftest\;add,tr %%r0,%%r0,%%r0\;b%* %0\";
|
|
|
if (dbr_sequence_length () == 0 || INSN_ANNULLED_BRANCH_P (insn))
|
if (dbr_sequence_length () == 0 || INSN_ANNULLED_BRANCH_P (insn))
|
{
|
{
|
nullify = 1;
|
nullify = 1;
|
xdelay = 0;
|
xdelay = 0;
|
xoperands[0] = GEN_INT (length - 4);
|
xoperands[0] = GEN_INT (length - 4);
|
}
|
}
|
else
|
else
|
{
|
{
|
nullify = 0;
|
nullify = 0;
|
xdelay = 1;
|
xdelay = 1;
|
xoperands[0] = GEN_INT (length);
|
xoperands[0] = GEN_INT (length);
|
}
|
}
|
|
|
if (nullify)
|
if (nullify)
|
output_asm_insn (\"ftest\;b,n .+%0\", xoperands);
|
output_asm_insn (\"ftest\;b,n .+%0\", xoperands);
|
else
|
else
|
output_asm_insn (\"ftest\;b .+%0\", xoperands);
|
output_asm_insn (\"ftest\;b .+%0\", xoperands);
|
return output_lbranch (operands[0], insn, xdelay);
|
return output_lbranch (operands[0], insn, xdelay);
|
}"
|
}"
|
[(set_attr "type" "fbranch")
|
[(set_attr "type" "fbranch")
|
(set (attr "length")
|
(set (attr "length")
|
(cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 12)
|
(const_int 12)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 28)
|
(const_int 28)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 24)]
|
(const_int 24)]
|
(const_int 32)))])
|
(const_int 32)))])
|
|
|
;; Move instructions
|
;; Move instructions
|
|
|
(define_expand "movsi"
|
(define_expand "movsi"
|
[(set (match_operand:SI 0 "general_operand" "")
|
[(set (match_operand:SI 0 "general_operand" "")
|
(match_operand:SI 1 "general_operand" ""))]
|
(match_operand:SI 1 "general_operand" ""))]
|
""
|
""
|
"
|
"
|
{
|
{
|
if (emit_move_sequence (operands, SImode, 0))
|
if (emit_move_sequence (operands, SImode, 0))
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
;; Handle SImode input reloads requiring %r1 as a scratch register.
|
;; Handle SImode input reloads requiring %r1 as a scratch register.
|
(define_expand "reload_insi_r1"
|
(define_expand "reload_insi_r1"
|
[(set (match_operand:SI 0 "register_operand" "=Z")
|
[(set (match_operand:SI 0 "register_operand" "=Z")
|
(match_operand:SI 1 "non_hard_reg_operand" ""))
|
(match_operand:SI 1 "non_hard_reg_operand" ""))
|
(clobber (match_operand:SI 2 "register_operand" "=&a"))]
|
(clobber (match_operand:SI 2 "register_operand" "=&a"))]
|
""
|
""
|
"
|
"
|
{
|
{
|
if (emit_move_sequence (operands, SImode, operands[2]))
|
if (emit_move_sequence (operands, SImode, operands[2]))
|
DONE;
|
DONE;
|
|
|
/* We don't want the clobber emitted, so handle this ourselves. */
|
/* We don't want the clobber emitted, so handle this ourselves. */
|
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
|
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
;; Handle SImode input reloads requiring a general register as a
|
;; Handle SImode input reloads requiring a general register as a
|
;; scratch register.
|
;; scratch register.
|
(define_expand "reload_insi"
|
(define_expand "reload_insi"
|
[(set (match_operand:SI 0 "register_operand" "=Z")
|
[(set (match_operand:SI 0 "register_operand" "=Z")
|
(match_operand:SI 1 "non_hard_reg_operand" ""))
|
(match_operand:SI 1 "non_hard_reg_operand" ""))
|
(clobber (match_operand:SI 2 "register_operand" "=&r"))]
|
(clobber (match_operand:SI 2 "register_operand" "=&r"))]
|
""
|
""
|
"
|
"
|
{
|
{
|
if (emit_move_sequence (operands, SImode, operands[2]))
|
if (emit_move_sequence (operands, SImode, operands[2]))
|
DONE;
|
DONE;
|
|
|
/* We don't want the clobber emitted, so handle this ourselves. */
|
/* We don't want the clobber emitted, so handle this ourselves. */
|
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
|
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
;; Handle SImode output reloads requiring a general register as a
|
;; Handle SImode output reloads requiring a general register as a
|
;; scratch register.
|
;; scratch register.
|
(define_expand "reload_outsi"
|
(define_expand "reload_outsi"
|
[(set (match_operand:SI 0 "non_hard_reg_operand" "")
|
[(set (match_operand:SI 0 "non_hard_reg_operand" "")
|
(match_operand:SI 1 "register_operand" "Z"))
|
(match_operand:SI 1 "register_operand" "Z"))
|
(clobber (match_operand:SI 2 "register_operand" "=&r"))]
|
(clobber (match_operand:SI 2 "register_operand" "=&r"))]
|
""
|
""
|
"
|
"
|
{
|
{
|
if (emit_move_sequence (operands, SImode, operands[2]))
|
if (emit_move_sequence (operands, SImode, operands[2]))
|
DONE;
|
DONE;
|
|
|
/* We don't want the clobber emitted, so handle this ourselves. */
|
/* We don't want the clobber emitted, so handle this ourselves. */
|
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
|
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "move_dest_operand"
|
[(set (match_operand:SI 0 "move_dest_operand"
|
"=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T,?r,?*f")
|
"=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T,?r,?*f")
|
(match_operand:SI 1 "move_src_operand"
|
(match_operand:SI 1 "move_src_operand"
|
"A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f,*f,r"))]
|
"A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f,*f,r"))]
|
"(register_operand (operands[0], SImode)
|
"(register_operand (operands[0], SImode)
|
|| reg_or_0_operand (operands[1], SImode))
|
|| reg_or_0_operand (operands[1], SImode))
|
&& !TARGET_SOFT_FLOAT
|
&& !TARGET_SOFT_FLOAT
|
&& !TARGET_64BIT"
|
&& !TARGET_64BIT"
|
"@
|
"@
|
ldw RT'%A1,%0
|
ldw RT'%A1,%0
|
copy %1,%0
|
copy %1,%0
|
ldi %1,%0
|
ldi %1,%0
|
ldil L'%1,%0
|
ldil L'%1,%0
|
{zdepi|depwi,z} %Z1,%0
|
{zdepi|depwi,z} %Z1,%0
|
ldw%M1 %1,%0
|
ldw%M1 %1,%0
|
stw%M0 %r1,%0
|
stw%M0 %r1,%0
|
mtsar %r1
|
mtsar %r1
|
{mfctl|mfctl,w} %%sar,%0
|
{mfctl|mfctl,w} %%sar,%0
|
fcpy,sgl %f1,%0
|
fcpy,sgl %f1,%0
|
fldw%F1 %1,%0
|
fldw%F1 %1,%0
|
fstw%F0 %1,%0
|
fstw%F0 %1,%0
|
{fstws|fstw} %1,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%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"
|
{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 "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 "pa_combine_type" "addmove")
|
(set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,8,8")])
|
(set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,8,8")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "move_dest_operand"
|
[(set (match_operand:SI 0 "move_dest_operand"
|
"=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T")
|
"=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T")
|
(match_operand:SI 1 "move_src_operand"
|
(match_operand:SI 1 "move_src_operand"
|
"A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f"))]
|
"A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f"))]
|
"(register_operand (operands[0], SImode)
|
"(register_operand (operands[0], SImode)
|
|| reg_or_0_operand (operands[1], SImode))
|
|| reg_or_0_operand (operands[1], SImode))
|
&& !TARGET_SOFT_FLOAT
|
&& !TARGET_SOFT_FLOAT
|
&& TARGET_64BIT"
|
&& TARGET_64BIT"
|
"@
|
"@
|
ldw RT'%A1,%0
|
ldw RT'%A1,%0
|
copy %1,%0
|
copy %1,%0
|
ldi %1,%0
|
ldi %1,%0
|
ldil L'%1,%0
|
ldil L'%1,%0
|
{zdepi|depwi,z} %Z1,%0
|
{zdepi|depwi,z} %Z1,%0
|
ldw%M1 %1,%0
|
ldw%M1 %1,%0
|
stw%M0 %r1,%0
|
stw%M0 %r1,%0
|
mtsar %r1
|
mtsar %r1
|
{mfctl|mfctl,w} %%sar,%0
|
{mfctl|mfctl,w} %%sar,%0
|
fcpy,sgl %f1,%0
|
fcpy,sgl %f1,%0
|
fldw%F1 %1,%0
|
fldw%F1 %1,%0
|
fstw%F0 %1,%0"
|
fstw%F0 %1,%0"
|
[(set_attr "type" "load,move,move,move,shift,load,store,move,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 "pa_combine_type" "addmove")
|
(set_attr "length" "4,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 ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "indexed_memory_operand" "=R")
|
[(set (match_operand:SI 0 "indexed_memory_operand" "=R")
|
(match_operand:SI 1 "register_operand" "f"))]
|
(match_operand:SI 1 "register_operand" "f"))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& reload_completed"
|
&& reload_completed"
|
"fstw%F0 %1,%0"
|
"fstw%F0 %1,%0"
|
[(set_attr "type" "fpstore")
|
[(set_attr "type" "fpstore")
|
(set_attr "pa_combine_type" "addmove")
|
(set_attr "pa_combine_type" "addmove")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
; Rewrite RTL using an indexed store. This will allow the insn that
|
; Rewrite RTL using an indexed store. This will allow the insn that
|
; computes the address to be deleted if the register it sets is dead.
|
; computes the address to be deleted if the register it sets is dead.
|
(define_peephole2
|
(define_peephole2
|
[(set (match_operand:SI 0 "register_operand" "")
|
[(set (match_operand:SI 0 "register_operand" "")
|
(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
|
(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
|
(const_int 4))
|
(const_int 4))
|
(match_operand:SI 2 "register_operand" "")))
|
(match_operand:SI 2 "register_operand" "")))
|
(set (mem:SI (match_dup 0))
|
(set (mem:SI (match_dup 0))
|
(match_operand:SI 3 "register_operand" ""))]
|
(match_operand:SI 3 "register_operand" ""))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
&& 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 (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
|
(match_dup 3))
|
(match_dup 3))
|
(set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4))
|
(set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4))
|
(match_dup 2)))]
|
(match_dup 2)))]
|
"")
|
"")
|
|
|
(define_peephole2
|
(define_peephole2
|
[(set (match_operand:SI 0 "register_operand" "")
|
[(set (match_operand:SI 0 "register_operand" "")
|
(plus:SI (match_operand:SI 2 "register_operand" "")
|
(plus:SI (match_operand:SI 2 "register_operand" "")
|
(mult:SI (match_operand:SI 1 "register_operand" "")
|
(mult:SI (match_operand:SI 1 "register_operand" "")
|
(const_int 4))))
|
(const_int 4))))
|
(set (mem:SI (match_dup 0))
|
(set (mem:SI (match_dup 0))
|
(match_operand:SI 3 "register_operand" ""))]
|
(match_operand:SI 3 "register_operand" ""))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
&& 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 (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
|
(match_dup 3))
|
(match_dup 3))
|
(set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4))
|
(set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4))
|
(match_dup 2)))]
|
(match_dup 2)))]
|
"")
|
"")
|
|
|
(define_peephole2
|
(define_peephole2
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
|
(plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
|
(const_int 4))
|
(const_int 4))
|
(match_operand:DI 2 "register_operand" "")))
|
(match_operand:DI 2 "register_operand" "")))
|
(set (mem:SI (match_dup 0))
|
(set (mem:SI (match_dup 0))
|
(match_operand:SI 3 "register_operand" ""))]
|
(match_operand:SI 3 "register_operand" ""))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& TARGET_64BIT
|
&& TARGET_64BIT
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
[(set (mem:SI (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
|
[(set (mem:SI (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
|
(match_dup 3))
|
(match_dup 3))
|
(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4))
|
(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4))
|
(match_dup 2)))]
|
(match_dup 2)))]
|
"")
|
"")
|
|
|
(define_peephole2
|
(define_peephole2
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(plus:DI (match_operand:DI 2 "register_operand" "")
|
(plus:DI (match_operand:DI 2 "register_operand" "")
|
(mult:DI (match_operand:DI 1 "register_operand" "")
|
(mult:DI (match_operand:DI 1 "register_operand" "")
|
(const_int 4))))
|
(const_int 4))))
|
(set (mem:SI (match_dup 0))
|
(set (mem:SI (match_dup 0))
|
(match_operand:SI 3 "register_operand" ""))]
|
(match_operand:SI 3 "register_operand" ""))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& TARGET_64BIT
|
&& TARGET_64BIT
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
[(set (mem:SI (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
|
[(set (mem:SI (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
|
(match_dup 3))
|
(match_dup 3))
|
(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4))
|
(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4))
|
(match_dup 2)))]
|
(match_dup 2)))]
|
"")
|
"")
|
|
|
(define_peephole2
|
(define_peephole2
|
[(set (match_operand:SI 0 "register_operand" "")
|
[(set (match_operand:SI 0 "register_operand" "")
|
(plus:SI (match_operand:SI 1 "register_operand" "")
|
(plus:SI (match_operand:SI 1 "register_operand" "")
|
(match_operand:SI 2 "register_operand" "")))
|
(match_operand:SI 2 "register_operand" "")))
|
(set (mem:SI (match_dup 0))
|
(set (mem:SI (match_dup 0))
|
(match_operand:SI 3 "register_operand" ""))]
|
(match_operand:SI 3 "register_operand" ""))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& TARGET_NO_SPACE_REGS
|
&& TARGET_NO_SPACE_REGS
|
&& REG_OK_FOR_INDEX_P (operands[1])
|
&& REG_OK_FOR_INDEX_P (operands[1])
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
[(set (mem:SI (plus:SI (match_dup 1) (match_dup 2)))
|
[(set (mem:SI (plus:SI (match_dup 1) (match_dup 2)))
|
(match_dup 3))
|
(match_dup 3))
|
(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
|
(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
|
"")
|
"")
|
|
|
(define_peephole2
|
(define_peephole2
|
[(set (match_operand:SI 0 "register_operand" "")
|
[(set (match_operand:SI 0 "register_operand" "")
|
(plus:SI (match_operand:SI 1 "register_operand" "")
|
(plus:SI (match_operand:SI 1 "register_operand" "")
|
(match_operand:SI 2 "register_operand" "")))
|
(match_operand:SI 2 "register_operand" "")))
|
(set (mem:SI (match_dup 0))
|
(set (mem:SI (match_dup 0))
|
(match_operand:SI 3 "register_operand" ""))]
|
(match_operand:SI 3 "register_operand" ""))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& TARGET_NO_SPACE_REGS
|
&& TARGET_NO_SPACE_REGS
|
&& REG_OK_FOR_BASE_P (operands[1])
|
&& REG_OK_FOR_BASE_P (operands[1])
|
&& REG_OK_FOR_INDEX_P (operands[2])
|
&& REG_OK_FOR_INDEX_P (operands[2])
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
[(set (mem:SI (plus:SI (match_dup 2) (match_dup 1)))
|
[(set (mem:SI (plus:SI (match_dup 2) (match_dup 1)))
|
(match_dup 3))
|
(match_dup 3))
|
(set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
|
(set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
|
"")
|
"")
|
|
|
(define_peephole2
|
(define_peephole2
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(plus:DI (match_operand:DI 1 "register_operand" "")
|
(plus:DI (match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 2 "register_operand" "")))
|
(match_operand:DI 2 "register_operand" "")))
|
(set (mem:SI (match_dup 0))
|
(set (mem:SI (match_dup 0))
|
(match_operand:SI 3 "register_operand" ""))]
|
(match_operand:SI 3 "register_operand" ""))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& TARGET_64BIT
|
&& TARGET_64BIT
|
&& TARGET_NO_SPACE_REGS
|
&& TARGET_NO_SPACE_REGS
|
&& REG_OK_FOR_INDEX_P (operands[1])
|
&& REG_OK_FOR_INDEX_P (operands[1])
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
[(set (mem:SI (plus:DI (match_dup 1) (match_dup 2)))
|
[(set (mem:SI (plus:DI (match_dup 1) (match_dup 2)))
|
(match_dup 3))
|
(match_dup 3))
|
(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
|
(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
|
"")
|
"")
|
|
|
(define_peephole2
|
(define_peephole2
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(plus:DI (match_operand:DI 1 "register_operand" "")
|
(plus:DI (match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 2 "register_operand" "")))
|
(match_operand:DI 2 "register_operand" "")))
|
(set (mem:SI (match_dup 0))
|
(set (mem:SI (match_dup 0))
|
(match_operand:SI 3 "register_operand" ""))]
|
(match_operand:SI 3 "register_operand" ""))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& TARGET_64BIT
|
&& TARGET_64BIT
|
&& TARGET_NO_SPACE_REGS
|
&& TARGET_NO_SPACE_REGS
|
&& REG_OK_FOR_BASE_P (operands[1])
|
&& REG_OK_FOR_BASE_P (operands[1])
|
&& REG_OK_FOR_INDEX_P (operands[2])
|
&& REG_OK_FOR_INDEX_P (operands[2])
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
[(set (mem:SI (plus:DI (match_dup 2) (match_dup 1)))
|
[(set (mem:SI (plus:DI (match_dup 2) (match_dup 1)))
|
(match_dup 3))
|
(match_dup 3))
|
(set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
|
(set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
|
"")
|
"")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "move_dest_operand"
|
[(set (match_operand:SI 0 "move_dest_operand"
|
"=r,r,r,r,r,r,Q,!*q,!r")
|
"=r,r,r,r,r,r,Q,!*q,!r")
|
(match_operand:SI 1 "move_src_operand"
|
(match_operand:SI 1 "move_src_operand"
|
"A,r,J,N,K,RQ,rM,!rM,!*q"))]
|
"A,r,J,N,K,RQ,rM,!rM,!*q"))]
|
"(register_operand (operands[0], SImode)
|
"(register_operand (operands[0], SImode)
|
|| reg_or_0_operand (operands[1], SImode))
|
|| reg_or_0_operand (operands[1], SImode))
|
&& TARGET_SOFT_FLOAT"
|
&& TARGET_SOFT_FLOAT"
|
"@
|
"@
|
ldw RT'%A1,%0
|
ldw RT'%A1,%0
|
copy %1,%0
|
copy %1,%0
|
ldi %1,%0
|
ldi %1,%0
|
ldil L'%1,%0
|
ldil L'%1,%0
|
{zdepi|depwi,z} %Z1,%0
|
{zdepi|depwi,z} %Z1,%0
|
ldw%M1 %1,%0
|
ldw%M1 %1,%0
|
stw%M0 %r1,%0
|
stw%M0 %r1,%0
|
mtsar %r1
|
mtsar %r1
|
{mfctl|mfctl,w} %%sar,%0"
|
{mfctl|mfctl,w} %%sar,%0"
|
[(set_attr "type" "load,move,move,move,move,load,store,move,move")
|
[(set_attr "type" "load,move,move,move,move,load,store,move,move")
|
(set_attr "pa_combine_type" "addmove")
|
(set_attr "pa_combine_type" "addmove")
|
(set_attr "length" "4,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.
|
;; Load or store with base-register modification.
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(mem:SI (plus:DI (match_operand:DI 1 "register_operand" "+r")
|
(mem:SI (plus:DI (match_operand:DI 1 "register_operand" "+r")
|
(match_operand:DI 2 "int5_operand" "L"))))
|
(match_operand:DI 2 "int5_operand" "L"))))
|
(set (match_dup 1)
|
(set (match_dup 1)
|
(plus:DI (match_dup 1) (match_dup 2)))]
|
(plus:DI (match_dup 1) (match_dup 2)))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"ldw,mb %2(%1),%0"
|
"ldw,mb %2(%1),%0"
|
[(set_attr "type" "load")
|
[(set_attr "type" "load")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
; And a zero extended variant.
|
; And a zero extended variant.
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(zero_extend:DI (mem:SI
|
(zero_extend:DI (mem:SI
|
(plus:DI
|
(plus:DI
|
(match_operand:DI 1 "register_operand" "+r")
|
(match_operand:DI 1 "register_operand" "+r")
|
(match_operand:DI 2 "int5_operand" "L")))))
|
(match_operand:DI 2 "int5_operand" "L")))))
|
(set (match_dup 1)
|
(set (match_dup 1)
|
(plus:DI (match_dup 1) (match_dup 2)))]
|
(plus:DI (match_dup 1) (match_dup 2)))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"ldw,mb %2(%1),%0"
|
"ldw,mb %2(%1),%0"
|
[(set_attr "type" "load")
|
[(set_attr "type" "load")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_expand "pre_load"
|
(define_expand "pre_load"
|
[(parallel [(set (match_operand:SI 0 "register_operand" "")
|
[(parallel [(set (match_operand:SI 0 "register_operand" "")
|
(mem (plus (match_operand 1 "register_operand" "")
|
(mem (plus (match_operand 1 "register_operand" "")
|
(match_operand 2 "pre_cint_operand" ""))))
|
(match_operand 2 "pre_cint_operand" ""))))
|
(set (match_dup 1)
|
(set (match_dup 1)
|
(plus (match_dup 1) (match_dup 2)))])]
|
(plus (match_dup 1) (match_dup 2)))])]
|
""
|
""
|
"
|
"
|
{
|
{
|
if (TARGET_64BIT)
|
if (TARGET_64BIT)
|
{
|
{
|
emit_insn (gen_pre_ldd (operands[0], operands[1], operands[2]));
|
emit_insn (gen_pre_ldd (operands[0], operands[1], operands[2]));
|
DONE;
|
DONE;
|
}
|
}
|
emit_insn (gen_pre_ldw (operands[0], operands[1], operands[2]));
|
emit_insn (gen_pre_ldw (operands[0], operands[1], operands[2]));
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
(define_insn "pre_ldw"
|
(define_insn "pre_ldw"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "+r")
|
(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "+r")
|
(match_operand:SI 2 "pre_cint_operand" ""))))
|
(match_operand:SI 2 "pre_cint_operand" ""))))
|
(set (match_dup 1)
|
(set (match_dup 1)
|
(plus:SI (match_dup 1) (match_dup 2)))]
|
(plus:SI (match_dup 1) (match_dup 2)))]
|
""
|
""
|
"*
|
"*
|
{
|
{
|
if (INTVAL (operands[2]) < 0)
|
if (INTVAL (operands[2]) < 0)
|
return \"{ldwm|ldw,mb} %2(%1),%0\";
|
return \"{ldwm|ldw,mb} %2(%1),%0\";
|
return \"{ldws|ldw},mb %2(%1),%0\";
|
return \"{ldws|ldw},mb %2(%1),%0\";
|
}"
|
}"
|
[(set_attr "type" "load")
|
[(set_attr "type" "load")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "pre_ldd"
|
(define_insn "pre_ldd"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(mem:DI (plus:DI (match_operand:DI 1 "register_operand" "+r")
|
(mem:DI (plus:DI (match_operand:DI 1 "register_operand" "+r")
|
(match_operand:DI 2 "pre_cint_operand" ""))))
|
(match_operand:DI 2 "pre_cint_operand" ""))))
|
(set (match_dup 1)
|
(set (match_dup 1)
|
(plus:DI (match_dup 1) (match_dup 2)))]
|
(plus:DI (match_dup 1) (match_dup 2)))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"ldd,mb %2(%1),%0"
|
"ldd,mb %2(%1),%0"
|
[(set_attr "type" "load")
|
[(set_attr "type" "load")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "+r")
|
[(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "+r")
|
(match_operand:SI 1 "pre_cint_operand" "")))
|
(match_operand:SI 1 "pre_cint_operand" "")))
|
(match_operand:SI 2 "reg_or_0_operand" "rM"))
|
(match_operand:SI 2 "reg_or_0_operand" "rM"))
|
(set (match_dup 0)
|
(set (match_dup 0)
|
(plus:SI (match_dup 0) (match_dup 1)))]
|
(plus:SI (match_dup 0) (match_dup 1)))]
|
""
|
""
|
"*
|
"*
|
{
|
{
|
if (INTVAL (operands[1]) < 0)
|
if (INTVAL (operands[1]) < 0)
|
return \"{stwm|stw,mb} %r2,%1(%0)\";
|
return \"{stwm|stw,mb} %r2,%1(%0)\";
|
return \"{stws|stw},mb %r2,%1(%0)\";
|
return \"{stws|stw},mb %r2,%1(%0)\";
|
}"
|
}"
|
[(set_attr "type" "store")
|
[(set_attr "type" "store")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(mem:SI (match_operand:SI 1 "register_operand" "+r")))
|
(mem:SI (match_operand:SI 1 "register_operand" "+r")))
|
(set (match_dup 1)
|
(set (match_dup 1)
|
(plus:SI (match_dup 1)
|
(plus:SI (match_dup 1)
|
(match_operand:SI 2 "post_cint_operand" "")))]
|
(match_operand:SI 2 "post_cint_operand" "")))]
|
""
|
""
|
"*
|
"*
|
{
|
{
|
if (INTVAL (operands[2]) > 0)
|
if (INTVAL (operands[2]) > 0)
|
return \"{ldwm|ldw,ma} %2(%1),%0\";
|
return \"{ldwm|ldw,ma} %2(%1),%0\";
|
return \"{ldws|ldw},ma %2(%1),%0\";
|
return \"{ldws|ldw},ma %2(%1),%0\";
|
}"
|
}"
|
[(set_attr "type" "load")
|
[(set_attr "type" "load")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_expand "post_store"
|
(define_expand "post_store"
|
[(parallel [(set (mem (match_operand 0 "register_operand" ""))
|
[(parallel [(set (mem (match_operand 0 "register_operand" ""))
|
(match_operand 1 "reg_or_0_operand" ""))
|
(match_operand 1 "reg_or_0_operand" ""))
|
(set (match_dup 0)
|
(set (match_dup 0)
|
(plus (match_dup 0)
|
(plus (match_dup 0)
|
(match_operand 2 "post_cint_operand" "")))])]
|
(match_operand 2 "post_cint_operand" "")))])]
|
""
|
""
|
"
|
"
|
{
|
{
|
if (TARGET_64BIT)
|
if (TARGET_64BIT)
|
{
|
{
|
emit_insn (gen_post_std (operands[0], operands[1], operands[2]));
|
emit_insn (gen_post_std (operands[0], operands[1], operands[2]));
|
DONE;
|
DONE;
|
}
|
}
|
emit_insn (gen_post_stw (operands[0], operands[1], operands[2]));
|
emit_insn (gen_post_stw (operands[0], operands[1], operands[2]));
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
(define_insn "post_stw"
|
(define_insn "post_stw"
|
[(set (mem:SI (match_operand:SI 0 "register_operand" "+r"))
|
[(set (mem:SI (match_operand:SI 0 "register_operand" "+r"))
|
(match_operand:SI 1 "reg_or_0_operand" "rM"))
|
(match_operand:SI 1 "reg_or_0_operand" "rM"))
|
(set (match_dup 0)
|
(set (match_dup 0)
|
(plus:SI (match_dup 0)
|
(plus:SI (match_dup 0)
|
(match_operand:SI 2 "post_cint_operand" "")))]
|
(match_operand:SI 2 "post_cint_operand" "")))]
|
""
|
""
|
"*
|
"*
|
{
|
{
|
if (INTVAL (operands[2]) > 0)
|
if (INTVAL (operands[2]) > 0)
|
return \"{stwm|stw,ma} %r1,%2(%0)\";
|
return \"{stwm|stw,ma} %r1,%2(%0)\";
|
return \"{stws|stw},ma %r1,%2(%0)\";
|
return \"{stws|stw},ma %r1,%2(%0)\";
|
}"
|
}"
|
[(set_attr "type" "store")
|
[(set_attr "type" "store")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "post_std"
|
(define_insn "post_std"
|
[(set (mem:DI (match_operand:DI 0 "register_operand" "+r"))
|
[(set (mem:DI (match_operand:DI 0 "register_operand" "+r"))
|
(match_operand:DI 1 "reg_or_0_operand" "rM"))
|
(match_operand:DI 1 "reg_or_0_operand" "rM"))
|
(set (match_dup 0)
|
(set (match_dup 0)
|
(plus:DI (match_dup 0)
|
(plus:DI (match_dup 0)
|
(match_operand:DI 2 "post_cint_operand" "")))]
|
(match_operand:DI 2 "post_cint_operand" "")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"std,ma %r1,%2(%0)"
|
"std,ma %r1,%2(%0)"
|
[(set_attr "type" "store")
|
[(set_attr "type" "store")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
;; For loading the address of a label while generating PIC code.
|
;; For loading the address of a label while generating PIC code.
|
;; Note since this pattern can be created at reload time (via movsi), all
|
;; 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).
|
;; the same rules for movsi apply here. (no new pseudos, no temporaries).
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand 0 "pmode_register_operand" "=a")
|
[(set (match_operand 0 "pmode_register_operand" "=a")
|
(match_operand 1 "pic_label_operand" ""))]
|
(match_operand 1 "pic_label_operand" ""))]
|
"TARGET_PA_20"
|
"TARGET_PA_20"
|
"*
|
"*
|
{
|
{
|
rtx xoperands[3];
|
rtx xoperands[3];
|
|
|
xoperands[0] = operands[0];
|
xoperands[0] = operands[0];
|
xoperands[1] = operands[1];
|
xoperands[1] = operands[1];
|
xoperands[2] = gen_label_rtx ();
|
xoperands[2] = gen_label_rtx ();
|
|
|
(*targetm.asm_out.internal_label) (asm_out_file, \"L\",
|
(*targetm.asm_out.internal_label) (asm_out_file, \"L\",
|
CODE_LABEL_NUMBER (xoperands[2]));
|
CODE_LABEL_NUMBER (xoperands[2]));
|
output_asm_insn (\"mfia %0\", xoperands);
|
output_asm_insn (\"mfia %0\", xoperands);
|
|
|
/* If we're trying to load the address of a label that happens to be
|
/* If we're trying to load the address of a label that happens to be
|
close, then we can use a shorter sequence. */
|
close, then we can use a shorter sequence. */
|
if (GET_CODE (operands[1]) == LABEL_REF
|
if (GET_CODE (operands[1]) == LABEL_REF
|
&& !LABEL_REF_NONLOCAL_P (operands[1])
|
&& !LABEL_REF_NONLOCAL_P (operands[1])
|
&& INSN_ADDRESSES_SET_P ()
|
&& INSN_ADDRESSES_SET_P ()
|
&& abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
|
&& abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
|
- INSN_ADDRESSES (INSN_UID (insn))) < 8100)
|
- INSN_ADDRESSES (INSN_UID (insn))) < 8100)
|
output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
|
output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
|
else
|
else
|
{
|
{
|
output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
|
output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
|
output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
|
output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
|
}
|
}
|
return \"\";
|
return \"\";
|
}"
|
}"
|
[(set_attr "type" "multi")
|
[(set_attr "type" "multi")
|
(set_attr "length" "12")]) ; 8 or 12
|
(set_attr "length" "12")]) ; 8 or 12
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand 0 "pmode_register_operand" "=a")
|
[(set (match_operand 0 "pmode_register_operand" "=a")
|
(match_operand 1 "pic_label_operand" ""))]
|
(match_operand 1 "pic_label_operand" ""))]
|
"!TARGET_PA_20"
|
"!TARGET_PA_20"
|
"*
|
"*
|
{
|
{
|
rtx xoperands[3];
|
rtx xoperands[3];
|
|
|
xoperands[0] = operands[0];
|
xoperands[0] = operands[0];
|
xoperands[1] = operands[1];
|
xoperands[1] = operands[1];
|
xoperands[2] = gen_label_rtx ();
|
xoperands[2] = gen_label_rtx ();
|
|
|
output_asm_insn (\"bl .+8,%0\", xoperands);
|
output_asm_insn (\"bl .+8,%0\", xoperands);
|
output_asm_insn (\"depi 0,31,2,%0\", xoperands);
|
output_asm_insn (\"depi 0,31,2,%0\", xoperands);
|
(*targetm.asm_out.internal_label) (asm_out_file, \"L\",
|
(*targetm.asm_out.internal_label) (asm_out_file, \"L\",
|
CODE_LABEL_NUMBER (xoperands[2]));
|
CODE_LABEL_NUMBER (xoperands[2]));
|
|
|
/* If we're trying to load the address of a label that happens to be
|
/* If we're trying to load the address of a label that happens to be
|
close, then we can use a shorter sequence. */
|
close, then we can use a shorter sequence. */
|
if (GET_CODE (operands[1]) == LABEL_REF
|
if (GET_CODE (operands[1]) == LABEL_REF
|
&& !LABEL_REF_NONLOCAL_P (operands[1])
|
&& !LABEL_REF_NONLOCAL_P (operands[1])
|
&& INSN_ADDRESSES_SET_P ()
|
&& INSN_ADDRESSES_SET_P ()
|
&& abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
|
&& abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
|
- INSN_ADDRESSES (INSN_UID (insn))) < 8100)
|
- INSN_ADDRESSES (INSN_UID (insn))) < 8100)
|
output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
|
output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
|
else
|
else
|
{
|
{
|
output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
|
output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
|
output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
|
output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
|
}
|
}
|
return \"\";
|
return \"\";
|
}"
|
}"
|
[(set_attr "type" "multi")
|
[(set_attr "type" "multi")
|
(set_attr "length" "16")]) ; 12 or 16
|
(set_attr "length" "16")]) ; 12 or 16
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=a")
|
[(set (match_operand:SI 0 "register_operand" "=a")
|
(plus:SI (match_operand:SI 1 "register_operand" "r")
|
(plus:SI (match_operand:SI 1 "register_operand" "r")
|
(high:SI (match_operand 2 "" ""))))]
|
(high:SI (match_operand 2 "" ""))))]
|
"symbolic_operand (operands[2], Pmode)
|
"symbolic_operand (operands[2], Pmode)
|
&& ! function_label_operand (operands[2], Pmode)
|
&& ! function_label_operand (operands[2], Pmode)
|
&& flag_pic"
|
&& flag_pic"
|
"addil LT'%G2,%1"
|
"addil LT'%G2,%1"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=a")
|
[(set (match_operand:DI 0 "register_operand" "=a")
|
(plus:DI (match_operand:DI 1 "register_operand" "r")
|
(plus:DI (match_operand:DI 1 "register_operand" "r")
|
(high:DI (match_operand 2 "" ""))))]
|
(high:DI (match_operand 2 "" ""))))]
|
"symbolic_operand (operands[2], Pmode)
|
"symbolic_operand (operands[2], Pmode)
|
&& ! function_label_operand (operands[2], Pmode)
|
&& ! function_label_operand (operands[2], Pmode)
|
&& TARGET_64BIT
|
&& TARGET_64BIT
|
&& flag_pic"
|
&& flag_pic"
|
"addil LT'%G2,%1"
|
"addil LT'%G2,%1"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
;; Always use addil rather than ldil;add sequences. This allows the
|
;; Always use addil rather than ldil;add sequences. This allows the
|
;; HP linker to eliminate the dp relocation if the symbolic operand
|
;; HP linker to eliminate the dp relocation if the symbolic operand
|
;; lives in the TEXT space.
|
;; lives in the TEXT space.
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=a")
|
[(set (match_operand:SI 0 "register_operand" "=a")
|
(high:SI (match_operand 1 "" "")))]
|
(high:SI (match_operand 1 "" "")))]
|
"symbolic_operand (operands[1], Pmode)
|
"symbolic_operand (operands[1], Pmode)
|
&& ! function_label_operand (operands[1], Pmode)
|
&& ! function_label_operand (operands[1], Pmode)
|
&& ! read_only_operand (operands[1], Pmode)
|
&& ! read_only_operand (operands[1], Pmode)
|
&& ! flag_pic"
|
&& ! flag_pic"
|
"*
|
"*
|
{
|
{
|
if (TARGET_LONG_LOAD_STORE)
|
if (TARGET_LONG_LOAD_STORE)
|
return \"addil NLR'%H1,%%r27\;ldo N'%H1(%%r1),%%r1\";
|
return \"addil NLR'%H1,%%r27\;ldo N'%H1(%%r1),%%r1\";
|
else
|
else
|
return \"addil LR'%H1,%%r27\";
|
return \"addil LR'%H1,%%r27\";
|
}"
|
}"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set (attr "length")
|
(set (attr "length")
|
(if_then_else (eq (symbol_ref "TARGET_LONG_LOAD_STORE") (const_int 0))
|
(if_then_else (eq (symbol_ref "TARGET_LONG_LOAD_STORE") (const_int 0))
|
(const_int 4)
|
(const_int 4)
|
(const_int 8)))])
|
(const_int 8)))])
|
|
|
|
|
;; This is for use in the prologue/epilogue code. We need it
|
;; This is for use in the prologue/epilogue code. We need it
|
;; to add large constants to a stack pointer or frame pointer.
|
;; to add large constants to a stack pointer or frame pointer.
|
;; Because of the additional %r1 pressure, we probably do not
|
;; Because of the additional %r1 pressure, we probably do not
|
;; want to use this in general code, so make it available
|
;; want to use this in general code, so make it available
|
;; only after reload.
|
;; only after reload.
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=!a,*r")
|
[(set (match_operand:SI 0 "register_operand" "=!a,*r")
|
(plus:SI (match_operand:SI 1 "register_operand" "r,r")
|
(plus:SI (match_operand:SI 1 "register_operand" "r,r")
|
(high:SI (match_operand 2 "const_int_operand" ""))))]
|
(high:SI (match_operand 2 "const_int_operand" ""))))]
|
"reload_completed"
|
"reload_completed"
|
"@
|
"@
|
addil L'%G2,%1
|
addil L'%G2,%1
|
ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
|
ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
|
[(set_attr "type" "binary,binary")
|
[(set_attr "type" "binary,binary")
|
(set_attr "length" "4,8")])
|
(set_attr "length" "4,8")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=!a,*r")
|
[(set (match_operand:DI 0 "register_operand" "=!a,*r")
|
(plus:DI (match_operand:DI 1 "register_operand" "r,r")
|
(plus:DI (match_operand:DI 1 "register_operand" "r,r")
|
(high:DI (match_operand 2 "const_int_operand" ""))))]
|
(high:DI (match_operand 2 "const_int_operand" ""))))]
|
"reload_completed && TARGET_64BIT"
|
"reload_completed && TARGET_64BIT"
|
"@
|
"@
|
addil L'%G2,%1
|
addil L'%G2,%1
|
ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
|
ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
|
[(set_attr "type" "binary,binary")
|
[(set_attr "type" "binary,binary")
|
(set_attr "length" "4,8")])
|
(set_attr "length" "4,8")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(high:SI (match_operand 1 "" "")))]
|
(high:SI (match_operand 1 "" "")))]
|
"(!flag_pic || !symbolic_operand (operands[1], Pmode))
|
"(!flag_pic || !symbolic_operand (operands[1], Pmode))
|
&& !is_function_label_plus_const (operands[1])"
|
&& !is_function_label_plus_const (operands[1])"
|
"*
|
"*
|
{
|
{
|
if (symbolic_operand (operands[1], Pmode))
|
if (symbolic_operand (operands[1], Pmode))
|
return \"ldil LR'%H1,%0\";
|
return \"ldil LR'%H1,%0\";
|
else
|
else
|
return \"ldil L'%G1,%0\";
|
return \"ldil L'%G1,%0\";
|
}"
|
}"
|
[(set_attr "type" "move")
|
[(set_attr "type" "move")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(high:DI (match_operand 1 "const_int_operand" "")))]
|
(high:DI (match_operand 1 "const_int_operand" "")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"ldil L'%G1,%0";
|
"ldil L'%G1,%0";
|
[(set_attr "type" "move")
|
[(set_attr "type" "move")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
|
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
|
(match_operand:DI 2 "const_int_operand" "i")))]
|
(match_operand:DI 2 "const_int_operand" "i")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"ldo R'%G2(%1),%0";
|
"ldo R'%G2(%1),%0";
|
[(set_attr "type" "move")
|
[(set_attr "type" "move")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(lo_sum:SI (match_operand:SI 1 "register_operand" "r")
|
(lo_sum:SI (match_operand:SI 1 "register_operand" "r")
|
(match_operand:SI 2 "immediate_operand" "i")))]
|
(match_operand:SI 2 "immediate_operand" "i")))]
|
"!is_function_label_plus_const (operands[2])"
|
"!is_function_label_plus_const (operands[2])"
|
"*
|
"*
|
{
|
{
|
gcc_assert (!flag_pic || !symbolic_operand (operands[2], Pmode));
|
gcc_assert (!flag_pic || !symbolic_operand (operands[2], Pmode));
|
|
|
if (symbolic_operand (operands[2], Pmode))
|
if (symbolic_operand (operands[2], Pmode))
|
return \"ldo RR'%G2(%1),%0\";
|
return \"ldo RR'%G2(%1),%0\";
|
else
|
else
|
return \"ldo R'%G2(%1),%0\";
|
return \"ldo R'%G2(%1),%0\";
|
}"
|
}"
|
[(set_attr "type" "move")
|
[(set_attr "type" "move")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
;; Now that a symbolic_address plus a constant is broken up early
|
;; Now that a symbolic_address plus a constant is broken up early
|
;; in the compilation phase (for better CSE) we need a special
|
;; in the compilation phase (for better CSE) we need a special
|
;; combiner pattern to load the symbolic address plus the constant
|
;; combiner pattern to load the symbolic address plus the constant
|
;; in only 2 instructions. (For cases where the symbolic address
|
;; in only 2 instructions. (For cases where the symbolic address
|
;; was not a common subexpression.)
|
;; was not a common subexpression.)
|
(define_split
|
(define_split
|
[(set (match_operand:SI 0 "register_operand" "")
|
[(set (match_operand:SI 0 "register_operand" "")
|
(match_operand:SI 1 "symbolic_operand" ""))
|
(match_operand:SI 1 "symbolic_operand" ""))
|
(clobber (match_operand:SI 2 "register_operand" ""))]
|
(clobber (match_operand:SI 2 "register_operand" ""))]
|
"! (flag_pic && pic_label_operand (operands[1], SImode))"
|
"! (flag_pic && pic_label_operand (operands[1], SImode))"
|
[(set (match_dup 2) (high:SI (match_dup 1)))
|
[(set (match_dup 2) (high:SI (match_dup 1)))
|
(set (match_dup 0) (lo_sum:SI (match_dup 2) (match_dup 1)))]
|
(set (match_dup 0) (lo_sum:SI (match_dup 2) (match_dup 1)))]
|
"")
|
"")
|
|
|
;; hppa_legitimize_address goes to a great deal of trouble to
|
;; hppa_legitimize_address goes to a great deal of trouble to
|
;; create addresses which use indexing. In some cases, this
|
;; create addresses which use indexing. In some cases, this
|
;; is a lose because there isn't any store instructions which
|
;; is a lose because there isn't any store instructions which
|
;; allow indexed addresses (with integer register source).
|
;; allow indexed addresses (with integer register source).
|
;;
|
;;
|
;; These define_splits try to turn a 3 insn store into
|
;; These define_splits try to turn a 3 insn store into
|
;; a 2 insn store with some creative RTL rewriting.
|
;; a 2 insn store with some creative RTL rewriting.
|
(define_split
|
(define_split
|
[(set (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
|
[(set (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
|
(match_operand:SI 1 "shadd_operand" ""))
|
(match_operand:SI 1 "shadd_operand" ""))
|
(plus:SI (match_operand:SI 2 "register_operand" "")
|
(plus:SI (match_operand:SI 2 "register_operand" "")
|
(match_operand:SI 3 "const_int_operand" ""))))
|
(match_operand:SI 3 "const_int_operand" ""))))
|
(match_operand:SI 4 "register_operand" ""))
|
(match_operand:SI 4 "register_operand" ""))
|
(clobber (match_operand:SI 5 "register_operand" ""))]
|
(clobber (match_operand:SI 5 "register_operand" ""))]
|
""
|
""
|
[(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
|
[(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
|
(match_dup 2)))
|
(match_dup 2)))
|
(set (mem:SI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
|
(set (mem:SI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
|
"")
|
"")
|
|
|
(define_split
|
(define_split
|
[(set (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
|
[(set (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
|
(match_operand:SI 1 "shadd_operand" ""))
|
(match_operand:SI 1 "shadd_operand" ""))
|
(plus:SI (match_operand:SI 2 "register_operand" "")
|
(plus:SI (match_operand:SI 2 "register_operand" "")
|
(match_operand:SI 3 "const_int_operand" ""))))
|
(match_operand:SI 3 "const_int_operand" ""))))
|
(match_operand:HI 4 "register_operand" ""))
|
(match_operand:HI 4 "register_operand" ""))
|
(clobber (match_operand:SI 5 "register_operand" ""))]
|
(clobber (match_operand:SI 5 "register_operand" ""))]
|
""
|
""
|
[(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
|
[(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
|
(match_dup 2)))
|
(match_dup 2)))
|
(set (mem:HI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
|
(set (mem:HI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
|
"")
|
"")
|
|
|
(define_split
|
(define_split
|
[(set (mem:QI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
|
[(set (mem:QI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
|
(match_operand:SI 1 "shadd_operand" ""))
|
(match_operand:SI 1 "shadd_operand" ""))
|
(plus:SI (match_operand:SI 2 "register_operand" "")
|
(plus:SI (match_operand:SI 2 "register_operand" "")
|
(match_operand:SI 3 "const_int_operand" ""))))
|
(match_operand:SI 3 "const_int_operand" ""))))
|
(match_operand:QI 4 "register_operand" ""))
|
(match_operand:QI 4 "register_operand" ""))
|
(clobber (match_operand:SI 5 "register_operand" ""))]
|
(clobber (match_operand:SI 5 "register_operand" ""))]
|
""
|
""
|
[(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
|
[(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
|
(match_dup 2)))
|
(match_dup 2)))
|
(set (mem:QI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
|
(set (mem:QI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
|
"")
|
"")
|
|
|
(define_expand "movhi"
|
(define_expand "movhi"
|
[(set (match_operand:HI 0 "general_operand" "")
|
[(set (match_operand:HI 0 "general_operand" "")
|
(match_operand:HI 1 "general_operand" ""))]
|
(match_operand:HI 1 "general_operand" ""))]
|
""
|
""
|
"
|
"
|
{
|
{
|
if (emit_move_sequence (operands, HImode, 0))
|
if (emit_move_sequence (operands, HImode, 0))
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
;; Handle HImode input reloads requiring a general register as a
|
;; Handle HImode input reloads requiring a general register as a
|
;; scratch register.
|
;; scratch register.
|
(define_expand "reload_inhi"
|
(define_expand "reload_inhi"
|
[(set (match_operand:HI 0 "register_operand" "=Z")
|
[(set (match_operand:HI 0 "register_operand" "=Z")
|
(match_operand:HI 1 "non_hard_reg_operand" ""))
|
(match_operand:HI 1 "non_hard_reg_operand" ""))
|
(clobber (match_operand:HI 2 "register_operand" "=&r"))]
|
(clobber (match_operand:HI 2 "register_operand" "=&r"))]
|
""
|
""
|
"
|
"
|
{
|
{
|
if (emit_move_sequence (operands, HImode, operands[2]))
|
if (emit_move_sequence (operands, HImode, operands[2]))
|
DONE;
|
DONE;
|
|
|
/* We don't want the clobber emitted, so handle this ourselves. */
|
/* We don't want the clobber emitted, so handle this ourselves. */
|
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
|
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
;; Handle HImode output reloads requiring a general register as a
|
;; Handle HImode output reloads requiring a general register as a
|
;; scratch register.
|
;; scratch register.
|
(define_expand "reload_outhi"
|
(define_expand "reload_outhi"
|
[(set (match_operand:HI 0 "non_hard_reg_operand" "")
|
[(set (match_operand:HI 0 "non_hard_reg_operand" "")
|
(match_operand:HI 1 "register_operand" "Z"))
|
(match_operand:HI 1 "register_operand" "Z"))
|
(clobber (match_operand:HI 2 "register_operand" "=&r"))]
|
(clobber (match_operand:HI 2 "register_operand" "=&r"))]
|
""
|
""
|
"
|
"
|
{
|
{
|
if (emit_move_sequence (operands, HImode, operands[2]))
|
if (emit_move_sequence (operands, HImode, operands[2]))
|
DONE;
|
DONE;
|
|
|
/* We don't want the clobber emitted, so handle this ourselves. */
|
/* We don't want the clobber emitted, so handle this ourselves. */
|
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
|
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:HI 0 "move_dest_operand"
|
[(set (match_operand:HI 0 "move_dest_operand"
|
"=r,r,r,r,r,Q,!*q,!r")
|
"=r,r,r,r,r,Q,!*q,!r")
|
(match_operand:HI 1 "move_src_operand"
|
(match_operand:HI 1 "move_src_operand"
|
"r,J,N,K,RQ,rM,!rM,!*q"))]
|
"r,J,N,K,RQ,rM,!rM,!*q"))]
|
"(register_operand (operands[0], HImode)
|
"(register_operand (operands[0], HImode)
|
|| reg_or_0_operand (operands[1], HImode))"
|
|| reg_or_0_operand (operands[1], HImode))"
|
"@
|
"@
|
copy %1,%0
|
copy %1,%0
|
ldi %1,%0
|
ldi %1,%0
|
ldil L'%1,%0
|
ldil L'%1,%0
|
{zdepi|depwi,z} %Z1,%0
|
{zdepi|depwi,z} %Z1,%0
|
ldh%M1 %1,%0
|
ldh%M1 %1,%0
|
sth%M0 %r1,%0
|
sth%M0 %r1,%0
|
mtsar %r1
|
mtsar %r1
|
{mfctl|mfctl,w} %sar,%0"
|
{mfctl|mfctl,w} %sar,%0"
|
[(set_attr "type" "move,move,move,shift,load,store,move,move")
|
[(set_attr "type" "move,move,move,shift,load,store,move,move")
|
(set_attr "pa_combine_type" "addmove")
|
(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")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
(mem:HI (plus:SI (match_operand:SI 1 "register_operand" "+r")
|
(mem:HI (plus:SI (match_operand:SI 1 "register_operand" "+r")
|
(match_operand:SI 2 "int5_operand" "L"))))
|
(match_operand:SI 2 "int5_operand" "L"))))
|
(set (match_dup 1)
|
(set (match_dup 1)
|
(plus:SI (match_dup 1) (match_dup 2)))]
|
(plus:SI (match_dup 1) (match_dup 2)))]
|
""
|
""
|
"{ldhs|ldh},mb %2(%1),%0"
|
"{ldhs|ldh},mb %2(%1),%0"
|
[(set_attr "type" "load")
|
[(set_attr "type" "load")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
(mem:HI (plus:DI (match_operand:DI 1 "register_operand" "+r")
|
(mem:HI (plus:DI (match_operand:DI 1 "register_operand" "+r")
|
(match_operand:DI 2 "int5_operand" "L"))))
|
(match_operand:DI 2 "int5_operand" "L"))))
|
(set (match_dup 1)
|
(set (match_dup 1)
|
(plus:DI (match_dup 1) (match_dup 2)))]
|
(plus:DI (match_dup 1) (match_dup 2)))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"ldh,mb %2(%1),%0"
|
"ldh,mb %2(%1),%0"
|
[(set_attr "type" "load")
|
[(set_attr "type" "load")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
; And a zero extended variant.
|
; And a zero extended variant.
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(zero_extend:DI (mem:HI
|
(zero_extend:DI (mem:HI
|
(plus:DI
|
(plus:DI
|
(match_operand:DI 1 "register_operand" "+r")
|
(match_operand:DI 1 "register_operand" "+r")
|
(match_operand:DI 2 "int5_operand" "L")))))
|
(match_operand:DI 2 "int5_operand" "L")))))
|
(set (match_dup 1)
|
(set (match_dup 1)
|
(plus:DI (match_dup 1) (match_dup 2)))]
|
(plus:DI (match_dup 1) (match_dup 2)))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"ldh,mb %2(%1),%0"
|
"ldh,mb %2(%1),%0"
|
[(set_attr "type" "load")
|
[(set_attr "type" "load")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(zero_extend:SI (mem:HI
|
(zero_extend:SI (mem:HI
|
(plus:SI
|
(plus:SI
|
(match_operand:SI 1 "register_operand" "+r")
|
(match_operand:SI 1 "register_operand" "+r")
|
(match_operand:SI 2 "int5_operand" "L")))))
|
(match_operand:SI 2 "int5_operand" "L")))))
|
(set (match_dup 1)
|
(set (match_dup 1)
|
(plus:SI (match_dup 1) (match_dup 2)))]
|
(plus:SI (match_dup 1) (match_dup 2)))]
|
""
|
""
|
"{ldhs|ldh},mb %2(%1),%0"
|
"{ldhs|ldh},mb %2(%1),%0"
|
[(set_attr "type" "load")
|
[(set_attr "type" "load")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(zero_extend:SI (mem:HI
|
(zero_extend:SI (mem:HI
|
(plus:DI
|
(plus:DI
|
(match_operand:DI 1 "register_operand" "+r")
|
(match_operand:DI 1 "register_operand" "+r")
|
(match_operand:DI 2 "int5_operand" "L")))))
|
(match_operand:DI 2 "int5_operand" "L")))))
|
(set (match_dup 1)
|
(set (match_dup 1)
|
(plus:DI (match_dup 1) (match_dup 2)))]
|
(plus:DI (match_dup 1) (match_dup 2)))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"ldh,mb %2(%1),%0"
|
"ldh,mb %2(%1),%0"
|
[(set_attr "type" "load")
|
[(set_attr "type" "load")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "+r")
|
[(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "+r")
|
(match_operand:SI 1 "int5_operand" "L")))
|
(match_operand:SI 1 "int5_operand" "L")))
|
(match_operand:HI 2 "reg_or_0_operand" "rM"))
|
(match_operand:HI 2 "reg_or_0_operand" "rM"))
|
(set (match_dup 0)
|
(set (match_dup 0)
|
(plus:SI (match_dup 0) (match_dup 1)))]
|
(plus:SI (match_dup 0) (match_dup 1)))]
|
""
|
""
|
"{sths|sth},mb %r2,%1(%0)"
|
"{sths|sth},mb %r2,%1(%0)"
|
[(set_attr "type" "store")
|
[(set_attr "type" "store")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (mem:HI (plus:DI (match_operand:DI 0 "register_operand" "+r")
|
[(set (mem:HI (plus:DI (match_operand:DI 0 "register_operand" "+r")
|
(match_operand:DI 1 "int5_operand" "L")))
|
(match_operand:DI 1 "int5_operand" "L")))
|
(match_operand:HI 2 "reg_or_0_operand" "rM"))
|
(match_operand:HI 2 "reg_or_0_operand" "rM"))
|
(set (match_dup 0)
|
(set (match_dup 0)
|
(plus:DI (match_dup 0) (match_dup 1)))]
|
(plus:DI (match_dup 0) (match_dup 1)))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"sth,mb %r2,%1(%0)"
|
"sth,mb %r2,%1(%0)"
|
[(set_attr "type" "store")
|
[(set_attr "type" "store")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
(plus:HI (match_operand:HI 1 "register_operand" "r")
|
(plus:HI (match_operand:HI 1 "register_operand" "r")
|
(match_operand 2 "const_int_operand" "J")))]
|
(match_operand 2 "const_int_operand" "J")))]
|
""
|
""
|
"ldo %2(%1),%0"
|
"ldo %2(%1),%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "pa_combine_type" "addmove")
|
(set_attr "pa_combine_type" "addmove")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_expand "movqi"
|
(define_expand "movqi"
|
[(set (match_operand:QI 0 "general_operand" "")
|
[(set (match_operand:QI 0 "general_operand" "")
|
(match_operand:QI 1 "general_operand" ""))]
|
(match_operand:QI 1 "general_operand" ""))]
|
""
|
""
|
"
|
"
|
{
|
{
|
if (emit_move_sequence (operands, QImode, 0))
|
if (emit_move_sequence (operands, QImode, 0))
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
;; Handle QImode input reloads requiring a general register as a
|
;; Handle QImode input reloads requiring a general register as a
|
;; scratch register.
|
;; scratch register.
|
(define_expand "reload_inqi"
|
(define_expand "reload_inqi"
|
[(set (match_operand:QI 0 "register_operand" "=Z")
|
[(set (match_operand:QI 0 "register_operand" "=Z")
|
(match_operand:QI 1 "non_hard_reg_operand" ""))
|
(match_operand:QI 1 "non_hard_reg_operand" ""))
|
(clobber (match_operand:QI 2 "register_operand" "=&r"))]
|
(clobber (match_operand:QI 2 "register_operand" "=&r"))]
|
""
|
""
|
"
|
"
|
{
|
{
|
if (emit_move_sequence (operands, QImode, operands[2]))
|
if (emit_move_sequence (operands, QImode, operands[2]))
|
DONE;
|
DONE;
|
|
|
/* We don't want the clobber emitted, so handle this ourselves. */
|
/* We don't want the clobber emitted, so handle this ourselves. */
|
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
|
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
;; Handle QImode output reloads requiring a general register as a
|
;; Handle QImode output reloads requiring a general register as a
|
;; scratch register.
|
;; scratch register.
|
(define_expand "reload_outqi"
|
(define_expand "reload_outqi"
|
[(set (match_operand:QI 0 "non_hard_reg_operand" "")
|
[(set (match_operand:QI 0 "non_hard_reg_operand" "")
|
(match_operand:QI 1 "register_operand" "Z"))
|
(match_operand:QI 1 "register_operand" "Z"))
|
(clobber (match_operand:QI 2 "register_operand" "=&r"))]
|
(clobber (match_operand:QI 2 "register_operand" "=&r"))]
|
""
|
""
|
"
|
"
|
{
|
{
|
if (emit_move_sequence (operands, QImode, operands[2]))
|
if (emit_move_sequence (operands, QImode, operands[2]))
|
DONE;
|
DONE;
|
|
|
/* We don't want the clobber emitted, so handle this ourselves. */
|
/* We don't want the clobber emitted, so handle this ourselves. */
|
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
|
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:QI 0 "move_dest_operand"
|
[(set (match_operand:QI 0 "move_dest_operand"
|
"=r,r,r,r,r,Q,!*q,!r")
|
"=r,r,r,r,r,Q,!*q,!r")
|
(match_operand:QI 1 "move_src_operand"
|
(match_operand:QI 1 "move_src_operand"
|
"r,J,N,K,RQ,rM,!rM,!*q"))]
|
"r,J,N,K,RQ,rM,!rM,!*q"))]
|
"(register_operand (operands[0], QImode)
|
"(register_operand (operands[0], QImode)
|
|| reg_or_0_operand (operands[1], QImode))"
|
|| reg_or_0_operand (operands[1], QImode))"
|
"@
|
"@
|
copy %1,%0
|
copy %1,%0
|
ldi %1,%0
|
ldi %1,%0
|
ldil L'%1,%0
|
ldil L'%1,%0
|
{zdepi|depwi,z} %Z1,%0
|
{zdepi|depwi,z} %Z1,%0
|
ldb%M1 %1,%0
|
ldb%M1 %1,%0
|
stb%M0 %r1,%0
|
stb%M0 %r1,%0
|
mtsar %r1
|
mtsar %r1
|
{mfctl|mfctl,w} %%sar,%0"
|
{mfctl|mfctl,w} %%sar,%0"
|
[(set_attr "type" "move,move,move,shift,load,store,move,move")
|
[(set_attr "type" "move,move,move,shift,load,store,move,move")
|
(set_attr "pa_combine_type" "addmove")
|
(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")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:QI 0 "register_operand" "=r")
|
[(set (match_operand:QI 0 "register_operand" "=r")
|
(mem:QI (plus:SI (match_operand:SI 1 "register_operand" "+r")
|
(mem:QI (plus:SI (match_operand:SI 1 "register_operand" "+r")
|
(match_operand:SI 2 "int5_operand" "L"))))
|
(match_operand:SI 2 "int5_operand" "L"))))
|
(set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
|
(set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
|
""
|
""
|
"{ldbs|ldb},mb %2(%1),%0"
|
"{ldbs|ldb},mb %2(%1),%0"
|
[(set_attr "type" "load")
|
[(set_attr "type" "load")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:QI 0 "register_operand" "=r")
|
[(set (match_operand:QI 0 "register_operand" "=r")
|
(mem:QI (plus:DI (match_operand:DI 1 "register_operand" "+r")
|
(mem:QI (plus:DI (match_operand:DI 1 "register_operand" "+r")
|
(match_operand:DI 2 "int5_operand" "L"))))
|
(match_operand:DI 2 "int5_operand" "L"))))
|
(set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
|
(set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"ldb,mb %2(%1),%0"
|
"ldb,mb %2(%1),%0"
|
[(set_attr "type" "load")
|
[(set_attr "type" "load")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
; Now the same thing with zero extensions.
|
; Now the same thing with zero extensions.
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(zero_extend:DI (mem:QI (plus:DI
|
(zero_extend:DI (mem:QI (plus:DI
|
(match_operand:DI 1 "register_operand" "+r")
|
(match_operand:DI 1 "register_operand" "+r")
|
(match_operand:DI 2 "int5_operand" "L")))))
|
(match_operand:DI 2 "int5_operand" "L")))))
|
(set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
|
(set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"ldb,mb %2(%1),%0"
|
"ldb,mb %2(%1),%0"
|
[(set_attr "type" "load")
|
[(set_attr "type" "load")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(zero_extend:SI (mem:QI (plus:SI
|
(zero_extend:SI (mem:QI (plus:SI
|
(match_operand:SI 1 "register_operand" "+r")
|
(match_operand:SI 1 "register_operand" "+r")
|
(match_operand:SI 2 "int5_operand" "L")))))
|
(match_operand:SI 2 "int5_operand" "L")))))
|
(set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
|
(set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
|
""
|
""
|
"{ldbs|ldb},mb %2(%1),%0"
|
"{ldbs|ldb},mb %2(%1),%0"
|
[(set_attr "type" "load")
|
[(set_attr "type" "load")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(zero_extend:SI (mem:QI (plus:DI
|
(zero_extend:SI (mem:QI (plus:DI
|
(match_operand:DI 1 "register_operand" "+r")
|
(match_operand:DI 1 "register_operand" "+r")
|
(match_operand:DI 2 "int5_operand" "L")))))
|
(match_operand:DI 2 "int5_operand" "L")))))
|
(set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
|
(set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"ldb,mb %2(%1),%0"
|
"ldb,mb %2(%1),%0"
|
[(set_attr "type" "load")
|
[(set_attr "type" "load")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
(zero_extend:HI (mem:QI (plus:SI
|
(zero_extend:HI (mem:QI (plus:SI
|
(match_operand:SI 1 "register_operand" "+r")
|
(match_operand:SI 1 "register_operand" "+r")
|
(match_operand:SI 2 "int5_operand" "L")))))
|
(match_operand:SI 2 "int5_operand" "L")))))
|
(set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
|
(set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
|
""
|
""
|
"{ldbs|ldb},mb %2(%1),%0"
|
"{ldbs|ldb},mb %2(%1),%0"
|
[(set_attr "type" "load")
|
[(set_attr "type" "load")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
(zero_extend:HI (mem:QI (plus:DI
|
(zero_extend:HI (mem:QI (plus:DI
|
(match_operand:DI 1 "register_operand" "+r")
|
(match_operand:DI 1 "register_operand" "+r")
|
(match_operand:DI 2 "int5_operand" "L")))))
|
(match_operand:DI 2 "int5_operand" "L")))))
|
(set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
|
(set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"ldb,mb %2(%1),%0"
|
"ldb,mb %2(%1),%0"
|
[(set_attr "type" "load")
|
[(set_attr "type" "load")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "+r")
|
[(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "+r")
|
(match_operand:SI 1 "int5_operand" "L")))
|
(match_operand:SI 1 "int5_operand" "L")))
|
(match_operand:QI 2 "reg_or_0_operand" "rM"))
|
(match_operand:QI 2 "reg_or_0_operand" "rM"))
|
(set (match_dup 0)
|
(set (match_dup 0)
|
(plus:SI (match_dup 0) (match_dup 1)))]
|
(plus:SI (match_dup 0) (match_dup 1)))]
|
""
|
""
|
"{stbs|stb},mb %r2,%1(%0)"
|
"{stbs|stb},mb %r2,%1(%0)"
|
[(set_attr "type" "store")
|
[(set_attr "type" "store")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (mem:QI (plus:DI (match_operand:DI 0 "register_operand" "+r")
|
[(set (mem:QI (plus:DI (match_operand:DI 0 "register_operand" "+r")
|
(match_operand:DI 1 "int5_operand" "L")))
|
(match_operand:DI 1 "int5_operand" "L")))
|
(match_operand:QI 2 "reg_or_0_operand" "rM"))
|
(match_operand:QI 2 "reg_or_0_operand" "rM"))
|
(set (match_dup 0)
|
(set (match_dup 0)
|
(plus:DI (match_dup 0) (match_dup 1)))]
|
(plus:DI (match_dup 0) (match_dup 1)))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"stb,mb %r2,%1(%0)"
|
"stb,mb %r2,%1(%0)"
|
[(set_attr "type" "store")
|
[(set_attr "type" "store")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
;; The definition of this insn does not really explain what it does,
|
;; The definition of this insn does not really explain what it does,
|
;; but it should suffice that anything generated as this insn will be
|
;; but it should suffice that anything generated as this insn will be
|
;; recognized as a movmemsi operation, and that it will not successfully
|
;; recognized as a movmemsi operation, and that it will not successfully
|
;; combine with anything.
|
;; combine with anything.
|
(define_expand "movmemsi"
|
(define_expand "movmemsi"
|
[(parallel [(set (match_operand:BLK 0 "" "")
|
[(parallel [(set (match_operand:BLK 0 "" "")
|
(match_operand:BLK 1 "" ""))
|
(match_operand:BLK 1 "" ""))
|
(clobber (match_dup 4))
|
(clobber (match_dup 4))
|
(clobber (match_dup 5))
|
(clobber (match_dup 5))
|
(clobber (match_dup 6))
|
(clobber (match_dup 6))
|
(clobber (match_dup 7))
|
(clobber (match_dup 7))
|
(clobber (match_dup 8))
|
(clobber (match_dup 8))
|
(use (match_operand:SI 2 "arith_operand" ""))
|
(use (match_operand:SI 2 "arith_operand" ""))
|
(use (match_operand:SI 3 "const_int_operand" ""))])]
|
(use (match_operand:SI 3 "const_int_operand" ""))])]
|
"!TARGET_64BIT && optimize > 0"
|
"!TARGET_64BIT && optimize > 0"
|
"
|
"
|
{
|
{
|
int size, align;
|
int size, align;
|
|
|
/* HP provides very fast block move library routine for the PA;
|
/* HP provides very fast block move library routine for the PA;
|
this routine includes:
|
this routine includes:
|
|
|
4x4 byte at a time block moves,
|
4x4 byte at a time block moves,
|
1x4 byte at a time with alignment checked at runtime with
|
1x4 byte at a time with alignment checked at runtime with
|
attempts to align the source and destination as needed
|
attempts to align the source and destination as needed
|
1x1 byte loop
|
1x1 byte loop
|
|
|
With that in mind, here's the heuristics to try and guess when
|
With that in mind, here's the heuristics to try and guess when
|
the inlined block move will be better than the library block
|
the inlined block move will be better than the library block
|
move:
|
move:
|
|
|
If the size isn't constant, then always use the library routines.
|
If the size isn't constant, then always use the library routines.
|
|
|
If the size is large in respect to the known alignment, then use
|
If the size is large in respect to the known alignment, then use
|
the library routines.
|
the library routines.
|
|
|
If the size is small in respect to the known alignment, then open
|
If the size is small in respect to the known alignment, then open
|
code the copy (since that will lead to better scheduling).
|
code the copy (since that will lead to better scheduling).
|
|
|
Else use the block move pattern. */
|
Else use the block move pattern. */
|
|
|
/* Undetermined size, use the library routine. */
|
/* Undetermined size, use the library routine. */
|
if (GET_CODE (operands[2]) != CONST_INT)
|
if (GET_CODE (operands[2]) != CONST_INT)
|
FAIL;
|
FAIL;
|
|
|
size = INTVAL (operands[2]);
|
size = INTVAL (operands[2]);
|
align = INTVAL (operands[3]);
|
align = INTVAL (operands[3]);
|
align = align > 4 ? 4 : (align ? align : 1);
|
align = align > 4 ? 4 : (align ? align : 1);
|
|
|
/* If size/alignment is large, then use the library routines. */
|
/* If size/alignment is large, then use the library routines. */
|
if (size / align > 16)
|
if (size / align > 16)
|
FAIL;
|
FAIL;
|
|
|
/* This does happen, but not often enough to worry much about. */
|
/* This does happen, but not often enough to worry much about. */
|
if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
|
if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
|
FAIL;
|
FAIL;
|
|
|
/* Fall through means we're going to use our block move pattern. */
|
/* Fall through means we're going to use our block move pattern. */
|
operands[0]
|
operands[0]
|
= replace_equiv_address (operands[0],
|
= replace_equiv_address (operands[0],
|
copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
|
copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
|
operands[1]
|
operands[1]
|
= replace_equiv_address (operands[1],
|
= replace_equiv_address (operands[1],
|
copy_to_mode_reg (SImode, XEXP (operands[1], 0)));
|
copy_to_mode_reg (SImode, XEXP (operands[1], 0)));
|
operands[4] = gen_reg_rtx (SImode);
|
operands[4] = gen_reg_rtx (SImode);
|
operands[5] = gen_reg_rtx (SImode);
|
operands[5] = gen_reg_rtx (SImode);
|
operands[6] = gen_reg_rtx (SImode);
|
operands[6] = gen_reg_rtx (SImode);
|
operands[7] = gen_reg_rtx (SImode);
|
operands[7] = gen_reg_rtx (SImode);
|
operands[8] = gen_reg_rtx (SImode);
|
operands[8] = gen_reg_rtx (SImode);
|
}")
|
}")
|
|
|
;; The operand constraints are written like this to support both compile-time
|
;; The operand constraints are written like this to support both compile-time
|
;; and run-time determined byte counts. The expander and output_block_move
|
;; and run-time determined byte counts. The expander and output_block_move
|
;; only support compile-time determined counts at this time.
|
;; only support compile-time determined counts at this time.
|
;;
|
;;
|
;; If the count is run-time determined, the register with the byte count
|
;; If the count is run-time determined, the register with the byte count
|
;; is clobbered by the copying code, and therefore it is forced to operand 2.
|
;; is clobbered by the copying code, and therefore it is forced to operand 2.
|
;;
|
;;
|
;; We used to clobber operands 0 and 1. However, a change to regrename.c
|
;; We used to clobber operands 0 and 1. However, a change to regrename.c
|
;; broke this semantic for pseudo registers. We can't use match_scratch
|
;; broke this semantic for pseudo registers. We can't use match_scratch
|
;; as this requires two registers in the class R1_REGS when the MEMs for
|
;; as this requires two registers in the class R1_REGS when the MEMs for
|
;; operands 0 and 1 are both equivalent to symbolic MEMs. Thus, we are
|
;; 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,
|
;; forced to internally copy operands 0 and 1 to operands 7 and 8,
|
;; respectively. We then split or peephole optimize after reload.
|
;; respectively. We then split or peephole optimize after reload.
|
(define_insn "movmemsi_prereload"
|
(define_insn "movmemsi_prereload"
|
[(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r"))
|
[(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r"))
|
(mem:BLK (match_operand:SI 1 "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 3 "register_operand" "=&r,&r")) ;item tmp1
|
(clobber (match_operand:SI 6 "register_operand" "=&r,&r")) ;item tmp2
|
(clobber (match_operand:SI 6 "register_operand" "=&r,&r")) ;item tmp2
|
(clobber (match_operand:SI 7 "register_operand" "=&r,&r")) ;item tmp3
|
(clobber (match_operand:SI 7 "register_operand" "=&r,&r")) ;item tmp3
|
(clobber (match_operand:SI 8 "register_operand" "=&r,&r")) ;item tmp4
|
(clobber (match_operand:SI 8 "register_operand" "=&r,&r")) ;item tmp4
|
(use (match_operand:SI 4 "arith_operand" "J,2")) ;byte count
|
(use (match_operand:SI 4 "arith_operand" "J,2")) ;byte count
|
(use (match_operand:SI 5 "const_int_operand" "n,n"))] ;alignment
|
(use (match_operand:SI 5 "const_int_operand" "n,n"))] ;alignment
|
"!TARGET_64BIT"
|
"!TARGET_64BIT"
|
"#"
|
"#"
|
[(set_attr "type" "multi,multi")])
|
[(set_attr "type" "multi,multi")])
|
|
|
(define_split
|
(define_split
|
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
|
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
|
(match_operand:BLK 1 "memory_operand" ""))
|
(match_operand:BLK 1 "memory_operand" ""))
|
(clobber (match_operand:SI 2 "register_operand" ""))
|
(clobber (match_operand:SI 2 "register_operand" ""))
|
(clobber (match_operand:SI 3 "register_operand" ""))
|
(clobber (match_operand:SI 3 "register_operand" ""))
|
(clobber (match_operand:SI 6 "register_operand" ""))
|
(clobber (match_operand:SI 6 "register_operand" ""))
|
(clobber (match_operand:SI 7 "register_operand" ""))
|
(clobber (match_operand:SI 7 "register_operand" ""))
|
(clobber (match_operand:SI 8 "register_operand" ""))
|
(clobber (match_operand:SI 8 "register_operand" ""))
|
(use (match_operand:SI 4 "arith_operand" ""))
|
(use (match_operand:SI 4 "arith_operand" ""))
|
(use (match_operand:SI 5 "const_int_operand" ""))])]
|
(use (match_operand:SI 5 "const_int_operand" ""))])]
|
"!TARGET_64BIT && reload_completed && !flag_peephole2
|
"!TARGET_64BIT && reload_completed && !flag_peephole2
|
&& GET_CODE (operands[0]) == MEM
|
&& GET_CODE (operands[0]) == MEM
|
&& register_operand (XEXP (operands[0], 0), SImode)
|
&& register_operand (XEXP (operands[0], 0), SImode)
|
&& GET_CODE (operands[1]) == MEM
|
&& GET_CODE (operands[1]) == MEM
|
&& register_operand (XEXP (operands[1], 0), SImode)"
|
&& register_operand (XEXP (operands[1], 0), SImode)"
|
[(set (match_dup 7) (match_dup 9))
|
[(set (match_dup 7) (match_dup 9))
|
(set (match_dup 8) (match_dup 10))
|
(set (match_dup 8) (match_dup 10))
|
(parallel [(set (match_dup 0) (match_dup 1))
|
(parallel [(set (match_dup 0) (match_dup 1))
|
(clobber (match_dup 2))
|
(clobber (match_dup 2))
|
(clobber (match_dup 3))
|
(clobber (match_dup 3))
|
(clobber (match_dup 6))
|
(clobber (match_dup 6))
|
(clobber (match_dup 7))
|
(clobber (match_dup 7))
|
(clobber (match_dup 8))
|
(clobber (match_dup 8))
|
(use (match_dup 4))
|
(use (match_dup 4))
|
(use (match_dup 5))
|
(use (match_dup 5))
|
(const_int 0)])]
|
(const_int 0)])]
|
"
|
"
|
{
|
{
|
operands[9] = XEXP (operands[0], 0);
|
operands[9] = XEXP (operands[0], 0);
|
operands[10] = XEXP (operands[1], 0);
|
operands[10] = XEXP (operands[1], 0);
|
operands[0] = replace_equiv_address (operands[0], operands[7]);
|
operands[0] = replace_equiv_address (operands[0], operands[7]);
|
operands[1] = replace_equiv_address (operands[1], operands[8]);
|
operands[1] = replace_equiv_address (operands[1], operands[8]);
|
}")
|
}")
|
|
|
(define_peephole2
|
(define_peephole2
|
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
|
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
|
(match_operand:BLK 1 "memory_operand" ""))
|
(match_operand:BLK 1 "memory_operand" ""))
|
(clobber (match_operand:SI 2 "register_operand" ""))
|
(clobber (match_operand:SI 2 "register_operand" ""))
|
(clobber (match_operand:SI 3 "register_operand" ""))
|
(clobber (match_operand:SI 3 "register_operand" ""))
|
(clobber (match_operand:SI 6 "register_operand" ""))
|
(clobber (match_operand:SI 6 "register_operand" ""))
|
(clobber (match_operand:SI 7 "register_operand" ""))
|
(clobber (match_operand:SI 7 "register_operand" ""))
|
(clobber (match_operand:SI 8 "register_operand" ""))
|
(clobber (match_operand:SI 8 "register_operand" ""))
|
(use (match_operand:SI 4 "arith_operand" ""))
|
(use (match_operand:SI 4 "arith_operand" ""))
|
(use (match_operand:SI 5 "const_int_operand" ""))])]
|
(use (match_operand:SI 5 "const_int_operand" ""))])]
|
"!TARGET_64BIT
|
"!TARGET_64BIT
|
&& GET_CODE (operands[0]) == MEM
|
&& GET_CODE (operands[0]) == MEM
|
&& register_operand (XEXP (operands[0], 0), SImode)
|
&& register_operand (XEXP (operands[0], 0), SImode)
|
&& GET_CODE (operands[1]) == MEM
|
&& GET_CODE (operands[1]) == MEM
|
&& register_operand (XEXP (operands[1], 0), SImode)"
|
&& register_operand (XEXP (operands[1], 0), SImode)"
|
[(parallel [(set (match_dup 0) (match_dup 1))
|
[(parallel [(set (match_dup 0) (match_dup 1))
|
(clobber (match_dup 2))
|
(clobber (match_dup 2))
|
(clobber (match_dup 3))
|
(clobber (match_dup 3))
|
(clobber (match_dup 6))
|
(clobber (match_dup 6))
|
(clobber (match_dup 7))
|
(clobber (match_dup 7))
|
(clobber (match_dup 8))
|
(clobber (match_dup 8))
|
(use (match_dup 4))
|
(use (match_dup 4))
|
(use (match_dup 5))
|
(use (match_dup 5))
|
(const_int 0)])]
|
(const_int 0)])]
|
"
|
"
|
{
|
{
|
rtx addr = XEXP (operands[0], 0);
|
rtx addr = XEXP (operands[0], 0);
|
if (dead_or_set_p (curr_insn, addr))
|
if (dead_or_set_p (curr_insn, addr))
|
operands[7] = addr;
|
operands[7] = addr;
|
else
|
else
|
{
|
{
|
emit_insn (gen_rtx_SET (VOIDmode, operands[7], addr));
|
emit_insn (gen_rtx_SET (VOIDmode, operands[7], addr));
|
operands[0] = replace_equiv_address (operands[0], operands[7]);
|
operands[0] = replace_equiv_address (operands[0], operands[7]);
|
}
|
}
|
|
|
addr = XEXP (operands[1], 0);
|
addr = XEXP (operands[1], 0);
|
if (dead_or_set_p (curr_insn, addr))
|
if (dead_or_set_p (curr_insn, addr))
|
operands[8] = addr;
|
operands[8] = addr;
|
else
|
else
|
{
|
{
|
emit_insn (gen_rtx_SET (VOIDmode, operands[8], addr));
|
emit_insn (gen_rtx_SET (VOIDmode, operands[8], addr));
|
operands[1] = replace_equiv_address (operands[1], operands[8]);
|
operands[1] = replace_equiv_address (operands[1], operands[8]);
|
}
|
}
|
}")
|
}")
|
|
|
(define_insn "movmemsi_postreload"
|
(define_insn "movmemsi_postreload"
|
[(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
|
[(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
|
(mem:BLK (match_operand:SI 1 "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 3 "register_operand" "=&r,&r")) ;item tmp1
|
(clobber (match_operand:SI 6 "register_operand" "=&r,&r")) ;item tmp2
|
(clobber (match_operand:SI 6 "register_operand" "=&r,&r")) ;item tmp2
|
(clobber (match_dup 0))
|
(clobber (match_dup 0))
|
(clobber (match_dup 1))
|
(clobber (match_dup 1))
|
(use (match_operand:SI 4 "arith_operand" "J,2")) ;byte count
|
(use (match_operand:SI 4 "arith_operand" "J,2")) ;byte count
|
(use (match_operand:SI 5 "const_int_operand" "n,n")) ;alignment
|
(use (match_operand:SI 5 "const_int_operand" "n,n")) ;alignment
|
(const_int 0)]
|
(const_int 0)]
|
"!TARGET_64BIT && reload_completed"
|
"!TARGET_64BIT && reload_completed"
|
"* return output_block_move (operands, !which_alternative);"
|
"* return output_block_move (operands, !which_alternative);"
|
[(set_attr "type" "multi,multi")])
|
[(set_attr "type" "multi,multi")])
|
|
|
(define_expand "movmemdi"
|
(define_expand "movmemdi"
|
[(parallel [(set (match_operand:BLK 0 "" "")
|
[(parallel [(set (match_operand:BLK 0 "" "")
|
(match_operand:BLK 1 "" ""))
|
(match_operand:BLK 1 "" ""))
|
(clobber (match_dup 4))
|
(clobber (match_dup 4))
|
(clobber (match_dup 5))
|
(clobber (match_dup 5))
|
(clobber (match_dup 6))
|
(clobber (match_dup 6))
|
(clobber (match_dup 7))
|
(clobber (match_dup 7))
|
(clobber (match_dup 8))
|
(clobber (match_dup 8))
|
(use (match_operand:DI 2 "arith_operand" ""))
|
(use (match_operand:DI 2 "arith_operand" ""))
|
(use (match_operand:DI 3 "const_int_operand" ""))])]
|
(use (match_operand:DI 3 "const_int_operand" ""))])]
|
"TARGET_64BIT && optimize > 0"
|
"TARGET_64BIT && optimize > 0"
|
"
|
"
|
{
|
{
|
int size, align;
|
int size, align;
|
|
|
/* HP provides very fast block move library routine for the PA;
|
/* HP provides very fast block move library routine for the PA;
|
this routine includes:
|
this routine includes:
|
|
|
4x4 byte at a time block moves,
|
4x4 byte at a time block moves,
|
1x4 byte at a time with alignment checked at runtime with
|
1x4 byte at a time with alignment checked at runtime with
|
attempts to align the source and destination as needed
|
attempts to align the source and destination as needed
|
1x1 byte loop
|
1x1 byte loop
|
|
|
With that in mind, here's the heuristics to try and guess when
|
With that in mind, here's the heuristics to try and guess when
|
the inlined block move will be better than the library block
|
the inlined block move will be better than the library block
|
move:
|
move:
|
|
|
If the size isn't constant, then always use the library routines.
|
If the size isn't constant, then always use the library routines.
|
|
|
If the size is large in respect to the known alignment, then use
|
If the size is large in respect to the known alignment, then use
|
the library routines.
|
the library routines.
|
|
|
If the size is small in respect to the known alignment, then open
|
If the size is small in respect to the known alignment, then open
|
code the copy (since that will lead to better scheduling).
|
code the copy (since that will lead to better scheduling).
|
|
|
Else use the block move pattern. */
|
Else use the block move pattern. */
|
|
|
/* Undetermined size, use the library routine. */
|
/* Undetermined size, use the library routine. */
|
if (GET_CODE (operands[2]) != CONST_INT)
|
if (GET_CODE (operands[2]) != CONST_INT)
|
FAIL;
|
FAIL;
|
|
|
size = INTVAL (operands[2]);
|
size = INTVAL (operands[2]);
|
align = INTVAL (operands[3]);
|
align = INTVAL (operands[3]);
|
align = align > 8 ? 8 : (align ? align : 1);
|
align = align > 8 ? 8 : (align ? align : 1);
|
|
|
/* If size/alignment is large, then use the library routines. */
|
/* If size/alignment is large, then use the library routines. */
|
if (size / align > 16)
|
if (size / align > 16)
|
FAIL;
|
FAIL;
|
|
|
/* This does happen, but not often enough to worry much about. */
|
/* This does happen, but not often enough to worry much about. */
|
if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
|
if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
|
FAIL;
|
FAIL;
|
|
|
/* Fall through means we're going to use our block move pattern. */
|
/* Fall through means we're going to use our block move pattern. */
|
operands[0]
|
operands[0]
|
= replace_equiv_address (operands[0],
|
= replace_equiv_address (operands[0],
|
copy_to_mode_reg (DImode, XEXP (operands[0], 0)));
|
copy_to_mode_reg (DImode, XEXP (operands[0], 0)));
|
operands[1]
|
operands[1]
|
= replace_equiv_address (operands[1],
|
= replace_equiv_address (operands[1],
|
copy_to_mode_reg (DImode, XEXP (operands[1], 0)));
|
copy_to_mode_reg (DImode, XEXP (operands[1], 0)));
|
operands[4] = gen_reg_rtx (DImode);
|
operands[4] = gen_reg_rtx (DImode);
|
operands[5] = gen_reg_rtx (DImode);
|
operands[5] = gen_reg_rtx (DImode);
|
operands[6] = gen_reg_rtx (DImode);
|
operands[6] = gen_reg_rtx (DImode);
|
operands[7] = gen_reg_rtx (DImode);
|
operands[7] = gen_reg_rtx (DImode);
|
operands[8] = gen_reg_rtx (DImode);
|
operands[8] = gen_reg_rtx (DImode);
|
}")
|
}")
|
|
|
;; The operand constraints are written like this to support both compile-time
|
;; The operand constraints are written like this to support both compile-time
|
;; and run-time determined byte counts. The expander and output_block_move
|
;; and run-time determined byte counts. The expander and output_block_move
|
;; only support compile-time determined counts at this time.
|
;; only support compile-time determined counts at this time.
|
;;
|
;;
|
;; If the count is run-time determined, the register with the byte count
|
;; If the count is run-time determined, the register with the byte count
|
;; is clobbered by the copying code, and therefore it is forced to operand 2.
|
;; is clobbered by the copying code, and therefore it is forced to operand 2.
|
;;
|
;;
|
;; We used to clobber operands 0 and 1. However, a change to regrename.c
|
;; We used to clobber operands 0 and 1. However, a change to regrename.c
|
;; broke this semantic for pseudo registers. We can't use match_scratch
|
;; broke this semantic for pseudo registers. We can't use match_scratch
|
;; as this requires two registers in the class R1_REGS when the MEMs for
|
;; as this requires two registers in the class R1_REGS when the MEMs for
|
;; operands 0 and 1 are both equivalent to symbolic MEMs. Thus, we are
|
;; 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,
|
;; forced to internally copy operands 0 and 1 to operands 7 and 8,
|
;; respectively. We then split or peephole optimize after reload.
|
;; respectively. We then split or peephole optimize after reload.
|
(define_insn "movmemdi_prereload"
|
(define_insn "movmemdi_prereload"
|
[(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r"))
|
[(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r"))
|
(mem:BLK (match_operand:DI 1 "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 3 "register_operand" "=&r,&r")) ;item tmp1
|
(clobber (match_operand:DI 6 "register_operand" "=&r,&r")) ;item tmp2
|
(clobber (match_operand:DI 6 "register_operand" "=&r,&r")) ;item tmp2
|
(clobber (match_operand:DI 7 "register_operand" "=&r,&r")) ;item tmp3
|
(clobber (match_operand:DI 7 "register_operand" "=&r,&r")) ;item tmp3
|
(clobber (match_operand:DI 8 "register_operand" "=&r,&r")) ;item tmp4
|
(clobber (match_operand:DI 8 "register_operand" "=&r,&r")) ;item tmp4
|
(use (match_operand:DI 4 "arith_operand" "J,2")) ;byte count
|
(use (match_operand:DI 4 "arith_operand" "J,2")) ;byte count
|
(use (match_operand:DI 5 "const_int_operand" "n,n"))] ;alignment
|
(use (match_operand:DI 5 "const_int_operand" "n,n"))] ;alignment
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"#"
|
"#"
|
[(set_attr "type" "multi,multi")])
|
[(set_attr "type" "multi,multi")])
|
|
|
(define_split
|
(define_split
|
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
|
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
|
(match_operand:BLK 1 "memory_operand" ""))
|
(match_operand:BLK 1 "memory_operand" ""))
|
(clobber (match_operand:DI 2 "register_operand" ""))
|
(clobber (match_operand:DI 2 "register_operand" ""))
|
(clobber (match_operand:DI 3 "register_operand" ""))
|
(clobber (match_operand:DI 3 "register_operand" ""))
|
(clobber (match_operand:DI 6 "register_operand" ""))
|
(clobber (match_operand:DI 6 "register_operand" ""))
|
(clobber (match_operand:DI 7 "register_operand" ""))
|
(clobber (match_operand:DI 7 "register_operand" ""))
|
(clobber (match_operand:DI 8 "register_operand" ""))
|
(clobber (match_operand:DI 8 "register_operand" ""))
|
(use (match_operand:DI 4 "arith_operand" ""))
|
(use (match_operand:DI 4 "arith_operand" ""))
|
(use (match_operand:DI 5 "const_int_operand" ""))])]
|
(use (match_operand:DI 5 "const_int_operand" ""))])]
|
"TARGET_64BIT && reload_completed && !flag_peephole2
|
"TARGET_64BIT && reload_completed && !flag_peephole2
|
&& GET_CODE (operands[0]) == MEM
|
&& GET_CODE (operands[0]) == MEM
|
&& register_operand (XEXP (operands[0], 0), DImode)
|
&& register_operand (XEXP (operands[0], 0), DImode)
|
&& GET_CODE (operands[1]) == MEM
|
&& GET_CODE (operands[1]) == MEM
|
&& register_operand (XEXP (operands[1], 0), DImode)"
|
&& register_operand (XEXP (operands[1], 0), DImode)"
|
[(set (match_dup 7) (match_dup 9))
|
[(set (match_dup 7) (match_dup 9))
|
(set (match_dup 8) (match_dup 10))
|
(set (match_dup 8) (match_dup 10))
|
(parallel [(set (match_dup 0) (match_dup 1))
|
(parallel [(set (match_dup 0) (match_dup 1))
|
(clobber (match_dup 2))
|
(clobber (match_dup 2))
|
(clobber (match_dup 3))
|
(clobber (match_dup 3))
|
(clobber (match_dup 6))
|
(clobber (match_dup 6))
|
(clobber (match_dup 7))
|
(clobber (match_dup 7))
|
(clobber (match_dup 8))
|
(clobber (match_dup 8))
|
(use (match_dup 4))
|
(use (match_dup 4))
|
(use (match_dup 5))
|
(use (match_dup 5))
|
(const_int 0)])]
|
(const_int 0)])]
|
"
|
"
|
{
|
{
|
operands[9] = XEXP (operands[0], 0);
|
operands[9] = XEXP (operands[0], 0);
|
operands[10] = XEXP (operands[1], 0);
|
operands[10] = XEXP (operands[1], 0);
|
operands[0] = replace_equiv_address (operands[0], operands[7]);
|
operands[0] = replace_equiv_address (operands[0], operands[7]);
|
operands[1] = replace_equiv_address (operands[1], operands[8]);
|
operands[1] = replace_equiv_address (operands[1], operands[8]);
|
}")
|
}")
|
|
|
(define_peephole2
|
(define_peephole2
|
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
|
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
|
(match_operand:BLK 1 "memory_operand" ""))
|
(match_operand:BLK 1 "memory_operand" ""))
|
(clobber (match_operand:DI 2 "register_operand" ""))
|
(clobber (match_operand:DI 2 "register_operand" ""))
|
(clobber (match_operand:DI 3 "register_operand" ""))
|
(clobber (match_operand:DI 3 "register_operand" ""))
|
(clobber (match_operand:DI 6 "register_operand" ""))
|
(clobber (match_operand:DI 6 "register_operand" ""))
|
(clobber (match_operand:DI 7 "register_operand" ""))
|
(clobber (match_operand:DI 7 "register_operand" ""))
|
(clobber (match_operand:DI 8 "register_operand" ""))
|
(clobber (match_operand:DI 8 "register_operand" ""))
|
(use (match_operand:DI 4 "arith_operand" ""))
|
(use (match_operand:DI 4 "arith_operand" ""))
|
(use (match_operand:DI 5 "const_int_operand" ""))])]
|
(use (match_operand:DI 5 "const_int_operand" ""))])]
|
"TARGET_64BIT
|
"TARGET_64BIT
|
&& GET_CODE (operands[0]) == MEM
|
&& GET_CODE (operands[0]) == MEM
|
&& register_operand (XEXP (operands[0], 0), DImode)
|
&& register_operand (XEXP (operands[0], 0), DImode)
|
&& GET_CODE (operands[1]) == MEM
|
&& GET_CODE (operands[1]) == MEM
|
&& register_operand (XEXP (operands[1], 0), DImode)"
|
&& register_operand (XEXP (operands[1], 0), DImode)"
|
[(parallel [(set (match_dup 0) (match_dup 1))
|
[(parallel [(set (match_dup 0) (match_dup 1))
|
(clobber (match_dup 2))
|
(clobber (match_dup 2))
|
(clobber (match_dup 3))
|
(clobber (match_dup 3))
|
(clobber (match_dup 6))
|
(clobber (match_dup 6))
|
(clobber (match_dup 7))
|
(clobber (match_dup 7))
|
(clobber (match_dup 8))
|
(clobber (match_dup 8))
|
(use (match_dup 4))
|
(use (match_dup 4))
|
(use (match_dup 5))
|
(use (match_dup 5))
|
(const_int 0)])]
|
(const_int 0)])]
|
"
|
"
|
{
|
{
|
rtx addr = XEXP (operands[0], 0);
|
rtx addr = XEXP (operands[0], 0);
|
if (dead_or_set_p (curr_insn, addr))
|
if (dead_or_set_p (curr_insn, addr))
|
operands[7] = addr;
|
operands[7] = addr;
|
else
|
else
|
{
|
{
|
emit_insn (gen_rtx_SET (VOIDmode, operands[7], addr));
|
emit_insn (gen_rtx_SET (VOIDmode, operands[7], addr));
|
operands[0] = replace_equiv_address (operands[0], operands[7]);
|
operands[0] = replace_equiv_address (operands[0], operands[7]);
|
}
|
}
|
|
|
addr = XEXP (operands[1], 0);
|
addr = XEXP (operands[1], 0);
|
if (dead_or_set_p (curr_insn, addr))
|
if (dead_or_set_p (curr_insn, addr))
|
operands[8] = addr;
|
operands[8] = addr;
|
else
|
else
|
{
|
{
|
emit_insn (gen_rtx_SET (VOIDmode, operands[8], addr));
|
emit_insn (gen_rtx_SET (VOIDmode, operands[8], addr));
|
operands[1] = replace_equiv_address (operands[1], operands[8]);
|
operands[1] = replace_equiv_address (operands[1], operands[8]);
|
}
|
}
|
}")
|
}")
|
|
|
(define_insn "movmemdi_postreload"
|
(define_insn "movmemdi_postreload"
|
[(set (mem:BLK (match_operand:DI 0 "register_operand" "+r,r"))
|
[(set (mem:BLK (match_operand:DI 0 "register_operand" "+r,r"))
|
(mem:BLK (match_operand:DI 1 "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 3 "register_operand" "=&r,&r")) ;item tmp1
|
(clobber (match_operand:DI 6 "register_operand" "=&r,&r")) ;item tmp2
|
(clobber (match_operand:DI 6 "register_operand" "=&r,&r")) ;item tmp2
|
(clobber (match_dup 0))
|
(clobber (match_dup 0))
|
(clobber (match_dup 1))
|
(clobber (match_dup 1))
|
(use (match_operand:DI 4 "arith_operand" "J,2")) ;byte count
|
(use (match_operand:DI 4 "arith_operand" "J,2")) ;byte count
|
(use (match_operand:DI 5 "const_int_operand" "n,n")) ;alignment
|
(use (match_operand:DI 5 "const_int_operand" "n,n")) ;alignment
|
(const_int 0)]
|
(const_int 0)]
|
"TARGET_64BIT && reload_completed"
|
"TARGET_64BIT && reload_completed"
|
"* return output_block_move (operands, !which_alternative);"
|
"* return output_block_move (operands, !which_alternative);"
|
[(set_attr "type" "multi,multi")])
|
[(set_attr "type" "multi,multi")])
|
|
|
(define_expand "setmemsi"
|
(define_expand "setmemsi"
|
[(parallel [(set (match_operand:BLK 0 "" "")
|
[(parallel [(set (match_operand:BLK 0 "" "")
|
(match_operand 2 "const_int_operand" ""))
|
(match_operand 2 "const_int_operand" ""))
|
(clobber (match_dup 4))
|
(clobber (match_dup 4))
|
(clobber (match_dup 5))
|
(clobber (match_dup 5))
|
(use (match_operand:SI 1 "arith_operand" ""))
|
(use (match_operand:SI 1 "arith_operand" ""))
|
(use (match_operand:SI 3 "const_int_operand" ""))])]
|
(use (match_operand:SI 3 "const_int_operand" ""))])]
|
"!TARGET_64BIT && optimize > 0"
|
"!TARGET_64BIT && optimize > 0"
|
"
|
"
|
{
|
{
|
int size, align;
|
int size, align;
|
|
|
/* If value to set is not zero, use the library routine. */
|
/* If value to set is not zero, use the library routine. */
|
if (operands[2] != const0_rtx)
|
if (operands[2] != const0_rtx)
|
FAIL;
|
FAIL;
|
|
|
/* Undetermined size, use the library routine. */
|
/* Undetermined size, use the library routine. */
|
if (GET_CODE (operands[1]) != CONST_INT)
|
if (GET_CODE (operands[1]) != CONST_INT)
|
FAIL;
|
FAIL;
|
|
|
size = INTVAL (operands[1]);
|
size = INTVAL (operands[1]);
|
align = INTVAL (operands[3]);
|
align = INTVAL (operands[3]);
|
align = align > 4 ? 4 : align;
|
align = align > 4 ? 4 : align;
|
|
|
/* If size/alignment is large, then use the library routines. */
|
/* If size/alignment is large, then use the library routines. */
|
if (size / align > 16)
|
if (size / align > 16)
|
FAIL;
|
FAIL;
|
|
|
/* This does happen, but not often enough to worry much about. */
|
/* This does happen, but not often enough to worry much about. */
|
if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
|
if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
|
FAIL;
|
FAIL;
|
|
|
/* Fall through means we're going to use our block clear pattern. */
|
/* Fall through means we're going to use our block clear pattern. */
|
operands[0]
|
operands[0]
|
= replace_equiv_address (operands[0],
|
= replace_equiv_address (operands[0],
|
copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
|
copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
|
operands[4] = gen_reg_rtx (SImode);
|
operands[4] = gen_reg_rtx (SImode);
|
operands[5] = gen_reg_rtx (SImode);
|
operands[5] = gen_reg_rtx (SImode);
|
}")
|
}")
|
|
|
(define_insn "clrmemsi_prereload"
|
(define_insn "clrmemsi_prereload"
|
[(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r"))
|
[(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r"))
|
(const_int 0))
|
(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
|
(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 2 "arith_operand" "J,1")) ;byte count
|
(use (match_operand:SI 3 "const_int_operand" "n,n"))] ;alignment
|
(use (match_operand:SI 3 "const_int_operand" "n,n"))] ;alignment
|
"!TARGET_64BIT"
|
"!TARGET_64BIT"
|
"#"
|
"#"
|
[(set_attr "type" "multi,multi")])
|
[(set_attr "type" "multi,multi")])
|
|
|
(define_split
|
(define_split
|
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
|
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
|
(const_int 0))
|
(const_int 0))
|
(clobber (match_operand:SI 1 "register_operand" ""))
|
(clobber (match_operand:SI 1 "register_operand" ""))
|
(clobber (match_operand:SI 4 "register_operand" ""))
|
(clobber (match_operand:SI 4 "register_operand" ""))
|
(use (match_operand:SI 2 "arith_operand" ""))
|
(use (match_operand:SI 2 "arith_operand" ""))
|
(use (match_operand:SI 3 "const_int_operand" ""))])]
|
(use (match_operand:SI 3 "const_int_operand" ""))])]
|
"!TARGET_64BIT && reload_completed && !flag_peephole2
|
"!TARGET_64BIT && reload_completed && !flag_peephole2
|
&& GET_CODE (operands[0]) == MEM
|
&& GET_CODE (operands[0]) == MEM
|
&& register_operand (XEXP (operands[0], 0), SImode)"
|
&& register_operand (XEXP (operands[0], 0), SImode)"
|
[(set (match_dup 4) (match_dup 5))
|
[(set (match_dup 4) (match_dup 5))
|
(parallel [(set (match_dup 0) (const_int 0))
|
(parallel [(set (match_dup 0) (const_int 0))
|
(clobber (match_dup 1))
|
(clobber (match_dup 1))
|
(clobber (match_dup 4))
|
(clobber (match_dup 4))
|
(use (match_dup 2))
|
(use (match_dup 2))
|
(use (match_dup 3))
|
(use (match_dup 3))
|
(const_int 0)])]
|
(const_int 0)])]
|
"
|
"
|
{
|
{
|
operands[5] = XEXP (operands[0], 0);
|
operands[5] = XEXP (operands[0], 0);
|
operands[0] = replace_equiv_address (operands[0], operands[4]);
|
operands[0] = replace_equiv_address (operands[0], operands[4]);
|
}")
|
}")
|
|
|
(define_peephole2
|
(define_peephole2
|
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
|
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
|
(const_int 0))
|
(const_int 0))
|
(clobber (match_operand:SI 1 "register_operand" ""))
|
(clobber (match_operand:SI 1 "register_operand" ""))
|
(clobber (match_operand:SI 4 "register_operand" ""))
|
(clobber (match_operand:SI 4 "register_operand" ""))
|
(use (match_operand:SI 2 "arith_operand" ""))
|
(use (match_operand:SI 2 "arith_operand" ""))
|
(use (match_operand:SI 3 "const_int_operand" ""))])]
|
(use (match_operand:SI 3 "const_int_operand" ""))])]
|
"!TARGET_64BIT
|
"!TARGET_64BIT
|
&& GET_CODE (operands[0]) == MEM
|
&& GET_CODE (operands[0]) == MEM
|
&& register_operand (XEXP (operands[0], 0), SImode)"
|
&& register_operand (XEXP (operands[0], 0), SImode)"
|
[(parallel [(set (match_dup 0) (const_int 0))
|
[(parallel [(set (match_dup 0) (const_int 0))
|
(clobber (match_dup 1))
|
(clobber (match_dup 1))
|
(clobber (match_dup 4))
|
(clobber (match_dup 4))
|
(use (match_dup 2))
|
(use (match_dup 2))
|
(use (match_dup 3))
|
(use (match_dup 3))
|
(const_int 0)])]
|
(const_int 0)])]
|
"
|
"
|
{
|
{
|
rtx addr = XEXP (operands[0], 0);
|
rtx addr = XEXP (operands[0], 0);
|
if (dead_or_set_p (curr_insn, addr))
|
if (dead_or_set_p (curr_insn, addr))
|
operands[4] = addr;
|
operands[4] = addr;
|
else
|
else
|
{
|
{
|
emit_insn (gen_rtx_SET (VOIDmode, operands[4], addr));
|
emit_insn (gen_rtx_SET (VOIDmode, operands[4], addr));
|
operands[0] = replace_equiv_address (operands[0], operands[4]);
|
operands[0] = replace_equiv_address (operands[0], operands[4]);
|
}
|
}
|
}")
|
}")
|
|
|
(define_insn "clrmemsi_postreload"
|
(define_insn "clrmemsi_postreload"
|
[(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
|
[(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
|
(const_int 0))
|
(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))
|
(clobber (match_dup 0))
|
(use (match_operand:SI 2 "arith_operand" "J,1")) ;byte count
|
(use (match_operand:SI 2 "arith_operand" "J,1")) ;byte count
|
(use (match_operand:SI 3 "const_int_operand" "n,n")) ;alignment
|
(use (match_operand:SI 3 "const_int_operand" "n,n")) ;alignment
|
(const_int 0)]
|
(const_int 0)]
|
"!TARGET_64BIT && reload_completed"
|
"!TARGET_64BIT && reload_completed"
|
"* return output_block_clear (operands, !which_alternative);"
|
"* return output_block_clear (operands, !which_alternative);"
|
[(set_attr "type" "multi,multi")])
|
[(set_attr "type" "multi,multi")])
|
|
|
(define_expand "setmemdi"
|
(define_expand "setmemdi"
|
[(parallel [(set (match_operand:BLK 0 "" "")
|
[(parallel [(set (match_operand:BLK 0 "" "")
|
(match_operand 2 "const_int_operand" ""))
|
(match_operand 2 "const_int_operand" ""))
|
(clobber (match_dup 4))
|
(clobber (match_dup 4))
|
(clobber (match_dup 5))
|
(clobber (match_dup 5))
|
(use (match_operand:DI 1 "arith_operand" ""))
|
(use (match_operand:DI 1 "arith_operand" ""))
|
(use (match_operand:DI 3 "const_int_operand" ""))])]
|
(use (match_operand:DI 3 "const_int_operand" ""))])]
|
"TARGET_64BIT && optimize > 0"
|
"TARGET_64BIT && optimize > 0"
|
"
|
"
|
{
|
{
|
int size, align;
|
int size, align;
|
|
|
/* If value to set is not zero, use the library routine. */
|
/* If value to set is not zero, use the library routine. */
|
if (operands[2] != const0_rtx)
|
if (operands[2] != const0_rtx)
|
FAIL;
|
FAIL;
|
|
|
/* Undetermined size, use the library routine. */
|
/* Undetermined size, use the library routine. */
|
if (GET_CODE (operands[1]) != CONST_INT)
|
if (GET_CODE (operands[1]) != CONST_INT)
|
FAIL;
|
FAIL;
|
|
|
size = INTVAL (operands[1]);
|
size = INTVAL (operands[1]);
|
align = INTVAL (operands[3]);
|
align = INTVAL (operands[3]);
|
align = align > 8 ? 8 : align;
|
align = align > 8 ? 8 : align;
|
|
|
/* If size/alignment is large, then use the library routines. */
|
/* If size/alignment is large, then use the library routines. */
|
if (size / align > 16)
|
if (size / align > 16)
|
FAIL;
|
FAIL;
|
|
|
/* This does happen, but not often enough to worry much about. */
|
/* This does happen, but not often enough to worry much about. */
|
if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
|
if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
|
FAIL;
|
FAIL;
|
|
|
/* Fall through means we're going to use our block clear pattern. */
|
/* Fall through means we're going to use our block clear pattern. */
|
operands[0]
|
operands[0]
|
= replace_equiv_address (operands[0],
|
= replace_equiv_address (operands[0],
|
copy_to_mode_reg (DImode, XEXP (operands[0], 0)));
|
copy_to_mode_reg (DImode, XEXP (operands[0], 0)));
|
operands[4] = gen_reg_rtx (DImode);
|
operands[4] = gen_reg_rtx (DImode);
|
operands[5] = gen_reg_rtx (DImode);
|
operands[5] = gen_reg_rtx (DImode);
|
}")
|
}")
|
|
|
(define_insn "clrmemdi_prereload"
|
(define_insn "clrmemdi_prereload"
|
[(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r"))
|
[(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r"))
|
(const_int 0))
|
(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
|
(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 2 "arith_operand" "J,1")) ;byte count
|
(use (match_operand:DI 3 "const_int_operand" "n,n"))] ;alignment
|
(use (match_operand:DI 3 "const_int_operand" "n,n"))] ;alignment
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"#"
|
"#"
|
[(set_attr "type" "multi,multi")])
|
[(set_attr "type" "multi,multi")])
|
|
|
(define_split
|
(define_split
|
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
|
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
|
(const_int 0))
|
(const_int 0))
|
(clobber (match_operand:DI 1 "register_operand" ""))
|
(clobber (match_operand:DI 1 "register_operand" ""))
|
(clobber (match_operand:DI 4 "register_operand" ""))
|
(clobber (match_operand:DI 4 "register_operand" ""))
|
(use (match_operand:DI 2 "arith_operand" ""))
|
(use (match_operand:DI 2 "arith_operand" ""))
|
(use (match_operand:DI 3 "const_int_operand" ""))])]
|
(use (match_operand:DI 3 "const_int_operand" ""))])]
|
"TARGET_64BIT && reload_completed && !flag_peephole2
|
"TARGET_64BIT && reload_completed && !flag_peephole2
|
&& GET_CODE (operands[0]) == MEM
|
&& GET_CODE (operands[0]) == MEM
|
&& register_operand (XEXP (operands[0], 0), DImode)"
|
&& register_operand (XEXP (operands[0], 0), DImode)"
|
[(set (match_dup 4) (match_dup 5))
|
[(set (match_dup 4) (match_dup 5))
|
(parallel [(set (match_dup 0) (const_int 0))
|
(parallel [(set (match_dup 0) (const_int 0))
|
(clobber (match_dup 1))
|
(clobber (match_dup 1))
|
(clobber (match_dup 4))
|
(clobber (match_dup 4))
|
(use (match_dup 2))
|
(use (match_dup 2))
|
(use (match_dup 3))
|
(use (match_dup 3))
|
(const_int 0)])]
|
(const_int 0)])]
|
"
|
"
|
{
|
{
|
operands[5] = XEXP (operands[0], 0);
|
operands[5] = XEXP (operands[0], 0);
|
operands[0] = replace_equiv_address (operands[0], operands[4]);
|
operands[0] = replace_equiv_address (operands[0], operands[4]);
|
}")
|
}")
|
|
|
(define_peephole2
|
(define_peephole2
|
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
|
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
|
(const_int 0))
|
(const_int 0))
|
(clobber (match_operand:DI 1 "register_operand" ""))
|
(clobber (match_operand:DI 1 "register_operand" ""))
|
(clobber (match_operand:DI 4 "register_operand" ""))
|
(clobber (match_operand:DI 4 "register_operand" ""))
|
(use (match_operand:DI 2 "arith_operand" ""))
|
(use (match_operand:DI 2 "arith_operand" ""))
|
(use (match_operand:DI 3 "const_int_operand" ""))])]
|
(use (match_operand:DI 3 "const_int_operand" ""))])]
|
"TARGET_64BIT
|
"TARGET_64BIT
|
&& GET_CODE (operands[0]) == MEM
|
&& GET_CODE (operands[0]) == MEM
|
&& register_operand (XEXP (operands[0], 0), DImode)"
|
&& register_operand (XEXP (operands[0], 0), DImode)"
|
[(parallel [(set (match_dup 0) (const_int 0))
|
[(parallel [(set (match_dup 0) (const_int 0))
|
(clobber (match_dup 1))
|
(clobber (match_dup 1))
|
(clobber (match_dup 4))
|
(clobber (match_dup 4))
|
(use (match_dup 2))
|
(use (match_dup 2))
|
(use (match_dup 3))
|
(use (match_dup 3))
|
(const_int 0)])]
|
(const_int 0)])]
|
"
|
"
|
{
|
{
|
rtx addr = XEXP (operands[0], 0);
|
rtx addr = XEXP (operands[0], 0);
|
if (dead_or_set_p (curr_insn, addr))
|
if (dead_or_set_p (curr_insn, addr))
|
operands[4] = addr;
|
operands[4] = addr;
|
else
|
else
|
{
|
{
|
emit_insn (gen_rtx_SET (VOIDmode, operands[4], addr));
|
emit_insn (gen_rtx_SET (VOIDmode, operands[4], addr));
|
operands[0] = replace_equiv_address (operands[0], operands[4]);
|
operands[0] = replace_equiv_address (operands[0], operands[4]);
|
}
|
}
|
}")
|
}")
|
|
|
(define_insn "clrmemdi_postreload"
|
(define_insn "clrmemdi_postreload"
|
[(set (mem:BLK (match_operand:DI 0 "register_operand" "+r,r"))
|
[(set (mem:BLK (match_operand:DI 0 "register_operand" "+r,r"))
|
(const_int 0))
|
(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))
|
(clobber (match_dup 0))
|
(use (match_operand:DI 2 "arith_operand" "J,1")) ;byte count
|
(use (match_operand:DI 2 "arith_operand" "J,1")) ;byte count
|
(use (match_operand:DI 3 "const_int_operand" "n,n")) ;alignment
|
(use (match_operand:DI 3 "const_int_operand" "n,n")) ;alignment
|
(const_int 0)]
|
(const_int 0)]
|
"TARGET_64BIT && reload_completed"
|
"TARGET_64BIT && reload_completed"
|
"* return output_block_clear (operands, !which_alternative);"
|
"* return output_block_clear (operands, !which_alternative);"
|
[(set_attr "type" "multi,multi")])
|
[(set_attr "type" "multi,multi")])
|
|
|
;; Floating point move insns
|
;; Floating point move insns
|
|
|
;; This pattern forces (set (reg:DF ...) (const_double ...))
|
;; This pattern forces (set (reg:DF ...) (const_double ...))
|
;; to be reloaded by putting the constant into memory when
|
;; to be reloaded by putting the constant into memory when
|
;; reg is a floating point register.
|
;; reg is a floating point register.
|
;;
|
;;
|
;; For integer registers we use ldil;ldo to set the appropriate
|
;; For integer registers we use ldil;ldo to set the appropriate
|
;; value.
|
;; value.
|
;;
|
;;
|
;; This must come before the movdf pattern, and it must be present
|
;; This must come before the movdf pattern, and it must be present
|
;; to handle obscure reloading cases.
|
;; to handle obscure reloading cases.
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DF 0 "register_operand" "=?r,f")
|
[(set (match_operand:DF 0 "register_operand" "=?r,f")
|
(match_operand:DF 1 "" "?F,m"))]
|
(match_operand:DF 1 "" "?F,m"))]
|
"GET_CODE (operands[1]) == CONST_DOUBLE
|
"GET_CODE (operands[1]) == CONST_DOUBLE
|
&& operands[1] != CONST0_RTX (DFmode)
|
&& operands[1] != CONST0_RTX (DFmode)
|
&& !TARGET_64BIT
|
&& !TARGET_64BIT
|
&& !TARGET_SOFT_FLOAT"
|
&& !TARGET_SOFT_FLOAT"
|
"* return (which_alternative == 0 ? output_move_double (operands)
|
"* return (which_alternative == 0 ? output_move_double (operands)
|
: \"fldd%F1 %1,%0\");"
|
: \"fldd%F1 %1,%0\");"
|
[(set_attr "type" "move,fpload")
|
[(set_attr "type" "move,fpload")
|
(set_attr "length" "16,4")])
|
(set_attr "length" "16,4")])
|
|
|
(define_expand "movdf"
|
(define_expand "movdf"
|
[(set (match_operand:DF 0 "general_operand" "")
|
[(set (match_operand:DF 0 "general_operand" "")
|
(match_operand:DF 1 "general_operand" ""))]
|
(match_operand:DF 1 "general_operand" ""))]
|
""
|
""
|
"
|
"
|
{
|
{
|
if (GET_CODE (operands[1]) == CONST_DOUBLE
|
if (GET_CODE (operands[1]) == CONST_DOUBLE
|
&& operands[1] != CONST0_RTX (DFmode))
|
&& operands[1] != CONST0_RTX (DFmode))
|
{
|
{
|
/* Reject CONST_DOUBLE loads to all hard registers when
|
/* Reject CONST_DOUBLE loads to all hard registers when
|
generating 64-bit code and to floating point registers
|
generating 64-bit code and to floating point registers
|
when generating 32-bit code. */
|
when generating 32-bit code. */
|
if (REG_P (operands[0])
|
if (REG_P (operands[0])
|
&& HARD_REGISTER_P (operands[0])
|
&& HARD_REGISTER_P (operands[0])
|
&& (TARGET_64BIT || REGNO (operands[0]) >= 32))
|
&& (TARGET_64BIT || REGNO (operands[0]) >= 32))
|
FAIL;
|
FAIL;
|
|
|
if (TARGET_64BIT)
|
if (TARGET_64BIT)
|
operands[1] = force_const_mem (DFmode, operands[1]);
|
operands[1] = force_const_mem (DFmode, operands[1]);
|
}
|
}
|
|
|
if (emit_move_sequence (operands, DFmode, 0))
|
if (emit_move_sequence (operands, DFmode, 0))
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
;; Handle DFmode input reloads requiring a general register as a
|
;; Handle DFmode input reloads requiring a general register as a
|
;; scratch register.
|
;; scratch register.
|
(define_expand "reload_indf"
|
(define_expand "reload_indf"
|
[(set (match_operand:DF 0 "register_operand" "=Z")
|
[(set (match_operand:DF 0 "register_operand" "=Z")
|
(match_operand:DF 1 "non_hard_reg_operand" ""))
|
(match_operand:DF 1 "non_hard_reg_operand" ""))
|
(clobber (match_operand:DF 2 "register_operand" "=&r"))]
|
(clobber (match_operand:DF 2 "register_operand" "=&r"))]
|
""
|
""
|
"
|
"
|
{
|
{
|
if (emit_move_sequence (operands, DFmode, operands[2]))
|
if (emit_move_sequence (operands, DFmode, operands[2]))
|
DONE;
|
DONE;
|
|
|
/* We don't want the clobber emitted, so handle this ourselves. */
|
/* We don't want the clobber emitted, so handle this ourselves. */
|
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
|
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
;; Handle DFmode output reloads requiring a general register as a
|
;; Handle DFmode output reloads requiring a general register as a
|
;; scratch register.
|
;; scratch register.
|
(define_expand "reload_outdf"
|
(define_expand "reload_outdf"
|
[(set (match_operand:DF 0 "non_hard_reg_operand" "")
|
[(set (match_operand:DF 0 "non_hard_reg_operand" "")
|
(match_operand:DF 1 "register_operand" "Z"))
|
(match_operand:DF 1 "register_operand" "Z"))
|
(clobber (match_operand:DF 2 "register_operand" "=&r"))]
|
(clobber (match_operand:DF 2 "register_operand" "=&r"))]
|
""
|
""
|
"
|
"
|
{
|
{
|
if (emit_move_sequence (operands, DFmode, operands[2]))
|
if (emit_move_sequence (operands, DFmode, operands[2]))
|
DONE;
|
DONE;
|
|
|
/* We don't want the clobber emitted, so handle this ourselves. */
|
/* We don't want the clobber emitted, so handle this ourselves. */
|
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
|
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DF 0 "move_dest_operand"
|
[(set (match_operand:DF 0 "move_dest_operand"
|
"=f,*r,Q,?o,?Q,f,*r,*r,?*r,?f")
|
"=f,*r,Q,?o,?Q,f,*r,*r,?*r,?f")
|
(match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
|
(match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
|
"fG,*rG,f,*r,*r,RQ,o,RQ,f,*r"))]
|
"fG,*rG,f,*r,*r,RQ,o,RQ,f,*r"))]
|
"(register_operand (operands[0], DFmode)
|
"(register_operand (operands[0], DFmode)
|
|| reg_or_0_operand (operands[1], DFmode))
|
|| reg_or_0_operand (operands[1], DFmode))
|
&& !(GET_CODE (operands[1]) == CONST_DOUBLE
|
&& !(GET_CODE (operands[1]) == CONST_DOUBLE
|
&& GET_CODE (operands[0]) == MEM)
|
&& GET_CODE (operands[0]) == MEM)
|
&& !TARGET_64BIT
|
&& !TARGET_64BIT
|
&& !TARGET_SOFT_FLOAT"
|
&& !TARGET_SOFT_FLOAT"
|
"*
|
"*
|
{
|
{
|
if ((FP_REG_P (operands[0]) || FP_REG_P (operands[1])
|
if ((FP_REG_P (operands[0]) || FP_REG_P (operands[1])
|
|| operands[1] == CONST0_RTX (DFmode))
|
|| operands[1] == CONST0_RTX (DFmode))
|
&& !(REG_P (operands[0]) && REG_P (operands[1])
|
&& !(REG_P (operands[0]) && REG_P (operands[1])
|
&& FP_REG_P (operands[0]) ^ FP_REG_P (operands[1])))
|
&& FP_REG_P (operands[0]) ^ FP_REG_P (operands[1])))
|
return output_fp_move_double (operands);
|
return output_fp_move_double (operands);
|
return output_move_double (operands);
|
return output_move_double (operands);
|
}"
|
}"
|
[(set_attr "type" "fpalu,move,fpstore,store,store,fpload,load,load,fpstore_load,store_fpload")
|
[(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")])
|
(set_attr "length" "4,8,4,8,16,4,8,16,12,12")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DF 0 "indexed_memory_operand" "=R")
|
[(set (match_operand:DF 0 "indexed_memory_operand" "=R")
|
(match_operand:DF 1 "reg_or_0_operand" "f"))]
|
(match_operand:DF 1 "reg_or_0_operand" "f"))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& reload_completed"
|
&& reload_completed"
|
"fstd%F0 %1,%0"
|
"fstd%F0 %1,%0"
|
[(set_attr "type" "fpstore")
|
[(set_attr "type" "fpstore")
|
(set_attr "pa_combine_type" "addmove")
|
(set_attr "pa_combine_type" "addmove")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_peephole2
|
(define_peephole2
|
[(set (match_operand:SI 0 "register_operand" "")
|
[(set (match_operand:SI 0 "register_operand" "")
|
(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
|
(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
|
(const_int 8))
|
(const_int 8))
|
(match_operand:SI 2 "register_operand" "")))
|
(match_operand:SI 2 "register_operand" "")))
|
(set (mem:DF (match_dup 0))
|
(set (mem:DF (match_dup 0))
|
(match_operand:DF 3 "register_operand" ""))]
|
(match_operand:DF 3 "register_operand" ""))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
&& 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 (plus:SI (mult:SI (match_dup 1) (const_int 8)) (match_dup 2)))
|
(match_dup 3))
|
(match_dup 3))
|
(set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 8))
|
(set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 8))
|
(match_dup 2)))]
|
(match_dup 2)))]
|
"")
|
"")
|
|
|
(define_peephole2
|
(define_peephole2
|
[(set (match_operand:SI 0 "register_operand" "")
|
[(set (match_operand:SI 0 "register_operand" "")
|
(plus:SI (match_operand:SI 2 "register_operand" "")
|
(plus:SI (match_operand:SI 2 "register_operand" "")
|
(mult:SI (match_operand:SI 1 "register_operand" "")
|
(mult:SI (match_operand:SI 1 "register_operand" "")
|
(const_int 8))))
|
(const_int 8))))
|
(set (mem:DF (match_dup 0))
|
(set (mem:DF (match_dup 0))
|
(match_operand:DF 3 "register_operand" ""))]
|
(match_operand:DF 3 "register_operand" ""))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
&& 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 (plus:SI (mult:SI (match_dup 1) (const_int 8)) (match_dup 2)))
|
(match_dup 3))
|
(match_dup 3))
|
(set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 8))
|
(set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 8))
|
(match_dup 2)))]
|
(match_dup 2)))]
|
"")
|
"")
|
|
|
(define_peephole2
|
(define_peephole2
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
|
(plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
|
(const_int 8))
|
(const_int 8))
|
(match_operand:DI 2 "register_operand" "")))
|
(match_operand:DI 2 "register_operand" "")))
|
(set (mem:DF (match_dup 0))
|
(set (mem:DF (match_dup 0))
|
(match_operand:DF 3 "register_operand" ""))]
|
(match_operand:DF 3 "register_operand" ""))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& TARGET_64BIT
|
&& TARGET_64BIT
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
[(set (mem:DF (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
|
[(set (mem:DF (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
|
(match_dup 3))
|
(match_dup 3))
|
(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8))
|
(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8))
|
(match_dup 2)))]
|
(match_dup 2)))]
|
"")
|
"")
|
|
|
(define_peephole2
|
(define_peephole2
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(plus:DI (match_operand:DI 2 "register_operand" "")
|
(plus:DI (match_operand:DI 2 "register_operand" "")
|
(mult:DI (match_operand:DI 1 "register_operand" "")
|
(mult:DI (match_operand:DI 1 "register_operand" "")
|
(const_int 8))))
|
(const_int 8))))
|
(set (mem:DF (match_dup 0))
|
(set (mem:DF (match_dup 0))
|
(match_operand:DF 3 "register_operand" ""))]
|
(match_operand:DF 3 "register_operand" ""))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& TARGET_64BIT
|
&& TARGET_64BIT
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
[(set (mem:DF (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
|
[(set (mem:DF (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
|
(match_dup 3))
|
(match_dup 3))
|
(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8))
|
(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8))
|
(match_dup 2)))]
|
(match_dup 2)))]
|
"")
|
"")
|
|
|
(define_peephole2
|
(define_peephole2
|
[(set (match_operand:SI 0 "register_operand" "")
|
[(set (match_operand:SI 0 "register_operand" "")
|
(plus:SI (match_operand:SI 1 "register_operand" "")
|
(plus:SI (match_operand:SI 1 "register_operand" "")
|
(match_operand:SI 2 "register_operand" "")))
|
(match_operand:SI 2 "register_operand" "")))
|
(set (mem:DF (match_dup 0))
|
(set (mem:DF (match_dup 0))
|
(match_operand:DF 3 "register_operand" ""))]
|
(match_operand:DF 3 "register_operand" ""))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& TARGET_NO_SPACE_REGS
|
&& TARGET_NO_SPACE_REGS
|
&& REG_OK_FOR_INDEX_P (operands[1])
|
&& REG_OK_FOR_INDEX_P (operands[1])
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
[(set (mem:DF (plus:SI (match_dup 1) (match_dup 2)))
|
[(set (mem:DF (plus:SI (match_dup 1) (match_dup 2)))
|
(match_dup 3))
|
(match_dup 3))
|
(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
|
(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
|
"")
|
"")
|
|
|
(define_peephole2
|
(define_peephole2
|
[(set (match_operand:SI 0 "register_operand" "")
|
[(set (match_operand:SI 0 "register_operand" "")
|
(plus:SI (match_operand:SI 1 "register_operand" "")
|
(plus:SI (match_operand:SI 1 "register_operand" "")
|
(match_operand:SI 2 "register_operand" "")))
|
(match_operand:SI 2 "register_operand" "")))
|
(set (mem:DF (match_dup 0))
|
(set (mem:DF (match_dup 0))
|
(match_operand:DF 3 "register_operand" ""))]
|
(match_operand:DF 3 "register_operand" ""))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& TARGET_NO_SPACE_REGS
|
&& TARGET_NO_SPACE_REGS
|
&& REG_OK_FOR_BASE_P (operands[1])
|
&& REG_OK_FOR_BASE_P (operands[1])
|
&& REG_OK_FOR_INDEX_P (operands[2])
|
&& REG_OK_FOR_INDEX_P (operands[2])
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
[(set (mem:DF (plus:SI (match_dup 2) (match_dup 1)))
|
[(set (mem:DF (plus:SI (match_dup 2) (match_dup 1)))
|
(match_dup 3))
|
(match_dup 3))
|
(set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
|
(set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
|
"")
|
"")
|
|
|
(define_peephole2
|
(define_peephole2
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(plus:DI (match_operand:DI 1 "register_operand" "")
|
(plus:DI (match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 2 "register_operand" "")))
|
(match_operand:DI 2 "register_operand" "")))
|
(set (mem:DF (match_dup 0))
|
(set (mem:DF (match_dup 0))
|
(match_operand:DF 3 "register_operand" ""))]
|
(match_operand:DF 3 "register_operand" ""))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& TARGET_64BIT
|
&& TARGET_64BIT
|
&& TARGET_NO_SPACE_REGS
|
&& TARGET_NO_SPACE_REGS
|
&& REG_OK_FOR_INDEX_P (operands[1])
|
&& REG_OK_FOR_INDEX_P (operands[1])
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
[(set (mem:DF (plus:DI (match_dup 1) (match_dup 2)))
|
[(set (mem:DF (plus:DI (match_dup 1) (match_dup 2)))
|
(match_dup 3))
|
(match_dup 3))
|
(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
|
(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
|
"")
|
"")
|
|
|
(define_peephole2
|
(define_peephole2
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(plus:DI (match_operand:DI 1 "register_operand" "")
|
(plus:DI (match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 2 "register_operand" "")))
|
(match_operand:DI 2 "register_operand" "")))
|
(set (mem:DF (match_dup 0))
|
(set (mem:DF (match_dup 0))
|
(match_operand:DF 3 "register_operand" ""))]
|
(match_operand:DF 3 "register_operand" ""))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& TARGET_64BIT
|
&& TARGET_64BIT
|
&& TARGET_NO_SPACE_REGS
|
&& TARGET_NO_SPACE_REGS
|
&& REG_OK_FOR_BASE_P (operands[1])
|
&& REG_OK_FOR_BASE_P (operands[1])
|
&& REG_OK_FOR_INDEX_P (operands[2])
|
&& REG_OK_FOR_INDEX_P (operands[2])
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
[(set (mem:DF (plus:DI (match_dup 2) (match_dup 1)))
|
[(set (mem:DF (plus:DI (match_dup 2) (match_dup 1)))
|
(match_dup 3))
|
(match_dup 3))
|
(set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
|
(set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
|
"")
|
"")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DF 0 "move_dest_operand"
|
[(set (match_operand:DF 0 "move_dest_operand"
|
"=r,?o,?Q,r,r")
|
"=r,?o,?Q,r,r")
|
(match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
|
(match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
|
"rG,r,r,o,RQ"))]
|
"rG,r,r,o,RQ"))]
|
"(register_operand (operands[0], DFmode)
|
"(register_operand (operands[0], DFmode)
|
|| reg_or_0_operand (operands[1], DFmode))
|
|| reg_or_0_operand (operands[1], DFmode))
|
&& !TARGET_64BIT
|
&& !TARGET_64BIT
|
&& TARGET_SOFT_FLOAT"
|
&& TARGET_SOFT_FLOAT"
|
"*
|
"*
|
{
|
{
|
return output_move_double (operands);
|
return output_move_double (operands);
|
}"
|
}"
|
[(set_attr "type" "move,store,store,load,load")
|
[(set_attr "type" "move,store,store,load,load")
|
(set_attr "length" "8,8,16,8,16")])
|
(set_attr "length" "8,8,16,8,16")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DF 0 "move_dest_operand"
|
[(set (match_operand:DF 0 "move_dest_operand"
|
"=!*r,*r,*r,*r,*r,Q,f,f,T")
|
"=!*r,*r,*r,*r,*r,Q,f,f,T")
|
(match_operand:DF 1 "move_src_operand"
|
(match_operand:DF 1 "move_src_operand"
|
"!*r,J,N,K,RQ,*rG,fG,RT,f"))]
|
"!*r,J,N,K,RQ,*rG,fG,RT,f"))]
|
"(register_operand (operands[0], DFmode)
|
"(register_operand (operands[0], DFmode)
|
|| reg_or_0_operand (operands[1], DFmode))
|
|| reg_or_0_operand (operands[1], DFmode))
|
&& !TARGET_SOFT_FLOAT && TARGET_64BIT"
|
&& !TARGET_SOFT_FLOAT && TARGET_64BIT"
|
"@
|
"@
|
copy %1,%0
|
copy %1,%0
|
ldi %1,%0
|
ldi %1,%0
|
ldil L'%1,%0
|
ldil L'%1,%0
|
depdi,z %z1,%0
|
depdi,z %z1,%0
|
ldd%M1 %1,%0
|
ldd%M1 %1,%0
|
std%M0 %r1,%0
|
std%M0 %r1,%0
|
fcpy,dbl %f1,%0
|
fcpy,dbl %f1,%0
|
fldd%F1 %1,%0
|
fldd%F1 %1,%0
|
fstd%F0 %1,%0"
|
fstd%F0 %1,%0"
|
[(set_attr "type" "move,move,move,shift,load,store,fpalu,fpload,fpstore")
|
[(set_attr "type" "move,move,move,shift,load,store,fpalu,fpload,fpstore")
|
(set_attr "pa_combine_type" "addmove")
|
(set_attr "pa_combine_type" "addmove")
|
(set_attr "length" "4,4,4,4,4,4,4,4,4")])
|
(set_attr "length" "4,4,4,4,4,4,4,4,4")])
|
|
|
|
|
(define_expand "movdi"
|
(define_expand "movdi"
|
[(set (match_operand:DI 0 "general_operand" "")
|
[(set (match_operand:DI 0 "general_operand" "")
|
(match_operand:DI 1 "general_operand" ""))]
|
(match_operand:DI 1 "general_operand" ""))]
|
""
|
""
|
"
|
"
|
{
|
{
|
/* Except for zero, we don't support loading a CONST_INT directly
|
/* Except for zero, we don't support loading a CONST_INT directly
|
to a hard floating-point register since a scratch register is
|
to a hard floating-point register since a scratch register is
|
needed for the operation. While the operation could be handled
|
needed for the operation. While the operation could be handled
|
before register allocation, the simplest solution is to fail. */
|
before register allocation, the simplest solution is to fail. */
|
if (TARGET_64BIT
|
if (TARGET_64BIT
|
&& GET_CODE (operands[1]) == CONST_INT
|
&& GET_CODE (operands[1]) == CONST_INT
|
&& operands[1] != CONST0_RTX (DImode)
|
&& operands[1] != CONST0_RTX (DImode)
|
&& REG_P (operands[0])
|
&& REG_P (operands[0])
|
&& HARD_REGISTER_P (operands[0])
|
&& HARD_REGISTER_P (operands[0])
|
&& REGNO (operands[0]) >= 32)
|
&& REGNO (operands[0]) >= 32)
|
FAIL;
|
FAIL;
|
|
|
if (emit_move_sequence (operands, DImode, 0))
|
if (emit_move_sequence (operands, DImode, 0))
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
;; Handle DImode input reloads requiring %r1 as a scratch register.
|
;; Handle DImode input reloads requiring %r1 as a scratch register.
|
(define_expand "reload_indi_r1"
|
(define_expand "reload_indi_r1"
|
[(set (match_operand:DI 0 "register_operand" "=Z")
|
[(set (match_operand:DI 0 "register_operand" "=Z")
|
(match_operand:DI 1 "non_hard_reg_operand" ""))
|
(match_operand:DI 1 "non_hard_reg_operand" ""))
|
(clobber (match_operand:SI 2 "register_operand" "=&a"))]
|
(clobber (match_operand:SI 2 "register_operand" "=&a"))]
|
""
|
""
|
"
|
"
|
{
|
{
|
if (emit_move_sequence (operands, DImode, operands[2]))
|
if (emit_move_sequence (operands, DImode, operands[2]))
|
DONE;
|
DONE;
|
|
|
/* We don't want the clobber emitted, so handle this ourselves. */
|
/* We don't want the clobber emitted, so handle this ourselves. */
|
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
|
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
;; Handle DImode input reloads requiring a general register as a
|
;; Handle DImode input reloads requiring a general register as a
|
;; scratch register.
|
;; scratch register.
|
(define_expand "reload_indi"
|
(define_expand "reload_indi"
|
[(set (match_operand:DI 0 "register_operand" "=Z")
|
[(set (match_operand:DI 0 "register_operand" "=Z")
|
(match_operand:DI 1 "non_hard_reg_operand" ""))
|
(match_operand:DI 1 "non_hard_reg_operand" ""))
|
(clobber (match_operand:SI 2 "register_operand" "=&r"))]
|
(clobber (match_operand:SI 2 "register_operand" "=&r"))]
|
""
|
""
|
"
|
"
|
{
|
{
|
if (emit_move_sequence (operands, DImode, operands[2]))
|
if (emit_move_sequence (operands, DImode, operands[2]))
|
DONE;
|
DONE;
|
|
|
/* We don't want the clobber emitted, so handle this ourselves. */
|
/* We don't want the clobber emitted, so handle this ourselves. */
|
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
|
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
;; Handle DImode output reloads requiring a general register as a
|
;; Handle DImode output reloads requiring a general register as a
|
;; scratch register.
|
;; scratch register.
|
(define_expand "reload_outdi"
|
(define_expand "reload_outdi"
|
[(set (match_operand:DI 0 "non_hard_reg_operand" "")
|
[(set (match_operand:DI 0 "non_hard_reg_operand" "")
|
(match_operand:DI 1 "register_operand" "Z"))
|
(match_operand:DI 1 "register_operand" "Z"))
|
(clobber (match_operand:SI 2 "register_operand" "=&r"))]
|
(clobber (match_operand:SI 2 "register_operand" "=&r"))]
|
""
|
""
|
"
|
"
|
{
|
{
|
if (emit_move_sequence (operands, DImode, operands[2]))
|
if (emit_move_sequence (operands, DImode, operands[2]))
|
DONE;
|
DONE;
|
|
|
/* We don't want the clobber emitted, so handle this ourselves. */
|
/* We don't want the clobber emitted, so handle this ourselves. */
|
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
|
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(high:DI (match_operand 1 "" "")))]
|
(high:DI (match_operand 1 "" "")))]
|
"!TARGET_64BIT"
|
"!TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
rtx op0 = operands[0];
|
rtx op0 = operands[0];
|
rtx op1 = operands[1];
|
rtx op1 = operands[1];
|
|
|
switch (GET_CODE (op1))
|
switch (GET_CODE (op1))
|
{
|
{
|
case CONST_INT:
|
case CONST_INT:
|
#if HOST_BITS_PER_WIDE_INT <= 32
|
#if HOST_BITS_PER_WIDE_INT <= 32
|
operands[0] = operand_subword (op0, 1, 0, DImode);
|
operands[0] = operand_subword (op0, 1, 0, DImode);
|
output_asm_insn (\"ldil L'%1,%0\", operands);
|
output_asm_insn (\"ldil L'%1,%0\", operands);
|
|
|
operands[0] = operand_subword (op0, 0, 0, DImode);
|
operands[0] = operand_subword (op0, 0, 0, DImode);
|
if (INTVAL (op1) < 0)
|
if (INTVAL (op1) < 0)
|
output_asm_insn (\"ldi -1,%0\", operands);
|
output_asm_insn (\"ldi -1,%0\", operands);
|
else
|
else
|
output_asm_insn (\"ldi 0,%0\", operands);
|
output_asm_insn (\"ldi 0,%0\", operands);
|
#else
|
#else
|
operands[0] = operand_subword (op0, 1, 0, DImode);
|
operands[0] = operand_subword (op0, 1, 0, DImode);
|
operands[1] = GEN_INT (INTVAL (op1) & 0xffffffff);
|
operands[1] = GEN_INT (INTVAL (op1) & 0xffffffff);
|
output_asm_insn (\"ldil L'%1,%0\", operands);
|
output_asm_insn (\"ldil L'%1,%0\", operands);
|
|
|
operands[0] = operand_subword (op0, 0, 0, DImode);
|
operands[0] = operand_subword (op0, 0, 0, DImode);
|
operands[1] = GEN_INT (INTVAL (op1) >> 32);
|
operands[1] = GEN_INT (INTVAL (op1) >> 32);
|
output_asm_insn (singlemove_string (operands), operands);
|
output_asm_insn (singlemove_string (operands), operands);
|
#endif
|
#endif
|
break;
|
break;
|
|
|
case CONST_DOUBLE:
|
case CONST_DOUBLE:
|
operands[0] = operand_subword (op0, 1, 0, DImode);
|
operands[0] = operand_subword (op0, 1, 0, DImode);
|
operands[1] = GEN_INT (CONST_DOUBLE_LOW (op1));
|
operands[1] = GEN_INT (CONST_DOUBLE_LOW (op1));
|
output_asm_insn (\"ldil L'%1,%0\", operands);
|
output_asm_insn (\"ldil L'%1,%0\", operands);
|
|
|
operands[0] = operand_subword (op0, 0, 0, DImode);
|
operands[0] = operand_subword (op0, 0, 0, DImode);
|
operands[1] = GEN_INT (CONST_DOUBLE_HIGH (op1));
|
operands[1] = GEN_INT (CONST_DOUBLE_HIGH (op1));
|
output_asm_insn (singlemove_string (operands), operands);
|
output_asm_insn (singlemove_string (operands), operands);
|
break;
|
break;
|
|
|
default:
|
default:
|
gcc_unreachable ();
|
gcc_unreachable ();
|
}
|
}
|
return \"\";
|
return \"\";
|
}"
|
}"
|
[(set_attr "type" "move")
|
[(set_attr "type" "move")
|
(set_attr "length" "12")])
|
(set_attr "length" "12")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "move_dest_operand"
|
[(set (match_operand:DI 0 "move_dest_operand"
|
"=r,o,Q,r,r,r,*f,*f,T,?r,?*f")
|
"=r,o,Q,r,r,r,*f,*f,T,?r,?*f")
|
(match_operand:DI 1 "general_operand"
|
(match_operand:DI 1 "general_operand"
|
"rM,r,r,o*R,Q,i,*fM,RT,*f,*f,r"))]
|
"rM,r,r,o*R,Q,i,*fM,RT,*f,*f,r"))]
|
"(register_operand (operands[0], DImode)
|
"(register_operand (operands[0], DImode)
|
|| reg_or_0_operand (operands[1], DImode))
|
|| reg_or_0_operand (operands[1], DImode))
|
&& !TARGET_64BIT
|
&& !TARGET_64BIT
|
&& !TARGET_SOFT_FLOAT"
|
&& !TARGET_SOFT_FLOAT"
|
"*
|
"*
|
{
|
{
|
if ((FP_REG_P (operands[0]) || FP_REG_P (operands[1])
|
if ((FP_REG_P (operands[0]) || FP_REG_P (operands[1])
|
|| operands[1] == CONST0_RTX (DFmode))
|
|| operands[1] == CONST0_RTX (DFmode))
|
&& !(REG_P (operands[0]) && REG_P (operands[1])
|
&& !(REG_P (operands[0]) && REG_P (operands[1])
|
&& FP_REG_P (operands[0]) ^ FP_REG_P (operands[1])))
|
&& FP_REG_P (operands[0]) ^ FP_REG_P (operands[1])))
|
return output_fp_move_double (operands);
|
return output_fp_move_double (operands);
|
return output_move_double (operands);
|
return output_move_double (operands);
|
}"
|
}"
|
[(set_attr "type"
|
[(set_attr "type"
|
"move,store,store,load,load,multi,fpalu,fpload,fpstore,fpstore_load,store_fpload")
|
"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")])
|
(set_attr "length" "8,8,16,8,16,16,4,4,4,12,12")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "move_dest_operand"
|
[(set (match_operand:DI 0 "move_dest_operand"
|
"=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T")
|
"=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T")
|
(match_operand:DI 1 "move_src_operand"
|
(match_operand:DI 1 "move_src_operand"
|
"A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f"))]
|
"A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f"))]
|
"(register_operand (operands[0], DImode)
|
"(register_operand (operands[0], DImode)
|
|| reg_or_0_operand (operands[1], DImode))
|
|| reg_or_0_operand (operands[1], DImode))
|
&& !TARGET_SOFT_FLOAT && TARGET_64BIT"
|
&& !TARGET_SOFT_FLOAT && TARGET_64BIT"
|
"@
|
"@
|
ldd RT'%A1,%0
|
ldd RT'%A1,%0
|
copy %1,%0
|
copy %1,%0
|
ldi %1,%0
|
ldi %1,%0
|
ldil L'%1,%0
|
ldil L'%1,%0
|
depdi,z %z1,%0
|
depdi,z %z1,%0
|
ldd%M1 %1,%0
|
ldd%M1 %1,%0
|
std%M0 %r1,%0
|
std%M0 %r1,%0
|
mtsar %r1
|
mtsar %r1
|
{mfctl|mfctl,w} %%sar,%0
|
{mfctl|mfctl,w} %%sar,%0
|
fcpy,dbl %f1,%0
|
fcpy,dbl %f1,%0
|
fldd%F1 %1,%0
|
fldd%F1 %1,%0
|
fstd%F0 %1,%0"
|
fstd%F0 %1,%0"
|
[(set_attr "type" "load,move,move,move,shift,load,store,move,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 "pa_combine_type" "addmove")
|
(set_attr "length" "4,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 ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "indexed_memory_operand" "=R")
|
[(set (match_operand:DI 0 "indexed_memory_operand" "=R")
|
(match_operand:DI 1 "register_operand" "f"))]
|
(match_operand:DI 1 "register_operand" "f"))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& TARGET_64BIT
|
&& TARGET_64BIT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& reload_completed"
|
&& reload_completed"
|
"fstd%F0 %1,%0"
|
"fstd%F0 %1,%0"
|
[(set_attr "type" "fpstore")
|
[(set_attr "type" "fpstore")
|
(set_attr "pa_combine_type" "addmove")
|
(set_attr "pa_combine_type" "addmove")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_peephole2
|
(define_peephole2
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
|
(plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
|
(const_int 8))
|
(const_int 8))
|
(match_operand:DI 2 "register_operand" "")))
|
(match_operand:DI 2 "register_operand" "")))
|
(set (mem:DI (match_dup 0))
|
(set (mem:DI (match_dup 0))
|
(match_operand:DI 3 "register_operand" ""))]
|
(match_operand:DI 3 "register_operand" ""))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& TARGET_64BIT
|
&& TARGET_64BIT
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
[(set (mem:DI (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
|
[(set (mem:DI (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
|
(match_dup 3))
|
(match_dup 3))
|
(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8))
|
(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8))
|
(match_dup 2)))]
|
(match_dup 2)))]
|
"")
|
"")
|
|
|
(define_peephole2
|
(define_peephole2
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(plus:DI (match_operand:DI 2 "register_operand" "")
|
(plus:DI (match_operand:DI 2 "register_operand" "")
|
(mult:DI (match_operand:DI 1 "register_operand" "")
|
(mult:DI (match_operand:DI 1 "register_operand" "")
|
(const_int 8))))
|
(const_int 8))))
|
(set (mem:DI (match_dup 0))
|
(set (mem:DI (match_dup 0))
|
(match_operand:DI 3 "register_operand" ""))]
|
(match_operand:DI 3 "register_operand" ""))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& TARGET_64BIT
|
&& TARGET_64BIT
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
[(set (mem:DI (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
|
[(set (mem:DI (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
|
(match_dup 3))
|
(match_dup 3))
|
(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8))
|
(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8))
|
(match_dup 2)))]
|
(match_dup 2)))]
|
"")
|
"")
|
|
|
(define_peephole2
|
(define_peephole2
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(plus:DI (match_operand:DI 1 "register_operand" "")
|
(plus:DI (match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 2 "register_operand" "")))
|
(match_operand:DI 2 "register_operand" "")))
|
(set (mem:DI (match_dup 0))
|
(set (mem:DI (match_dup 0))
|
(match_operand:DI 3 "register_operand" ""))]
|
(match_operand:DI 3 "register_operand" ""))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& TARGET_64BIT
|
&& TARGET_64BIT
|
&& TARGET_NO_SPACE_REGS
|
&& TARGET_NO_SPACE_REGS
|
&& REG_OK_FOR_INDEX_P (operands[1])
|
&& REG_OK_FOR_INDEX_P (operands[1])
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
[(set (mem:DI (plus:DI (match_dup 1) (match_dup 2)))
|
[(set (mem:DI (plus:DI (match_dup 1) (match_dup 2)))
|
(match_dup 3))
|
(match_dup 3))
|
(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
|
(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
|
"")
|
"")
|
|
|
(define_peephole2
|
(define_peephole2
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(plus:DI (match_operand:DI 1 "register_operand" "")
|
(plus:DI (match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 2 "register_operand" "")))
|
(match_operand:DI 2 "register_operand" "")))
|
(set (mem:DI (match_dup 0))
|
(set (mem:DI (match_dup 0))
|
(match_operand:DI 3 "register_operand" ""))]
|
(match_operand:DI 3 "register_operand" ""))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& TARGET_64BIT
|
&& TARGET_64BIT
|
&& TARGET_NO_SPACE_REGS
|
&& TARGET_NO_SPACE_REGS
|
&& REG_OK_FOR_BASE_P (operands[1])
|
&& REG_OK_FOR_BASE_P (operands[1])
|
&& REG_OK_FOR_INDEX_P (operands[2])
|
&& REG_OK_FOR_INDEX_P (operands[2])
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
[(set (mem:DI (plus:DI (match_dup 2) (match_dup 1)))
|
[(set (mem:DI (plus:DI (match_dup 2) (match_dup 1)))
|
(match_dup 3))
|
(match_dup 3))
|
(set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
|
(set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
|
"")
|
"")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "move_dest_operand"
|
[(set (match_operand:DI 0 "move_dest_operand"
|
"=r,o,Q,r,r,r")
|
"=r,o,Q,r,r,r")
|
(match_operand:DI 1 "general_operand"
|
(match_operand:DI 1 "general_operand"
|
"rM,r,r,o,Q,i"))]
|
"rM,r,r,o,Q,i"))]
|
"(register_operand (operands[0], DImode)
|
"(register_operand (operands[0], DImode)
|
|| reg_or_0_operand (operands[1], DImode))
|
|| reg_or_0_operand (operands[1], DImode))
|
&& !TARGET_64BIT
|
&& !TARGET_64BIT
|
&& TARGET_SOFT_FLOAT"
|
&& TARGET_SOFT_FLOAT"
|
"*
|
"*
|
{
|
{
|
return output_move_double (operands);
|
return output_move_double (operands);
|
}"
|
}"
|
[(set_attr "type" "move,store,store,load,load,multi")
|
[(set_attr "type" "move,store,store,load,load,multi")
|
(set_attr "length" "8,8,16,8,16,16")])
|
(set_attr "length" "8,8,16,8,16,16")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r,&r")
|
[(set (match_operand:DI 0 "register_operand" "=r,&r")
|
(lo_sum:DI (match_operand:DI 1 "register_operand" "0,r")
|
(lo_sum:DI (match_operand:DI 1 "register_operand" "0,r")
|
(match_operand:DI 2 "immediate_operand" "i,i")))]
|
(match_operand:DI 2 "immediate_operand" "i,i")))]
|
"!TARGET_64BIT"
|
"!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. */
|
handle it correctly. */
|
if (GET_CODE (operands[2]) == CONST_DOUBLE)
|
if (GET_CODE (operands[2]) == CONST_DOUBLE)
|
operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[2]));
|
operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[2]));
|
else if (HOST_BITS_PER_WIDE_INT > 32
|
else if (HOST_BITS_PER_WIDE_INT > 32
|
&& GET_CODE (operands[2]) == CONST_INT)
|
&& GET_CODE (operands[2]) == CONST_INT)
|
operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffffffff);
|
operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffffffff);
|
if (which_alternative == 1)
|
if (which_alternative == 1)
|
output_asm_insn (\"copy %1,%0\", operands);
|
output_asm_insn (\"copy %1,%0\", operands);
|
return \"ldo R'%G2(%R1),%R0\";
|
return \"ldo R'%G2(%R1),%R0\";
|
}"
|
}"
|
[(set_attr "type" "move,move")
|
[(set_attr "type" "move,move")
|
(set_attr "length" "4,8")])
|
(set_attr "length" "4,8")])
|
|
|
;; This pattern forces (set (reg:SF ...) (const_double ...))
|
;; This pattern forces (set (reg:SF ...) (const_double ...))
|
;; to be reloaded by putting the constant into memory when
|
;; to be reloaded by putting the constant into memory when
|
;; reg is a floating point register.
|
;; reg is a floating point register.
|
;;
|
;;
|
;; For integer registers we use ldil;ldo to set the appropriate
|
;; For integer registers we use ldil;ldo to set the appropriate
|
;; value.
|
;; value.
|
;;
|
;;
|
;; This must come before the movsf pattern, and it must be present
|
;; This must come before the movsf pattern, and it must be present
|
;; to handle obscure reloading cases.
|
;; to handle obscure reloading cases.
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SF 0 "register_operand" "=?r,f")
|
[(set (match_operand:SF 0 "register_operand" "=?r,f")
|
(match_operand:SF 1 "" "?F,m"))]
|
(match_operand:SF 1 "" "?F,m"))]
|
"GET_CODE (operands[1]) == CONST_DOUBLE
|
"GET_CODE (operands[1]) == CONST_DOUBLE
|
&& operands[1] != CONST0_RTX (SFmode)
|
&& operands[1] != CONST0_RTX (SFmode)
|
&& ! TARGET_SOFT_FLOAT"
|
&& ! TARGET_SOFT_FLOAT"
|
"* return (which_alternative == 0 ? singlemove_string (operands)
|
"* return (which_alternative == 0 ? singlemove_string (operands)
|
: \" fldw%F1 %1,%0\");"
|
: \" fldw%F1 %1,%0\");"
|
[(set_attr "type" "move,fpload")
|
[(set_attr "type" "move,fpload")
|
(set_attr "length" "8,4")])
|
(set_attr "length" "8,4")])
|
|
|
(define_expand "movsf"
|
(define_expand "movsf"
|
[(set (match_operand:SF 0 "general_operand" "")
|
[(set (match_operand:SF 0 "general_operand" "")
|
(match_operand:SF 1 "general_operand" ""))]
|
(match_operand:SF 1 "general_operand" ""))]
|
""
|
""
|
"
|
"
|
{
|
{
|
/* Reject CONST_DOUBLE loads to floating point registers. */
|
/* Reject CONST_DOUBLE loads to floating point registers. */
|
if (GET_CODE (operands[1]) == CONST_DOUBLE
|
if (GET_CODE (operands[1]) == CONST_DOUBLE
|
&& operands[1] != CONST0_RTX (SFmode)
|
&& operands[1] != CONST0_RTX (SFmode)
|
&& REG_P (operands[0])
|
&& REG_P (operands[0])
|
&& HARD_REGISTER_P (operands[0])
|
&& HARD_REGISTER_P (operands[0])
|
&& REGNO (operands[0]) >= 32)
|
&& REGNO (operands[0]) >= 32)
|
FAIL;
|
FAIL;
|
|
|
if (emit_move_sequence (operands, SFmode, 0))
|
if (emit_move_sequence (operands, SFmode, 0))
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
;; Handle SFmode input reloads requiring a general register as a
|
;; Handle SFmode input reloads requiring a general register as a
|
;; scratch register.
|
;; scratch register.
|
(define_expand "reload_insf"
|
(define_expand "reload_insf"
|
[(set (match_operand:SF 0 "register_operand" "=Z")
|
[(set (match_operand:SF 0 "register_operand" "=Z")
|
(match_operand:SF 1 "non_hard_reg_operand" ""))
|
(match_operand:SF 1 "non_hard_reg_operand" ""))
|
(clobber (match_operand:SF 2 "register_operand" "=&r"))]
|
(clobber (match_operand:SF 2 "register_operand" "=&r"))]
|
""
|
""
|
"
|
"
|
{
|
{
|
if (emit_move_sequence (operands, SFmode, operands[2]))
|
if (emit_move_sequence (operands, SFmode, operands[2]))
|
DONE;
|
DONE;
|
|
|
/* We don't want the clobber emitted, so handle this ourselves. */
|
/* We don't want the clobber emitted, so handle this ourselves. */
|
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
|
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
;; Handle SFmode output reloads requiring a general register as a
|
;; Handle SFmode output reloads requiring a general register as a
|
;; scratch register.
|
;; scratch register.
|
(define_expand "reload_outsf"
|
(define_expand "reload_outsf"
|
[(set (match_operand:SF 0 "non_hard_reg_operand" "")
|
[(set (match_operand:SF 0 "non_hard_reg_operand" "")
|
(match_operand:SF 1 "register_operand" "Z"))
|
(match_operand:SF 1 "register_operand" "Z"))
|
(clobber (match_operand:SF 2 "register_operand" "=&r"))]
|
(clobber (match_operand:SF 2 "register_operand" "=&r"))]
|
""
|
""
|
"
|
"
|
{
|
{
|
if (emit_move_sequence (operands, SFmode, operands[2]))
|
if (emit_move_sequence (operands, SFmode, operands[2]))
|
DONE;
|
DONE;
|
|
|
/* We don't want the clobber emitted, so handle this ourselves. */
|
/* We don't want the clobber emitted, so handle this ourselves. */
|
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
|
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SF 0 "move_dest_operand"
|
[(set (match_operand:SF 0 "move_dest_operand"
|
"=f,!*r,f,*r,Q,Q,?*r,?f")
|
"=f,!*r,f,*r,Q,Q,?*r,?f")
|
(match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
|
(match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
|
"fG,!*rG,RQ,RQ,f,*rG,f,*r"))]
|
"fG,!*rG,RQ,RQ,f,*rG,f,*r"))]
|
"(register_operand (operands[0], SFmode)
|
"(register_operand (operands[0], SFmode)
|
|| reg_or_0_operand (operands[1], SFmode))
|
|| reg_or_0_operand (operands[1], SFmode))
|
&& !TARGET_SOFT_FLOAT
|
&& !TARGET_SOFT_FLOAT
|
&& !TARGET_64BIT"
|
&& !TARGET_64BIT"
|
"@
|
"@
|
fcpy,sgl %f1,%0
|
fcpy,sgl %f1,%0
|
copy %r1,%0
|
copy %r1,%0
|
fldw%F1 %1,%0
|
fldw%F1 %1,%0
|
ldw%M1 %1,%0
|
ldw%M1 %1,%0
|
fstw%F0 %1,%0
|
fstw%F0 %1,%0
|
stw%M0 %r1,%0
|
stw%M0 %r1,%0
|
{fstws|fstw} %1,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%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"
|
{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 "type" "fpalu,move,fpload,load,fpstore,store,fpstore_load,store_fpload")
|
(set_attr "pa_combine_type" "addmove")
|
(set_attr "pa_combine_type" "addmove")
|
(set_attr "length" "4,4,4,4,4,4,8,8")])
|
(set_attr "length" "4,4,4,4,4,4,8,8")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SF 0 "move_dest_operand"
|
[(set (match_operand:SF 0 "move_dest_operand"
|
"=f,!*r,f,*r,Q,Q")
|
"=f,!*r,f,*r,Q,Q")
|
(match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
|
(match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
|
"fG,!*rG,RQ,RQ,f,*rG"))]
|
"fG,!*rG,RQ,RQ,f,*rG"))]
|
"(register_operand (operands[0], SFmode)
|
"(register_operand (operands[0], SFmode)
|
|| reg_or_0_operand (operands[1], SFmode))
|
|| reg_or_0_operand (operands[1], SFmode))
|
&& !TARGET_SOFT_FLOAT
|
&& !TARGET_SOFT_FLOAT
|
&& TARGET_64BIT"
|
&& TARGET_64BIT"
|
"@
|
"@
|
fcpy,sgl %f1,%0
|
fcpy,sgl %f1,%0
|
copy %r1,%0
|
copy %r1,%0
|
fldw%F1 %1,%0
|
fldw%F1 %1,%0
|
ldw%M1 %1,%0
|
ldw%M1 %1,%0
|
fstw%F0 %1,%0
|
fstw%F0 %1,%0
|
stw%M0 %r1,%0"
|
stw%M0 %r1,%0"
|
[(set_attr "type" "fpalu,move,fpload,load,fpstore,store")
|
[(set_attr "type" "fpalu,move,fpload,load,fpstore,store")
|
(set_attr "pa_combine_type" "addmove")
|
(set_attr "pa_combine_type" "addmove")
|
(set_attr "length" "4,4,4,4,4,4")])
|
(set_attr "length" "4,4,4,4,4,4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SF 0 "indexed_memory_operand" "=R")
|
[(set (match_operand:SF 0 "indexed_memory_operand" "=R")
|
(match_operand:SF 1 "register_operand" "f"))]
|
(match_operand:SF 1 "register_operand" "f"))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& reload_completed"
|
&& reload_completed"
|
"fstw%F0 %1,%0"
|
"fstw%F0 %1,%0"
|
[(set_attr "type" "fpstore")
|
[(set_attr "type" "fpstore")
|
(set_attr "pa_combine_type" "addmove")
|
(set_attr "pa_combine_type" "addmove")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_peephole2
|
(define_peephole2
|
[(set (match_operand:SI 0 "register_operand" "")
|
[(set (match_operand:SI 0 "register_operand" "")
|
(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
|
(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
|
(const_int 4))
|
(const_int 4))
|
(match_operand:SI 2 "register_operand" "")))
|
(match_operand:SI 2 "register_operand" "")))
|
(set (mem:SF (match_dup 0))
|
(set (mem:SF (match_dup 0))
|
(match_operand:SF 3 "register_operand" ""))]
|
(match_operand:SF 3 "register_operand" ""))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
&& 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 (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
|
(match_dup 3))
|
(match_dup 3))
|
(set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4))
|
(set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4))
|
(match_dup 2)))]
|
(match_dup 2)))]
|
"")
|
"")
|
|
|
(define_peephole2
|
(define_peephole2
|
[(set (match_operand:SI 0 "register_operand" "")
|
[(set (match_operand:SI 0 "register_operand" "")
|
(plus:SI (match_operand:SI 2 "register_operand" "")
|
(plus:SI (match_operand:SI 2 "register_operand" "")
|
(mult:SI (match_operand:SI 1 "register_operand" "")
|
(mult:SI (match_operand:SI 1 "register_operand" "")
|
(const_int 4))))
|
(const_int 4))))
|
(set (mem:SF (match_dup 0))
|
(set (mem:SF (match_dup 0))
|
(match_operand:SF 3 "register_operand" ""))]
|
(match_operand:SF 3 "register_operand" ""))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
&& 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 (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
|
(match_dup 3))
|
(match_dup 3))
|
(set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4))
|
(set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4))
|
(match_dup 2)))]
|
(match_dup 2)))]
|
"")
|
"")
|
|
|
(define_peephole2
|
(define_peephole2
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
|
(plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
|
(const_int 4))
|
(const_int 4))
|
(match_operand:DI 2 "register_operand" "")))
|
(match_operand:DI 2 "register_operand" "")))
|
(set (mem:SF (match_dup 0))
|
(set (mem:SF (match_dup 0))
|
(match_operand:SF 3 "register_operand" ""))]
|
(match_operand:SF 3 "register_operand" ""))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& TARGET_64BIT
|
&& TARGET_64BIT
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
[(set (mem:SF (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
|
[(set (mem:SF (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
|
(match_dup 3))
|
(match_dup 3))
|
(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4))
|
(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4))
|
(match_dup 2)))]
|
(match_dup 2)))]
|
"")
|
"")
|
|
|
(define_peephole2
|
(define_peephole2
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(plus:DI (match_operand:DI 2 "register_operand" "")
|
(plus:DI (match_operand:DI 2 "register_operand" "")
|
(mult:DI (match_operand:DI 1 "register_operand" "")
|
(mult:DI (match_operand:DI 1 "register_operand" "")
|
(const_int 4))))
|
(const_int 4))))
|
(set (mem:SF (match_dup 0))
|
(set (mem:SF (match_dup 0))
|
(match_operand:SF 3 "register_operand" ""))]
|
(match_operand:SF 3 "register_operand" ""))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& TARGET_64BIT
|
&& TARGET_64BIT
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
[(set (mem:SF (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
|
[(set (mem:SF (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
|
(match_dup 3))
|
(match_dup 3))
|
(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4))
|
(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4))
|
(match_dup 2)))]
|
(match_dup 2)))]
|
"")
|
"")
|
|
|
(define_peephole2
|
(define_peephole2
|
[(set (match_operand:SI 0 "register_operand" "")
|
[(set (match_operand:SI 0 "register_operand" "")
|
(plus:SI (match_operand:SI 1 "register_operand" "")
|
(plus:SI (match_operand:SI 1 "register_operand" "")
|
(match_operand:SI 2 "register_operand" "")))
|
(match_operand:SI 2 "register_operand" "")))
|
(set (mem:SF (match_dup 0))
|
(set (mem:SF (match_dup 0))
|
(match_operand:SF 3 "register_operand" ""))]
|
(match_operand:SF 3 "register_operand" ""))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& TARGET_NO_SPACE_REGS
|
&& TARGET_NO_SPACE_REGS
|
&& REG_OK_FOR_INDEX_P (operands[1])
|
&& REG_OK_FOR_INDEX_P (operands[1])
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
[(set (mem:SF (plus:SI (match_dup 1) (match_dup 2)))
|
[(set (mem:SF (plus:SI (match_dup 1) (match_dup 2)))
|
(match_dup 3))
|
(match_dup 3))
|
(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
|
(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
|
"")
|
"")
|
|
|
(define_peephole2
|
(define_peephole2
|
[(set (match_operand:SI 0 "register_operand" "")
|
[(set (match_operand:SI 0 "register_operand" "")
|
(plus:SI (match_operand:SI 1 "register_operand" "")
|
(plus:SI (match_operand:SI 1 "register_operand" "")
|
(match_operand:SI 2 "register_operand" "")))
|
(match_operand:SI 2 "register_operand" "")))
|
(set (mem:SF (match_dup 0))
|
(set (mem:SF (match_dup 0))
|
(match_operand:SF 3 "register_operand" ""))]
|
(match_operand:SF 3 "register_operand" ""))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& TARGET_NO_SPACE_REGS
|
&& TARGET_NO_SPACE_REGS
|
&& REG_OK_FOR_BASE_P (operands[1])
|
&& REG_OK_FOR_BASE_P (operands[1])
|
&& REG_OK_FOR_INDEX_P (operands[2])
|
&& REG_OK_FOR_INDEX_P (operands[2])
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
[(set (mem:SF (plus:SI (match_dup 2) (match_dup 1)))
|
[(set (mem:SF (plus:SI (match_dup 2) (match_dup 1)))
|
(match_dup 3))
|
(match_dup 3))
|
(set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
|
(set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
|
"")
|
"")
|
|
|
(define_peephole2
|
(define_peephole2
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(plus:DI (match_operand:DI 1 "register_operand" "")
|
(plus:DI (match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 2 "register_operand" "")))
|
(match_operand:DI 2 "register_operand" "")))
|
(set (mem:SF (match_dup 0))
|
(set (mem:SF (match_dup 0))
|
(match_operand:SF 3 "register_operand" ""))]
|
(match_operand:SF 3 "register_operand" ""))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& TARGET_64BIT
|
&& TARGET_64BIT
|
&& TARGET_NO_SPACE_REGS
|
&& TARGET_NO_SPACE_REGS
|
&& REG_OK_FOR_INDEX_P (operands[1])
|
&& REG_OK_FOR_INDEX_P (operands[1])
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& REG_OK_FOR_BASE_P (operands[2])
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
[(set (mem:SF (plus:DI (match_dup 1) (match_dup 2)))
|
[(set (mem:SF (plus:DI (match_dup 1) (match_dup 2)))
|
(match_dup 3))
|
(match_dup 3))
|
(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
|
(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
|
"")
|
"")
|
|
|
(define_peephole2
|
(define_peephole2
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(plus:DI (match_operand:DI 1 "register_operand" "")
|
(plus:DI (match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 2 "register_operand" "")))
|
(match_operand:DI 2 "register_operand" "")))
|
(set (mem:SF (match_dup 0))
|
(set (mem:SF (match_dup 0))
|
(match_operand:SF 3 "register_operand" ""))]
|
(match_operand:SF 3 "register_operand" ""))]
|
"!TARGET_SOFT_FLOAT
|
"!TARGET_SOFT_FLOAT
|
&& !TARGET_DISABLE_INDEXING
|
&& !TARGET_DISABLE_INDEXING
|
&& TARGET_64BIT
|
&& TARGET_64BIT
|
&& TARGET_NO_SPACE_REGS
|
&& TARGET_NO_SPACE_REGS
|
&& REG_OK_FOR_BASE_P (operands[1])
|
&& REG_OK_FOR_BASE_P (operands[1])
|
&& REG_OK_FOR_INDEX_P (operands[2])
|
&& REG_OK_FOR_INDEX_P (operands[2])
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
&& FP_REGNO_P (REGNO (operands[3]))"
|
[(set (mem:SF (plus:DI (match_dup 2) (match_dup 1)))
|
[(set (mem:SF (plus:DI (match_dup 2) (match_dup 1)))
|
(match_dup 3))
|
(match_dup 3))
|
(set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
|
(set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
|
"")
|
"")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SF 0 "move_dest_operand"
|
[(set (match_operand:SF 0 "move_dest_operand"
|
"=r,r,Q")
|
"=r,r,Q")
|
(match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
|
(match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
|
"rG,RQ,rG"))]
|
"rG,RQ,rG"))]
|
"(register_operand (operands[0], SFmode)
|
"(register_operand (operands[0], SFmode)
|
|| reg_or_0_operand (operands[1], SFmode))
|
|| reg_or_0_operand (operands[1], SFmode))
|
&& TARGET_SOFT_FLOAT"
|
&& TARGET_SOFT_FLOAT"
|
"@
|
"@
|
copy %r1,%0
|
copy %r1,%0
|
ldw%M1 %1,%0
|
ldw%M1 %1,%0
|
stw%M0 %r1,%0"
|
stw%M0 %r1,%0"
|
[(set_attr "type" "move,load,store")
|
[(set_attr "type" "move,load,store")
|
(set_attr "pa_combine_type" "addmove")
|
(set_attr "pa_combine_type" "addmove")
|
(set_attr "length" "4,4,4")])
|
(set_attr "length" "4,4,4")])
|
|
|
|
|
|
|
;;- zero extension instructions
|
;;- zero extension instructions
|
;; We have define_expand for zero extension patterns to make sure the
|
;; We have define_expand for zero extension patterns to make sure the
|
;; operands get loaded into registers. The define_insns accept
|
;; operands get loaded into registers. The define_insns accept
|
;; memory operands. This gives us better overall code than just
|
;; memory operands. This gives us better overall code than just
|
;; having a pattern that does or does not accept memory operands.
|
;; having a pattern that does or does not accept memory operands.
|
|
|
(define_expand "zero_extendqihi2"
|
(define_expand "zero_extendqihi2"
|
[(set (match_operand:HI 0 "register_operand" "")
|
[(set (match_operand:HI 0 "register_operand" "")
|
(zero_extend:HI
|
(zero_extend:HI
|
(match_operand:QI 1 "register_operand" "")))]
|
(match_operand:QI 1 "register_operand" "")))]
|
""
|
""
|
"")
|
"")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:HI 0 "register_operand" "=r,r")
|
[(set (match_operand:HI 0 "register_operand" "=r,r")
|
(zero_extend:HI
|
(zero_extend:HI
|
(match_operand:QI 1 "move_src_operand" "r,RQ")))]
|
(match_operand:QI 1 "move_src_operand" "r,RQ")))]
|
"GET_CODE (operands[1]) != CONST_INT"
|
"GET_CODE (operands[1]) != CONST_INT"
|
"@
|
"@
|
{extru|extrw,u} %1,31,8,%0
|
{extru|extrw,u} %1,31,8,%0
|
ldb%M1 %1,%0"
|
ldb%M1 %1,%0"
|
[(set_attr "type" "shift,load")
|
[(set_attr "type" "shift,load")
|
(set_attr "length" "4,4")])
|
(set_attr "length" "4,4")])
|
|
|
(define_expand "zero_extendqisi2"
|
(define_expand "zero_extendqisi2"
|
[(set (match_operand:SI 0 "register_operand" "")
|
[(set (match_operand:SI 0 "register_operand" "")
|
(zero_extend:SI
|
(zero_extend:SI
|
(match_operand:QI 1 "register_operand" "")))]
|
(match_operand:QI 1 "register_operand" "")))]
|
""
|
""
|
"")
|
"")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
(zero_extend:SI
|
(zero_extend:SI
|
(match_operand:QI 1 "move_src_operand" "r,RQ")))]
|
(match_operand:QI 1 "move_src_operand" "r,RQ")))]
|
"GET_CODE (operands[1]) != CONST_INT"
|
"GET_CODE (operands[1]) != CONST_INT"
|
"@
|
"@
|
{extru|extrw,u} %1,31,8,%0
|
{extru|extrw,u} %1,31,8,%0
|
ldb%M1 %1,%0"
|
ldb%M1 %1,%0"
|
[(set_attr "type" "shift,load")
|
[(set_attr "type" "shift,load")
|
(set_attr "length" "4,4")])
|
(set_attr "length" "4,4")])
|
|
|
(define_expand "zero_extendhisi2"
|
(define_expand "zero_extendhisi2"
|
[(set (match_operand:SI 0 "register_operand" "")
|
[(set (match_operand:SI 0 "register_operand" "")
|
(zero_extend:SI
|
(zero_extend:SI
|
(match_operand:HI 1 "register_operand" "")))]
|
(match_operand:HI 1 "register_operand" "")))]
|
""
|
""
|
"")
|
"")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
(zero_extend:SI
|
(zero_extend:SI
|
(match_operand:HI 1 "move_src_operand" "r,RQ")))]
|
(match_operand:HI 1 "move_src_operand" "r,RQ")))]
|
"GET_CODE (operands[1]) != CONST_INT"
|
"GET_CODE (operands[1]) != CONST_INT"
|
"@
|
"@
|
{extru|extrw,u} %1,31,16,%0
|
{extru|extrw,u} %1,31,16,%0
|
ldh%M1 %1,%0"
|
ldh%M1 %1,%0"
|
[(set_attr "type" "shift,load")
|
[(set_attr "type" "shift,load")
|
(set_attr "length" "4,4")])
|
(set_attr "length" "4,4")])
|
|
|
(define_expand "zero_extendqidi2"
|
(define_expand "zero_extendqidi2"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(zero_extend:DI
|
(zero_extend:DI
|
(match_operand:QI 1 "register_operand" "")))]
|
(match_operand:QI 1 "register_operand" "")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"")
|
"")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
(zero_extend:DI
|
(zero_extend:DI
|
(match_operand:QI 1 "move_src_operand" "r,RQ")))]
|
(match_operand:QI 1 "move_src_operand" "r,RQ")))]
|
"TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
|
"TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
|
"@
|
"@
|
extrd,u %1,63,8,%0
|
extrd,u %1,63,8,%0
|
ldb%M1 %1,%0"
|
ldb%M1 %1,%0"
|
[(set_attr "type" "shift,load")
|
[(set_attr "type" "shift,load")
|
(set_attr "length" "4,4")])
|
(set_attr "length" "4,4")])
|
|
|
(define_expand "zero_extendhidi2"
|
(define_expand "zero_extendhidi2"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(zero_extend:DI
|
(zero_extend:DI
|
(match_operand:HI 1 "register_operand" "")))]
|
(match_operand:HI 1 "register_operand" "")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"")
|
"")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
(zero_extend:DI
|
(zero_extend:DI
|
(match_operand:HI 1 "move_src_operand" "r,RQ")))]
|
(match_operand:HI 1 "move_src_operand" "r,RQ")))]
|
"TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
|
"TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
|
"@
|
"@
|
extrd,u %1,63,16,%0
|
extrd,u %1,63,16,%0
|
ldh%M1 %1,%0"
|
ldh%M1 %1,%0"
|
[(set_attr "type" "shift,load")
|
[(set_attr "type" "shift,load")
|
(set_attr "length" "4,4")])
|
(set_attr "length" "4,4")])
|
|
|
(define_expand "zero_extendsidi2"
|
(define_expand "zero_extendsidi2"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(zero_extend:DI
|
(zero_extend:DI
|
(match_operand:SI 1 "register_operand" "")))]
|
(match_operand:SI 1 "register_operand" "")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"")
|
"")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
(zero_extend:DI
|
(zero_extend:DI
|
(match_operand:SI 1 "move_src_operand" "r,RQ")))]
|
(match_operand:SI 1 "move_src_operand" "r,RQ")))]
|
"TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
|
"TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
|
"@
|
"@
|
extrd,u %1,63,32,%0
|
extrd,u %1,63,32,%0
|
ldw%M1 %1,%0"
|
ldw%M1 %1,%0"
|
[(set_attr "type" "shift,load")
|
[(set_attr "type" "shift,load")
|
(set_attr "length" "4,4")])
|
(set_attr "length" "4,4")])
|
|
|
;;- sign extension instructions
|
;;- sign extension instructions
|
|
|
(define_insn "extendhisi2"
|
(define_insn "extendhisi2"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
|
(sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
|
""
|
""
|
"{extrs|extrw,s} %1,31,16,%0"
|
"{extrs|extrw,s} %1,31,16,%0"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "extendqihi2"
|
(define_insn "extendqihi2"
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
(sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
|
(sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
|
""
|
""
|
"{extrs|extrw,s} %1,31,8,%0"
|
"{extrs|extrw,s} %1,31,8,%0"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "extendqisi2"
|
(define_insn "extendqisi2"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
|
(sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
|
""
|
""
|
"{extrs|extrw,s} %1,31,8,%0"
|
"{extrs|extrw,s} %1,31,8,%0"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "extendqidi2"
|
(define_insn "extendqidi2"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
|
(sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"extrd,s %1,63,8,%0"
|
"extrd,s %1,63,8,%0"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "extendhidi2"
|
(define_insn "extendhidi2"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
|
(sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"extrd,s %1,63,16,%0"
|
"extrd,s %1,63,16,%0"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "extendsidi2"
|
(define_insn "extendsidi2"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(sign_extend:DI (match_operand:SI 1 "register_operand" "r")))]
|
(sign_extend:DI (match_operand:SI 1 "register_operand" "r")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"extrd,s %1,63,32,%0"
|
"extrd,s %1,63,32,%0"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
|
|
;; Conversions between float and double.
|
;; Conversions between float and double.
|
|
|
(define_insn "extendsfdf2"
|
(define_insn "extendsfdf2"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(float_extend:DF
|
(float_extend:DF
|
(match_operand:SF 1 "register_operand" "f")))]
|
(match_operand:SF 1 "register_operand" "f")))]
|
"! TARGET_SOFT_FLOAT"
|
"! TARGET_SOFT_FLOAT"
|
"{fcnvff|fcnv},sgl,dbl %1,%0"
|
"{fcnvff|fcnv},sgl,dbl %1,%0"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "truncdfsf2"
|
(define_insn "truncdfsf2"
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(float_truncate:SF
|
(float_truncate:SF
|
(match_operand:DF 1 "register_operand" "f")))]
|
(match_operand:DF 1 "register_operand" "f")))]
|
"! TARGET_SOFT_FLOAT"
|
"! TARGET_SOFT_FLOAT"
|
"{fcnvff|fcnv},dbl,sgl %1,%0"
|
"{fcnvff|fcnv},dbl,sgl %1,%0"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
;; Conversion between fixed point and floating point.
|
;; Conversion between fixed point and floating point.
|
;; Note that among the fix-to-float insns
|
;; Note that among the fix-to-float insns
|
;; the ones that start with SImode come first.
|
;; the ones that start with SImode come first.
|
;; That is so that an operand that is a CONST_INT
|
;; That is so that an operand that is a CONST_INT
|
;; (and therefore lacks a specific machine mode).
|
;; (and therefore lacks a specific machine mode).
|
;; will be recognized as SImode (which is always valid)
|
;; will be recognized as SImode (which is always valid)
|
;; rather than as QImode or HImode.
|
;; rather than as QImode or HImode.
|
|
|
;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
|
;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
|
;; to be reloaded by putting the constant into memory.
|
;; to be reloaded by putting the constant into memory.
|
;; It must come before the more general floatsisf2 pattern.
|
;; It must come before the more general floatsisf2 pattern.
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(float:SF (match_operand:SI 1 "const_int_operand" "m")))]
|
(float:SF (match_operand:SI 1 "const_int_operand" "m")))]
|
"! TARGET_SOFT_FLOAT"
|
"! TARGET_SOFT_FLOAT"
|
"fldw%F1 %1,%0\;{fcnvxf,sgl,sgl|fcnv,w,sgl} %0,%0"
|
"fldw%F1 %1,%0\;{fcnvxf,sgl,sgl|fcnv,w,sgl} %0,%0"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn "floatsisf2"
|
(define_insn "floatsisf2"
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(float:SF (match_operand:SI 1 "register_operand" "f")))]
|
(float:SF (match_operand:SI 1 "register_operand" "f")))]
|
"! TARGET_SOFT_FLOAT"
|
"! TARGET_SOFT_FLOAT"
|
"{fcnvxf,sgl,sgl|fcnv,w,sgl} %1,%0"
|
"{fcnvxf,sgl,sgl|fcnv,w,sgl} %1,%0"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...)))
|
;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...)))
|
;; to be reloaded by putting the constant into memory.
|
;; to be reloaded by putting the constant into memory.
|
;; It must come before the more general floatsidf2 pattern.
|
;; It must come before the more general floatsidf2 pattern.
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(float:DF (match_operand:SI 1 "const_int_operand" "m")))]
|
(float:DF (match_operand:SI 1 "const_int_operand" "m")))]
|
"! TARGET_SOFT_FLOAT"
|
"! TARGET_SOFT_FLOAT"
|
"fldw%F1 %1,%0\;{fcnvxf,sgl,dbl|fcnv,w,dbl} %0,%0"
|
"fldw%F1 %1,%0\;{fcnvxf,sgl,dbl|fcnv,w,dbl} %0,%0"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn "floatsidf2"
|
(define_insn "floatsidf2"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(float:DF (match_operand:SI 1 "register_operand" "f")))]
|
(float:DF (match_operand:SI 1 "register_operand" "f")))]
|
"! TARGET_SOFT_FLOAT"
|
"! TARGET_SOFT_FLOAT"
|
"{fcnvxf,sgl,dbl|fcnv,w,dbl} %1,%0"
|
"{fcnvxf,sgl,dbl|fcnv,w,dbl} %1,%0"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_expand "floatunssisf2"
|
(define_expand "floatunssisf2"
|
[(set (subreg:SI (match_dup 2) 4)
|
[(set (subreg:SI (match_dup 2) 4)
|
(match_operand:SI 1 "register_operand" ""))
|
(match_operand:SI 1 "register_operand" ""))
|
(set (subreg:SI (match_dup 2) 0)
|
(set (subreg:SI (match_dup 2) 0)
|
(const_int 0))
|
(const_int 0))
|
(set (match_operand:SF 0 "register_operand" "")
|
(set (match_operand:SF 0 "register_operand" "")
|
(float:SF (match_dup 2)))]
|
(float:SF (match_dup 2)))]
|
"TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
|
"TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
|
"
|
"
|
{
|
{
|
if (TARGET_PA_20)
|
if (TARGET_PA_20)
|
{
|
{
|
emit_insn (gen_floatunssisf2_pa20 (operands[0], operands[1]));
|
emit_insn (gen_floatunssisf2_pa20 (operands[0], operands[1]));
|
DONE;
|
DONE;
|
}
|
}
|
operands[2] = gen_reg_rtx (DImode);
|
operands[2] = gen_reg_rtx (DImode);
|
}")
|
}")
|
|
|
(define_expand "floatunssidf2"
|
(define_expand "floatunssidf2"
|
[(set (subreg:SI (match_dup 2) 4)
|
[(set (subreg:SI (match_dup 2) 4)
|
(match_operand:SI 1 "register_operand" ""))
|
(match_operand:SI 1 "register_operand" ""))
|
(set (subreg:SI (match_dup 2) 0)
|
(set (subreg:SI (match_dup 2) 0)
|
(const_int 0))
|
(const_int 0))
|
(set (match_operand:DF 0 "register_operand" "")
|
(set (match_operand:DF 0 "register_operand" "")
|
(float:DF (match_dup 2)))]
|
(float:DF (match_dup 2)))]
|
"TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
|
"TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
|
"
|
"
|
{
|
{
|
if (TARGET_PA_20)
|
if (TARGET_PA_20)
|
{
|
{
|
emit_insn (gen_floatunssidf2_pa20 (operands[0], operands[1]));
|
emit_insn (gen_floatunssidf2_pa20 (operands[0], operands[1]));
|
DONE;
|
DONE;
|
}
|
}
|
operands[2] = gen_reg_rtx (DImode);
|
operands[2] = gen_reg_rtx (DImode);
|
}")
|
}")
|
|
|
(define_insn "floatdisf2"
|
(define_insn "floatdisf2"
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(float:SF (match_operand:DI 1 "register_operand" "f")))]
|
(float:SF (match_operand:DI 1 "register_operand" "f")))]
|
"TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
|
"TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
|
"{fcnvxf,dbl,sgl|fcnv,dw,sgl} %1,%0"
|
"{fcnvxf,dbl,sgl|fcnv,dw,sgl} %1,%0"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "floatdidf2"
|
(define_insn "floatdidf2"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(float:DF (match_operand:DI 1 "register_operand" "f")))]
|
(float:DF (match_operand:DI 1 "register_operand" "f")))]
|
"TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
|
"TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
|
"{fcnvxf,dbl,dbl|fcnv,dw,dbl} %1,%0"
|
"{fcnvxf,dbl,dbl|fcnv,dw,dbl} %1,%0"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
;; Convert a float to an actual integer.
|
;; Convert a float to an actual integer.
|
;; Truncation is performed as part of the conversion.
|
;; Truncation is performed as part of the conversion.
|
|
|
(define_insn "fix_truncsfsi2"
|
(define_insn "fix_truncsfsi2"
|
[(set (match_operand:SI 0 "register_operand" "=f")
|
[(set (match_operand:SI 0 "register_operand" "=f")
|
(fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
|
(fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
|
"! TARGET_SOFT_FLOAT"
|
"! TARGET_SOFT_FLOAT"
|
"{fcnvfxt,sgl,sgl|fcnv,t,sgl,w} %1,%0"
|
"{fcnvfxt,sgl,sgl|fcnv,t,sgl,w} %1,%0"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "fix_truncdfsi2"
|
(define_insn "fix_truncdfsi2"
|
[(set (match_operand:SI 0 "register_operand" "=f")
|
[(set (match_operand:SI 0 "register_operand" "=f")
|
(fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
|
(fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
|
"! TARGET_SOFT_FLOAT"
|
"! TARGET_SOFT_FLOAT"
|
"{fcnvfxt,dbl,sgl|fcnv,t,dbl,w} %1,%0"
|
"{fcnvfxt,dbl,sgl|fcnv,t,dbl,w} %1,%0"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "fix_truncsfdi2"
|
(define_insn "fix_truncsfdi2"
|
[(set (match_operand:DI 0 "register_operand" "=f")
|
[(set (match_operand:DI 0 "register_operand" "=f")
|
(fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
|
(fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
|
"TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
|
"TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
|
"{fcnvfxt,sgl,dbl|fcnv,t,sgl,dw} %1,%0"
|
"{fcnvfxt,sgl,dbl|fcnv,t,sgl,dw} %1,%0"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "fix_truncdfdi2"
|
(define_insn "fix_truncdfdi2"
|
[(set (match_operand:DI 0 "register_operand" "=f")
|
[(set (match_operand:DI 0 "register_operand" "=f")
|
(fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
|
(fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
|
"TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
|
"TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
|
"{fcnvfxt,dbl,dbl|fcnv,t,dbl,dw} %1,%0"
|
"{fcnvfxt,dbl,dbl|fcnv,t,dbl,dw} %1,%0"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "floatunssidf2_pa20"
|
(define_insn "floatunssidf2_pa20"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(unsigned_float:DF (match_operand:SI 1 "register_operand" "f")))]
|
(unsigned_float:DF (match_operand:SI 1 "register_operand" "f")))]
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"fcnv,uw,dbl %1,%0"
|
"fcnv,uw,dbl %1,%0"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "floatunssisf2_pa20"
|
(define_insn "floatunssisf2_pa20"
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(unsigned_float:SF (match_operand:SI 1 "register_operand" "f")))]
|
(unsigned_float:SF (match_operand:SI 1 "register_operand" "f")))]
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"fcnv,uw,sgl %1,%0"
|
"fcnv,uw,sgl %1,%0"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "floatunsdisf2"
|
(define_insn "floatunsdisf2"
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(unsigned_float:SF (match_operand:DI 1 "register_operand" "f")))]
|
(unsigned_float:SF (match_operand:DI 1 "register_operand" "f")))]
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"fcnv,udw,sgl %1,%0"
|
"fcnv,udw,sgl %1,%0"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "floatunsdidf2"
|
(define_insn "floatunsdidf2"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(unsigned_float:DF (match_operand:DI 1 "register_operand" "f")))]
|
(unsigned_float:DF (match_operand:DI 1 "register_operand" "f")))]
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"fcnv,udw,dbl %1,%0"
|
"fcnv,udw,dbl %1,%0"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "fixuns_truncsfsi2"
|
(define_insn "fixuns_truncsfsi2"
|
[(set (match_operand:SI 0 "register_operand" "=f")
|
[(set (match_operand:SI 0 "register_operand" "=f")
|
(unsigned_fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
|
(unsigned_fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"fcnv,t,sgl,uw %1,%0"
|
"fcnv,t,sgl,uw %1,%0"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "fixuns_truncdfsi2"
|
(define_insn "fixuns_truncdfsi2"
|
[(set (match_operand:SI 0 "register_operand" "=f")
|
[(set (match_operand:SI 0 "register_operand" "=f")
|
(unsigned_fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
|
(unsigned_fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"fcnv,t,dbl,uw %1,%0"
|
"fcnv,t,dbl,uw %1,%0"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "fixuns_truncsfdi2"
|
(define_insn "fixuns_truncsfdi2"
|
[(set (match_operand:DI 0 "register_operand" "=f")
|
[(set (match_operand:DI 0 "register_operand" "=f")
|
(unsigned_fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
|
(unsigned_fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"fcnv,t,sgl,udw %1,%0"
|
"fcnv,t,sgl,udw %1,%0"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "fixuns_truncdfdi2"
|
(define_insn "fixuns_truncdfdi2"
|
[(set (match_operand:DI 0 "register_operand" "=f")
|
[(set (match_operand:DI 0 "register_operand" "=f")
|
(unsigned_fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
|
(unsigned_fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"fcnv,t,dbl,udw %1,%0"
|
"fcnv,t,dbl,udw %1,%0"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
;;- arithmetic instructions
|
;;- arithmetic instructions
|
|
|
(define_expand "adddi3"
|
(define_expand "adddi3"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(plus:DI (match_operand:DI 1 "register_operand" "")
|
(plus:DI (match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 2 "adddi3_operand" "")))]
|
(match_operand:DI 2 "adddi3_operand" "")))]
|
""
|
""
|
"")
|
"")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(plus:DI (match_operand:DI 1 "register_operand" "%r")
|
(plus:DI (match_operand:DI 1 "register_operand" "%r")
|
(match_operand:DI 2 "arith11_operand" "rI")))]
|
(match_operand:DI 2 "arith11_operand" "rI")))]
|
"!TARGET_64BIT"
|
"!TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
if (GET_CODE (operands[2]) == CONST_INT)
|
if (GET_CODE (operands[2]) == CONST_INT)
|
{
|
{
|
if (INTVAL (operands[2]) >= 0)
|
if (INTVAL (operands[2]) >= 0)
|
return \"addi %2,%R1,%R0\;{addc|add,c} %1,%%r0,%0\";
|
return \"addi %2,%R1,%R0\;{addc|add,c} %1,%%r0,%0\";
|
else
|
else
|
return \"addi %2,%R1,%R0\;{subb|sub,b} %1,%%r0,%0\";
|
return \"addi %2,%R1,%R0\;{subb|sub,b} %1,%%r0,%0\";
|
}
|
}
|
else
|
else
|
return \"add %R2,%R1,%R0\;{addc|add,c} %2,%1,%0\";
|
return \"add %R2,%R1,%R0\;{addc|add,c} %2,%1,%0\";
|
}"
|
}"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
(plus:DI (match_operand:DI 1 "register_operand" "%r,r")
|
(plus:DI (match_operand:DI 1 "register_operand" "%r,r")
|
(match_operand:DI 2 "arith_operand" "r,J")))]
|
(match_operand:DI 2 "arith_operand" "r,J")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"@
|
"@
|
add,l %1,%2,%0
|
add,l %1,%2,%0
|
ldo %2(%1),%0"
|
ldo %2(%1),%0"
|
[(set_attr "type" "binary,binary")
|
[(set_attr "type" "binary,binary")
|
(set_attr "pa_combine_type" "addmove")
|
(set_attr "pa_combine_type" "addmove")
|
(set_attr "length" "4,4")])
|
(set_attr "length" "4,4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(plus:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
|
(plus:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
|
(match_operand:DI 2 "register_operand" "r")))]
|
(match_operand:DI 2 "register_operand" "r")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"uaddcm %2,%1,%0"
|
"uaddcm %2,%1,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(plus:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
|
(plus:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
|
(match_operand:SI 2 "register_operand" "r")))]
|
(match_operand:SI 2 "register_operand" "r")))]
|
""
|
""
|
"uaddcm %2,%1,%0"
|
"uaddcm %2,%1,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_expand "addvdi3"
|
(define_expand "addvdi3"
|
[(parallel [(set (match_operand:DI 0 "register_operand" "")
|
[(parallel [(set (match_operand:DI 0 "register_operand" "")
|
(plus:DI (match_operand:DI 1 "reg_or_0_operand" "")
|
(plus:DI (match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 2 "arith11_operand" "")))
|
(match_operand:DI 2 "arith11_operand" "")))
|
(trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
|
(trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
|
(sign_extend:TI (match_dup 2)))
|
(sign_extend:TI (match_dup 2)))
|
(sign_extend:TI (plus:DI (match_dup 1)
|
(sign_extend:TI (plus:DI (match_dup 1)
|
(match_dup 2))))
|
(match_dup 2))))
|
(const_int 0))])]
|
(const_int 0))])]
|
""
|
""
|
"")
|
"")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
(plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rM,rM")
|
(plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rM,rM")
|
(match_operand:DI 2 "arith11_operand" "r,I")))
|
(match_operand:DI 2 "arith11_operand" "r,I")))
|
(trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
|
(trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
|
(sign_extend:TI (match_dup 2)))
|
(sign_extend:TI (match_dup 2)))
|
(sign_extend:TI (plus:DI (match_dup 1)
|
(sign_extend:TI (plus:DI (match_dup 1)
|
(match_dup 2))))
|
(match_dup 2))))
|
(const_int 0))]
|
(const_int 0))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"@
|
"@
|
add,tsv,* %2,%1,%0
|
add,tsv,* %2,%1,%0
|
addi,tsv,* %2,%1,%0"
|
addi,tsv,* %2,%1,%0"
|
[(set_attr "type" "binary,binary")
|
[(set_attr "type" "binary,binary")
|
(set_attr "length" "4,4")])
|
(set_attr "length" "4,4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rM")
|
(plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rM")
|
(match_operand:DI 2 "arith11_operand" "rI")))
|
(match_operand:DI 2 "arith11_operand" "rI")))
|
(trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
|
(trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
|
(sign_extend:TI (match_dup 2)))
|
(sign_extend:TI (match_dup 2)))
|
(sign_extend:TI (plus:DI (match_dup 1)
|
(sign_extend:TI (plus:DI (match_dup 1)
|
(match_dup 2))))
|
(match_dup 2))))
|
(const_int 0))]
|
(const_int 0))]
|
"!TARGET_64BIT"
|
"!TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
if (GET_CODE (operands[2]) == CONST_INT)
|
if (GET_CODE (operands[2]) == CONST_INT)
|
{
|
{
|
if (INTVAL (operands[2]) >= 0)
|
if (INTVAL (operands[2]) >= 0)
|
return \"addi %2,%R1,%R0\;{addco|add,c,tsv} %1,%%r0,%0\";
|
return \"addi %2,%R1,%R0\;{addco|add,c,tsv} %1,%%r0,%0\";
|
else
|
else
|
return \"addi %2,%R1,%R0\;{subbo|sub,b,tsv} %1,%%r0,%0\";
|
return \"addi %2,%R1,%R0\;{subbo|sub,b,tsv} %1,%%r0,%0\";
|
}
|
}
|
else
|
else
|
return \"add %R2,%R1,%R0\;{addco|add,c,tsv} %2,%1,%0\";
|
return \"add %R2,%R1,%R0\;{addco|add,c,tsv} %2,%1,%0\";
|
}"
|
}"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
;; define_splits to optimize cases of adding a constant integer
|
;; define_splits to optimize cases of adding a constant integer
|
;; to a register when the constant does not fit in 14 bits. */
|
;; to a register when the constant does not fit in 14 bits. */
|
(define_split
|
(define_split
|
[(set (match_operand:SI 0 "register_operand" "")
|
[(set (match_operand:SI 0 "register_operand" "")
|
(plus:SI (match_operand:SI 1 "register_operand" "")
|
(plus:SI (match_operand:SI 1 "register_operand" "")
|
(match_operand:SI 2 "const_int_operand" "")))
|
(match_operand:SI 2 "const_int_operand" "")))
|
(clobber (match_operand:SI 4 "register_operand" ""))]
|
(clobber (match_operand:SI 4 "register_operand" ""))]
|
"! cint_ok_for_move (INTVAL (operands[2]))
|
"! cint_ok_for_move (INTVAL (operands[2]))
|
&& VAL_14_BITS_P (INTVAL (operands[2]) >> 1)"
|
&& VAL_14_BITS_P (INTVAL (operands[2]) >> 1)"
|
[(set (match_dup 4) (plus:SI (match_dup 1) (match_dup 2)))
|
[(set (match_dup 4) (plus:SI (match_dup 1) (match_dup 2)))
|
(set (match_dup 0) (plus:SI (match_dup 4) (match_dup 3)))]
|
(set (match_dup 0) (plus:SI (match_dup 4) (match_dup 3)))]
|
"
|
"
|
{
|
{
|
int val = INTVAL (operands[2]);
|
int val = INTVAL (operands[2]);
|
int low = (val < 0) ? -0x2000 : 0x1fff;
|
int low = (val < 0) ? -0x2000 : 0x1fff;
|
int rest = val - low;
|
int rest = val - low;
|
|
|
operands[2] = GEN_INT (rest);
|
operands[2] = GEN_INT (rest);
|
operands[3] = GEN_INT (low);
|
operands[3] = GEN_INT (low);
|
}")
|
}")
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:SI 0 "register_operand" "")
|
[(set (match_operand:SI 0 "register_operand" "")
|
(plus:SI (match_operand:SI 1 "register_operand" "")
|
(plus:SI (match_operand:SI 1 "register_operand" "")
|
(match_operand:SI 2 "const_int_operand" "")))
|
(match_operand:SI 2 "const_int_operand" "")))
|
(clobber (match_operand:SI 4 "register_operand" ""))]
|
(clobber (match_operand:SI 4 "register_operand" ""))]
|
"! cint_ok_for_move (INTVAL (operands[2]))"
|
"! cint_ok_for_move (INTVAL (operands[2]))"
|
[(set (match_dup 4) (match_dup 2))
|
[(set (match_dup 4) (match_dup 2))
|
(set (match_dup 0) (plus:SI (mult:SI (match_dup 4) (match_dup 3))
|
(set (match_dup 0) (plus:SI (mult:SI (match_dup 4) (match_dup 3))
|
(match_dup 1)))]
|
(match_dup 1)))]
|
"
|
"
|
{
|
{
|
HOST_WIDE_INT intval = INTVAL (operands[2]);
|
HOST_WIDE_INT intval = INTVAL (operands[2]);
|
|
|
/* Try dividing the constant by 2, then 4, and finally 8 to see
|
/* Try dividing the constant by 2, then 4, and finally 8 to see
|
if we can get a constant which can be loaded into a register
|
if we can get a constant which can be loaded into a register
|
in a single instruction (cint_ok_for_move).
|
in a single instruction (cint_ok_for_move).
|
|
|
If that fails, try to negate the constant and subtract it
|
If that fails, try to negate the constant and subtract it
|
from our input operand. */
|
from our input operand. */
|
if (intval % 2 == 0 && cint_ok_for_move (intval / 2))
|
if (intval % 2 == 0 && cint_ok_for_move (intval / 2))
|
{
|
{
|
operands[2] = GEN_INT (intval / 2);
|
operands[2] = GEN_INT (intval / 2);
|
operands[3] = const2_rtx;
|
operands[3] = const2_rtx;
|
}
|
}
|
else if (intval % 4 == 0 && cint_ok_for_move (intval / 4))
|
else if (intval % 4 == 0 && cint_ok_for_move (intval / 4))
|
{
|
{
|
operands[2] = GEN_INT (intval / 4);
|
operands[2] = GEN_INT (intval / 4);
|
operands[3] = GEN_INT (4);
|
operands[3] = GEN_INT (4);
|
}
|
}
|
else if (intval % 8 == 0 && cint_ok_for_move (intval / 8))
|
else if (intval % 8 == 0 && cint_ok_for_move (intval / 8))
|
{
|
{
|
operands[2] = GEN_INT (intval / 8);
|
operands[2] = GEN_INT (intval / 8);
|
operands[3] = GEN_INT (8);
|
operands[3] = GEN_INT (8);
|
}
|
}
|
else if (cint_ok_for_move (-intval))
|
else if (cint_ok_for_move (-intval))
|
{
|
{
|
emit_insn (gen_rtx_SET (VOIDmode, operands[4], GEN_INT (-intval)));
|
emit_insn (gen_rtx_SET (VOIDmode, operands[4], GEN_INT (-intval)));
|
emit_insn (gen_subsi3 (operands[0], operands[1], operands[4]));
|
emit_insn (gen_subsi3 (operands[0], operands[1], operands[4]));
|
DONE;
|
DONE;
|
}
|
}
|
else
|
else
|
FAIL;
|
FAIL;
|
}")
|
}")
|
|
|
(define_insn "addsi3"
|
(define_insn "addsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
(plus:SI (match_operand:SI 1 "register_operand" "%r,r")
|
(plus:SI (match_operand:SI 1 "register_operand" "%r,r")
|
(match_operand:SI 2 "arith_operand" "r,J")))]
|
(match_operand:SI 2 "arith_operand" "r,J")))]
|
""
|
""
|
"@
|
"@
|
{addl|add,l} %1,%2,%0
|
{addl|add,l} %1,%2,%0
|
ldo %2(%1),%0"
|
ldo %2(%1),%0"
|
[(set_attr "type" "binary,binary")
|
[(set_attr "type" "binary,binary")
|
(set_attr "pa_combine_type" "addmove")
|
(set_attr "pa_combine_type" "addmove")
|
(set_attr "length" "4,4")])
|
(set_attr "length" "4,4")])
|
|
|
(define_insn "addvsi3"
|
(define_insn "addvsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
(plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rM,rM")
|
(plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rM,rM")
|
(match_operand:SI 2 "arith11_operand" "r,I")))
|
(match_operand:SI 2 "arith11_operand" "r,I")))
|
(trap_if (ne (plus:DI (sign_extend:DI (match_dup 1))
|
(trap_if (ne (plus:DI (sign_extend:DI (match_dup 1))
|
(sign_extend:DI (match_dup 2)))
|
(sign_extend:DI (match_dup 2)))
|
(sign_extend:DI (plus:SI (match_dup 1)
|
(sign_extend:DI (plus:SI (match_dup 1)
|
(match_dup 2))))
|
(match_dup 2))))
|
(const_int 0))]
|
(const_int 0))]
|
""
|
""
|
"@
|
"@
|
{addo|add,tsv} %2,%1,%0
|
{addo|add,tsv} %2,%1,%0
|
{addio|addi,tsv} %2,%1,%0"
|
{addio|addi,tsv} %2,%1,%0"
|
[(set_attr "type" "binary,binary")
|
[(set_attr "type" "binary,binary")
|
(set_attr "length" "4,4")])
|
(set_attr "length" "4,4")])
|
|
|
(define_expand "subdi3"
|
(define_expand "subdi3"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(minus:DI (match_operand:DI 1 "arith11_operand" "")
|
(minus:DI (match_operand:DI 1 "arith11_operand" "")
|
(match_operand:DI 2 "reg_or_0_operand" "")))]
|
(match_operand:DI 2 "reg_or_0_operand" "")))]
|
""
|
""
|
"")
|
"")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r,r,!q")
|
[(set (match_operand:DI 0 "register_operand" "=r,r,!q")
|
(minus:DI (match_operand:DI 1 "arith11_operand" "r,I,!U")
|
(minus:DI (match_operand:DI 1 "arith11_operand" "r,I,!U")
|
(match_operand:DI 2 "reg_or_0_operand" "rM,rM,!rM")))]
|
(match_operand:DI 2 "reg_or_0_operand" "rM,rM,!rM")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"@
|
"@
|
sub %1,%2,%0
|
sub %1,%2,%0
|
subi %1,%2,%0
|
subi %1,%2,%0
|
mtsarcm %2"
|
mtsarcm %2"
|
[(set_attr "type" "binary,binary,move")
|
[(set_attr "type" "binary,binary,move")
|
(set_attr "length" "4,4,4")])
|
(set_attr "length" "4,4,4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r,&r")
|
[(set (match_operand:DI 0 "register_operand" "=r,&r")
|
(minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
|
(minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
|
(match_operand:DI 2 "reg_or_0_operand" "rM,rM")))]
|
(match_operand:DI 2 "reg_or_0_operand" "rM,rM")))]
|
"!TARGET_64BIT"
|
"!TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
if (GET_CODE (operands[1]) == CONST_INT)
|
if (GET_CODE (operands[1]) == CONST_INT)
|
{
|
{
|
if (INTVAL (operands[1]) >= 0)
|
if (INTVAL (operands[1]) >= 0)
|
return \"subi %1,%R2,%R0\;{subb|sub,b} %%r0,%2,%0\";
|
return \"subi %1,%R2,%R0\;{subb|sub,b} %%r0,%2,%0\";
|
else
|
else
|
return \"ldi -1,%0\;subi %1,%R2,%R0\;{subb|sub,b} %0,%2,%0\";
|
return \"ldi -1,%0\;subi %1,%R2,%R0\;{subb|sub,b} %0,%2,%0\";
|
}
|
}
|
else
|
else
|
return \"sub %R1,%R2,%R0\;{subb|sub,b} %1,%2,%0\";
|
return \"sub %R1,%R2,%R0\;{subb|sub,b} %1,%2,%0\";
|
}"
|
}"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set (attr "length")
|
(set (attr "length")
|
(if_then_else (eq_attr "alternative" "0")
|
(if_then_else (eq_attr "alternative" "0")
|
(const_int 8)
|
(const_int 8)
|
(if_then_else (ge (symbol_ref "INTVAL (operands[1])")
|
(if_then_else (ge (symbol_ref "INTVAL (operands[1])")
|
(const_int 0))
|
(const_int 0))
|
(const_int 8)
|
(const_int 8)
|
(const_int 12))))])
|
(const_int 12))))])
|
|
|
(define_expand "subvdi3"
|
(define_expand "subvdi3"
|
[(parallel [(set (match_operand:DI 0 "register_operand" "")
|
[(parallel [(set (match_operand:DI 0 "register_operand" "")
|
(minus:DI (match_operand:DI 1 "arith11_operand" "")
|
(minus:DI (match_operand:DI 1 "arith11_operand" "")
|
(match_operand:DI 2 "reg_or_0_operand" "")))
|
(match_operand:DI 2 "reg_or_0_operand" "")))
|
(trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
|
(trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
|
(sign_extend:TI (match_dup 2)))
|
(sign_extend:TI (match_dup 2)))
|
(sign_extend:TI (minus:DI (match_dup 1)
|
(sign_extend:TI (minus:DI (match_dup 1)
|
(match_dup 2))))
|
(match_dup 2))))
|
(const_int 0))])]
|
(const_int 0))])]
|
""
|
""
|
"")
|
"")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
(minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
|
(minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
|
(match_operand:DI 2 "reg_or_0_operand" "rM,rM")))
|
(match_operand:DI 2 "reg_or_0_operand" "rM,rM")))
|
(trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
|
(trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
|
(sign_extend:TI (match_dup 2)))
|
(sign_extend:TI (match_dup 2)))
|
(sign_extend:TI (minus:DI (match_dup 1)
|
(sign_extend:TI (minus:DI (match_dup 1)
|
(match_dup 2))))
|
(match_dup 2))))
|
(const_int 0))]
|
(const_int 0))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"@
|
"@
|
{subo|sub,tsv} %1,%2,%0
|
{subo|sub,tsv} %1,%2,%0
|
{subio|subi,tsv} %1,%2,%0"
|
{subio|subi,tsv} %1,%2,%0"
|
[(set_attr "type" "binary,binary")
|
[(set_attr "type" "binary,binary")
|
(set_attr "length" "4,4")])
|
(set_attr "length" "4,4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r,&r")
|
[(set (match_operand:DI 0 "register_operand" "=r,&r")
|
(minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
|
(minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
|
(match_operand:DI 2 "reg_or_0_operand" "rM,rM")))
|
(match_operand:DI 2 "reg_or_0_operand" "rM,rM")))
|
(trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
|
(trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
|
(sign_extend:TI (match_dup 2)))
|
(sign_extend:TI (match_dup 2)))
|
(sign_extend:TI (minus:DI (match_dup 1)
|
(sign_extend:TI (minus:DI (match_dup 1)
|
(match_dup 2))))
|
(match_dup 2))))
|
(const_int 0))]
|
(const_int 0))]
|
"!TARGET_64BIT"
|
"!TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
if (GET_CODE (operands[1]) == CONST_INT)
|
if (GET_CODE (operands[1]) == CONST_INT)
|
{
|
{
|
if (INTVAL (operands[1]) >= 0)
|
if (INTVAL (operands[1]) >= 0)
|
return \"subi %1,%R2,%R0\;{subbo|sub,b,tsv} %%r0,%2,%0\";
|
return \"subi %1,%R2,%R0\;{subbo|sub,b,tsv} %%r0,%2,%0\";
|
else
|
else
|
return \"ldi -1,%0\;subi %1,%R2,%R0\;{subbo|sub,b,tsv} %0,%2,%0\";
|
return \"ldi -1,%0\;subi %1,%R2,%R0\;{subbo|sub,b,tsv} %0,%2,%0\";
|
}
|
}
|
else
|
else
|
return \"sub %R1,%R2,%R0\;{subbo|sub,b,tsv} %1,%2,%0\";
|
return \"sub %R1,%R2,%R0\;{subbo|sub,b,tsv} %1,%2,%0\";
|
}"
|
}"
|
[(set_attr "type" "binary,binary")
|
[(set_attr "type" "binary,binary")
|
(set (attr "length")
|
(set (attr "length")
|
(if_then_else (eq_attr "alternative" "0")
|
(if_then_else (eq_attr "alternative" "0")
|
(const_int 8)
|
(const_int 8)
|
(if_then_else (ge (symbol_ref "INTVAL (operands[1])")
|
(if_then_else (ge (symbol_ref "INTVAL (operands[1])")
|
(const_int 0))
|
(const_int 0))
|
(const_int 8)
|
(const_int 8)
|
(const_int 12))))])
|
(const_int 12))))])
|
|
|
(define_expand "subsi3"
|
(define_expand "subsi3"
|
[(set (match_operand:SI 0 "register_operand" "")
|
[(set (match_operand:SI 0 "register_operand" "")
|
(minus:SI (match_operand:SI 1 "arith11_operand" "")
|
(minus:SI (match_operand:SI 1 "arith11_operand" "")
|
(match_operand:SI 2 "register_operand" "")))]
|
(match_operand:SI 2 "register_operand" "")))]
|
""
|
""
|
"")
|
"")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
(minus:SI (match_operand:SI 1 "arith11_operand" "r,I")
|
(minus:SI (match_operand:SI 1 "arith11_operand" "r,I")
|
(match_operand:SI 2 "register_operand" "r,r")))]
|
(match_operand:SI 2 "register_operand" "r,r")))]
|
"!TARGET_PA_20"
|
"!TARGET_PA_20"
|
"@
|
"@
|
sub %1,%2,%0
|
sub %1,%2,%0
|
subi %1,%2,%0"
|
subi %1,%2,%0"
|
[(set_attr "type" "binary,binary")
|
[(set_attr "type" "binary,binary")
|
(set_attr "length" "4,4")])
|
(set_attr "length" "4,4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r,r,!q")
|
[(set (match_operand:SI 0 "register_operand" "=r,r,!q")
|
(minus:SI (match_operand:SI 1 "arith11_operand" "r,I,!S")
|
(minus:SI (match_operand:SI 1 "arith11_operand" "r,I,!S")
|
(match_operand:SI 2 "register_operand" "r,r,!r")))]
|
(match_operand:SI 2 "register_operand" "r,r,!r")))]
|
"TARGET_PA_20"
|
"TARGET_PA_20"
|
"@
|
"@
|
sub %1,%2,%0
|
sub %1,%2,%0
|
subi %1,%2,%0
|
subi %1,%2,%0
|
mtsarcm %2"
|
mtsarcm %2"
|
[(set_attr "type" "binary,binary,move")
|
[(set_attr "type" "binary,binary,move")
|
(set_attr "length" "4,4,4")])
|
(set_attr "length" "4,4,4")])
|
|
|
(define_insn "subvsi3"
|
(define_insn "subvsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
(minus:SI (match_operand:SI 1 "arith11_operand" "rM,I")
|
(minus:SI (match_operand:SI 1 "arith11_operand" "rM,I")
|
(match_operand:SI 2 "reg_or_0_operand" "rM,rM")))
|
(match_operand:SI 2 "reg_or_0_operand" "rM,rM")))
|
(trap_if (ne (minus:DI (sign_extend:DI (match_dup 1))
|
(trap_if (ne (minus:DI (sign_extend:DI (match_dup 1))
|
(sign_extend:DI (match_dup 2)))
|
(sign_extend:DI (match_dup 2)))
|
(sign_extend:DI (minus:SI (match_dup 1)
|
(sign_extend:DI (minus:SI (match_dup 1)
|
(match_dup 2))))
|
(match_dup 2))))
|
(const_int 0))]
|
(const_int 0))]
|
""
|
""
|
"@
|
"@
|
{subo|sub,tsv} %1,%2,%0
|
{subo|sub,tsv} %1,%2,%0
|
{subio|subi,tsv} %1,%2,%0"
|
{subio|subi,tsv} %1,%2,%0"
|
[(set_attr "type" "binary,binary")
|
[(set_attr "type" "binary,binary")
|
(set_attr "length" "4,4")])
|
(set_attr "length" "4,4")])
|
|
|
;; Clobbering a "register_operand" instead of a match_scratch
|
;; Clobbering a "register_operand" instead of a match_scratch
|
;; in operand3 of millicode calls avoids spilling %r1 and
|
;; in operand3 of millicode calls avoids spilling %r1 and
|
;; produces better code.
|
;; produces better code.
|
|
|
;; The mulsi3 insns set up registers for the millicode call.
|
;; The mulsi3 insns set up registers for the millicode call.
|
(define_expand "mulsi3"
|
(define_expand "mulsi3"
|
[(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
|
[(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
|
(set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
|
(set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
|
(parallel [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
|
(parallel [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
|
(clobber (match_dup 3))
|
(clobber (match_dup 3))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 25))
|
(clobber (reg:SI 25))
|
(clobber (match_dup 4))])
|
(clobber (match_dup 4))])
|
(set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
|
(set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
|
""
|
""
|
"
|
"
|
{
|
{
|
operands[4] = gen_rtx_REG (SImode, TARGET_64BIT ? 2 : 31);
|
operands[4] = gen_rtx_REG (SImode, TARGET_64BIT ? 2 : 31);
|
if (TARGET_PA_11 && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT)
|
if (TARGET_PA_11 && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT)
|
{
|
{
|
rtx scratch = gen_reg_rtx (DImode);
|
rtx scratch = gen_reg_rtx (DImode);
|
operands[1] = force_reg (SImode, operands[1]);
|
operands[1] = force_reg (SImode, operands[1]);
|
operands[2] = force_reg (SImode, operands[2]);
|
operands[2] = force_reg (SImode, operands[2]);
|
emit_insn (gen_umulsidi3 (scratch, operands[1], operands[2]));
|
emit_insn (gen_umulsidi3 (scratch, operands[1], operands[2]));
|
emit_insn (gen_movsi (operands[0],
|
emit_insn (gen_movsi (operands[0],
|
gen_rtx_SUBREG (SImode, scratch,
|
gen_rtx_SUBREG (SImode, scratch,
|
GET_MODE_SIZE (SImode))));
|
GET_MODE_SIZE (SImode))));
|
DONE;
|
DONE;
|
}
|
}
|
operands[3] = gen_reg_rtx (SImode);
|
operands[3] = gen_reg_rtx (SImode);
|
}")
|
}")
|
|
|
(define_insn "umulsidi3"
|
(define_insn "umulsidi3"
|
[(set (match_operand:DI 0 "nonimmediate_operand" "=f")
|
[(set (match_operand:DI 0 "nonimmediate_operand" "=f")
|
(mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
|
(mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
|
(zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "f"))))]
|
(zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "f"))))]
|
"TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT"
|
"TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT"
|
"xmpyu %1,%2,%0"
|
"xmpyu %1,%2,%0"
|
[(set_attr "type" "fpmuldbl")
|
[(set_attr "type" "fpmuldbl")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "nonimmediate_operand" "=f")
|
[(set (match_operand:DI 0 "nonimmediate_operand" "=f")
|
(mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
|
(mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
|
(match_operand:DI 2 "uint32_operand" "f")))]
|
(match_operand:DI 2 "uint32_operand" "f")))]
|
"TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT && !TARGET_64BIT"
|
"TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT && !TARGET_64BIT"
|
"xmpyu %1,%R2,%0"
|
"xmpyu %1,%R2,%0"
|
[(set_attr "type" "fpmuldbl")
|
[(set_attr "type" "fpmuldbl")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "nonimmediate_operand" "=f")
|
[(set (match_operand:DI 0 "nonimmediate_operand" "=f")
|
(mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
|
(mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
|
(match_operand:DI 2 "uint32_operand" "f")))]
|
(match_operand:DI 2 "uint32_operand" "f")))]
|
"TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT && TARGET_64BIT"
|
"TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT && TARGET_64BIT"
|
"xmpyu %1,%2R,%0"
|
"xmpyu %1,%2R,%0"
|
[(set_attr "type" "fpmuldbl")
|
[(set_attr "type" "fpmuldbl")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
|
[(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
|
(clobber (match_operand:SI 0 "register_operand" "=a"))
|
(clobber (match_operand:SI 0 "register_operand" "=a"))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 25))
|
(clobber (reg:SI 25))
|
(clobber (reg:SI 31))]
|
(clobber (reg:SI 31))]
|
"!TARGET_64BIT"
|
"!TARGET_64BIT"
|
"* return output_mul_insn (0, insn);"
|
"* return output_mul_insn (0, insn);"
|
[(set_attr "type" "milli")
|
[(set_attr "type" "milli")
|
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
|
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
|
[(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
|
(clobber (match_operand:SI 0 "register_operand" "=a"))
|
(clobber (match_operand:SI 0 "register_operand" "=a"))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 25))
|
(clobber (reg:SI 25))
|
(clobber (reg:SI 2))]
|
(clobber (reg:SI 2))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"* return output_mul_insn (0, insn);"
|
"* return output_mul_insn (0, insn);"
|
[(set_attr "type" "milli")
|
[(set_attr "type" "milli")
|
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
|
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
|
|
|
(define_expand "muldi3"
|
(define_expand "muldi3"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(mult:DI (match_operand:DI 1 "register_operand" "")
|
(mult:DI (match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 2 "register_operand" "")))]
|
(match_operand:DI 2 "register_operand" "")))]
|
"TARGET_64BIT && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT"
|
"TARGET_64BIT && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT"
|
"
|
"
|
{
|
{
|
rtx low_product = gen_reg_rtx (DImode);
|
rtx low_product = gen_reg_rtx (DImode);
|
rtx cross_product1 = gen_reg_rtx (DImode);
|
rtx cross_product1 = gen_reg_rtx (DImode);
|
rtx cross_product2 = gen_reg_rtx (DImode);
|
rtx cross_product2 = gen_reg_rtx (DImode);
|
rtx cross_scratch = gen_reg_rtx (DImode);
|
rtx cross_scratch = gen_reg_rtx (DImode);
|
rtx cross_product = gen_reg_rtx (DImode);
|
rtx cross_product = gen_reg_rtx (DImode);
|
rtx op1l, op1r, op2l, op2r;
|
rtx op1l, op1r, op2l, op2r;
|
rtx op1shifted, op2shifted;
|
rtx op1shifted, op2shifted;
|
|
|
op1shifted = gen_reg_rtx (DImode);
|
op1shifted = gen_reg_rtx (DImode);
|
op2shifted = gen_reg_rtx (DImode);
|
op2shifted = gen_reg_rtx (DImode);
|
op1l = gen_reg_rtx (SImode);
|
op1l = gen_reg_rtx (SImode);
|
op1r = gen_reg_rtx (SImode);
|
op1r = gen_reg_rtx (SImode);
|
op2l = gen_reg_rtx (SImode);
|
op2l = gen_reg_rtx (SImode);
|
op2r = gen_reg_rtx (SImode);
|
op2r = gen_reg_rtx (SImode);
|
|
|
emit_move_insn (op1shifted, gen_rtx_LSHIFTRT (DImode, operands[1],
|
emit_move_insn (op1shifted, gen_rtx_LSHIFTRT (DImode, operands[1],
|
GEN_INT (32)));
|
GEN_INT (32)));
|
emit_move_insn (op2shifted, gen_rtx_LSHIFTRT (DImode, operands[2],
|
emit_move_insn (op2shifted, gen_rtx_LSHIFTRT (DImode, operands[2],
|
GEN_INT (32)));
|
GEN_INT (32)));
|
op1r = force_reg (SImode, gen_rtx_SUBREG (SImode, operands[1], 4));
|
op1r = force_reg (SImode, gen_rtx_SUBREG (SImode, operands[1], 4));
|
op2r = force_reg (SImode, gen_rtx_SUBREG (SImode, operands[2], 4));
|
op2r = force_reg (SImode, gen_rtx_SUBREG (SImode, operands[2], 4));
|
op1l = force_reg (SImode, gen_rtx_SUBREG (SImode, op1shifted, 4));
|
op1l = force_reg (SImode, gen_rtx_SUBREG (SImode, op1shifted, 4));
|
op2l = force_reg (SImode, gen_rtx_SUBREG (SImode, op2shifted, 4));
|
op2l = force_reg (SImode, gen_rtx_SUBREG (SImode, op2shifted, 4));
|
|
|
/* Emit multiplies for the cross products. */
|
/* Emit multiplies for the cross products. */
|
emit_insn (gen_umulsidi3 (cross_product1, op2r, op1l));
|
emit_insn (gen_umulsidi3 (cross_product1, op2r, op1l));
|
emit_insn (gen_umulsidi3 (cross_product2, op2l, op1r));
|
emit_insn (gen_umulsidi3 (cross_product2, op2l, op1r));
|
|
|
/* Emit a multiply for the low sub-word. */
|
/* Emit a multiply for the low sub-word. */
|
emit_insn (gen_umulsidi3 (low_product, copy_rtx (op2r), copy_rtx (op1r)));
|
emit_insn (gen_umulsidi3 (low_product, copy_rtx (op2r), copy_rtx (op1r)));
|
|
|
/* Sum the cross products and shift them into proper position. */
|
/* Sum the cross products and shift them into proper position. */
|
emit_insn (gen_adddi3 (cross_scratch, cross_product1, cross_product2));
|
emit_insn (gen_adddi3 (cross_scratch, cross_product1, cross_product2));
|
emit_insn (gen_ashldi3 (cross_product, cross_scratch, GEN_INT (32)));
|
emit_insn (gen_ashldi3 (cross_product, cross_scratch, GEN_INT (32)));
|
|
|
/* Add the cross product to the low product and store the result
|
/* Add the cross product to the low product and store the result
|
into the output operand . */
|
into the output operand . */
|
emit_insn (gen_adddi3 (operands[0], cross_product, low_product));
|
emit_insn (gen_adddi3 (operands[0], cross_product, low_product));
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
;;; Division and mod.
|
;;; Division and mod.
|
(define_expand "divsi3"
|
(define_expand "divsi3"
|
[(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
|
[(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
|
(set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
|
(set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
|
(parallel [(set (reg:SI 29) (div:SI (reg:SI 26) (reg:SI 25)))
|
(parallel [(set (reg:SI 29) (div:SI (reg:SI 26) (reg:SI 25)))
|
(clobber (match_dup 3))
|
(clobber (match_dup 3))
|
(clobber (match_dup 4))
|
(clobber (match_dup 4))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 25))
|
(clobber (reg:SI 25))
|
(clobber (match_dup 5))])
|
(clobber (match_dup 5))])
|
(set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
|
(set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
|
""
|
""
|
"
|
"
|
{
|
{
|
operands[3] = gen_reg_rtx (SImode);
|
operands[3] = gen_reg_rtx (SImode);
|
if (TARGET_64BIT)
|
if (TARGET_64BIT)
|
{
|
{
|
operands[5] = gen_rtx_REG (SImode, 2);
|
operands[5] = gen_rtx_REG (SImode, 2);
|
operands[4] = operands[5];
|
operands[4] = operands[5];
|
}
|
}
|
else
|
else
|
{
|
{
|
operands[5] = gen_rtx_REG (SImode, 31);
|
operands[5] = gen_rtx_REG (SImode, 31);
|
operands[4] = gen_reg_rtx (SImode);
|
operands[4] = gen_reg_rtx (SImode);
|
}
|
}
|
if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 0))
|
if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 0))
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (reg:SI 29)
|
[(set (reg:SI 29)
|
(div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
|
(div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
|
(clobber (match_operand:SI 1 "register_operand" "=a"))
|
(clobber (match_operand:SI 1 "register_operand" "=a"))
|
(clobber (match_operand:SI 2 "register_operand" "=&r"))
|
(clobber (match_operand:SI 2 "register_operand" "=&r"))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 25))
|
(clobber (reg:SI 25))
|
(clobber (reg:SI 31))]
|
(clobber (reg:SI 31))]
|
"!TARGET_64BIT"
|
"!TARGET_64BIT"
|
"*
|
"*
|
return output_div_insn (operands, 0, insn);"
|
return output_div_insn (operands, 0, insn);"
|
[(set_attr "type" "milli")
|
[(set_attr "type" "milli")
|
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
|
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (reg:SI 29)
|
[(set (reg:SI 29)
|
(div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
|
(div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
|
(clobber (match_operand:SI 1 "register_operand" "=a"))
|
(clobber (match_operand:SI 1 "register_operand" "=a"))
|
(clobber (match_operand:SI 2 "register_operand" "=&r"))
|
(clobber (match_operand:SI 2 "register_operand" "=&r"))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 25))
|
(clobber (reg:SI 25))
|
(clobber (reg:SI 2))]
|
(clobber (reg:SI 2))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"*
|
"*
|
return output_div_insn (operands, 0, insn);"
|
return output_div_insn (operands, 0, insn);"
|
[(set_attr "type" "milli")
|
[(set_attr "type" "milli")
|
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
|
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
|
|
|
(define_expand "udivsi3"
|
(define_expand "udivsi3"
|
[(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
|
[(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
|
(set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
|
(set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
|
(parallel [(set (reg:SI 29) (udiv:SI (reg:SI 26) (reg:SI 25)))
|
(parallel [(set (reg:SI 29) (udiv:SI (reg:SI 26) (reg:SI 25)))
|
(clobber (match_dup 3))
|
(clobber (match_dup 3))
|
(clobber (match_dup 4))
|
(clobber (match_dup 4))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 25))
|
(clobber (reg:SI 25))
|
(clobber (match_dup 5))])
|
(clobber (match_dup 5))])
|
(set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
|
(set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
|
""
|
""
|
"
|
"
|
{
|
{
|
operands[3] = gen_reg_rtx (SImode);
|
operands[3] = gen_reg_rtx (SImode);
|
|
|
if (TARGET_64BIT)
|
if (TARGET_64BIT)
|
{
|
{
|
operands[5] = gen_rtx_REG (SImode, 2);
|
operands[5] = gen_rtx_REG (SImode, 2);
|
operands[4] = operands[5];
|
operands[4] = operands[5];
|
}
|
}
|
else
|
else
|
{
|
{
|
operands[5] = gen_rtx_REG (SImode, 31);
|
operands[5] = gen_rtx_REG (SImode, 31);
|
operands[4] = gen_reg_rtx (SImode);
|
operands[4] = gen_reg_rtx (SImode);
|
}
|
}
|
if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 1))
|
if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 1))
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (reg:SI 29)
|
[(set (reg:SI 29)
|
(udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
|
(udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
|
(clobber (match_operand:SI 1 "register_operand" "=a"))
|
(clobber (match_operand:SI 1 "register_operand" "=a"))
|
(clobber (match_operand:SI 2 "register_operand" "=&r"))
|
(clobber (match_operand:SI 2 "register_operand" "=&r"))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 25))
|
(clobber (reg:SI 25))
|
(clobber (reg:SI 31))]
|
(clobber (reg:SI 31))]
|
"!TARGET_64BIT"
|
"!TARGET_64BIT"
|
"*
|
"*
|
return output_div_insn (operands, 1, insn);"
|
return output_div_insn (operands, 1, insn);"
|
[(set_attr "type" "milli")
|
[(set_attr "type" "milli")
|
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
|
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (reg:SI 29)
|
[(set (reg:SI 29)
|
(udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
|
(udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
|
(clobber (match_operand:SI 1 "register_operand" "=a"))
|
(clobber (match_operand:SI 1 "register_operand" "=a"))
|
(clobber (match_operand:SI 2 "register_operand" "=&r"))
|
(clobber (match_operand:SI 2 "register_operand" "=&r"))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 25))
|
(clobber (reg:SI 25))
|
(clobber (reg:SI 2))]
|
(clobber (reg:SI 2))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"*
|
"*
|
return output_div_insn (operands, 1, insn);"
|
return output_div_insn (operands, 1, insn);"
|
[(set_attr "type" "milli")
|
[(set_attr "type" "milli")
|
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
|
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
|
|
|
(define_expand "modsi3"
|
(define_expand "modsi3"
|
[(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
|
[(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
|
(set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
|
(set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
|
(parallel [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
|
(parallel [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
|
(clobber (match_dup 3))
|
(clobber (match_dup 3))
|
(clobber (match_dup 4))
|
(clobber (match_dup 4))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 25))
|
(clobber (reg:SI 25))
|
(clobber (match_dup 5))])
|
(clobber (match_dup 5))])
|
(set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
|
(set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
|
""
|
""
|
"
|
"
|
{
|
{
|
if (TARGET_64BIT)
|
if (TARGET_64BIT)
|
{
|
{
|
operands[5] = gen_rtx_REG (SImode, 2);
|
operands[5] = gen_rtx_REG (SImode, 2);
|
operands[4] = operands[5];
|
operands[4] = operands[5];
|
}
|
}
|
else
|
else
|
{
|
{
|
operands[5] = gen_rtx_REG (SImode, 31);
|
operands[5] = gen_rtx_REG (SImode, 31);
|
operands[4] = gen_reg_rtx (SImode);
|
operands[4] = gen_reg_rtx (SImode);
|
}
|
}
|
operands[3] = gen_reg_rtx (SImode);
|
operands[3] = gen_reg_rtx (SImode);
|
}")
|
}")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
|
[(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
|
(clobber (match_operand:SI 0 "register_operand" "=a"))
|
(clobber (match_operand:SI 0 "register_operand" "=a"))
|
(clobber (match_operand:SI 1 "register_operand" "=&r"))
|
(clobber (match_operand:SI 1 "register_operand" "=&r"))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 25))
|
(clobber (reg:SI 25))
|
(clobber (reg:SI 31))]
|
(clobber (reg:SI 31))]
|
"!TARGET_64BIT"
|
"!TARGET_64BIT"
|
"*
|
"*
|
return output_mod_insn (0, insn);"
|
return output_mod_insn (0, insn);"
|
[(set_attr "type" "milli")
|
[(set_attr "type" "milli")
|
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
|
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
|
[(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
|
(clobber (match_operand:SI 0 "register_operand" "=a"))
|
(clobber (match_operand:SI 0 "register_operand" "=a"))
|
(clobber (match_operand:SI 1 "register_operand" "=&r"))
|
(clobber (match_operand:SI 1 "register_operand" "=&r"))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 25))
|
(clobber (reg:SI 25))
|
(clobber (reg:SI 2))]
|
(clobber (reg:SI 2))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"*
|
"*
|
return output_mod_insn (0, insn);"
|
return output_mod_insn (0, insn);"
|
[(set_attr "type" "milli")
|
[(set_attr "type" "milli")
|
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
|
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
|
|
|
(define_expand "umodsi3"
|
(define_expand "umodsi3"
|
[(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
|
[(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
|
(set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
|
(set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
|
(parallel [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
|
(parallel [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
|
(clobber (match_dup 3))
|
(clobber (match_dup 3))
|
(clobber (match_dup 4))
|
(clobber (match_dup 4))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 25))
|
(clobber (reg:SI 25))
|
(clobber (match_dup 5))])
|
(clobber (match_dup 5))])
|
(set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
|
(set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
|
""
|
""
|
"
|
"
|
{
|
{
|
if (TARGET_64BIT)
|
if (TARGET_64BIT)
|
{
|
{
|
operands[5] = gen_rtx_REG (SImode, 2);
|
operands[5] = gen_rtx_REG (SImode, 2);
|
operands[4] = operands[5];
|
operands[4] = operands[5];
|
}
|
}
|
else
|
else
|
{
|
{
|
operands[5] = gen_rtx_REG (SImode, 31);
|
operands[5] = gen_rtx_REG (SImode, 31);
|
operands[4] = gen_reg_rtx (SImode);
|
operands[4] = gen_reg_rtx (SImode);
|
}
|
}
|
operands[3] = gen_reg_rtx (SImode);
|
operands[3] = gen_reg_rtx (SImode);
|
}")
|
}")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
|
[(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
|
(clobber (match_operand:SI 0 "register_operand" "=a"))
|
(clobber (match_operand:SI 0 "register_operand" "=a"))
|
(clobber (match_operand:SI 1 "register_operand" "=&r"))
|
(clobber (match_operand:SI 1 "register_operand" "=&r"))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 25))
|
(clobber (reg:SI 25))
|
(clobber (reg:SI 31))]
|
(clobber (reg:SI 31))]
|
"!TARGET_64BIT"
|
"!TARGET_64BIT"
|
"*
|
"*
|
return output_mod_insn (1, insn);"
|
return output_mod_insn (1, insn);"
|
[(set_attr "type" "milli")
|
[(set_attr "type" "milli")
|
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
|
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
|
[(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
|
(clobber (match_operand:SI 0 "register_operand" "=a"))
|
(clobber (match_operand:SI 0 "register_operand" "=a"))
|
(clobber (match_operand:SI 1 "register_operand" "=&r"))
|
(clobber (match_operand:SI 1 "register_operand" "=&r"))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 25))
|
(clobber (reg:SI 25))
|
(clobber (reg:SI 2))]
|
(clobber (reg:SI 2))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"*
|
"*
|
return output_mod_insn (1, insn);"
|
return output_mod_insn (1, insn);"
|
[(set_attr "type" "milli")
|
[(set_attr "type" "milli")
|
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
|
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
|
|
|
;;- and instructions
|
;;- and instructions
|
;; We define DImode `and` so with DImode `not` we can get
|
;; We define DImode `and` so with DImode `not` we can get
|
;; DImode `andn`. Other combinations are possible.
|
;; DImode `andn`. Other combinations are possible.
|
|
|
(define_expand "anddi3"
|
(define_expand "anddi3"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(and:DI (match_operand:DI 1 "register_operand" "")
|
(and:DI (match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 2 "and_operand" "")))]
|
(match_operand:DI 2 "and_operand" "")))]
|
""
|
""
|
"
|
"
|
{
|
{
|
/* Both operands must be register operands. */
|
/* Both operands must be register operands. */
|
if (!TARGET_64BIT && !register_operand (operands[2], DImode))
|
if (!TARGET_64BIT && !register_operand (operands[2], DImode))
|
FAIL;
|
FAIL;
|
}")
|
}")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(and:DI (match_operand:DI 1 "register_operand" "%r")
|
(and:DI (match_operand:DI 1 "register_operand" "%r")
|
(match_operand:DI 2 "register_operand" "r")))]
|
(match_operand:DI 2 "register_operand" "r")))]
|
"!TARGET_64BIT"
|
"!TARGET_64BIT"
|
"and %1,%2,%0\;and %R1,%R2,%R0"
|
"and %1,%2,%0\;and %R1,%R2,%R0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
(and:DI (match_operand:DI 1 "register_operand" "%?r,0")
|
(and:DI (match_operand:DI 1 "register_operand" "%?r,0")
|
(match_operand:DI 2 "and_operand" "rO,P")))]
|
(match_operand:DI 2 "and_operand" "rO,P")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"* return output_64bit_and (operands); "
|
"* return output_64bit_and (operands); "
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
; The ? for op1 makes reload prefer zdepi instead of loading a huge
|
; The ? for op1 makes reload prefer zdepi instead of loading a huge
|
; constant with ldil;ldo.
|
; constant with ldil;ldo.
|
(define_insn "andsi3"
|
(define_insn "andsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
(and:SI (match_operand:SI 1 "register_operand" "%?r,0")
|
(and:SI (match_operand:SI 1 "register_operand" "%?r,0")
|
(match_operand:SI 2 "and_operand" "rO,P")))]
|
(match_operand:SI 2 "and_operand" "rO,P")))]
|
""
|
""
|
"* return output_and (operands); "
|
"* return output_and (operands); "
|
[(set_attr "type" "binary,shift")
|
[(set_attr "type" "binary,shift")
|
(set_attr "length" "4,4")])
|
(set_attr "length" "4,4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
|
(and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
|
(match_operand:DI 2 "register_operand" "r")))]
|
(match_operand:DI 2 "register_operand" "r")))]
|
"!TARGET_64BIT"
|
"!TARGET_64BIT"
|
"andcm %2,%1,%0\;andcm %R2,%R1,%R0"
|
"andcm %2,%1,%0\;andcm %R2,%R1,%R0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
|
(and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
|
(match_operand:DI 2 "register_operand" "r")))]
|
(match_operand:DI 2 "register_operand" "r")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"andcm %2,%1,%0"
|
"andcm %2,%1,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
|
(and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
|
(match_operand:SI 2 "register_operand" "r")))]
|
(match_operand:SI 2 "register_operand" "r")))]
|
""
|
""
|
"andcm %2,%1,%0"
|
"andcm %2,%1,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_expand "iordi3"
|
(define_expand "iordi3"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(ior:DI (match_operand:DI 1 "register_operand" "")
|
(ior:DI (match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 2 "ior_operand" "")))]
|
(match_operand:DI 2 "ior_operand" "")))]
|
""
|
""
|
"
|
"
|
{
|
{
|
/* Both operands must be register operands. */
|
/* Both operands must be register operands. */
|
if (!TARGET_64BIT && !register_operand (operands[2], DImode))
|
if (!TARGET_64BIT && !register_operand (operands[2], DImode))
|
FAIL;
|
FAIL;
|
}")
|
}")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(ior:DI (match_operand:DI 1 "register_operand" "%r")
|
(ior:DI (match_operand:DI 1 "register_operand" "%r")
|
(match_operand:DI 2 "register_operand" "r")))]
|
(match_operand:DI 2 "register_operand" "r")))]
|
"!TARGET_64BIT"
|
"!TARGET_64BIT"
|
"or %1,%2,%0\;or %R1,%R2,%R0"
|
"or %1,%2,%0\;or %R1,%R2,%R0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
(ior:DI (match_operand:DI 1 "register_operand" "0,0")
|
(ior:DI (match_operand:DI 1 "register_operand" "0,0")
|
(match_operand:DI 2 "ior_operand" "M,i")))]
|
(match_operand:DI 2 "ior_operand" "M,i")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"* return output_64bit_ior (operands); "
|
"* return output_64bit_ior (operands); "
|
[(set_attr "type" "binary,shift")
|
[(set_attr "type" "binary,shift")
|
(set_attr "length" "4,4")])
|
(set_attr "length" "4,4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(ior:DI (match_operand:DI 1 "register_operand" "%r")
|
(ior:DI (match_operand:DI 1 "register_operand" "%r")
|
(match_operand:DI 2 "register_operand" "r")))]
|
(match_operand:DI 2 "register_operand" "r")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"or %1,%2,%0"
|
"or %1,%2,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
;; Need a define_expand because we've run out of CONST_OK... characters.
|
;; Need a define_expand because we've run out of CONST_OK... characters.
|
(define_expand "iorsi3"
|
(define_expand "iorsi3"
|
[(set (match_operand:SI 0 "register_operand" "")
|
[(set (match_operand:SI 0 "register_operand" "")
|
(ior:SI (match_operand:SI 1 "register_operand" "")
|
(ior:SI (match_operand:SI 1 "register_operand" "")
|
(match_operand:SI 2 "arith32_operand" "")))]
|
(match_operand:SI 2 "arith32_operand" "")))]
|
""
|
""
|
"
|
"
|
{
|
{
|
if (! (ior_operand (operands[2], SImode)
|
if (! (ior_operand (operands[2], SImode)
|
|| register_operand (operands[2], SImode)))
|
|| register_operand (operands[2], SImode)))
|
operands[2] = force_reg (SImode, operands[2]);
|
operands[2] = force_reg (SImode, operands[2]);
|
}")
|
}")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
(ior:SI (match_operand:SI 1 "register_operand" "0,0")
|
(ior:SI (match_operand:SI 1 "register_operand" "0,0")
|
(match_operand:SI 2 "ior_operand" "M,i")))]
|
(match_operand:SI 2 "ior_operand" "M,i")))]
|
""
|
""
|
"* return output_ior (operands); "
|
"* return output_ior (operands); "
|
[(set_attr "type" "binary,shift")
|
[(set_attr "type" "binary,shift")
|
(set_attr "length" "4,4")])
|
(set_attr "length" "4,4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(ior:SI (match_operand:SI 1 "register_operand" "%r")
|
(ior:SI (match_operand:SI 1 "register_operand" "%r")
|
(match_operand:SI 2 "register_operand" "r")))]
|
(match_operand:SI 2 "register_operand" "r")))]
|
""
|
""
|
"or %1,%2,%0"
|
"or %1,%2,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_expand "xordi3"
|
(define_expand "xordi3"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(xor:DI (match_operand:DI 1 "register_operand" "")
|
(xor:DI (match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 2 "register_operand" "")))]
|
(match_operand:DI 2 "register_operand" "")))]
|
""
|
""
|
"
|
"
|
{
|
{
|
}")
|
}")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(xor:DI (match_operand:DI 1 "register_operand" "%r")
|
(xor:DI (match_operand:DI 1 "register_operand" "%r")
|
(match_operand:DI 2 "register_operand" "r")))]
|
(match_operand:DI 2 "register_operand" "r")))]
|
"!TARGET_64BIT"
|
"!TARGET_64BIT"
|
"xor %1,%2,%0\;xor %R1,%R2,%R0"
|
"xor %1,%2,%0\;xor %R1,%R2,%R0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(xor:DI (match_operand:DI 1 "register_operand" "%r")
|
(xor:DI (match_operand:DI 1 "register_operand" "%r")
|
(match_operand:DI 2 "register_operand" "r")))]
|
(match_operand:DI 2 "register_operand" "r")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"xor %1,%2,%0"
|
"xor %1,%2,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "xorsi3"
|
(define_insn "xorsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(xor:SI (match_operand:SI 1 "register_operand" "%r")
|
(xor:SI (match_operand:SI 1 "register_operand" "%r")
|
(match_operand:SI 2 "register_operand" "r")))]
|
(match_operand:SI 2 "register_operand" "r")))]
|
""
|
""
|
"xor %1,%2,%0"
|
"xor %1,%2,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_expand "negdi2"
|
(define_expand "negdi2"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(neg:DI (match_operand:DI 1 "register_operand" "")))]
|
(neg:DI (match_operand:DI 1 "register_operand" "")))]
|
""
|
""
|
"")
|
"")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(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")))]
|
"!TARGET_64BIT"
|
"!TARGET_64BIT"
|
"sub %%r0,%R1,%R0\;{subb|sub,b} %%r0,%1,%0"
|
"sub %%r0,%R1,%R0\;{subb|sub,b} %%r0,%1,%0"
|
[(set_attr "type" "unary")
|
[(set_attr "type" "unary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(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")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"sub %%r0,%1,%0"
|
"sub %%r0,%1,%0"
|
[(set_attr "type" "unary")
|
[(set_attr "type" "unary")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_expand "negvdi2"
|
(define_expand "negvdi2"
|
[(parallel [(set (match_operand:DI 0 "register_operand" "")
|
[(parallel [(set (match_operand:DI 0 "register_operand" "")
|
(neg:DI (match_operand:DI 1 "register_operand" "")))
|
(neg:DI (match_operand:DI 1 "register_operand" "")))
|
(trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
|
(trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
|
(sign_extend:TI (neg:DI (match_dup 1))))
|
(sign_extend:TI (neg:DI (match_dup 1))))
|
(const_int 0))])]
|
(const_int 0))])]
|
""
|
""
|
"")
|
"")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(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)))
|
(trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
|
(sign_extend:TI (neg:DI (match_dup 1))))
|
(sign_extend:TI (neg:DI (match_dup 1))))
|
(const_int 0))]
|
(const_int 0))]
|
"!TARGET_64BIT"
|
"!TARGET_64BIT"
|
"sub %%r0,%R1,%R0\;{subbo|sub,b,tsv} %%r0,%1,%0"
|
"sub %%r0,%R1,%R0\;{subbo|sub,b,tsv} %%r0,%1,%0"
|
[(set_attr "type" "unary")
|
[(set_attr "type" "unary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(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)))
|
(trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
|
(sign_extend:TI (neg:DI (match_dup 1))))
|
(sign_extend:TI (neg:DI (match_dup 1))))
|
(const_int 0))]
|
(const_int 0))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"sub,tsv %%r0,%1,%0"
|
"sub,tsv %%r0,%1,%0"
|
[(set_attr "type" "unary")
|
[(set_attr "type" "unary")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "negsi2"
|
(define_insn "negsi2"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(neg:SI (match_operand:SI 1 "register_operand" "r")))]
|
(neg:SI (match_operand:SI 1 "register_operand" "r")))]
|
""
|
""
|
"sub %%r0,%1,%0"
|
"sub %%r0,%1,%0"
|
[(set_attr "type" "unary")
|
[(set_attr "type" "unary")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "negvsi2"
|
(define_insn "negvsi2"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(neg:SI (match_operand:SI 1 "register_operand" "r")))
|
(neg:SI (match_operand:SI 1 "register_operand" "r")))
|
(trap_if (ne (neg:DI (sign_extend:DI (match_dup 1)))
|
(trap_if (ne (neg:DI (sign_extend:DI (match_dup 1)))
|
(sign_extend:DI (neg:SI (match_dup 1))))
|
(sign_extend:DI (neg:SI (match_dup 1))))
|
(const_int 0))]
|
(const_int 0))]
|
""
|
""
|
"{subo|sub,tsv} %%r0,%1,%0"
|
"{subo|sub,tsv} %%r0,%1,%0"
|
[(set_attr "type" "unary")
|
[(set_attr "type" "unary")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_expand "one_cmpldi2"
|
(define_expand "one_cmpldi2"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(not:DI (match_operand:DI 1 "register_operand" "")))]
|
(not:DI (match_operand:DI 1 "register_operand" "")))]
|
""
|
""
|
"
|
"
|
{
|
{
|
}")
|
}")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(not:DI (match_operand:DI 1 "register_operand" "r")))]
|
(not:DI (match_operand:DI 1 "register_operand" "r")))]
|
"!TARGET_64BIT"
|
"!TARGET_64BIT"
|
"uaddcm %%r0,%1,%0\;uaddcm %%r0,%R1,%R0"
|
"uaddcm %%r0,%1,%0\;uaddcm %%r0,%R1,%R0"
|
[(set_attr "type" "unary")
|
[(set_attr "type" "unary")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(not:DI (match_operand:DI 1 "register_operand" "r")))]
|
(not:DI (match_operand:DI 1 "register_operand" "r")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"uaddcm %%r0,%1,%0"
|
"uaddcm %%r0,%1,%0"
|
[(set_attr "type" "unary")
|
[(set_attr "type" "unary")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "one_cmplsi2"
|
(define_insn "one_cmplsi2"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(not:SI (match_operand:SI 1 "register_operand" "r")))]
|
(not:SI (match_operand:SI 1 "register_operand" "r")))]
|
""
|
""
|
"uaddcm %%r0,%1,%0"
|
"uaddcm %%r0,%1,%0"
|
[(set_attr "type" "unary")
|
[(set_attr "type" "unary")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
;; Floating point arithmetic instructions.
|
;; Floating point arithmetic instructions.
|
|
|
(define_insn "adddf3"
|
(define_insn "adddf3"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(plus:DF (match_operand:DF 1 "register_operand" "f")
|
(plus:DF (match_operand:DF 1 "register_operand" "f")
|
(match_operand:DF 2 "register_operand" "f")))]
|
(match_operand:DF 2 "register_operand" "f")))]
|
"! TARGET_SOFT_FLOAT"
|
"! TARGET_SOFT_FLOAT"
|
"fadd,dbl %1,%2,%0"
|
"fadd,dbl %1,%2,%0"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "pa_combine_type" "faddsub")
|
(set_attr "pa_combine_type" "faddsub")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "addsf3"
|
(define_insn "addsf3"
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(plus:SF (match_operand:SF 1 "register_operand" "f")
|
(plus:SF (match_operand:SF 1 "register_operand" "f")
|
(match_operand:SF 2 "register_operand" "f")))]
|
(match_operand:SF 2 "register_operand" "f")))]
|
"! TARGET_SOFT_FLOAT"
|
"! TARGET_SOFT_FLOAT"
|
"fadd,sgl %1,%2,%0"
|
"fadd,sgl %1,%2,%0"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "pa_combine_type" "faddsub")
|
(set_attr "pa_combine_type" "faddsub")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "subdf3"
|
(define_insn "subdf3"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(minus:DF (match_operand:DF 1 "register_operand" "f")
|
(minus:DF (match_operand:DF 1 "register_operand" "f")
|
(match_operand:DF 2 "register_operand" "f")))]
|
(match_operand:DF 2 "register_operand" "f")))]
|
"! TARGET_SOFT_FLOAT"
|
"! TARGET_SOFT_FLOAT"
|
"fsub,dbl %1,%2,%0"
|
"fsub,dbl %1,%2,%0"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "pa_combine_type" "faddsub")
|
(set_attr "pa_combine_type" "faddsub")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "subsf3"
|
(define_insn "subsf3"
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(minus:SF (match_operand:SF 1 "register_operand" "f")
|
(minus:SF (match_operand:SF 1 "register_operand" "f")
|
(match_operand:SF 2 "register_operand" "f")))]
|
(match_operand:SF 2 "register_operand" "f")))]
|
"! TARGET_SOFT_FLOAT"
|
"! TARGET_SOFT_FLOAT"
|
"fsub,sgl %1,%2,%0"
|
"fsub,sgl %1,%2,%0"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "pa_combine_type" "faddsub")
|
(set_attr "pa_combine_type" "faddsub")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "muldf3"
|
(define_insn "muldf3"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(mult:DF (match_operand:DF 1 "register_operand" "f")
|
(mult:DF (match_operand:DF 1 "register_operand" "f")
|
(match_operand:DF 2 "register_operand" "f")))]
|
(match_operand:DF 2 "register_operand" "f")))]
|
"! TARGET_SOFT_FLOAT"
|
"! TARGET_SOFT_FLOAT"
|
"fmpy,dbl %1,%2,%0"
|
"fmpy,dbl %1,%2,%0"
|
[(set_attr "type" "fpmuldbl")
|
[(set_attr "type" "fpmuldbl")
|
(set_attr "pa_combine_type" "fmpy")
|
(set_attr "pa_combine_type" "fmpy")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "mulsf3"
|
(define_insn "mulsf3"
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(mult:SF (match_operand:SF 1 "register_operand" "f")
|
(mult:SF (match_operand:SF 1 "register_operand" "f")
|
(match_operand:SF 2 "register_operand" "f")))]
|
(match_operand:SF 2 "register_operand" "f")))]
|
"! TARGET_SOFT_FLOAT"
|
"! TARGET_SOFT_FLOAT"
|
"fmpy,sgl %1,%2,%0"
|
"fmpy,sgl %1,%2,%0"
|
[(set_attr "type" "fpmulsgl")
|
[(set_attr "type" "fpmulsgl")
|
(set_attr "pa_combine_type" "fmpy")
|
(set_attr "pa_combine_type" "fmpy")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "divdf3"
|
(define_insn "divdf3"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(div:DF (match_operand:DF 1 "register_operand" "f")
|
(div:DF (match_operand:DF 1 "register_operand" "f")
|
(match_operand:DF 2 "register_operand" "f")))]
|
(match_operand:DF 2 "register_operand" "f")))]
|
"! TARGET_SOFT_FLOAT"
|
"! TARGET_SOFT_FLOAT"
|
"fdiv,dbl %1,%2,%0"
|
"fdiv,dbl %1,%2,%0"
|
[(set_attr "type" "fpdivdbl")
|
[(set_attr "type" "fpdivdbl")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "divsf3"
|
(define_insn "divsf3"
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(div:SF (match_operand:SF 1 "register_operand" "f")
|
(div:SF (match_operand:SF 1 "register_operand" "f")
|
(match_operand:SF 2 "register_operand" "f")))]
|
(match_operand:SF 2 "register_operand" "f")))]
|
"! TARGET_SOFT_FLOAT"
|
"! TARGET_SOFT_FLOAT"
|
"fdiv,sgl %1,%2,%0"
|
"fdiv,sgl %1,%2,%0"
|
[(set_attr "type" "fpdivsgl")
|
[(set_attr "type" "fpdivsgl")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
;; Processors prior to PA 2.0 don't have a fneg instruction. Fast
|
;; Processors prior to PA 2.0 don't have a fneg instruction. Fast
|
;; negation can be done by subtracting from plus zero. However, this
|
;; negation can be done by subtracting from plus zero. However, this
|
;; violates the IEEE standard when negating plus and minus zero.
|
;; violates the IEEE standard when negating plus and minus zero.
|
;; The slow path toggles the sign bit in the general registers.
|
;; The slow path toggles the sign bit in the general registers.
|
(define_expand "negdf2"
|
(define_expand "negdf2"
|
[(set (match_operand:DF 0 "register_operand" "")
|
[(set (match_operand:DF 0 "register_operand" "")
|
(neg:DF (match_operand:DF 1 "register_operand" "")))]
|
(neg:DF (match_operand:DF 1 "register_operand" "")))]
|
"!TARGET_SOFT_FLOAT"
|
"!TARGET_SOFT_FLOAT"
|
{
|
{
|
if (TARGET_PA_20 || flag_unsafe_math_optimizations)
|
if (TARGET_PA_20 || flag_unsafe_math_optimizations)
|
emit_insn (gen_negdf2_fast (operands[0], operands[1]));
|
emit_insn (gen_negdf2_fast (operands[0], operands[1]));
|
else
|
else
|
emit_insn (gen_negdf2_slow (operands[0], operands[1]));
|
emit_insn (gen_negdf2_slow (operands[0], operands[1]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_insn "negdf2_slow"
|
(define_insn "negdf2_slow"
|
[(set (match_operand:DF 0 "register_operand" "=r")
|
[(set (match_operand:DF 0 "register_operand" "=r")
|
(neg:DF (match_operand:DF 1 "register_operand" "r")))]
|
(neg:DF (match_operand:DF 1 "register_operand" "r")))]
|
"!TARGET_SOFT_FLOAT && !TARGET_PA_20"
|
"!TARGET_SOFT_FLOAT && !TARGET_PA_20"
|
"*
|
"*
|
{
|
{
|
if (rtx_equal_p (operands[0], operands[1]))
|
if (rtx_equal_p (operands[0], operands[1]))
|
return \"and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0\";
|
return \"and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0\";
|
else
|
else
|
return \"and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0\;copy %R1,%R0\";
|
return \"and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0\;copy %R1,%R0\";
|
}"
|
}"
|
[(set_attr "type" "multi")
|
[(set_attr "type" "multi")
|
(set (attr "length")
|
(set (attr "length")
|
(if_then_else (ne (symbol_ref "rtx_equal_p (operands[0], operands[1])")
|
(if_then_else (ne (symbol_ref "rtx_equal_p (operands[0], operands[1])")
|
(const_int 0))
|
(const_int 0))
|
(const_int 12)
|
(const_int 12)
|
(const_int 16)))])
|
(const_int 16)))])
|
|
|
(define_insn "negdf2_fast"
|
(define_insn "negdf2_fast"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(neg:DF (match_operand:DF 1 "register_operand" "f")))]
|
(neg:DF (match_operand:DF 1 "register_operand" "f")))]
|
"!TARGET_SOFT_FLOAT"
|
"!TARGET_SOFT_FLOAT"
|
"*
|
"*
|
{
|
{
|
if (TARGET_PA_20)
|
if (TARGET_PA_20)
|
return \"fneg,dbl %1,%0\";
|
return \"fneg,dbl %1,%0\";
|
else
|
else
|
return \"fsub,dbl %%fr0,%1,%0\";
|
return \"fsub,dbl %%fr0,%1,%0\";
|
}"
|
}"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_expand "negsf2"
|
(define_expand "negsf2"
|
[(set (match_operand:SF 0 "register_operand" "")
|
[(set (match_operand:SF 0 "register_operand" "")
|
(neg:SF (match_operand:SF 1 "register_operand" "")))]
|
(neg:SF (match_operand:SF 1 "register_operand" "")))]
|
"!TARGET_SOFT_FLOAT"
|
"!TARGET_SOFT_FLOAT"
|
{
|
{
|
if (TARGET_PA_20 || flag_unsafe_math_optimizations)
|
if (TARGET_PA_20 || flag_unsafe_math_optimizations)
|
emit_insn (gen_negsf2_fast (operands[0], operands[1]));
|
emit_insn (gen_negsf2_fast (operands[0], operands[1]));
|
else
|
else
|
emit_insn (gen_negsf2_slow (operands[0], operands[1]));
|
emit_insn (gen_negsf2_slow (operands[0], operands[1]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_insn "negsf2_slow"
|
(define_insn "negsf2_slow"
|
[(set (match_operand:SF 0 "register_operand" "=r")
|
[(set (match_operand:SF 0 "register_operand" "=r")
|
(neg:SF (match_operand:SF 1 "register_operand" "r")))]
|
(neg:SF (match_operand:SF 1 "register_operand" "r")))]
|
"!TARGET_SOFT_FLOAT && !TARGET_PA_20"
|
"!TARGET_SOFT_FLOAT && !TARGET_PA_20"
|
"and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0"
|
"and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0"
|
[(set_attr "type" "multi")
|
[(set_attr "type" "multi")
|
(set_attr "length" "12")])
|
(set_attr "length" "12")])
|
|
|
(define_insn "negsf2_fast"
|
(define_insn "negsf2_fast"
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(neg:SF (match_operand:SF 1 "register_operand" "f")))]
|
(neg:SF (match_operand:SF 1 "register_operand" "f")))]
|
"!TARGET_SOFT_FLOAT"
|
"!TARGET_SOFT_FLOAT"
|
"*
|
"*
|
{
|
{
|
if (TARGET_PA_20)
|
if (TARGET_PA_20)
|
return \"fneg,sgl %1,%0\";
|
return \"fneg,sgl %1,%0\";
|
else
|
else
|
return \"fsub,sgl %%fr0,%1,%0\";
|
return \"fsub,sgl %%fr0,%1,%0\";
|
}"
|
}"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "absdf2"
|
(define_insn "absdf2"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(abs:DF (match_operand:DF 1 "register_operand" "f")))]
|
(abs:DF (match_operand:DF 1 "register_operand" "f")))]
|
"! TARGET_SOFT_FLOAT"
|
"! TARGET_SOFT_FLOAT"
|
"fabs,dbl %1,%0"
|
"fabs,dbl %1,%0"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "abssf2"
|
(define_insn "abssf2"
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(abs:SF (match_operand:SF 1 "register_operand" "f")))]
|
(abs:SF (match_operand:SF 1 "register_operand" "f")))]
|
"! TARGET_SOFT_FLOAT"
|
"! TARGET_SOFT_FLOAT"
|
"fabs,sgl %1,%0"
|
"fabs,sgl %1,%0"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "sqrtdf2"
|
(define_insn "sqrtdf2"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
|
(sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
|
"! TARGET_SOFT_FLOAT"
|
"! TARGET_SOFT_FLOAT"
|
"fsqrt,dbl %1,%0"
|
"fsqrt,dbl %1,%0"
|
[(set_attr "type" "fpsqrtdbl")
|
[(set_attr "type" "fpsqrtdbl")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "sqrtsf2"
|
(define_insn "sqrtsf2"
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
|
(sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
|
"! TARGET_SOFT_FLOAT"
|
"! TARGET_SOFT_FLOAT"
|
"fsqrt,sgl %1,%0"
|
"fsqrt,sgl %1,%0"
|
[(set_attr "type" "fpsqrtsgl")
|
[(set_attr "type" "fpsqrtsgl")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
;; PA 2.0 floating point instructions
|
;; PA 2.0 floating point instructions
|
|
|
; fmpyfadd patterns
|
; fmpyfadd patterns
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
|
(plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
|
(match_operand:DF 2 "register_operand" "f"))
|
(match_operand:DF 2 "register_operand" "f"))
|
(match_operand:DF 3 "register_operand" "f")))]
|
(match_operand:DF 3 "register_operand" "f")))]
|
"TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
|
"TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
|
"fmpyfadd,dbl %1,%2,%3,%0"
|
"fmpyfadd,dbl %1,%2,%3,%0"
|
[(set_attr "type" "fpmuldbl")
|
[(set_attr "type" "fpmuldbl")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(plus:DF (match_operand:DF 1 "register_operand" "f")
|
(plus:DF (match_operand:DF 1 "register_operand" "f")
|
(mult:DF (match_operand:DF 2 "register_operand" "f")
|
(mult:DF (match_operand:DF 2 "register_operand" "f")
|
(match_operand:DF 3 "register_operand" "f"))))]
|
(match_operand:DF 3 "register_operand" "f"))))]
|
"TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
|
"TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
|
"fmpyfadd,dbl %2,%3,%1,%0"
|
"fmpyfadd,dbl %2,%3,%1,%0"
|
[(set_attr "type" "fpmuldbl")
|
[(set_attr "type" "fpmuldbl")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
|
(plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
|
(match_operand:SF 2 "register_operand" "f"))
|
(match_operand:SF 2 "register_operand" "f"))
|
(match_operand:SF 3 "register_operand" "f")))]
|
(match_operand:SF 3 "register_operand" "f")))]
|
"TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
|
"TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
|
"fmpyfadd,sgl %1,%2,%3,%0"
|
"fmpyfadd,sgl %1,%2,%3,%0"
|
[(set_attr "type" "fpmulsgl")
|
[(set_attr "type" "fpmulsgl")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(plus:SF (match_operand:SF 1 "register_operand" "f")
|
(plus:SF (match_operand:SF 1 "register_operand" "f")
|
(mult:SF (match_operand:SF 2 "register_operand" "f")
|
(mult:SF (match_operand:SF 2 "register_operand" "f")
|
(match_operand:SF 3 "register_operand" "f"))))]
|
(match_operand:SF 3 "register_operand" "f"))))]
|
"TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
|
"TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
|
"fmpyfadd,sgl %2,%3,%1,%0"
|
"fmpyfadd,sgl %2,%3,%1,%0"
|
[(set_attr "type" "fpmulsgl")
|
[(set_attr "type" "fpmulsgl")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
; fmpynfadd patterns
|
; fmpynfadd patterns
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(minus:DF (match_operand:DF 1 "register_operand" "f")
|
(minus:DF (match_operand:DF 1 "register_operand" "f")
|
(mult:DF (match_operand:DF 2 "register_operand" "f")
|
(mult:DF (match_operand:DF 2 "register_operand" "f")
|
(match_operand:DF 3 "register_operand" "f"))))]
|
(match_operand:DF 3 "register_operand" "f"))))]
|
"TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
|
"TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
|
"fmpynfadd,dbl %2,%3,%1,%0"
|
"fmpynfadd,dbl %2,%3,%1,%0"
|
[(set_attr "type" "fpmuldbl")
|
[(set_attr "type" "fpmuldbl")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(minus:SF (match_operand:SF 1 "register_operand" "f")
|
(minus:SF (match_operand:SF 1 "register_operand" "f")
|
(mult:SF (match_operand:SF 2 "register_operand" "f")
|
(mult:SF (match_operand:SF 2 "register_operand" "f")
|
(match_operand:SF 3 "register_operand" "f"))))]
|
(match_operand:SF 3 "register_operand" "f"))))]
|
"TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
|
"TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
|
"fmpynfadd,sgl %2,%3,%1,%0"
|
"fmpynfadd,sgl %2,%3,%1,%0"
|
[(set_attr "type" "fpmulsgl")
|
[(set_attr "type" "fpmulsgl")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
; fnegabs patterns
|
; fnegabs patterns
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))]
|
(neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))]
|
"TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
|
"TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
|
"fnegabs,dbl %1,%0"
|
"fnegabs,dbl %1,%0"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))]
|
(neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))]
|
"TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
|
"TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
|
"fnegabs,sgl %1,%0"
|
"fnegabs,sgl %1,%0"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
;; Generating a fused multiply sequence is a win for this case as it will
|
;; Generating a fused multiply sequence is a win for this case as it will
|
;; reduce the latency for the fused case without impacting the plain
|
;; reduce the latency for the fused case without impacting the plain
|
;; multiply case.
|
;; multiply case.
|
;;
|
;;
|
;; Similar possibilities exist for fnegabs, shadd and other insns which
|
;; Similar possibilities exist for fnegabs, shadd and other insns which
|
;; perform two operations with the result of the first feeding the second.
|
;; perform two operations with the result of the first feeding the second.
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
|
(plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
|
(match_operand:DF 2 "register_operand" "f"))
|
(match_operand:DF 2 "register_operand" "f"))
|
(match_operand:DF 3 "register_operand" "f")))
|
(match_operand:DF 3 "register_operand" "f")))
|
(set (match_operand:DF 4 "register_operand" "=&f")
|
(set (match_operand:DF 4 "register_operand" "=&f")
|
(mult:DF (match_dup 1) (match_dup 2)))]
|
(mult:DF (match_dup 1) (match_dup 2)))]
|
"(! TARGET_SOFT_FLOAT && TARGET_PA_20
|
"(! TARGET_SOFT_FLOAT && TARGET_PA_20
|
&& ! (reg_overlap_mentioned_p (operands[4], operands[1])
|
&& ! (reg_overlap_mentioned_p (operands[4], operands[1])
|
|| reg_overlap_mentioned_p (operands[4], operands[2])))"
|
|| reg_overlap_mentioned_p (operands[4], operands[2])))"
|
"#"
|
"#"
|
[(set_attr "type" "fpmuldbl")
|
[(set_attr "type" "fpmuldbl")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
;; We want to split this up during scheduling since we want both insns
|
;; We want to split this up during scheduling since we want both insns
|
;; to schedule independently.
|
;; to schedule independently.
|
(define_split
|
(define_split
|
[(set (match_operand:DF 0 "register_operand" "")
|
[(set (match_operand:DF 0 "register_operand" "")
|
(plus:DF (mult:DF (match_operand:DF 1 "register_operand" "")
|
(plus:DF (mult:DF (match_operand:DF 1 "register_operand" "")
|
(match_operand:DF 2 "register_operand" ""))
|
(match_operand:DF 2 "register_operand" ""))
|
(match_operand:DF 3 "register_operand" "")))
|
(match_operand:DF 3 "register_operand" "")))
|
(set (match_operand:DF 4 "register_operand" "")
|
(set (match_operand:DF 4 "register_operand" "")
|
(mult:DF (match_dup 1) (match_dup 2)))]
|
(mult:DF (match_dup 1) (match_dup 2)))]
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
[(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2)))
|
[(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2)))
|
(set (match_dup 0) (plus:DF (mult:DF (match_dup 1) (match_dup 2))
|
(set (match_dup 0) (plus:DF (mult:DF (match_dup 1) (match_dup 2))
|
(match_dup 3)))]
|
(match_dup 3)))]
|
"")
|
"")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
|
(plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
|
(match_operand:SF 2 "register_operand" "f"))
|
(match_operand:SF 2 "register_operand" "f"))
|
(match_operand:SF 3 "register_operand" "f")))
|
(match_operand:SF 3 "register_operand" "f")))
|
(set (match_operand:SF 4 "register_operand" "=&f")
|
(set (match_operand:SF 4 "register_operand" "=&f")
|
(mult:SF (match_dup 1) (match_dup 2)))]
|
(mult:SF (match_dup 1) (match_dup 2)))]
|
"(! TARGET_SOFT_FLOAT && TARGET_PA_20
|
"(! TARGET_SOFT_FLOAT && TARGET_PA_20
|
&& ! (reg_overlap_mentioned_p (operands[4], operands[1])
|
&& ! (reg_overlap_mentioned_p (operands[4], operands[1])
|
|| reg_overlap_mentioned_p (operands[4], operands[2])))"
|
|| reg_overlap_mentioned_p (operands[4], operands[2])))"
|
"#"
|
"#"
|
[(set_attr "type" "fpmuldbl")
|
[(set_attr "type" "fpmuldbl")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
;; We want to split this up during scheduling since we want both insns
|
;; We want to split this up during scheduling since we want both insns
|
;; to schedule independently.
|
;; to schedule independently.
|
(define_split
|
(define_split
|
[(set (match_operand:SF 0 "register_operand" "")
|
[(set (match_operand:SF 0 "register_operand" "")
|
(plus:SF (mult:SF (match_operand:SF 1 "register_operand" "")
|
(plus:SF (mult:SF (match_operand:SF 1 "register_operand" "")
|
(match_operand:SF 2 "register_operand" ""))
|
(match_operand:SF 2 "register_operand" ""))
|
(match_operand:SF 3 "register_operand" "")))
|
(match_operand:SF 3 "register_operand" "")))
|
(set (match_operand:SF 4 "register_operand" "")
|
(set (match_operand:SF 4 "register_operand" "")
|
(mult:SF (match_dup 1) (match_dup 2)))]
|
(mult:SF (match_dup 1) (match_dup 2)))]
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
[(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2)))
|
[(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2)))
|
(set (match_dup 0) (plus:SF (mult:SF (match_dup 1) (match_dup 2))
|
(set (match_dup 0) (plus:SF (mult:SF (match_dup 1) (match_dup 2))
|
(match_dup 3)))]
|
(match_dup 3)))]
|
"")
|
"")
|
|
|
;; Negating a multiply can be faked by adding zero in a fused multiply-add
|
;; Negating a multiply can be faked by adding zero in a fused multiply-add
|
;; instruction.
|
;; instruction.
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
|
(neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
|
(match_operand:DF 2 "register_operand" "f"))))]
|
(match_operand:DF 2 "register_operand" "f"))))]
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"fmpynfadd,dbl %1,%2,%%fr0,%0"
|
"fmpynfadd,dbl %1,%2,%%fr0,%0"
|
[(set_attr "type" "fpmuldbl")
|
[(set_attr "type" "fpmuldbl")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
|
(neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
|
(match_operand:SF 2 "register_operand" "f"))))]
|
(match_operand:SF 2 "register_operand" "f"))))]
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"fmpynfadd,sgl %1,%2,%%fr0,%0"
|
"fmpynfadd,sgl %1,%2,%%fr0,%0"
|
[(set_attr "type" "fpmuldbl")
|
[(set_attr "type" "fpmuldbl")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
|
(neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
|
(match_operand:DF 2 "register_operand" "f"))))
|
(match_operand:DF 2 "register_operand" "f"))))
|
(set (match_operand:DF 3 "register_operand" "=&f")
|
(set (match_operand:DF 3 "register_operand" "=&f")
|
(mult:DF (match_dup 1) (match_dup 2)))]
|
(mult:DF (match_dup 1) (match_dup 2)))]
|
"(! TARGET_SOFT_FLOAT && TARGET_PA_20
|
"(! TARGET_SOFT_FLOAT && TARGET_PA_20
|
&& ! (reg_overlap_mentioned_p (operands[3], operands[1])
|
&& ! (reg_overlap_mentioned_p (operands[3], operands[1])
|
|| reg_overlap_mentioned_p (operands[3], operands[2])))"
|
|| reg_overlap_mentioned_p (operands[3], operands[2])))"
|
"#"
|
"#"
|
[(set_attr "type" "fpmuldbl")
|
[(set_attr "type" "fpmuldbl")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:DF 0 "register_operand" "")
|
[(set (match_operand:DF 0 "register_operand" "")
|
(neg:DF (mult:DF (match_operand:DF 1 "register_operand" "")
|
(neg:DF (mult:DF (match_operand:DF 1 "register_operand" "")
|
(match_operand:DF 2 "register_operand" ""))))
|
(match_operand:DF 2 "register_operand" ""))))
|
(set (match_operand:DF 3 "register_operand" "")
|
(set (match_operand:DF 3 "register_operand" "")
|
(mult:DF (match_dup 1) (match_dup 2)))]
|
(mult:DF (match_dup 1) (match_dup 2)))]
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
[(set (match_dup 3) (mult:DF (match_dup 1) (match_dup 2)))
|
[(set (match_dup 3) (mult:DF (match_dup 1) (match_dup 2)))
|
(set (match_dup 0) (neg:DF (mult:DF (match_dup 1) (match_dup 2))))]
|
(set (match_dup 0) (neg:DF (mult:DF (match_dup 1) (match_dup 2))))]
|
"")
|
"")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
|
(neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
|
(match_operand:SF 2 "register_operand" "f"))))
|
(match_operand:SF 2 "register_operand" "f"))))
|
(set (match_operand:SF 3 "register_operand" "=&f")
|
(set (match_operand:SF 3 "register_operand" "=&f")
|
(mult:SF (match_dup 1) (match_dup 2)))]
|
(mult:SF (match_dup 1) (match_dup 2)))]
|
"(! TARGET_SOFT_FLOAT && TARGET_PA_20
|
"(! TARGET_SOFT_FLOAT && TARGET_PA_20
|
&& ! (reg_overlap_mentioned_p (operands[3], operands[1])
|
&& ! (reg_overlap_mentioned_p (operands[3], operands[1])
|
|| reg_overlap_mentioned_p (operands[3], operands[2])))"
|
|| reg_overlap_mentioned_p (operands[3], operands[2])))"
|
"#"
|
"#"
|
[(set_attr "type" "fpmuldbl")
|
[(set_attr "type" "fpmuldbl")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:SF 0 "register_operand" "")
|
[(set (match_operand:SF 0 "register_operand" "")
|
(neg:SF (mult:SF (match_operand:SF 1 "register_operand" "")
|
(neg:SF (mult:SF (match_operand:SF 1 "register_operand" "")
|
(match_operand:SF 2 "register_operand" ""))))
|
(match_operand:SF 2 "register_operand" ""))))
|
(set (match_operand:SF 3 "register_operand" "")
|
(set (match_operand:SF 3 "register_operand" "")
|
(mult:SF (match_dup 1) (match_dup 2)))]
|
(mult:SF (match_dup 1) (match_dup 2)))]
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
[(set (match_dup 3) (mult:SF (match_dup 1) (match_dup 2)))
|
[(set (match_dup 3) (mult:SF (match_dup 1) (match_dup 2)))
|
(set (match_dup 0) (neg:SF (mult:SF (match_dup 1) (match_dup 2))))]
|
(set (match_dup 0) (neg:SF (mult:SF (match_dup 1) (match_dup 2))))]
|
"")
|
"")
|
|
|
;; Now fused multiplies with the result of the multiply negated.
|
;; Now fused multiplies with the result of the multiply negated.
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
|
(plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
|
(match_operand:DF 2 "register_operand" "f")))
|
(match_operand:DF 2 "register_operand" "f")))
|
(match_operand:DF 3 "register_operand" "f")))]
|
(match_operand:DF 3 "register_operand" "f")))]
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"fmpynfadd,dbl %1,%2,%3,%0"
|
"fmpynfadd,dbl %1,%2,%3,%0"
|
[(set_attr "type" "fpmuldbl")
|
[(set_attr "type" "fpmuldbl")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
|
(plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
|
(match_operand:SF 2 "register_operand" "f")))
|
(match_operand:SF 2 "register_operand" "f")))
|
(match_operand:SF 3 "register_operand" "f")))]
|
(match_operand:SF 3 "register_operand" "f")))]
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"fmpynfadd,sgl %1,%2,%3,%0"
|
"fmpynfadd,sgl %1,%2,%3,%0"
|
[(set_attr "type" "fpmuldbl")
|
[(set_attr "type" "fpmuldbl")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
|
(plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
|
(match_operand:DF 2 "register_operand" "f")))
|
(match_operand:DF 2 "register_operand" "f")))
|
(match_operand:DF 3 "register_operand" "f")))
|
(match_operand:DF 3 "register_operand" "f")))
|
(set (match_operand:DF 4 "register_operand" "=&f")
|
(set (match_operand:DF 4 "register_operand" "=&f")
|
(mult:DF (match_dup 1) (match_dup 2)))]
|
(mult:DF (match_dup 1) (match_dup 2)))]
|
"(! TARGET_SOFT_FLOAT && TARGET_PA_20
|
"(! TARGET_SOFT_FLOAT && TARGET_PA_20
|
&& ! (reg_overlap_mentioned_p (operands[4], operands[1])
|
&& ! (reg_overlap_mentioned_p (operands[4], operands[1])
|
|| reg_overlap_mentioned_p (operands[4], operands[2])))"
|
|| reg_overlap_mentioned_p (operands[4], operands[2])))"
|
"#"
|
"#"
|
[(set_attr "type" "fpmuldbl")
|
[(set_attr "type" "fpmuldbl")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:DF 0 "register_operand" "")
|
[(set (match_operand:DF 0 "register_operand" "")
|
(plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "")
|
(plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "")
|
(match_operand:DF 2 "register_operand" "")))
|
(match_operand:DF 2 "register_operand" "")))
|
(match_operand:DF 3 "register_operand" "")))
|
(match_operand:DF 3 "register_operand" "")))
|
(set (match_operand:DF 4 "register_operand" "")
|
(set (match_operand:DF 4 "register_operand" "")
|
(mult:DF (match_dup 1) (match_dup 2)))]
|
(mult:DF (match_dup 1) (match_dup 2)))]
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
[(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2)))
|
[(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2)))
|
(set (match_dup 0) (plus:DF (neg:DF (mult:DF (match_dup 1) (match_dup 2)))
|
(set (match_dup 0) (plus:DF (neg:DF (mult:DF (match_dup 1) (match_dup 2)))
|
(match_dup 3)))]
|
(match_dup 3)))]
|
"")
|
"")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
|
(plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
|
(match_operand:SF 2 "register_operand" "f")))
|
(match_operand:SF 2 "register_operand" "f")))
|
(match_operand:SF 3 "register_operand" "f")))
|
(match_operand:SF 3 "register_operand" "f")))
|
(set (match_operand:SF 4 "register_operand" "=&f")
|
(set (match_operand:SF 4 "register_operand" "=&f")
|
(mult:SF (match_dup 1) (match_dup 2)))]
|
(mult:SF (match_dup 1) (match_dup 2)))]
|
"(! TARGET_SOFT_FLOAT && TARGET_PA_20
|
"(! TARGET_SOFT_FLOAT && TARGET_PA_20
|
&& ! (reg_overlap_mentioned_p (operands[4], operands[1])
|
&& ! (reg_overlap_mentioned_p (operands[4], operands[1])
|
|| reg_overlap_mentioned_p (operands[4], operands[2])))"
|
|| reg_overlap_mentioned_p (operands[4], operands[2])))"
|
"#"
|
"#"
|
[(set_attr "type" "fpmuldbl")
|
[(set_attr "type" "fpmuldbl")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:SF 0 "register_operand" "")
|
[(set (match_operand:SF 0 "register_operand" "")
|
(plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "")
|
(plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "")
|
(match_operand:SF 2 "register_operand" "")))
|
(match_operand:SF 2 "register_operand" "")))
|
(match_operand:SF 3 "register_operand" "")))
|
(match_operand:SF 3 "register_operand" "")))
|
(set (match_operand:SF 4 "register_operand" "")
|
(set (match_operand:SF 4 "register_operand" "")
|
(mult:SF (match_dup 1) (match_dup 2)))]
|
(mult:SF (match_dup 1) (match_dup 2)))]
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
[(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2)))
|
[(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2)))
|
(set (match_dup 0) (plus:SF (neg:SF (mult:SF (match_dup 1) (match_dup 2)))
|
(set (match_dup 0) (plus:SF (neg:SF (mult:SF (match_dup 1) (match_dup 2)))
|
(match_dup 3)))]
|
(match_dup 3)))]
|
"")
|
"")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(minus:DF (match_operand:DF 3 "register_operand" "f")
|
(minus:DF (match_operand:DF 3 "register_operand" "f")
|
(mult:DF (match_operand:DF 1 "register_operand" "f")
|
(mult:DF (match_operand:DF 1 "register_operand" "f")
|
(match_operand:DF 2 "register_operand" "f"))))
|
(match_operand:DF 2 "register_operand" "f"))))
|
(set (match_operand:DF 4 "register_operand" "=&f")
|
(set (match_operand:DF 4 "register_operand" "=&f")
|
(mult:DF (match_dup 1) (match_dup 2)))]
|
(mult:DF (match_dup 1) (match_dup 2)))]
|
"(! TARGET_SOFT_FLOAT && TARGET_PA_20
|
"(! TARGET_SOFT_FLOAT && TARGET_PA_20
|
&& ! (reg_overlap_mentioned_p (operands[4], operands[1])
|
&& ! (reg_overlap_mentioned_p (operands[4], operands[1])
|
|| reg_overlap_mentioned_p (operands[4], operands[2])))"
|
|| reg_overlap_mentioned_p (operands[4], operands[2])))"
|
"#"
|
"#"
|
[(set_attr "type" "fpmuldbl")
|
[(set_attr "type" "fpmuldbl")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:DF 0 "register_operand" "")
|
[(set (match_operand:DF 0 "register_operand" "")
|
(minus:DF (match_operand:DF 3 "register_operand" "")
|
(minus:DF (match_operand:DF 3 "register_operand" "")
|
(mult:DF (match_operand:DF 1 "register_operand" "")
|
(mult:DF (match_operand:DF 1 "register_operand" "")
|
(match_operand:DF 2 "register_operand" ""))))
|
(match_operand:DF 2 "register_operand" ""))))
|
(set (match_operand:DF 4 "register_operand" "")
|
(set (match_operand:DF 4 "register_operand" "")
|
(mult:DF (match_dup 1) (match_dup 2)))]
|
(mult:DF (match_dup 1) (match_dup 2)))]
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
[(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2)))
|
[(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2)))
|
(set (match_dup 0) (minus:DF (match_dup 3)
|
(set (match_dup 0) (minus:DF (match_dup 3)
|
(mult:DF (match_dup 1) (match_dup 2))))]
|
(mult:DF (match_dup 1) (match_dup 2))))]
|
"")
|
"")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(minus:SF (match_operand:SF 3 "register_operand" "f")
|
(minus:SF (match_operand:SF 3 "register_operand" "f")
|
(mult:SF (match_operand:SF 1 "register_operand" "f")
|
(mult:SF (match_operand:SF 1 "register_operand" "f")
|
(match_operand:SF 2 "register_operand" "f"))))
|
(match_operand:SF 2 "register_operand" "f"))))
|
(set (match_operand:SF 4 "register_operand" "=&f")
|
(set (match_operand:SF 4 "register_operand" "=&f")
|
(mult:SF (match_dup 1) (match_dup 2)))]
|
(mult:SF (match_dup 1) (match_dup 2)))]
|
"(! TARGET_SOFT_FLOAT && TARGET_PA_20
|
"(! TARGET_SOFT_FLOAT && TARGET_PA_20
|
&& ! (reg_overlap_mentioned_p (operands[4], operands[1])
|
&& ! (reg_overlap_mentioned_p (operands[4], operands[1])
|
|| reg_overlap_mentioned_p (operands[4], operands[2])))"
|
|| reg_overlap_mentioned_p (operands[4], operands[2])))"
|
"#"
|
"#"
|
[(set_attr "type" "fpmuldbl")
|
[(set_attr "type" "fpmuldbl")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:SF 0 "register_operand" "")
|
[(set (match_operand:SF 0 "register_operand" "")
|
(minus:SF (match_operand:SF 3 "register_operand" "")
|
(minus:SF (match_operand:SF 3 "register_operand" "")
|
(mult:SF (match_operand:SF 1 "register_operand" "")
|
(mult:SF (match_operand:SF 1 "register_operand" "")
|
(match_operand:SF 2 "register_operand" ""))))
|
(match_operand:SF 2 "register_operand" ""))))
|
(set (match_operand:SF 4 "register_operand" "")
|
(set (match_operand:SF 4 "register_operand" "")
|
(mult:SF (match_dup 1) (match_dup 2)))]
|
(mult:SF (match_dup 1) (match_dup 2)))]
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
[(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2)))
|
[(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2)))
|
(set (match_dup 0) (minus:SF (match_dup 3)
|
(set (match_dup 0) (minus:SF (match_dup 3)
|
(mult:SF (match_dup 1) (match_dup 2))))]
|
(mult:SF (match_dup 1) (match_dup 2))))]
|
"")
|
"")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))
|
(neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))
|
(set (match_operand:DF 2 "register_operand" "=&f") (abs:DF (match_dup 1)))]
|
(set (match_operand:DF 2 "register_operand" "=&f") (abs:DF (match_dup 1)))]
|
"(! TARGET_SOFT_FLOAT && TARGET_PA_20
|
"(! TARGET_SOFT_FLOAT && TARGET_PA_20
|
&& ! reg_overlap_mentioned_p (operands[2], operands[1]))"
|
&& ! reg_overlap_mentioned_p (operands[2], operands[1]))"
|
"#"
|
"#"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:DF 0 "register_operand" "")
|
[(set (match_operand:DF 0 "register_operand" "")
|
(neg:DF (abs:DF (match_operand:DF 1 "register_operand" ""))))
|
(neg:DF (abs:DF (match_operand:DF 1 "register_operand" ""))))
|
(set (match_operand:DF 2 "register_operand" "") (abs:DF (match_dup 1)))]
|
(set (match_operand:DF 2 "register_operand" "") (abs:DF (match_dup 1)))]
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
[(set (match_dup 2) (abs:DF (match_dup 1)))
|
[(set (match_dup 2) (abs:DF (match_dup 1)))
|
(set (match_dup 0) (neg:DF (abs:DF (match_dup 1))))]
|
(set (match_dup 0) (neg:DF (abs:DF (match_dup 1))))]
|
"")
|
"")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))
|
(neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))
|
(set (match_operand:SF 2 "register_operand" "=&f") (abs:SF (match_dup 1)))]
|
(set (match_operand:SF 2 "register_operand" "=&f") (abs:SF (match_dup 1)))]
|
"(! TARGET_SOFT_FLOAT && TARGET_PA_20
|
"(! TARGET_SOFT_FLOAT && TARGET_PA_20
|
&& ! reg_overlap_mentioned_p (operands[2], operands[1]))"
|
&& ! reg_overlap_mentioned_p (operands[2], operands[1]))"
|
"#"
|
"#"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:SF 0 "register_operand" "")
|
[(set (match_operand:SF 0 "register_operand" "")
|
(neg:SF (abs:SF (match_operand:SF 1 "register_operand" ""))))
|
(neg:SF (abs:SF (match_operand:SF 1 "register_operand" ""))))
|
(set (match_operand:SF 2 "register_operand" "") (abs:SF (match_dup 1)))]
|
(set (match_operand:SF 2 "register_operand" "") (abs:SF (match_dup 1)))]
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
"! TARGET_SOFT_FLOAT && TARGET_PA_20"
|
[(set (match_dup 2) (abs:SF (match_dup 1)))
|
[(set (match_dup 2) (abs:SF (match_dup 1)))
|
(set (match_dup 0) (neg:SF (abs:SF (match_dup 1))))]
|
(set (match_dup 0) (neg:SF (abs:SF (match_dup 1))))]
|
"")
|
"")
|
|
|
;;- Shift instructions
|
;;- Shift instructions
|
|
|
;; Optimized special case of shifting.
|
;; Optimized special case of shifting.
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
|
(lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
|
(const_int 24)))]
|
(const_int 24)))]
|
""
|
""
|
"ldb%M1 %1,%0"
|
"ldb%M1 %1,%0"
|
[(set_attr "type" "load")
|
[(set_attr "type" "load")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
|
(lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
|
(const_int 16)))]
|
(const_int 16)))]
|
""
|
""
|
"ldh%M1 %1,%0"
|
"ldh%M1 %1,%0"
|
[(set_attr "type" "load")
|
[(set_attr "type" "load")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
|
(plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
|
(match_operand:SI 3 "shadd_operand" ""))
|
(match_operand:SI 3 "shadd_operand" ""))
|
(match_operand:SI 1 "register_operand" "r")))]
|
(match_operand:SI 1 "register_operand" "r")))]
|
""
|
""
|
"{sh%O3addl %2,%1,%0|shladd,l %2,%O3,%1,%0} "
|
"{sh%O3addl %2,%1,%0|shladd,l %2,%O3,%1,%0} "
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(plus:DI (mult:DI (match_operand:DI 2 "register_operand" "r")
|
(plus:DI (mult:DI (match_operand:DI 2 "register_operand" "r")
|
(match_operand:DI 3 "shadd_operand" ""))
|
(match_operand:DI 3 "shadd_operand" ""))
|
(match_operand:DI 1 "register_operand" "r")))]
|
(match_operand:DI 1 "register_operand" "r")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"shladd,l %2,%O3,%1,%0"
|
"shladd,l %2,%O3,%1,%0"
|
[(set_attr "type" "binary")
|
[(set_attr "type" "binary")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_expand "ashlsi3"
|
(define_expand "ashlsi3"
|
[(set (match_operand:SI 0 "register_operand" "")
|
[(set (match_operand:SI 0 "register_operand" "")
|
(ashift:SI (match_operand:SI 1 "lhs_lshift_operand" "")
|
(ashift:SI (match_operand:SI 1 "lhs_lshift_operand" "")
|
(match_operand:SI 2 "arith32_operand" "")))]
|
(match_operand:SI 2 "arith32_operand" "")))]
|
""
|
""
|
"
|
"
|
{
|
{
|
if (GET_CODE (operands[2]) != CONST_INT)
|
if (GET_CODE (operands[2]) != CONST_INT)
|
{
|
{
|
rtx temp = gen_reg_rtx (SImode);
|
rtx temp = gen_reg_rtx (SImode);
|
emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
|
emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
|
if (GET_CODE (operands[1]) == CONST_INT)
|
if (GET_CODE (operands[1]) == CONST_INT)
|
emit_insn (gen_zvdep_imm32 (operands[0], operands[1], temp));
|
emit_insn (gen_zvdep_imm32 (operands[0], operands[1], temp));
|
else
|
else
|
emit_insn (gen_zvdep32 (operands[0], operands[1], temp));
|
emit_insn (gen_zvdep32 (operands[0], operands[1], temp));
|
DONE;
|
DONE;
|
}
|
}
|
/* Make sure both inputs are not constants,
|
/* Make sure both inputs are not constants,
|
there are no patterns for that. */
|
there are no patterns for that. */
|
operands[1] = force_reg (SImode, operands[1]);
|
operands[1] = force_reg (SImode, operands[1]);
|
}")
|
}")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(ashift:SI (match_operand:SI 1 "register_operand" "r")
|
(ashift:SI (match_operand:SI 1 "register_operand" "r")
|
(match_operand:SI 2 "const_int_operand" "n")))]
|
(match_operand:SI 2 "const_int_operand" "n")))]
|
""
|
""
|
"{zdep|depw,z} %1,%P2,%L2,%0"
|
"{zdep|depw,z} %1,%P2,%L2,%0"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
; Match cases of op1 a CONST_INT here that zvdep_imm32 doesn't handle.
|
; Match cases of op1 a CONST_INT here that zvdep_imm32 doesn't handle.
|
; Doing it like this makes slightly better code since reload can
|
; Doing it like this makes slightly better code since reload can
|
; replace a register with a known value in range -16..15 with a
|
; replace a register with a known value in range -16..15 with a
|
; constant. Ideally, we would like to merge zvdep32 and zvdep_imm32,
|
; constant. Ideally, we would like to merge zvdep32 and zvdep_imm32,
|
; but since we have no more CONST_OK... characters, that is not
|
; but since we have no more CONST_OK... characters, that is not
|
; possible.
|
; possible.
|
(define_insn "zvdep32"
|
(define_insn "zvdep32"
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
(ashift:SI (match_operand:SI 1 "arith5_operand" "r,L")
|
(ashift:SI (match_operand:SI 1 "arith5_operand" "r,L")
|
(minus:SI (const_int 31)
|
(minus:SI (const_int 31)
|
(match_operand:SI 2 "register_operand" "q,q"))))]
|
(match_operand:SI 2 "register_operand" "q,q"))))]
|
""
|
""
|
"@
|
"@
|
{zvdep %1,32,%0|depw,z %1,%%sar,32,%0}
|
{zvdep %1,32,%0|depw,z %1,%%sar,32,%0}
|
{zvdepi %1,32,%0|depwi,z %1,%%sar,32,%0}"
|
{zvdepi %1,32,%0|depwi,z %1,%%sar,32,%0}"
|
[(set_attr "type" "shift,shift")
|
[(set_attr "type" "shift,shift")
|
(set_attr "length" "4,4")])
|
(set_attr "length" "4,4")])
|
|
|
(define_insn "zvdep_imm32"
|
(define_insn "zvdep_imm32"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(ashift:SI (match_operand:SI 1 "lhs_lshift_cint_operand" "")
|
(ashift:SI (match_operand:SI 1 "lhs_lshift_cint_operand" "")
|
(minus:SI (const_int 31)
|
(minus:SI (const_int 31)
|
(match_operand:SI 2 "register_operand" "q"))))]
|
(match_operand:SI 2 "register_operand" "q"))))]
|
""
|
""
|
"*
|
"*
|
{
|
{
|
int x = INTVAL (operands[1]);
|
int x = INTVAL (operands[1]);
|
operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
|
operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
|
operands[1] = GEN_INT ((x & 0xf) - 0x10);
|
operands[1] = GEN_INT ((x & 0xf) - 0x10);
|
return \"{zvdepi %1,%2,%0|depwi,z %1,%%sar,%2,%0}\";
|
return \"{zvdepi %1,%2,%0|depwi,z %1,%%sar,%2,%0}\";
|
}"
|
}"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "vdepi_ior"
|
(define_insn "vdepi_ior"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(ior:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
|
(ior:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
|
(minus:SI (const_int 31)
|
(minus:SI (const_int 31)
|
(match_operand:SI 2 "register_operand" "q")))
|
(match_operand:SI 2 "register_operand" "q")))
|
(match_operand:SI 3 "register_operand" "0")))]
|
(match_operand:SI 3 "register_operand" "0")))]
|
; accept ...0001...1, can this be generalized?
|
; 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]);
|
int x = INTVAL (operands[1]);
|
operands[2] = GEN_INT (exact_log2 (x + 1));
|
operands[2] = GEN_INT (exact_log2 (x + 1));
|
return \"{vdepi -1,%2,%0|depwi -1,%%sar,%2,%0}\";
|
return \"{vdepi -1,%2,%0|depwi -1,%%sar,%2,%0}\";
|
}"
|
}"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "vdepi_and"
|
(define_insn "vdepi_and"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(and:SI (rotate:SI (match_operand:SI 1 "const_int_operand" "")
|
(and:SI (rotate:SI (match_operand:SI 1 "const_int_operand" "")
|
(minus:SI (const_int 31)
|
(minus:SI (const_int 31)
|
(match_operand:SI 2 "register_operand" "q")))
|
(match_operand:SI 2 "register_operand" "q")))
|
(match_operand:SI 3 "register_operand" "0")))]
|
(match_operand:SI 3 "register_operand" "0")))]
|
; this can be generalized...!
|
; this can be generalized...!
|
"INTVAL (operands[1]) == -2"
|
"INTVAL (operands[1]) == -2"
|
"*
|
"*
|
{
|
{
|
int x = INTVAL (operands[1]);
|
int x = INTVAL (operands[1]);
|
operands[2] = GEN_INT (exact_log2 ((~x) + 1));
|
operands[2] = GEN_INT (exact_log2 ((~x) + 1));
|
return \"{vdepi 0,%2,%0|depwi 0,%%sar,%2,%0}\";
|
return \"{vdepi 0,%2,%0|depwi 0,%%sar,%2,%0}\";
|
}"
|
}"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_expand "ashldi3"
|
(define_expand "ashldi3"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(ashift:DI (match_operand:DI 1 "lhs_lshift_operand" "")
|
(ashift:DI (match_operand:DI 1 "lhs_lshift_operand" "")
|
(match_operand:DI 2 "arith32_operand" "")))]
|
(match_operand:DI 2 "arith32_operand" "")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"
|
"
|
{
|
{
|
if (GET_CODE (operands[2]) != CONST_INT)
|
if (GET_CODE (operands[2]) != CONST_INT)
|
{
|
{
|
rtx temp = gen_reg_rtx (DImode);
|
rtx temp = gen_reg_rtx (DImode);
|
emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2]));
|
emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2]));
|
if (GET_CODE (operands[1]) == CONST_INT)
|
if (GET_CODE (operands[1]) == CONST_INT)
|
emit_insn (gen_zvdep_imm64 (operands[0], operands[1], temp));
|
emit_insn (gen_zvdep_imm64 (operands[0], operands[1], temp));
|
else
|
else
|
emit_insn (gen_zvdep64 (operands[0], operands[1], temp));
|
emit_insn (gen_zvdep64 (operands[0], operands[1], temp));
|
DONE;
|
DONE;
|
}
|
}
|
/* Make sure both inputs are not constants,
|
/* Make sure both inputs are not constants,
|
there are no patterns for that. */
|
there are no patterns for that. */
|
operands[1] = force_reg (DImode, operands[1]);
|
operands[1] = force_reg (DImode, operands[1]);
|
}")
|
}")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(ashift:DI (match_operand:DI 1 "register_operand" "r")
|
(ashift:DI (match_operand:DI 1 "register_operand" "r")
|
(match_operand:DI 2 "const_int_operand" "n")))]
|
(match_operand:DI 2 "const_int_operand" "n")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"depd,z %1,%p2,%Q2,%0"
|
"depd,z %1,%p2,%Q2,%0"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
; Match cases of op1 a CONST_INT here that zvdep_imm64 doesn't handle.
|
; Match cases of op1 a CONST_INT here that zvdep_imm64 doesn't handle.
|
; Doing it like this makes slightly better code since reload can
|
; Doing it like this makes slightly better code since reload can
|
; replace a register with a known value in range -16..15 with a
|
; replace a register with a known value in range -16..15 with a
|
; constant. Ideally, we would like to merge zvdep64 and zvdep_imm64,
|
; constant. Ideally, we would like to merge zvdep64 and zvdep_imm64,
|
; but since we have no more CONST_OK... characters, that is not
|
; but since we have no more CONST_OK... characters, that is not
|
; possible.
|
; possible.
|
(define_insn "zvdep64"
|
(define_insn "zvdep64"
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
(ashift:DI (match_operand:DI 1 "arith5_operand" "r,L")
|
(ashift:DI (match_operand:DI 1 "arith5_operand" "r,L")
|
(minus:DI (const_int 63)
|
(minus:DI (const_int 63)
|
(match_operand:DI 2 "register_operand" "q,q"))))]
|
(match_operand:DI 2 "register_operand" "q,q"))))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"@
|
"@
|
depd,z %1,%%sar,64,%0
|
depd,z %1,%%sar,64,%0
|
depdi,z %1,%%sar,64,%0"
|
depdi,z %1,%%sar,64,%0"
|
[(set_attr "type" "shift,shift")
|
[(set_attr "type" "shift,shift")
|
(set_attr "length" "4,4")])
|
(set_attr "length" "4,4")])
|
|
|
(define_insn "zvdep_imm64"
|
(define_insn "zvdep_imm64"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(ashift:DI (match_operand:DI 1 "lhs_lshift_cint_operand" "")
|
(ashift:DI (match_operand:DI 1 "lhs_lshift_cint_operand" "")
|
(minus:DI (const_int 63)
|
(minus:DI (const_int 63)
|
(match_operand:DI 2 "register_operand" "q"))))]
|
(match_operand:DI 2 "register_operand" "q"))))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
int x = INTVAL (operands[1]);
|
int x = INTVAL (operands[1]);
|
operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
|
operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
|
operands[1] = GEN_INT ((x & 0x1f) - 0x20);
|
operands[1] = GEN_INT ((x & 0x1f) - 0x20);
|
return \"depdi,z %1,%%sar,%2,%0\";
|
return \"depdi,z %1,%%sar,%2,%0\";
|
}"
|
}"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(ior:DI (ashift:DI (match_operand:DI 1 "const_int_operand" "")
|
(ior:DI (ashift:DI (match_operand:DI 1 "const_int_operand" "")
|
(minus:DI (const_int 63)
|
(minus:DI (const_int 63)
|
(match_operand:DI 2 "register_operand" "q")))
|
(match_operand:DI 2 "register_operand" "q")))
|
(match_operand:DI 3 "register_operand" "0")))]
|
(match_operand:DI 3 "register_operand" "0")))]
|
; accept ...0001...1, can this be generalized?
|
; 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]);
|
int x = INTVAL (operands[1]);
|
operands[2] = GEN_INT (exact_log2 (x + 1));
|
operands[2] = GEN_INT (exact_log2 (x + 1));
|
return \"depdi -1,%%sar,%2,%0\";
|
return \"depdi -1,%%sar,%2,%0\";
|
}"
|
}"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(and:DI (rotate:DI (match_operand:DI 1 "const_int_operand" "")
|
(and:DI (rotate:DI (match_operand:DI 1 "const_int_operand" "")
|
(minus:DI (const_int 63)
|
(minus:DI (const_int 63)
|
(match_operand:DI 2 "register_operand" "q")))
|
(match_operand:DI 2 "register_operand" "q")))
|
(match_operand:DI 3 "register_operand" "0")))]
|
(match_operand:DI 3 "register_operand" "0")))]
|
; this can be generalized...!
|
; this can be generalized...!
|
"TARGET_64BIT && INTVAL (operands[1]) == -2"
|
"TARGET_64BIT && INTVAL (operands[1]) == -2"
|
"*
|
"*
|
{
|
{
|
int x = INTVAL (operands[1]);
|
int x = INTVAL (operands[1]);
|
operands[2] = GEN_INT (exact_log2 ((~x) + 1));
|
operands[2] = GEN_INT (exact_log2 ((~x) + 1));
|
return \"depdi 0,%%sar,%2,%0\";
|
return \"depdi 0,%%sar,%2,%0\";
|
}"
|
}"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_expand "ashrsi3"
|
(define_expand "ashrsi3"
|
[(set (match_operand:SI 0 "register_operand" "")
|
[(set (match_operand:SI 0 "register_operand" "")
|
(ashiftrt:SI (match_operand:SI 1 "register_operand" "")
|
(ashiftrt:SI (match_operand:SI 1 "register_operand" "")
|
(match_operand:SI 2 "arith32_operand" "")))]
|
(match_operand:SI 2 "arith32_operand" "")))]
|
""
|
""
|
"
|
"
|
{
|
{
|
if (GET_CODE (operands[2]) != CONST_INT)
|
if (GET_CODE (operands[2]) != CONST_INT)
|
{
|
{
|
rtx temp = gen_reg_rtx (SImode);
|
rtx temp = gen_reg_rtx (SImode);
|
emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
|
emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
|
emit_insn (gen_vextrs32 (operands[0], operands[1], temp));
|
emit_insn (gen_vextrs32 (operands[0], operands[1], temp));
|
DONE;
|
DONE;
|
}
|
}
|
}")
|
}")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
|
(ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
|
(match_operand:SI 2 "const_int_operand" "n")))]
|
(match_operand:SI 2 "const_int_operand" "n")))]
|
""
|
""
|
"{extrs|extrw,s} %1,%P2,%L2,%0"
|
"{extrs|extrw,s} %1,%P2,%L2,%0"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "vextrs32"
|
(define_insn "vextrs32"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
|
(ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
|
(minus:SI (const_int 31)
|
(minus:SI (const_int 31)
|
(match_operand:SI 2 "register_operand" "q"))))]
|
(match_operand:SI 2 "register_operand" "q"))))]
|
""
|
""
|
"{vextrs %1,32,%0|extrw,s %1,%%sar,32,%0}"
|
"{vextrs %1,32,%0|extrw,s %1,%%sar,32,%0}"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_expand "ashrdi3"
|
(define_expand "ashrdi3"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
|
(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 2 "arith32_operand" "")))]
|
(match_operand:DI 2 "arith32_operand" "")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"
|
"
|
{
|
{
|
if (GET_CODE (operands[2]) != CONST_INT)
|
if (GET_CODE (operands[2]) != CONST_INT)
|
{
|
{
|
rtx temp = gen_reg_rtx (DImode);
|
rtx temp = gen_reg_rtx (DImode);
|
emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2]));
|
emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2]));
|
emit_insn (gen_vextrs64 (operands[0], operands[1], temp));
|
emit_insn (gen_vextrs64 (operands[0], operands[1], temp));
|
DONE;
|
DONE;
|
}
|
}
|
}")
|
}")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
|
(ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
|
(match_operand:DI 2 "const_int_operand" "n")))]
|
(match_operand:DI 2 "const_int_operand" "n")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"extrd,s %1,%p2,%Q2,%0"
|
"extrd,s %1,%p2,%Q2,%0"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "vextrs64"
|
(define_insn "vextrs64"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
|
(ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
|
(minus:DI (const_int 63)
|
(minus:DI (const_int 63)
|
(match_operand:DI 2 "register_operand" "q"))))]
|
(match_operand:DI 2 "register_operand" "q"))))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"extrd,s %1,%%sar,64,%0"
|
"extrd,s %1,%%sar,64,%0"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "lshrsi3"
|
(define_insn "lshrsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
(lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
|
(lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
|
(match_operand:SI 2 "arith32_operand" "q,n")))]
|
(match_operand:SI 2 "arith32_operand" "q,n")))]
|
""
|
""
|
"@
|
"@
|
{vshd %%r0,%1,%0|shrpw %%r0,%1,%%sar,%0}
|
{vshd %%r0,%1,%0|shrpw %%r0,%1,%%sar,%0}
|
{extru|extrw,u} %1,%P2,%L2,%0"
|
{extru|extrw,u} %1,%P2,%L2,%0"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "lshrdi3"
|
(define_insn "lshrdi3"
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
(lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
|
(lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
|
(match_operand:DI 2 "arith32_operand" "q,n")))]
|
(match_operand:DI 2 "arith32_operand" "q,n")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"@
|
"@
|
shrpd %%r0,%1,%%sar,%0
|
shrpd %%r0,%1,%%sar,%0
|
extrd,u %1,%p2,%Q2,%0"
|
extrd,u %1,%p2,%Q2,%0"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "rotrsi3"
|
(define_insn "rotrsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
(rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
|
(rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
|
(match_operand:SI 2 "arith32_operand" "q,n")))]
|
(match_operand:SI 2 "arith32_operand" "q,n")))]
|
""
|
""
|
"*
|
"*
|
{
|
{
|
if (GET_CODE (operands[2]) == CONST_INT)
|
if (GET_CODE (operands[2]) == CONST_INT)
|
{
|
{
|
operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
|
operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
|
return \"{shd|shrpw} %1,%1,%2,%0\";
|
return \"{shd|shrpw} %1,%1,%2,%0\";
|
}
|
}
|
else
|
else
|
return \"{vshd %1,%1,%0|shrpw %1,%1,%%sar,%0}\";
|
return \"{vshd %1,%1,%0|shrpw %1,%1,%%sar,%0}\";
|
}"
|
}"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_expand "rotlsi3"
|
(define_expand "rotlsi3"
|
[(set (match_operand:SI 0 "register_operand" "")
|
[(set (match_operand:SI 0 "register_operand" "")
|
(rotate:SI (match_operand:SI 1 "register_operand" "")
|
(rotate:SI (match_operand:SI 1 "register_operand" "")
|
(match_operand:SI 2 "arith32_operand" "")))]
|
(match_operand:SI 2 "arith32_operand" "")))]
|
""
|
""
|
"
|
"
|
{
|
{
|
if (GET_CODE (operands[2]) != CONST_INT)
|
if (GET_CODE (operands[2]) != CONST_INT)
|
{
|
{
|
rtx temp = gen_reg_rtx (SImode);
|
rtx temp = gen_reg_rtx (SImode);
|
emit_insn (gen_subsi3 (temp, GEN_INT (32), operands[2]));
|
emit_insn (gen_subsi3 (temp, GEN_INT (32), operands[2]));
|
emit_insn (gen_rotrsi3 (operands[0], operands[1], temp));
|
emit_insn (gen_rotrsi3 (operands[0], operands[1], temp));
|
DONE;
|
DONE;
|
}
|
}
|
/* Else expand normally. */
|
/* Else expand normally. */
|
}")
|
}")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(rotate:SI (match_operand:SI 1 "register_operand" "r")
|
(rotate:SI (match_operand:SI 1 "register_operand" "r")
|
(match_operand:SI 2 "const_int_operand" "n")))]
|
(match_operand:SI 2 "const_int_operand" "n")))]
|
""
|
""
|
"*
|
"*
|
{
|
{
|
operands[2] = GEN_INT ((32 - INTVAL (operands[2])) & 31);
|
operands[2] = GEN_INT ((32 - INTVAL (operands[2])) & 31);
|
return \"{shd|shrpw} %1,%1,%2,%0\";
|
return \"{shd|shrpw} %1,%1,%2,%0\";
|
}"
|
}"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(match_operator:SI 5 "plus_xor_ior_operator"
|
(match_operator:SI 5 "plus_xor_ior_operator"
|
[(ashift:SI (match_operand:SI 1 "register_operand" "r")
|
[(ashift:SI (match_operand:SI 1 "register_operand" "r")
|
(match_operand:SI 3 "const_int_operand" "n"))
|
(match_operand:SI 3 "const_int_operand" "n"))
|
(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
|
(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
|
(match_operand:SI 4 "const_int_operand" "n"))]))]
|
(match_operand:SI 4 "const_int_operand" "n"))]))]
|
"INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
|
"INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
|
"{shd|shrpw} %1,%2,%4,%0"
|
"{shd|shrpw} %1,%2,%4,%0"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(match_operator:SI 5 "plus_xor_ior_operator"
|
(match_operator:SI 5 "plus_xor_ior_operator"
|
[(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
|
[(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
|
(match_operand:SI 4 "const_int_operand" "n"))
|
(match_operand:SI 4 "const_int_operand" "n"))
|
(ashift:SI (match_operand:SI 1 "register_operand" "r")
|
(ashift:SI (match_operand:SI 1 "register_operand" "r")
|
(match_operand:SI 3 "const_int_operand" "n"))]))]
|
(match_operand:SI 3 "const_int_operand" "n"))]))]
|
"INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
|
"INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
|
"{shd|shrpw} %1,%2,%4,%0"
|
"{shd|shrpw} %1,%2,%4,%0"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
|
(and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
|
(match_operand:SI 2 "const_int_operand" ""))
|
(match_operand:SI 2 "const_int_operand" ""))
|
(match_operand:SI 3 "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;
|
int cnt = INTVAL (operands[2]) & 31;
|
operands[3] = GEN_INT (exact_log2 (1 + (INTVAL (operands[3]) >> cnt)));
|
operands[3] = GEN_INT (exact_log2 (1 + (INTVAL (operands[3]) >> cnt)));
|
operands[2] = GEN_INT (31 - cnt);
|
operands[2] = GEN_INT (31 - cnt);
|
return \"{zdep|depw,z} %1,%2,%3,%0\";
|
return \"{zdep|depw,z} %1,%2,%3,%0\";
|
}"
|
}"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
;; Unconditional and other jump instructions.
|
;; Unconditional and other jump instructions.
|
|
|
;; This is used for most returns.
|
;; This is used for most returns.
|
(define_insn "return_internal"
|
(define_insn "return_internal"
|
[(return)
|
[(return)
|
(use (reg:SI 2))]
|
(use (reg:SI 2))]
|
""
|
""
|
"*
|
"*
|
{
|
{
|
if (TARGET_PA_20)
|
if (TARGET_PA_20)
|
return \"bve%* (%%r2)\";
|
return \"bve%* (%%r2)\";
|
return \"bv%* %%r0(%%r2)\";
|
return \"bv%* %%r0(%%r2)\";
|
}"
|
}"
|
[(set_attr "type" "branch")
|
[(set_attr "type" "branch")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
;; This is used for eh returns which bypass the return stub.
|
;; This is used for eh returns which bypass the return stub.
|
(define_insn "return_external_pic"
|
(define_insn "return_external_pic"
|
[(return)
|
[(return)
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(use (reg:SI 2))]
|
(use (reg:SI 2))]
|
"!TARGET_NO_SPACE_REGS
|
"!TARGET_NO_SPACE_REGS
|
&& !TARGET_PA_20
|
&& !TARGET_PA_20
|
&& flag_pic && crtl->calls_eh_return"
|
&& flag_pic && crtl->calls_eh_return"
|
"ldsid (%%sr0,%%r2),%%r1\;mtsp %%r1,%%sr0\;be%* 0(%%sr0,%%r2)"
|
"ldsid (%%sr0,%%r2),%%r1\;mtsp %%r1,%%sr0\;be%* 0(%%sr0,%%r2)"
|
[(set_attr "type" "branch")
|
[(set_attr "type" "branch")
|
(set_attr "length" "12")])
|
(set_attr "length" "12")])
|
|
|
(define_expand "prologue"
|
(define_expand "prologue"
|
[(const_int 0)]
|
[(const_int 0)]
|
""
|
""
|
"hppa_expand_prologue ();DONE;")
|
"hppa_expand_prologue ();DONE;")
|
|
|
(define_expand "sibcall_epilogue"
|
(define_expand "sibcall_epilogue"
|
[(return)]
|
[(return)]
|
""
|
""
|
"
|
"
|
{
|
{
|
hppa_expand_epilogue ();
|
hppa_expand_epilogue ();
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
(define_expand "epilogue"
|
(define_expand "epilogue"
|
[(return)]
|
[(return)]
|
""
|
""
|
"
|
"
|
{
|
{
|
rtx x;
|
rtx x;
|
|
|
/* Try to use the trivial return first. Else use the full epilogue. */
|
/* Try to use the trivial return first. Else use the full epilogue. */
|
if (reload_completed
|
if (reload_completed
|
&& !frame_pointer_needed
|
&& !frame_pointer_needed
|
&& !df_regs_ever_live_p (2)
|
&& !df_regs_ever_live_p (2)
|
&& (compute_frame_size (get_frame_size (), 0) ? 0 : 1))
|
&& (compute_frame_size (get_frame_size (), 0) ? 0 : 1))
|
x = gen_return_internal ();
|
x = gen_return_internal ();
|
else
|
else
|
{
|
{
|
hppa_expand_epilogue ();
|
hppa_expand_epilogue ();
|
|
|
/* EH returns bypass the normal return stub. Thus, we must do an
|
/* EH returns bypass the normal return stub. Thus, we must do an
|
interspace branch to return from functions that call eh_return.
|
interspace branch to return from functions that call eh_return.
|
This is only a problem for returns from shared code on ports
|
This is only a problem for returns from shared code on ports
|
using space registers. */
|
using space registers. */
|
if (!TARGET_NO_SPACE_REGS
|
if (!TARGET_NO_SPACE_REGS
|
&& !TARGET_PA_20
|
&& !TARGET_PA_20
|
&& flag_pic && crtl->calls_eh_return)
|
&& flag_pic && crtl->calls_eh_return)
|
x = gen_return_external_pic ();
|
x = gen_return_external_pic ();
|
else
|
else
|
x = gen_return_internal ();
|
x = gen_return_internal ();
|
}
|
}
|
emit_jump_insn (x);
|
emit_jump_insn (x);
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
; Used by hppa_profile_hook to load the starting address of the current
|
; Used by hppa_profile_hook to load the starting address of the current
|
; function; operand 1 contains the address of the label in operand 3
|
; function; operand 1 contains the address of the label in operand 3
|
(define_insn "load_offset_label_address"
|
(define_insn "load_offset_label_address"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(plus:SI (match_operand:SI 1 "register_operand" "r")
|
(plus:SI (match_operand:SI 1 "register_operand" "r")
|
(minus:SI (match_operand:SI 2 "" "")
|
(minus:SI (match_operand:SI 2 "" "")
|
(label_ref:SI (match_operand 3 "" "")))))]
|
(label_ref:SI (match_operand 3 "" "")))))]
|
""
|
""
|
"ldo %2-%l3(%1),%0"
|
"ldo %2-%l3(%1),%0"
|
[(set_attr "type" "multi")
|
[(set_attr "type" "multi")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
; Output a code label and load its address.
|
; Output a code label and load its address.
|
(define_insn "lcla1"
|
(define_insn "lcla1"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(label_ref:SI (match_operand 1 "" "")))
|
(label_ref:SI (match_operand 1 "" "")))
|
(const_int 0)]
|
(const_int 0)]
|
"!TARGET_PA_20"
|
"!TARGET_PA_20"
|
"*
|
"*
|
{
|
{
|
output_asm_insn (\"bl .+8,%0\;depi 0,31,2,%0\", operands);
|
output_asm_insn (\"bl .+8,%0\;depi 0,31,2,%0\", operands);
|
(*targetm.asm_out.internal_label) (asm_out_file, \"L\",
|
(*targetm.asm_out.internal_label) (asm_out_file, \"L\",
|
CODE_LABEL_NUMBER (operands[1]));
|
CODE_LABEL_NUMBER (operands[1]));
|
return \"\";
|
return \"\";
|
}"
|
}"
|
[(set_attr "type" "multi")
|
[(set_attr "type" "multi")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn "lcla2"
|
(define_insn "lcla2"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(label_ref:SI (match_operand 1 "" "")))
|
(label_ref:SI (match_operand 1 "" "")))
|
(const_int 0)]
|
(const_int 0)]
|
"TARGET_PA_20"
|
"TARGET_PA_20"
|
"*
|
"*
|
{
|
{
|
(*targetm.asm_out.internal_label) (asm_out_file, \"L\",
|
(*targetm.asm_out.internal_label) (asm_out_file, \"L\",
|
CODE_LABEL_NUMBER (operands[1]));
|
CODE_LABEL_NUMBER (operands[1]));
|
return \"mfia %0\";
|
return \"mfia %0\";
|
}"
|
}"
|
[(set_attr "type" "move")
|
[(set_attr "type" "move")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "blockage"
|
(define_insn "blockage"
|
[(unspec_volatile [(const_int 2)] UNSPECV_BLOCKAGE)]
|
[(unspec_volatile [(const_int 2)] UNSPECV_BLOCKAGE)]
|
""
|
""
|
""
|
""
|
[(set_attr "length" "0")])
|
[(set_attr "length" "0")])
|
|
|
(define_insn "jump"
|
(define_insn "jump"
|
[(set (pc) (label_ref (match_operand 0 "" "")))]
|
[(set (pc) (label_ref (match_operand 0 "" "")))]
|
""
|
""
|
"*
|
"*
|
{
|
{
|
/* An unconditional branch which can reach its target. */
|
/* An unconditional branch which can reach its target. */
|
if (get_attr_length (insn) < 16)
|
if (get_attr_length (insn) < 16)
|
return \"b%* %l0\";
|
return \"b%* %l0\";
|
|
|
return output_lbranch (operands[0], insn, 1);
|
return output_lbranch (operands[0], insn, 1);
|
}"
|
}"
|
[(set_attr "type" "uncond_branch")
|
[(set_attr "type" "uncond_branch")
|
(set_attr "pa_combine_type" "uncond_branch")
|
(set_attr "pa_combine_type" "uncond_branch")
|
(set (attr "length")
|
(set (attr "length")
|
(cond [(eq (symbol_ref "jump_in_call_delay (insn)") (const_int 1))
|
(cond [(eq (symbol_ref "jump_in_call_delay (insn)") (const_int 1))
|
(if_then_else (lt (abs (minus (match_dup 0)
|
(if_then_else (lt (abs (minus (match_dup 0)
|
(plus (pc) (const_int 8))))
|
(plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(const_int 8))
|
(const_int 8))
|
(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 20)
|
(const_int 20)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 16)]
|
(const_int 16)]
|
(const_int 24)))])
|
(const_int 24)))])
|
|
|
;;; Hope this is only within a function...
|
;;; Hope this is only within a function...
|
(define_insn "indirect_jump"
|
(define_insn "indirect_jump"
|
[(set (pc) (match_operand 0 "register_operand" "r"))]
|
[(set (pc) (match_operand 0 "register_operand" "r"))]
|
"GET_MODE (operands[0]) == word_mode"
|
"GET_MODE (operands[0]) == word_mode"
|
"bv%* %%r0(%0)"
|
"bv%* %%r0(%0)"
|
[(set_attr "type" "branch")
|
[(set_attr "type" "branch")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
;;; An indirect jump can be optimized to a direct jump. GAS for the
|
;;; 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.
|
;;; SOM target doesn't allow branching to a label inside a function.
|
;;; We also don't correctly compute branch distances for labels
|
;;; We also don't correctly compute branch distances for labels
|
;;; outside the current function. Thus, we use an indirect jump can't
|
;;; outside the current function. Thus, we use an indirect jump can't
|
;;; be optimized to a direct jump for all targets. We assume that
|
;;; be optimized to a direct jump for all targets. We assume that
|
;;; the branch target is in the same space (i.e., nested function
|
;;; the branch target is in the same space (i.e., nested function
|
;;; jumping to a label in an outer function in the same translation
|
;;; jumping to a label in an outer function in the same translation
|
;;; unit).
|
;;; unit).
|
(define_expand "nonlocal_goto"
|
(define_expand "nonlocal_goto"
|
[(use (match_operand 0 "general_operand" ""))
|
[(use (match_operand 0 "general_operand" ""))
|
(use (match_operand 1 "general_operand" ""))
|
(use (match_operand 1 "general_operand" ""))
|
(use (match_operand 2 "general_operand" ""))
|
(use (match_operand 2 "general_operand" ""))
|
(use (match_operand 3 "general_operand" ""))]
|
(use (match_operand 3 "general_operand" ""))]
|
""
|
""
|
{
|
{
|
rtx lab = operands[1];
|
rtx lab = operands[1];
|
rtx stack = operands[2];
|
rtx stack = operands[2];
|
rtx fp = operands[3];
|
rtx fp = operands[3];
|
|
|
lab = copy_to_reg (lab);
|
lab = copy_to_reg (lab);
|
|
|
emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
|
emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
|
emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
|
emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
|
|
|
/* Restore the frame pointer. The virtual_stack_vars_rtx is saved
|
/* Restore the frame pointer. The virtual_stack_vars_rtx is saved
|
instead of the hard_frame_pointer_rtx in the save area. As a
|
instead of the hard_frame_pointer_rtx in the save area. As a
|
result, an extra instruction is needed to adjust for the offset
|
result, an extra instruction is needed to adjust for the offset
|
of the virtual stack variables and the frame pointer. */
|
of the virtual stack variables and the frame pointer. */
|
if (GET_CODE (fp) != REG)
|
if (GET_CODE (fp) != REG)
|
fp = force_reg (Pmode, fp);
|
fp = force_reg (Pmode, fp);
|
emit_move_insn (virtual_stack_vars_rtx, fp);
|
emit_move_insn (virtual_stack_vars_rtx, fp);
|
|
|
emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
|
emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
|
|
|
emit_use (hard_frame_pointer_rtx);
|
emit_use (hard_frame_pointer_rtx);
|
emit_use (stack_pointer_rtx);
|
emit_use (stack_pointer_rtx);
|
|
|
/* Nonlocal goto jumps are only used between functions in the same
|
/* Nonlocal goto jumps are only used between functions in the same
|
translation unit. Thus, we can avoid the extra overhead of an
|
translation unit. Thus, we can avoid the extra overhead of an
|
interspace jump. */
|
interspace jump. */
|
emit_jump_insn (gen_indirect_goto (lab));
|
emit_jump_insn (gen_indirect_goto (lab));
|
emit_barrier ();
|
emit_barrier ();
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_insn "indirect_goto"
|
(define_insn "indirect_goto"
|
[(unspec [(match_operand 0 "register_operand" "=r")] UNSPEC_GOTO)]
|
[(unspec [(match_operand 0 "register_operand" "=r")] UNSPEC_GOTO)]
|
"GET_MODE (operands[0]) == word_mode"
|
"GET_MODE (operands[0]) == word_mode"
|
"bv%* %%r0(%0)"
|
"bv%* %%r0(%0)"
|
[(set_attr "type" "branch")
|
[(set_attr "type" "branch")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
;;; This jump is used in branch tables where the insn length is fixed.
|
;;; 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.
|
;;; The length of this insn is adjusted if the delay slot is not filled.
|
(define_insn "short_jump"
|
(define_insn "short_jump"
|
[(set (pc) (label_ref (match_operand 0 "" "")))
|
[(set (pc) (label_ref (match_operand 0 "" "")))
|
(const_int 0)]
|
(const_int 0)]
|
""
|
""
|
"b%* %l0%#"
|
"b%* %l0%#"
|
[(set_attr "type" "btable_branch")
|
[(set_attr "type" "btable_branch")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
;; Subroutines of "casesi".
|
;; Subroutines of "casesi".
|
;; operand 0 is index
|
;; operand 0 is index
|
;; operand 1 is the minimum bound
|
;; operand 1 is the minimum bound
|
;; operand 2 is the maximum bound - minimum bound + 1
|
;; operand 2 is the maximum bound - minimum bound + 1
|
;; operand 3 is CODE_LABEL for the table;
|
;; operand 3 is CODE_LABEL for the table;
|
;; operand 4 is the CODE_LABEL to go to if index out of range.
|
;; operand 4 is the CODE_LABEL to go to if index out of range.
|
|
|
(define_expand "casesi"
|
(define_expand "casesi"
|
[(match_operand:SI 0 "general_operand" "")
|
[(match_operand:SI 0 "general_operand" "")
|
(match_operand:SI 1 "const_int_operand" "")
|
(match_operand:SI 1 "const_int_operand" "")
|
(match_operand:SI 2 "const_int_operand" "")
|
(match_operand:SI 2 "const_int_operand" "")
|
(match_operand 3 "" "")
|
(match_operand 3 "" "")
|
(match_operand 4 "" "")]
|
(match_operand 4 "" "")]
|
""
|
""
|
"
|
"
|
{
|
{
|
if (GET_CODE (operands[0]) != REG)
|
if (GET_CODE (operands[0]) != REG)
|
operands[0] = force_reg (SImode, operands[0]);
|
operands[0] = force_reg (SImode, operands[0]);
|
|
|
if (operands[1] != const0_rtx)
|
if (operands[1] != const0_rtx)
|
{
|
{
|
rtx index = gen_reg_rtx (SImode);
|
rtx index = gen_reg_rtx (SImode);
|
|
|
operands[1] = GEN_INT (-INTVAL (operands[1]));
|
operands[1] = GEN_INT (-INTVAL (operands[1]));
|
if (!INT_14_BITS (operands[1]))
|
if (!INT_14_BITS (operands[1]))
|
operands[1] = force_reg (SImode, operands[1]);
|
operands[1] = force_reg (SImode, operands[1]);
|
emit_insn (gen_addsi3 (index, operands[0], operands[1]));
|
emit_insn (gen_addsi3 (index, operands[0], operands[1]));
|
operands[0] = index;
|
operands[0] = index;
|
}
|
}
|
|
|
if (!INT_5_BITS (operands[2]))
|
if (!INT_5_BITS (operands[2]))
|
operands[2] = force_reg (SImode, operands[2]);
|
operands[2] = force_reg (SImode, operands[2]);
|
|
|
/* This branch prevents us finding an insn for the delay slot of the
|
/* This branch prevents us finding an insn for the delay slot of the
|
following vectored branch. It might be possible to use the delay
|
following vectored branch. It might be possible to use the delay
|
slot if an index value of -1 was used to transfer to the out-of-range
|
slot if an index value of -1 was used to transfer to the out-of-range
|
label. In order to do this, we would have to output the -1 vector
|
label. In order to do this, we would have to output the -1 vector
|
element after the delay insn. The casesi output code would have to
|
element after the delay insn. The casesi output code would have to
|
check if the casesi insn is in a delay branch sequence and output
|
check if the casesi insn is in a delay branch sequence and output
|
the delay insn if one is found. If this was done, then it might
|
the delay insn if one is found. If this was done, then it might
|
then be worthwhile to split the casesi patterns to improve scheduling.
|
then be worthwhile to split the casesi patterns to improve scheduling.
|
However, it's not clear that all this extra complexity is worth
|
However, it's not clear that all this extra complexity is worth
|
the effort. */
|
the effort. */
|
{
|
{
|
rtx test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]);
|
rtx test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]);
|
emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2], operands[4]));
|
emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2], operands[4]));
|
}
|
}
|
|
|
/* In 64bit mode we must make sure to wipe the upper bits of the register
|
/* In 64bit mode we must make sure to wipe the upper bits of the register
|
just in case the addition overflowed or we had random bits in the
|
just in case the addition overflowed or we had random bits in the
|
high part of the register. */
|
high part of the register. */
|
if (TARGET_64BIT)
|
if (TARGET_64BIT)
|
{
|
{
|
rtx index = gen_reg_rtx (DImode);
|
rtx index = gen_reg_rtx (DImode);
|
|
|
emit_insn (gen_extendsidi2 (index, operands[0]));
|
emit_insn (gen_extendsidi2 (index, operands[0]));
|
operands[0] = index;
|
operands[0] = index;
|
}
|
}
|
|
|
if (TARGET_BIG_SWITCH)
|
if (TARGET_BIG_SWITCH)
|
{
|
{
|
if (TARGET_64BIT)
|
if (TARGET_64BIT)
|
emit_jump_insn (gen_casesi64p (operands[0], operands[3]));
|
emit_jump_insn (gen_casesi64p (operands[0], operands[3]));
|
else if (flag_pic)
|
else if (flag_pic)
|
emit_jump_insn (gen_casesi32p (operands[0], operands[3]));
|
emit_jump_insn (gen_casesi32p (operands[0], operands[3]));
|
else
|
else
|
emit_jump_insn (gen_casesi32 (operands[0], operands[3]));
|
emit_jump_insn (gen_casesi32 (operands[0], operands[3]));
|
}
|
}
|
else
|
else
|
emit_jump_insn (gen_casesi0 (operands[0], operands[3]));
|
emit_jump_insn (gen_casesi0 (operands[0], operands[3]));
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
;;; The rtl for this pattern doesn't accurately describe what the insn
|
;;; The rtl for this pattern doesn't accurately describe what the insn
|
;;; actually does, particularly when case-vector elements are exploded
|
;;; actually does, particularly when case-vector elements are exploded
|
;;; in pa_reorg. However, the initial SET in these patterns must show
|
;;; in pa_reorg. However, the initial SET in these patterns must show
|
;;; the connection of the insn to the following jump table.
|
;;; the connection of the insn to the following jump table.
|
(define_insn "casesi0"
|
(define_insn "casesi0"
|
[(set (pc) (mem:SI (plus:SI
|
[(set (pc) (mem:SI (plus:SI
|
(mult:SI (match_operand:SI 0 "register_operand" "r")
|
(mult:SI (match_operand:SI 0 "register_operand" "r")
|
(const_int 4))
|
(const_int 4))
|
(label_ref (match_operand 1 "" "")))))]
|
(label_ref (match_operand 1 "" "")))))]
|
""
|
""
|
"blr,n %0,%%r0\;nop"
|
"blr,n %0,%%r0\;nop"
|
[(set_attr "type" "multi")
|
[(set_attr "type" "multi")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
;;; 32-bit code, absolute branch table.
|
;;; 32-bit code, absolute branch table.
|
(define_insn "casesi32"
|
(define_insn "casesi32"
|
[(set (pc) (mem:SI (plus:SI
|
[(set (pc) (mem:SI (plus:SI
|
(mult:SI (match_operand:SI 0 "register_operand" "r")
|
(mult:SI (match_operand:SI 0 "register_operand" "r")
|
(const_int 4))
|
(const_int 4))
|
(label_ref (match_operand 1 "" "")))))
|
(label_ref (match_operand 1 "" "")))))
|
(clobber (match_scratch:SI 2 "=&r"))]
|
(clobber (match_scratch:SI 2 "=&r"))]
|
"!flag_pic"
|
"!flag_pic"
|
"ldil L'%l1,%2\;ldo R'%l1(%2),%2\;{ldwx|ldw},s %0(%2),%2\;bv,n %%r0(%2)"
|
"ldil L'%l1,%2\;ldo R'%l1(%2),%2\;{ldwx|ldw},s %0(%2),%2\;bv,n %%r0(%2)"
|
[(set_attr "type" "multi")
|
[(set_attr "type" "multi")
|
(set_attr "length" "16")])
|
(set_attr "length" "16")])
|
|
|
;;; 32-bit code, relative branch table.
|
;;; 32-bit code, relative branch table.
|
(define_insn "casesi32p"
|
(define_insn "casesi32p"
|
[(set (pc) (mem:SI (plus:SI
|
[(set (pc) (mem:SI (plus:SI
|
(mult:SI (match_operand:SI 0 "register_operand" "r")
|
(mult:SI (match_operand:SI 0 "register_operand" "r")
|
(const_int 4))
|
(const_int 4))
|
(label_ref (match_operand 1 "" "")))))
|
(label_ref (match_operand 1 "" "")))))
|
(clobber (match_scratch:SI 2 "=&r"))
|
(clobber (match_scratch:SI 2 "=&r"))
|
(clobber (match_scratch:SI 3 "=&r"))]
|
(clobber (match_scratch:SI 3 "=&r"))]
|
"flag_pic"
|
"flag_pic"
|
"{bl .+8,%2\;depi 0,31,2,%2|mfia %2}\;ldo {%l1-.|%l1+4-.}(%2),%2\;\
|
"{bl .+8,%2\;depi 0,31,2,%2|mfia %2}\;ldo {%l1-.|%l1+4-.}(%2),%2\;\
|
{ldwx|ldw},s %0(%2),%3\;{addl|add,l} %2,%3,%3\;bv,n %%r0(%3)"
|
{ldwx|ldw},s %0(%2),%3\;{addl|add,l} %2,%3,%3\;bv,n %%r0(%3)"
|
[(set_attr "type" "multi")
|
[(set_attr "type" "multi")
|
(set (attr "length")
|
(set (attr "length")
|
(if_then_else (ne (symbol_ref "TARGET_PA_20") (const_int 0))
|
(if_then_else (ne (symbol_ref "TARGET_PA_20") (const_int 0))
|
(const_int 20)
|
(const_int 20)
|
(const_int 24)))])
|
(const_int 24)))])
|
|
|
;;; 64-bit code, 32-bit relative branch table.
|
;;; 64-bit code, 32-bit relative branch table.
|
(define_insn "casesi64p"
|
(define_insn "casesi64p"
|
[(set (pc) (mem:DI (plus:DI
|
[(set (pc) (mem:DI (plus:DI
|
(mult:DI (match_operand:DI 0 "register_operand" "r")
|
(mult:DI (match_operand:DI 0 "register_operand" "r")
|
(const_int 8))
|
(const_int 8))
|
(label_ref (match_operand 1 "" "")))))
|
(label_ref (match_operand 1 "" "")))))
|
(clobber (match_scratch:DI 2 "=&r"))
|
(clobber (match_scratch:DI 2 "=&r"))
|
(clobber (match_scratch:DI 3 "=&r"))]
|
(clobber (match_scratch:DI 3 "=&r"))]
|
""
|
""
|
"mfia %2\;ldo %l1+4-.(%2),%2\;ldw,s %0(%2),%3\;extrd,s %3,63,32,%3\;\
|
"mfia %2\;ldo %l1+4-.(%2),%2\;ldw,s %0(%2),%3\;extrd,s %3,63,32,%3\;\
|
add,l %2,%3,%3\;bv,n %%r0(%3)"
|
add,l %2,%3,%3\;bv,n %%r0(%3)"
|
[(set_attr "type" "multi")
|
[(set_attr "type" "multi")
|
(set_attr "length" "24")])
|
(set_attr "length" "24")])
|
|
|
|
|
;; Call patterns.
|
;; Call patterns.
|
;;- jump to subroutine
|
;;- jump to subroutine
|
|
|
(define_expand "call"
|
(define_expand "call"
|
[(parallel [(call (match_operand:SI 0 "" "")
|
[(parallel [(call (match_operand:SI 0 "" "")
|
(match_operand 1 "" ""))
|
(match_operand 1 "" ""))
|
(clobber (reg:SI 2))])]
|
(clobber (reg:SI 2))])]
|
""
|
""
|
"
|
"
|
{
|
{
|
rtx op, call_insn;
|
rtx op, call_insn;
|
rtx nb = operands[1];
|
rtx nb = operands[1];
|
|
|
if (TARGET_PORTABLE_RUNTIME)
|
if (TARGET_PORTABLE_RUNTIME)
|
op = force_reg (SImode, XEXP (operands[0], 0));
|
op = force_reg (SImode, XEXP (operands[0], 0));
|
else
|
else
|
op = XEXP (operands[0], 0);
|
op = XEXP (operands[0], 0);
|
|
|
if (TARGET_64BIT)
|
if (TARGET_64BIT)
|
{
|
{
|
if (!virtuals_instantiated)
|
if (!virtuals_instantiated)
|
emit_move_insn (arg_pointer_rtx,
|
emit_move_insn (arg_pointer_rtx,
|
gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
|
gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
|
GEN_INT (64)));
|
GEN_INT (64)));
|
else
|
else
|
{
|
{
|
/* The loop pass can generate new libcalls after the virtual
|
/* The loop pass can generate new libcalls after the virtual
|
registers are instantiated when fpregs are disabled because
|
registers are instantiated when fpregs are disabled because
|
the only method that we have for doing DImode multiplication
|
the only method that we have for doing DImode multiplication
|
is with a libcall. This could be trouble if we haven't
|
is with a libcall. This could be trouble if we haven't
|
allocated enough space for the outgoing arguments. */
|
allocated enough space for the outgoing arguments. */
|
gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
|
gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
|
|
|
emit_move_insn (arg_pointer_rtx,
|
emit_move_insn (arg_pointer_rtx,
|
gen_rtx_PLUS (word_mode, stack_pointer_rtx,
|
gen_rtx_PLUS (word_mode, stack_pointer_rtx,
|
GEN_INT (STACK_POINTER_OFFSET + 64)));
|
GEN_INT (STACK_POINTER_OFFSET + 64)));
|
}
|
}
|
}
|
}
|
|
|
/* Use two different patterns for calls to explicitly named functions
|
/* Use two different patterns for calls to explicitly named functions
|
and calls through function pointers. This is necessary as these two
|
and calls through function pointers. This is necessary as these two
|
types of calls use different calling conventions, and CSE might try
|
types of calls use different calling conventions, and CSE might try
|
to change the named call into an indirect call in some cases (using
|
to change the named call into an indirect call in some cases (using
|
two patterns keeps CSE from performing this optimization).
|
two patterns keeps CSE from performing this optimization).
|
|
|
We now use even more call patterns as there was a subtle bug in
|
We now use even more call patterns as there was a subtle bug in
|
attempting to restore the pic register after a call using a simple
|
attempting to restore the pic register after a call using a simple
|
move insn. During reload, a instruction involving a pseudo register
|
move insn. During reload, a instruction involving a pseudo register
|
with no explicit dependence on the PIC register can be converted
|
with no explicit dependence on the PIC register can be converted
|
to an equivalent load from memory using the PIC register. If we
|
to an equivalent load from memory using the PIC register. If we
|
emit a simple move to restore the PIC register in the initial rtl
|
emit a simple move to restore the PIC register in the initial rtl
|
generation, then it can potentially be repositioned during scheduling.
|
generation, then it can potentially be repositioned during scheduling.
|
and an instruction that eventually uses the PIC register may end up
|
and an instruction that eventually uses the PIC register may end up
|
between the call and the PIC register restore.
|
between the call and the PIC register restore.
|
|
|
This only worked because there is a post call group of instructions
|
This only worked because there is a post call group of instructions
|
that are scheduled with the call. These instructions are included
|
that are scheduled with the call. These instructions are included
|
in the same basic block as the call. However, calls can throw in
|
in the same basic block as the call. However, calls can throw in
|
C++ code and a basic block has to terminate at the call if the call
|
C++ code and a basic block has to terminate at the call if the call
|
can throw. This results in the PIC register restore being scheduled
|
can throw. This results in the PIC register restore being scheduled
|
independently from the call. So, we now hide the save and restore
|
independently from the call. So, we now hide the save and restore
|
of the PIC register in the call pattern until after reload. Then,
|
of the PIC register in the call pattern until after reload. Then,
|
we split the moves out. A small side benefit is that we now don't
|
we split the moves out. A small side benefit is that we now don't
|
need to have a use of the PIC register in the return pattern and
|
need to have a use of the PIC register in the return pattern and
|
the final save/restore operation is not needed.
|
the final save/restore operation is not needed.
|
|
|
I elected to just use register %r4 in the PIC patterns instead
|
I elected to just use register %r4 in the PIC patterns instead
|
of trying to force hppa_pic_save_rtx () to a callee saved register.
|
of trying to force hppa_pic_save_rtx () to a callee saved register.
|
This might have required a new register class and constraint. It
|
This might have required a new register class and constraint. It
|
was also simpler to just handle the restore from a register than a
|
was also simpler to just handle the restore from a register than a
|
generic pseudo. */
|
generic pseudo. */
|
if (TARGET_64BIT)
|
if (TARGET_64BIT)
|
{
|
{
|
rtx r4 = gen_rtx_REG (word_mode, 4);
|
rtx r4 = gen_rtx_REG (word_mode, 4);
|
if (GET_CODE (op) == SYMBOL_REF)
|
if (GET_CODE (op) == SYMBOL_REF)
|
call_insn = emit_call_insn (gen_call_symref_64bit (op, nb, r4));
|
call_insn = emit_call_insn (gen_call_symref_64bit (op, nb, r4));
|
else
|
else
|
{
|
{
|
op = force_reg (word_mode, op);
|
op = force_reg (word_mode, op);
|
call_insn = emit_call_insn (gen_call_reg_64bit (op, nb, r4));
|
call_insn = emit_call_insn (gen_call_reg_64bit (op, nb, r4));
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
if (GET_CODE (op) == SYMBOL_REF)
|
if (GET_CODE (op) == SYMBOL_REF)
|
{
|
{
|
if (flag_pic)
|
if (flag_pic)
|
{
|
{
|
rtx r4 = gen_rtx_REG (word_mode, 4);
|
rtx r4 = gen_rtx_REG (word_mode, 4);
|
call_insn = emit_call_insn (gen_call_symref_pic (op, nb, r4));
|
call_insn = emit_call_insn (gen_call_symref_pic (op, nb, r4));
|
}
|
}
|
else
|
else
|
call_insn = emit_call_insn (gen_call_symref (op, nb));
|
call_insn = emit_call_insn (gen_call_symref (op, nb));
|
}
|
}
|
else
|
else
|
{
|
{
|
rtx tmpreg = gen_rtx_REG (word_mode, 22);
|
rtx tmpreg = gen_rtx_REG (word_mode, 22);
|
emit_move_insn (tmpreg, force_reg (word_mode, op));
|
emit_move_insn (tmpreg, force_reg (word_mode, op));
|
if (flag_pic)
|
if (flag_pic)
|
{
|
{
|
rtx r4 = gen_rtx_REG (word_mode, 4);
|
rtx r4 = gen_rtx_REG (word_mode, 4);
|
call_insn = emit_call_insn (gen_call_reg_pic (nb, r4));
|
call_insn = emit_call_insn (gen_call_reg_pic (nb, r4));
|
}
|
}
|
else
|
else
|
call_insn = emit_call_insn (gen_call_reg (nb));
|
call_insn = emit_call_insn (gen_call_reg (nb));
|
}
|
}
|
}
|
}
|
|
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
;; We use function calls to set the attribute length of calls and millicode
|
;; We use function calls to set the attribute length of calls and millicode
|
;; calls. This is necessary because of the large variety of call sequences.
|
;; calls. This is necessary because of the large variety of call sequences.
|
;; Implementing the calculation in rtl is difficult as well as ugly. As
|
;; Implementing the calculation in rtl is difficult as well as ugly. As
|
;; we need the same calculation in several places, maintenance becomes a
|
;; we need the same calculation in several places, maintenance becomes a
|
;; nightmare.
|
;; nightmare.
|
;;
|
;;
|
;; However, this has a subtle impact on branch shortening. When the
|
;; However, this has a subtle impact on branch shortening. When the
|
;; expression used to set the length attribute of an instruction depends
|
;; expression used to set the length attribute of an instruction depends
|
;; on a relative address (e.g., pc or a branch address), genattrtab
|
;; on a relative address (e.g., pc or a branch address), genattrtab
|
;; notes that the insn's length is variable, and attempts to determine a
|
;; notes that the insn's length is variable, and attempts to determine a
|
;; worst-case default length and code to compute an insn's current length.
|
;; worst-case default length and code to compute an insn's current length.
|
|
|
;; The use of a function call hides the variable dependence of our calls
|
;; The use of a function call hides the variable dependence of our calls
|
;; and millicode calls. The result is genattrtab doesn't treat the operation
|
;; and millicode calls. The result is genattrtab doesn't treat the operation
|
;; as variable and it only generates code for the default case using our
|
;; as variable and it only generates code for the default case using our
|
;; function call. Because of this, calls and millicode calls have a fixed
|
;; function call. Because of this, calls and millicode calls have a fixed
|
;; length in the branch shortening pass, and some branches will use a longer
|
;; length in the branch shortening pass, and some branches will use a longer
|
;; code sequence than necessary. However, the length of any given call
|
;; code sequence than necessary. However, the length of any given call
|
;; will still reflect its final code location and it may be shorter than
|
;; will still reflect its final code location and it may be shorter than
|
;; the initial length estimate.
|
;; the initial length estimate.
|
|
|
;; It's possible to trick genattrtab by adding an expression involving `pc'
|
;; It's possible to trick genattrtab by adding an expression involving `pc'
|
;; in the set. However, when genattrtab hits a function call in its attempt
|
;; in the set. However, when genattrtab hits a function call in its attempt
|
;; to compute the default length, it marks the result as unknown and sets
|
;; to compute the default length, it marks the result as unknown and sets
|
;; the default result to MAX_INT ;-( One possible fix that would allow
|
;; the default result to MAX_INT ;-( One possible fix that would allow
|
;; calls to participate in branch shortening would be to make the call to
|
;; calls to participate in branch shortening would be to make the call to
|
;; insn_default_length a target option. Then, we could massage unknown
|
;; insn_default_length a target option. Then, we could massage unknown
|
;; results. Another fix might be to change genattrtab so that it just does
|
;; results. Another fix might be to change genattrtab so that it just does
|
;; the call in the variable case as it already does for the fixed case.
|
;; the call in the variable case as it already does for the fixed case.
|
|
|
(define_insn "call_symref"
|
(define_insn "call_symref"
|
[(call (mem:SI (match_operand 0 "call_operand_address" ""))
|
[(call (mem:SI (match_operand 0 "call_operand_address" ""))
|
(match_operand 1 "" "i"))
|
(match_operand 1 "" "i"))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 2))
|
(clobber (reg:SI 2))
|
(use (const_int 0))]
|
(use (const_int 0))]
|
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
|
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
output_arg_descriptor (insn);
|
output_arg_descriptor (insn);
|
return output_call (insn, operands[0], 0);
|
return output_call (insn, operands[0], 0);
|
}"
|
}"
|
[(set_attr "type" "call")
|
[(set_attr "type" "call")
|
(set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))])
|
(set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))])
|
|
|
(define_insn "call_symref_pic"
|
(define_insn "call_symref_pic"
|
[(set (match_operand:SI 2 "register_operand" "=&r") (reg:SI 19))
|
[(set (match_operand:SI 2 "register_operand" "=&r") (reg:SI 19))
|
(call (mem:SI (match_operand 0 "call_operand_address" ""))
|
(call (mem:SI (match_operand 0 "call_operand_address" ""))
|
(match_operand 1 "" "i"))
|
(match_operand 1 "" "i"))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 2))
|
(clobber (reg:SI 2))
|
(use (match_dup 2))
|
(use (match_dup 2))
|
(use (reg:SI 19))
|
(use (reg:SI 19))
|
(use (const_int 0))]
|
(use (const_int 0))]
|
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
|
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
|
"#")
|
"#")
|
|
|
;; Split out the PIC register save and restore after reload. As the
|
;; Split out the PIC register save and restore after reload. As the
|
;; split is done after reload, there are some situations in which we
|
;; split is done after reload, there are some situations in which we
|
;; unnecessarily save and restore %r4. This happens when there is a
|
;; unnecessarily save and restore %r4. This happens when there is a
|
;; single call and the PIC register is not used after the call.
|
;; single call and the PIC register is not used after the call.
|
;;
|
;;
|
;; The split has to be done since call_from_call_insn () can't handle
|
;; The split has to be done since call_from_call_insn () can't handle
|
;; the pattern as is. Noreturn calls are special because they have to
|
;; the pattern as is. Noreturn calls are special because they have to
|
;; terminate the basic block. The split has to contain more than one
|
;; terminate the basic block. The split has to contain more than one
|
;; insn.
|
;; insn.
|
(define_split
|
(define_split
|
[(parallel [(set (match_operand:SI 2 "register_operand" "") (reg:SI 19))
|
[(parallel [(set (match_operand:SI 2 "register_operand" "") (reg:SI 19))
|
(call (mem:SI (match_operand 0 "call_operand_address" ""))
|
(call (mem:SI (match_operand 0 "call_operand_address" ""))
|
(match_operand 1 "" ""))
|
(match_operand 1 "" ""))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 2))
|
(clobber (reg:SI 2))
|
(use (match_dup 2))
|
(use (match_dup 2))
|
(use (reg:SI 19))
|
(use (reg:SI 19))
|
(use (const_int 0))])]
|
(use (const_int 0))])]
|
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
|
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
|
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
|
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
|
[(set (match_dup 2) (reg:SI 19))
|
[(set (match_dup 2) (reg:SI 19))
|
(parallel [(call (mem:SI (match_dup 0))
|
(parallel [(call (mem:SI (match_dup 0))
|
(match_dup 1))
|
(match_dup 1))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 2))
|
(clobber (reg:SI 2))
|
(use (reg:SI 19))
|
(use (reg:SI 19))
|
(use (const_int 0))])]
|
(use (const_int 0))])]
|
"")
|
"")
|
|
|
(define_split
|
(define_split
|
[(parallel [(set (match_operand:SI 2 "register_operand" "") (reg:SI 19))
|
[(parallel [(set (match_operand:SI 2 "register_operand" "") (reg:SI 19))
|
(call (mem:SI (match_operand 0 "call_operand_address" ""))
|
(call (mem:SI (match_operand 0 "call_operand_address" ""))
|
(match_operand 1 "" ""))
|
(match_operand 1 "" ""))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 2))
|
(clobber (reg:SI 2))
|
(use (match_dup 2))
|
(use (match_dup 2))
|
(use (reg:SI 19))
|
(use (reg:SI 19))
|
(use (const_int 0))])]
|
(use (const_int 0))])]
|
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
|
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
|
[(set (match_dup 2) (reg:SI 19))
|
[(set (match_dup 2) (reg:SI 19))
|
(parallel [(call (mem:SI (match_dup 0))
|
(parallel [(call (mem:SI (match_dup 0))
|
(match_dup 1))
|
(match_dup 1))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 2))
|
(clobber (reg:SI 2))
|
(use (reg:SI 19))
|
(use (reg:SI 19))
|
(use (const_int 0))])
|
(use (const_int 0))])
|
(set (reg:SI 19) (match_dup 2))]
|
(set (reg:SI 19) (match_dup 2))]
|
"")
|
"")
|
|
|
(define_insn "*call_symref_pic_post_reload"
|
(define_insn "*call_symref_pic_post_reload"
|
[(call (mem:SI (match_operand 0 "call_operand_address" ""))
|
[(call (mem:SI (match_operand 0 "call_operand_address" ""))
|
(match_operand 1 "" "i"))
|
(match_operand 1 "" "i"))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 2))
|
(clobber (reg:SI 2))
|
(use (reg:SI 19))
|
(use (reg:SI 19))
|
(use (const_int 0))]
|
(use (const_int 0))]
|
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
|
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
output_arg_descriptor (insn);
|
output_arg_descriptor (insn);
|
return output_call (insn, operands[0], 0);
|
return output_call (insn, operands[0], 0);
|
}"
|
}"
|
[(set_attr "type" "call")
|
[(set_attr "type" "call")
|
(set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))])
|
(set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))])
|
|
|
;; This pattern is split if it is necessary to save and restore the
|
;; This pattern is split if it is necessary to save and restore the
|
;; PIC register.
|
;; PIC register.
|
(define_insn "call_symref_64bit"
|
(define_insn "call_symref_64bit"
|
[(set (match_operand:DI 2 "register_operand" "=&r") (reg:DI 27))
|
[(set (match_operand:DI 2 "register_operand" "=&r") (reg:DI 27))
|
(call (mem:SI (match_operand 0 "call_operand_address" ""))
|
(call (mem:SI (match_operand 0 "call_operand_address" ""))
|
(match_operand 1 "" "i"))
|
(match_operand 1 "" "i"))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 2))
|
(clobber (reg:DI 2))
|
(use (match_dup 2))
|
(use (match_dup 2))
|
(use (reg:DI 27))
|
(use (reg:DI 27))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(use (const_int 0))]
|
(use (const_int 0))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"#")
|
"#")
|
|
|
;; Split out the PIC register save and restore after reload. As the
|
;; Split out the PIC register save and restore after reload. As the
|
;; split is done after reload, there are some situations in which we
|
;; split is done after reload, there are some situations in which we
|
;; unnecessarily save and restore %r4. This happens when there is a
|
;; unnecessarily save and restore %r4. This happens when there is a
|
;; single call and the PIC register is not used after the call.
|
;; single call and the PIC register is not used after the call.
|
;;
|
;;
|
;; The split has to be done since call_from_call_insn () can't handle
|
;; The split has to be done since call_from_call_insn () can't handle
|
;; the pattern as is. Noreturn calls are special because they have to
|
;; the pattern as is. Noreturn calls are special because they have to
|
;; terminate the basic block. The split has to contain more than one
|
;; terminate the basic block. The split has to contain more than one
|
;; insn.
|
;; insn.
|
(define_split
|
(define_split
|
[(parallel [(set (match_operand:DI 2 "register_operand" "") (reg:DI 27))
|
[(parallel [(set (match_operand:DI 2 "register_operand" "") (reg:DI 27))
|
(call (mem:SI (match_operand 0 "call_operand_address" ""))
|
(call (mem:SI (match_operand 0 "call_operand_address" ""))
|
(match_operand 1 "" ""))
|
(match_operand 1 "" ""))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 2))
|
(clobber (reg:DI 2))
|
(use (match_dup 2))
|
(use (match_dup 2))
|
(use (reg:DI 27))
|
(use (reg:DI 27))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(use (const_int 0))])]
|
(use (const_int 0))])]
|
"TARGET_64BIT && reload_completed
|
"TARGET_64BIT && reload_completed
|
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
|
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
|
[(set (match_dup 2) (reg:DI 27))
|
[(set (match_dup 2) (reg:DI 27))
|
(parallel [(call (mem:SI (match_dup 0))
|
(parallel [(call (mem:SI (match_dup 0))
|
(match_dup 1))
|
(match_dup 1))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 2))
|
(clobber (reg:DI 2))
|
(use (reg:DI 27))
|
(use (reg:DI 27))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(use (const_int 0))])]
|
(use (const_int 0))])]
|
"")
|
"")
|
|
|
(define_split
|
(define_split
|
[(parallel [(set (match_operand:DI 2 "register_operand" "") (reg:DI 27))
|
[(parallel [(set (match_operand:DI 2 "register_operand" "") (reg:DI 27))
|
(call (mem:SI (match_operand 0 "call_operand_address" ""))
|
(call (mem:SI (match_operand 0 "call_operand_address" ""))
|
(match_operand 1 "" ""))
|
(match_operand 1 "" ""))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 2))
|
(clobber (reg:DI 2))
|
(use (match_dup 2))
|
(use (match_dup 2))
|
(use (reg:DI 27))
|
(use (reg:DI 27))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(use (const_int 0))])]
|
(use (const_int 0))])]
|
"TARGET_64BIT && reload_completed"
|
"TARGET_64BIT && reload_completed"
|
[(set (match_dup 2) (reg:DI 27))
|
[(set (match_dup 2) (reg:DI 27))
|
(parallel [(call (mem:SI (match_dup 0))
|
(parallel [(call (mem:SI (match_dup 0))
|
(match_dup 1))
|
(match_dup 1))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 2))
|
(clobber (reg:DI 2))
|
(use (reg:DI 27))
|
(use (reg:DI 27))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(use (const_int 0))])
|
(use (const_int 0))])
|
(set (reg:DI 27) (match_dup 2))]
|
(set (reg:DI 27) (match_dup 2))]
|
"")
|
"")
|
|
|
(define_insn "*call_symref_64bit_post_reload"
|
(define_insn "*call_symref_64bit_post_reload"
|
[(call (mem:SI (match_operand 0 "call_operand_address" ""))
|
[(call (mem:SI (match_operand 0 "call_operand_address" ""))
|
(match_operand 1 "" "i"))
|
(match_operand 1 "" "i"))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 2))
|
(clobber (reg:DI 2))
|
(use (reg:DI 27))
|
(use (reg:DI 27))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(use (const_int 0))]
|
(use (const_int 0))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
output_arg_descriptor (insn);
|
output_arg_descriptor (insn);
|
return output_call (insn, operands[0], 0);
|
return output_call (insn, operands[0], 0);
|
}"
|
}"
|
[(set_attr "type" "call")
|
[(set_attr "type" "call")
|
(set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))])
|
(set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))])
|
|
|
(define_insn "call_reg"
|
(define_insn "call_reg"
|
[(call (mem:SI (reg:SI 22))
|
[(call (mem:SI (reg:SI 22))
|
(match_operand 0 "" "i"))
|
(match_operand 0 "" "i"))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 2))
|
(clobber (reg:SI 2))
|
(use (const_int 1))]
|
(use (const_int 1))]
|
"!TARGET_64BIT"
|
"!TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
return output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
|
return output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
|
}"
|
}"
|
[(set_attr "type" "dyncall")
|
[(set_attr "type" "dyncall")
|
(set (attr "length") (symbol_ref "attr_length_indirect_call (insn)"))])
|
(set (attr "length") (symbol_ref "attr_length_indirect_call (insn)"))])
|
|
|
;; This pattern is split if it is necessary to save and restore the
|
;; This pattern is split if it is necessary to save and restore the
|
;; PIC register.
|
;; PIC register.
|
(define_insn "call_reg_pic"
|
(define_insn "call_reg_pic"
|
[(set (match_operand:SI 1 "register_operand" "=&r") (reg:SI 19))
|
[(set (match_operand:SI 1 "register_operand" "=&r") (reg:SI 19))
|
(call (mem:SI (reg:SI 22))
|
(call (mem:SI (reg:SI 22))
|
(match_operand 0 "" "i"))
|
(match_operand 0 "" "i"))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 2))
|
(clobber (reg:SI 2))
|
(use (match_dup 1))
|
(use (match_dup 1))
|
(use (reg:SI 19))
|
(use (reg:SI 19))
|
(use (const_int 1))]
|
(use (const_int 1))]
|
"!TARGET_64BIT"
|
"!TARGET_64BIT"
|
"#")
|
"#")
|
|
|
;; Split out the PIC register save and restore after reload. As the
|
;; Split out the PIC register save and restore after reload. As the
|
;; split is done after reload, there are some situations in which we
|
;; split is done after reload, there are some situations in which we
|
;; unnecessarily save and restore %r4. This happens when there is a
|
;; unnecessarily save and restore %r4. This happens when there is a
|
;; single call and the PIC register is not used after the call.
|
;; single call and the PIC register is not used after the call.
|
;;
|
;;
|
;; The split has to be done since call_from_call_insn () can't handle
|
;; The split has to be done since call_from_call_insn () can't handle
|
;; the pattern as is. Noreturn calls are special because they have to
|
;; the pattern as is. Noreturn calls are special because they have to
|
;; terminate the basic block. The split has to contain more than one
|
;; terminate the basic block. The split has to contain more than one
|
;; insn.
|
;; insn.
|
(define_split
|
(define_split
|
[(parallel [(set (match_operand:SI 1 "register_operand" "") (reg:SI 19))
|
[(parallel [(set (match_operand:SI 1 "register_operand" "") (reg:SI 19))
|
(call (mem:SI (reg:SI 22))
|
(call (mem:SI (reg:SI 22))
|
(match_operand 0 "" ""))
|
(match_operand 0 "" ""))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 2))
|
(clobber (reg:SI 2))
|
(use (match_dup 1))
|
(use (match_dup 1))
|
(use (reg:SI 19))
|
(use (reg:SI 19))
|
(use (const_int 1))])]
|
(use (const_int 1))])]
|
"!TARGET_64BIT && reload_completed
|
"!TARGET_64BIT && reload_completed
|
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
|
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
|
[(set (match_dup 1) (reg:SI 19))
|
[(set (match_dup 1) (reg:SI 19))
|
(parallel [(call (mem:SI (reg:SI 22))
|
(parallel [(call (mem:SI (reg:SI 22))
|
(match_dup 0))
|
(match_dup 0))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 2))
|
(clobber (reg:SI 2))
|
(use (reg:SI 19))
|
(use (reg:SI 19))
|
(use (const_int 1))])]
|
(use (const_int 1))])]
|
"")
|
"")
|
|
|
(define_split
|
(define_split
|
[(parallel [(set (match_operand:SI 1 "register_operand" "") (reg:SI 19))
|
[(parallel [(set (match_operand:SI 1 "register_operand" "") (reg:SI 19))
|
(call (mem:SI (reg:SI 22))
|
(call (mem:SI (reg:SI 22))
|
(match_operand 0 "" ""))
|
(match_operand 0 "" ""))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 2))
|
(clobber (reg:SI 2))
|
(use (match_dup 1))
|
(use (match_dup 1))
|
(use (reg:SI 19))
|
(use (reg:SI 19))
|
(use (const_int 1))])]
|
(use (const_int 1))])]
|
"!TARGET_64BIT && reload_completed"
|
"!TARGET_64BIT && reload_completed"
|
[(set (match_dup 1) (reg:SI 19))
|
[(set (match_dup 1) (reg:SI 19))
|
(parallel [(call (mem:SI (reg:SI 22))
|
(parallel [(call (mem:SI (reg:SI 22))
|
(match_dup 0))
|
(match_dup 0))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 2))
|
(clobber (reg:SI 2))
|
(use (reg:SI 19))
|
(use (reg:SI 19))
|
(use (const_int 1))])
|
(use (const_int 1))])
|
(set (reg:SI 19) (match_dup 1))]
|
(set (reg:SI 19) (match_dup 1))]
|
"")
|
"")
|
|
|
(define_insn "*call_reg_pic_post_reload"
|
(define_insn "*call_reg_pic_post_reload"
|
[(call (mem:SI (reg:SI 22))
|
[(call (mem:SI (reg:SI 22))
|
(match_operand 0 "" "i"))
|
(match_operand 0 "" "i"))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 2))
|
(clobber (reg:SI 2))
|
(use (reg:SI 19))
|
(use (reg:SI 19))
|
(use (const_int 1))]
|
(use (const_int 1))]
|
"!TARGET_64BIT"
|
"!TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
return output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
|
return output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
|
}"
|
}"
|
[(set_attr "type" "dyncall")
|
[(set_attr "type" "dyncall")
|
(set (attr "length") (symbol_ref "attr_length_indirect_call (insn)"))])
|
(set (attr "length") (symbol_ref "attr_length_indirect_call (insn)"))])
|
|
|
;; This pattern is split if it is necessary to save and restore the
|
;; This pattern is split if it is necessary to save and restore the
|
;; PIC register.
|
;; PIC register.
|
(define_insn "call_reg_64bit"
|
(define_insn "call_reg_64bit"
|
[(set (match_operand:DI 2 "register_operand" "=&r") (reg:DI 27))
|
[(set (match_operand:DI 2 "register_operand" "=&r") (reg:DI 27))
|
(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
|
(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
|
(match_operand 1 "" "i"))
|
(match_operand 1 "" "i"))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 2))
|
(clobber (reg:DI 2))
|
(use (match_dup 2))
|
(use (match_dup 2))
|
(use (reg:DI 27))
|
(use (reg:DI 27))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(use (const_int 1))]
|
(use (const_int 1))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"#")
|
"#")
|
|
|
;; Split out the PIC register save and restore after reload. As the
|
;; Split out the PIC register save and restore after reload. As the
|
;; split is done after reload, there are some situations in which we
|
;; split is done after reload, there are some situations in which we
|
;; unnecessarily save and restore %r4. This happens when there is a
|
;; unnecessarily save and restore %r4. This happens when there is a
|
;; single call and the PIC register is not used after the call.
|
;; single call and the PIC register is not used after the call.
|
;;
|
;;
|
;; The split has to be done since call_from_call_insn () can't handle
|
;; The split has to be done since call_from_call_insn () can't handle
|
;; the pattern as is. Noreturn calls are special because they have to
|
;; the pattern as is. Noreturn calls are special because they have to
|
;; terminate the basic block. The split has to contain more than one
|
;; terminate the basic block. The split has to contain more than one
|
;; insn.
|
;; insn.
|
(define_split
|
(define_split
|
[(parallel [(set (match_operand:DI 2 "register_operand" "") (reg:DI 27))
|
[(parallel [(set (match_operand:DI 2 "register_operand" "") (reg:DI 27))
|
(call (mem:SI (match_operand 0 "register_operand" ""))
|
(call (mem:SI (match_operand 0 "register_operand" ""))
|
(match_operand 1 "" ""))
|
(match_operand 1 "" ""))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 2))
|
(clobber (reg:DI 2))
|
(use (match_dup 2))
|
(use (match_dup 2))
|
(use (reg:DI 27))
|
(use (reg:DI 27))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(use (const_int 1))])]
|
(use (const_int 1))])]
|
"TARGET_64BIT && reload_completed
|
"TARGET_64BIT && reload_completed
|
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
|
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
|
[(set (match_dup 2) (reg:DI 27))
|
[(set (match_dup 2) (reg:DI 27))
|
(parallel [(call (mem:SI (match_dup 0))
|
(parallel [(call (mem:SI (match_dup 0))
|
(match_dup 1))
|
(match_dup 1))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 2))
|
(clobber (reg:DI 2))
|
(use (reg:DI 27))
|
(use (reg:DI 27))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(use (const_int 1))])]
|
(use (const_int 1))])]
|
"")
|
"")
|
|
|
(define_split
|
(define_split
|
[(parallel [(set (match_operand:DI 2 "register_operand" "") (reg:DI 27))
|
[(parallel [(set (match_operand:DI 2 "register_operand" "") (reg:DI 27))
|
(call (mem:SI (match_operand 0 "register_operand" ""))
|
(call (mem:SI (match_operand 0 "register_operand" ""))
|
(match_operand 1 "" ""))
|
(match_operand 1 "" ""))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 2))
|
(clobber (reg:DI 2))
|
(use (match_dup 2))
|
(use (match_dup 2))
|
(use (reg:DI 27))
|
(use (reg:DI 27))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(use (const_int 1))])]
|
(use (const_int 1))])]
|
"TARGET_64BIT && reload_completed"
|
"TARGET_64BIT && reload_completed"
|
[(set (match_dup 2) (reg:DI 27))
|
[(set (match_dup 2) (reg:DI 27))
|
(parallel [(call (mem:SI (match_dup 0))
|
(parallel [(call (mem:SI (match_dup 0))
|
(match_dup 1))
|
(match_dup 1))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 2))
|
(clobber (reg:DI 2))
|
(use (reg:DI 27))
|
(use (reg:DI 27))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(use (const_int 1))])
|
(use (const_int 1))])
|
(set (reg:DI 27) (match_dup 2))]
|
(set (reg:DI 27) (match_dup 2))]
|
"")
|
"")
|
|
|
(define_insn "*call_reg_64bit_post_reload"
|
(define_insn "*call_reg_64bit_post_reload"
|
[(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
|
[(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
|
(match_operand 1 "" "i"))
|
(match_operand 1 "" "i"))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 2))
|
(clobber (reg:DI 2))
|
(use (reg:DI 27))
|
(use (reg:DI 27))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(use (const_int 1))]
|
(use (const_int 1))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
return output_indirect_call (insn, operands[0]);
|
return output_indirect_call (insn, operands[0]);
|
}"
|
}"
|
[(set_attr "type" "dyncall")
|
[(set_attr "type" "dyncall")
|
(set (attr "length") (symbol_ref "attr_length_indirect_call (insn)"))])
|
(set (attr "length") (symbol_ref "attr_length_indirect_call (insn)"))])
|
|
|
(define_expand "call_value"
|
(define_expand "call_value"
|
[(parallel [(set (match_operand 0 "" "")
|
[(parallel [(set (match_operand 0 "" "")
|
(call (match_operand:SI 1 "" "")
|
(call (match_operand:SI 1 "" "")
|
(match_operand 2 "" "")))
|
(match_operand 2 "" "")))
|
(clobber (reg:SI 2))])]
|
(clobber (reg:SI 2))])]
|
""
|
""
|
"
|
"
|
{
|
{
|
rtx op, call_insn;
|
rtx op, call_insn;
|
rtx dst = operands[0];
|
rtx dst = operands[0];
|
rtx nb = operands[2];
|
rtx nb = operands[2];
|
|
|
if (TARGET_PORTABLE_RUNTIME)
|
if (TARGET_PORTABLE_RUNTIME)
|
op = force_reg (SImode, XEXP (operands[1], 0));
|
op = force_reg (SImode, XEXP (operands[1], 0));
|
else
|
else
|
op = XEXP (operands[1], 0);
|
op = XEXP (operands[1], 0);
|
|
|
if (TARGET_64BIT)
|
if (TARGET_64BIT)
|
{
|
{
|
if (!virtuals_instantiated)
|
if (!virtuals_instantiated)
|
emit_move_insn (arg_pointer_rtx,
|
emit_move_insn (arg_pointer_rtx,
|
gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
|
gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
|
GEN_INT (64)));
|
GEN_INT (64)));
|
else
|
else
|
{
|
{
|
/* The loop pass can generate new libcalls after the virtual
|
/* The loop pass can generate new libcalls after the virtual
|
registers are instantiated when fpregs are disabled because
|
registers are instantiated when fpregs are disabled because
|
the only method that we have for doing DImode multiplication
|
the only method that we have for doing DImode multiplication
|
is with a libcall. This could be trouble if we haven't
|
is with a libcall. This could be trouble if we haven't
|
allocated enough space for the outgoing arguments. */
|
allocated enough space for the outgoing arguments. */
|
gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
|
gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
|
|
|
emit_move_insn (arg_pointer_rtx,
|
emit_move_insn (arg_pointer_rtx,
|
gen_rtx_PLUS (word_mode, stack_pointer_rtx,
|
gen_rtx_PLUS (word_mode, stack_pointer_rtx,
|
GEN_INT (STACK_POINTER_OFFSET + 64)));
|
GEN_INT (STACK_POINTER_OFFSET + 64)));
|
}
|
}
|
}
|
}
|
|
|
/* Use two different patterns for calls to explicitly named functions
|
/* Use two different patterns for calls to explicitly named functions
|
and calls through function pointers. This is necessary as these two
|
and calls through function pointers. This is necessary as these two
|
types of calls use different calling conventions, and CSE might try
|
types of calls use different calling conventions, and CSE might try
|
to change the named call into an indirect call in some cases (using
|
to change the named call into an indirect call in some cases (using
|
two patterns keeps CSE from performing this optimization).
|
two patterns keeps CSE from performing this optimization).
|
|
|
We now use even more call patterns as there was a subtle bug in
|
We now use even more call patterns as there was a subtle bug in
|
attempting to restore the pic register after a call using a simple
|
attempting to restore the pic register after a call using a simple
|
move insn. During reload, a instruction involving a pseudo register
|
move insn. During reload, a instruction involving a pseudo register
|
with no explicit dependence on the PIC register can be converted
|
with no explicit dependence on the PIC register can be converted
|
to an equivalent load from memory using the PIC register. If we
|
to an equivalent load from memory using the PIC register. If we
|
emit a simple move to restore the PIC register in the initial rtl
|
emit a simple move to restore the PIC register in the initial rtl
|
generation, then it can potentially be repositioned during scheduling.
|
generation, then it can potentially be repositioned during scheduling.
|
and an instruction that eventually uses the PIC register may end up
|
and an instruction that eventually uses the PIC register may end up
|
between the call and the PIC register restore.
|
between the call and the PIC register restore.
|
|
|
This only worked because there is a post call group of instructions
|
This only worked because there is a post call group of instructions
|
that are scheduled with the call. These instructions are included
|
that are scheduled with the call. These instructions are included
|
in the same basic block as the call. However, calls can throw in
|
in the same basic block as the call. However, calls can throw in
|
C++ code and a basic block has to terminate at the call if the call
|
C++ code and a basic block has to terminate at the call if the call
|
can throw. This results in the PIC register restore being scheduled
|
can throw. This results in the PIC register restore being scheduled
|
independently from the call. So, we now hide the save and restore
|
independently from the call. So, we now hide the save and restore
|
of the PIC register in the call pattern until after reload. Then,
|
of the PIC register in the call pattern until after reload. Then,
|
we split the moves out. A small side benefit is that we now don't
|
we split the moves out. A small side benefit is that we now don't
|
need to have a use of the PIC register in the return pattern and
|
need to have a use of the PIC register in the return pattern and
|
the final save/restore operation is not needed.
|
the final save/restore operation is not needed.
|
|
|
I elected to just use register %r4 in the PIC patterns instead
|
I elected to just use register %r4 in the PIC patterns instead
|
of trying to force hppa_pic_save_rtx () to a callee saved register.
|
of trying to force hppa_pic_save_rtx () to a callee saved register.
|
This might have required a new register class and constraint. It
|
This might have required a new register class and constraint. It
|
was also simpler to just handle the restore from a register than a
|
was also simpler to just handle the restore from a register than a
|
generic pseudo. */
|
generic pseudo. */
|
if (TARGET_64BIT)
|
if (TARGET_64BIT)
|
{
|
{
|
rtx r4 = gen_rtx_REG (word_mode, 4);
|
rtx r4 = gen_rtx_REG (word_mode, 4);
|
if (GET_CODE (op) == SYMBOL_REF)
|
if (GET_CODE (op) == SYMBOL_REF)
|
call_insn
|
call_insn
|
= emit_call_insn (gen_call_val_symref_64bit (dst, op, nb, r4));
|
= emit_call_insn (gen_call_val_symref_64bit (dst, op, nb, r4));
|
else
|
else
|
{
|
{
|
op = force_reg (word_mode, op);
|
op = force_reg (word_mode, op);
|
call_insn
|
call_insn
|
= emit_call_insn (gen_call_val_reg_64bit (dst, op, nb, r4));
|
= emit_call_insn (gen_call_val_reg_64bit (dst, op, nb, r4));
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
if (GET_CODE (op) == SYMBOL_REF)
|
if (GET_CODE (op) == SYMBOL_REF)
|
{
|
{
|
if (flag_pic)
|
if (flag_pic)
|
{
|
{
|
rtx r4 = gen_rtx_REG (word_mode, 4);
|
rtx r4 = gen_rtx_REG (word_mode, 4);
|
call_insn
|
call_insn
|
= emit_call_insn (gen_call_val_symref_pic (dst, op, nb, r4));
|
= emit_call_insn (gen_call_val_symref_pic (dst, op, nb, r4));
|
}
|
}
|
else
|
else
|
call_insn = emit_call_insn (gen_call_val_symref (dst, op, nb));
|
call_insn = emit_call_insn (gen_call_val_symref (dst, op, nb));
|
}
|
}
|
else
|
else
|
{
|
{
|
rtx tmpreg = gen_rtx_REG (word_mode, 22);
|
rtx tmpreg = gen_rtx_REG (word_mode, 22);
|
emit_move_insn (tmpreg, force_reg (word_mode, op));
|
emit_move_insn (tmpreg, force_reg (word_mode, op));
|
if (flag_pic)
|
if (flag_pic)
|
{
|
{
|
rtx r4 = gen_rtx_REG (word_mode, 4);
|
rtx r4 = gen_rtx_REG (word_mode, 4);
|
call_insn = emit_call_insn (gen_call_val_reg_pic (dst, nb, r4));
|
call_insn = emit_call_insn (gen_call_val_reg_pic (dst, nb, r4));
|
}
|
}
|
else
|
else
|
call_insn = emit_call_insn (gen_call_val_reg (dst, nb));
|
call_insn = emit_call_insn (gen_call_val_reg (dst, nb));
|
}
|
}
|
}
|
}
|
|
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
(define_insn "call_val_symref"
|
(define_insn "call_val_symref"
|
[(set (match_operand 0 "" "")
|
[(set (match_operand 0 "" "")
|
(call (mem:SI (match_operand 1 "call_operand_address" ""))
|
(call (mem:SI (match_operand 1 "call_operand_address" ""))
|
(match_operand 2 "" "i")))
|
(match_operand 2 "" "i")))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 2))
|
(clobber (reg:SI 2))
|
(use (const_int 0))]
|
(use (const_int 0))]
|
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
|
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
output_arg_descriptor (insn);
|
output_arg_descriptor (insn);
|
return output_call (insn, operands[1], 0);
|
return output_call (insn, operands[1], 0);
|
}"
|
}"
|
[(set_attr "type" "call")
|
[(set_attr "type" "call")
|
(set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))])
|
(set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))])
|
|
|
(define_insn "call_val_symref_pic"
|
(define_insn "call_val_symref_pic"
|
[(set (match_operand:SI 3 "register_operand" "=&r") (reg:SI 19))
|
[(set (match_operand:SI 3 "register_operand" "=&r") (reg:SI 19))
|
(set (match_operand 0 "" "")
|
(set (match_operand 0 "" "")
|
(call (mem:SI (match_operand 1 "call_operand_address" ""))
|
(call (mem:SI (match_operand 1 "call_operand_address" ""))
|
(match_operand 2 "" "i")))
|
(match_operand 2 "" "i")))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 2))
|
(clobber (reg:SI 2))
|
(use (match_dup 3))
|
(use (match_dup 3))
|
(use (reg:SI 19))
|
(use (reg:SI 19))
|
(use (const_int 0))]
|
(use (const_int 0))]
|
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
|
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
|
"#")
|
"#")
|
|
|
;; Split out the PIC register save and restore after reload. As the
|
;; Split out the PIC register save and restore after reload. As the
|
;; split is done after reload, there are some situations in which we
|
;; split is done after reload, there are some situations in which we
|
;; unnecessarily save and restore %r4. This happens when there is a
|
;; unnecessarily save and restore %r4. This happens when there is a
|
;; single call and the PIC register is not used after the call.
|
;; single call and the PIC register is not used after the call.
|
;;
|
;;
|
;; The split has to be done since call_from_call_insn () can't handle
|
;; The split has to be done since call_from_call_insn () can't handle
|
;; the pattern as is. Noreturn calls are special because they have to
|
;; the pattern as is. Noreturn calls are special because they have to
|
;; terminate the basic block. The split has to contain more than one
|
;; terminate the basic block. The split has to contain more than one
|
;; insn.
|
;; insn.
|
(define_split
|
(define_split
|
[(parallel [(set (match_operand:SI 3 "register_operand" "") (reg:SI 19))
|
[(parallel [(set (match_operand:SI 3 "register_operand" "") (reg:SI 19))
|
(set (match_operand 0 "" "")
|
(set (match_operand 0 "" "")
|
(call (mem:SI (match_operand 1 "call_operand_address" ""))
|
(call (mem:SI (match_operand 1 "call_operand_address" ""))
|
(match_operand 2 "" "")))
|
(match_operand 2 "" "")))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 2))
|
(clobber (reg:SI 2))
|
(use (match_dup 3))
|
(use (match_dup 3))
|
(use (reg:SI 19))
|
(use (reg:SI 19))
|
(use (const_int 0))])]
|
(use (const_int 0))])]
|
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
|
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
|
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
|
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
|
[(set (match_dup 3) (reg:SI 19))
|
[(set (match_dup 3) (reg:SI 19))
|
(parallel [(set (match_dup 0)
|
(parallel [(set (match_dup 0)
|
(call (mem:SI (match_dup 1))
|
(call (mem:SI (match_dup 1))
|
(match_dup 2)))
|
(match_dup 2)))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 2))
|
(clobber (reg:SI 2))
|
(use (reg:SI 19))
|
(use (reg:SI 19))
|
(use (const_int 0))])]
|
(use (const_int 0))])]
|
"")
|
"")
|
|
|
(define_split
|
(define_split
|
[(parallel [(set (match_operand:SI 3 "register_operand" "") (reg:SI 19))
|
[(parallel [(set (match_operand:SI 3 "register_operand" "") (reg:SI 19))
|
(set (match_operand 0 "" "")
|
(set (match_operand 0 "" "")
|
(call (mem:SI (match_operand 1 "call_operand_address" ""))
|
(call (mem:SI (match_operand 1 "call_operand_address" ""))
|
(match_operand 2 "" "")))
|
(match_operand 2 "" "")))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 2))
|
(clobber (reg:SI 2))
|
(use (match_dup 3))
|
(use (match_dup 3))
|
(use (reg:SI 19))
|
(use (reg:SI 19))
|
(use (const_int 0))])]
|
(use (const_int 0))])]
|
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
|
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
|
[(set (match_dup 3) (reg:SI 19))
|
[(set (match_dup 3) (reg:SI 19))
|
(parallel [(set (match_dup 0)
|
(parallel [(set (match_dup 0)
|
(call (mem:SI (match_dup 1))
|
(call (mem:SI (match_dup 1))
|
(match_dup 2)))
|
(match_dup 2)))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 2))
|
(clobber (reg:SI 2))
|
(use (reg:SI 19))
|
(use (reg:SI 19))
|
(use (const_int 0))])
|
(use (const_int 0))])
|
(set (reg:SI 19) (match_dup 3))]
|
(set (reg:SI 19) (match_dup 3))]
|
"")
|
"")
|
|
|
(define_insn "*call_val_symref_pic_post_reload"
|
(define_insn "*call_val_symref_pic_post_reload"
|
[(set (match_operand 0 "" "")
|
[(set (match_operand 0 "" "")
|
(call (mem:SI (match_operand 1 "call_operand_address" ""))
|
(call (mem:SI (match_operand 1 "call_operand_address" ""))
|
(match_operand 2 "" "i")))
|
(match_operand 2 "" "i")))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 2))
|
(clobber (reg:SI 2))
|
(use (reg:SI 19))
|
(use (reg:SI 19))
|
(use (const_int 0))]
|
(use (const_int 0))]
|
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
|
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
output_arg_descriptor (insn);
|
output_arg_descriptor (insn);
|
return output_call (insn, operands[1], 0);
|
return output_call (insn, operands[1], 0);
|
}"
|
}"
|
[(set_attr "type" "call")
|
[(set_attr "type" "call")
|
(set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))])
|
(set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))])
|
|
|
;; This pattern is split if it is necessary to save and restore the
|
;; This pattern is split if it is necessary to save and restore the
|
;; PIC register.
|
;; PIC register.
|
(define_insn "call_val_symref_64bit"
|
(define_insn "call_val_symref_64bit"
|
[(set (match_operand:DI 3 "register_operand" "=&r") (reg:DI 27))
|
[(set (match_operand:DI 3 "register_operand" "=&r") (reg:DI 27))
|
(set (match_operand 0 "" "")
|
(set (match_operand 0 "" "")
|
(call (mem:SI (match_operand 1 "call_operand_address" ""))
|
(call (mem:SI (match_operand 1 "call_operand_address" ""))
|
(match_operand 2 "" "i")))
|
(match_operand 2 "" "i")))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 2))
|
(clobber (reg:DI 2))
|
(use (match_dup 3))
|
(use (match_dup 3))
|
(use (reg:DI 27))
|
(use (reg:DI 27))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(use (const_int 0))]
|
(use (const_int 0))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"#")
|
"#")
|
|
|
;; Split out the PIC register save and restore after reload. As the
|
;; Split out the PIC register save and restore after reload. As the
|
;; split is done after reload, there are some situations in which we
|
;; split is done after reload, there are some situations in which we
|
;; unnecessarily save and restore %r4. This happens when there is a
|
;; unnecessarily save and restore %r4. This happens when there is a
|
;; single call and the PIC register is not used after the call.
|
;; single call and the PIC register is not used after the call.
|
;;
|
;;
|
;; The split has to be done since call_from_call_insn () can't handle
|
;; The split has to be done since call_from_call_insn () can't handle
|
;; the pattern as is. Noreturn calls are special because they have to
|
;; the pattern as is. Noreturn calls are special because they have to
|
;; terminate the basic block. The split has to contain more than one
|
;; terminate the basic block. The split has to contain more than one
|
;; insn.
|
;; insn.
|
(define_split
|
(define_split
|
[(parallel [(set (match_operand:DI 3 "register_operand" "") (reg:DI 27))
|
[(parallel [(set (match_operand:DI 3 "register_operand" "") (reg:DI 27))
|
(set (match_operand 0 "" "")
|
(set (match_operand 0 "" "")
|
(call (mem:SI (match_operand 1 "call_operand_address" ""))
|
(call (mem:SI (match_operand 1 "call_operand_address" ""))
|
(match_operand 2 "" "")))
|
(match_operand 2 "" "")))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 2))
|
(clobber (reg:DI 2))
|
(use (match_dup 3))
|
(use (match_dup 3))
|
(use (reg:DI 27))
|
(use (reg:DI 27))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(use (const_int 0))])]
|
(use (const_int 0))])]
|
"TARGET_64BIT && reload_completed
|
"TARGET_64BIT && reload_completed
|
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
|
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
|
[(set (match_dup 3) (reg:DI 27))
|
[(set (match_dup 3) (reg:DI 27))
|
(parallel [(set (match_dup 0)
|
(parallel [(set (match_dup 0)
|
(call (mem:SI (match_dup 1))
|
(call (mem:SI (match_dup 1))
|
(match_dup 2)))
|
(match_dup 2)))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 2))
|
(clobber (reg:DI 2))
|
(use (reg:DI 27))
|
(use (reg:DI 27))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(use (const_int 0))])]
|
(use (const_int 0))])]
|
"")
|
"")
|
|
|
(define_split
|
(define_split
|
[(parallel [(set (match_operand:DI 3 "register_operand" "") (reg:DI 27))
|
[(parallel [(set (match_operand:DI 3 "register_operand" "") (reg:DI 27))
|
(set (match_operand 0 "" "")
|
(set (match_operand 0 "" "")
|
(call (mem:SI (match_operand 1 "call_operand_address" ""))
|
(call (mem:SI (match_operand 1 "call_operand_address" ""))
|
(match_operand 2 "" "")))
|
(match_operand 2 "" "")))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 2))
|
(clobber (reg:DI 2))
|
(use (match_dup 3))
|
(use (match_dup 3))
|
(use (reg:DI 27))
|
(use (reg:DI 27))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(use (const_int 0))])]
|
(use (const_int 0))])]
|
"TARGET_64BIT && reload_completed"
|
"TARGET_64BIT && reload_completed"
|
[(set (match_dup 3) (reg:DI 27))
|
[(set (match_dup 3) (reg:DI 27))
|
(parallel [(set (match_dup 0)
|
(parallel [(set (match_dup 0)
|
(call (mem:SI (match_dup 1))
|
(call (mem:SI (match_dup 1))
|
(match_dup 2)))
|
(match_dup 2)))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 2))
|
(clobber (reg:DI 2))
|
(use (reg:DI 27))
|
(use (reg:DI 27))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(use (const_int 0))])
|
(use (const_int 0))])
|
(set (reg:DI 27) (match_dup 3))]
|
(set (reg:DI 27) (match_dup 3))]
|
"")
|
"")
|
|
|
(define_insn "*call_val_symref_64bit_post_reload"
|
(define_insn "*call_val_symref_64bit_post_reload"
|
[(set (match_operand 0 "" "")
|
[(set (match_operand 0 "" "")
|
(call (mem:SI (match_operand 1 "call_operand_address" ""))
|
(call (mem:SI (match_operand 1 "call_operand_address" ""))
|
(match_operand 2 "" "i")))
|
(match_operand 2 "" "i")))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 2))
|
(clobber (reg:DI 2))
|
(use (reg:DI 27))
|
(use (reg:DI 27))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(use (const_int 0))]
|
(use (const_int 0))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
output_arg_descriptor (insn);
|
output_arg_descriptor (insn);
|
return output_call (insn, operands[1], 0);
|
return output_call (insn, operands[1], 0);
|
}"
|
}"
|
[(set_attr "type" "call")
|
[(set_attr "type" "call")
|
(set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))])
|
(set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))])
|
|
|
(define_insn "call_val_reg"
|
(define_insn "call_val_reg"
|
[(set (match_operand 0 "" "")
|
[(set (match_operand 0 "" "")
|
(call (mem:SI (reg:SI 22))
|
(call (mem:SI (reg:SI 22))
|
(match_operand 1 "" "i")))
|
(match_operand 1 "" "i")))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 2))
|
(clobber (reg:SI 2))
|
(use (const_int 1))]
|
(use (const_int 1))]
|
"!TARGET_64BIT"
|
"!TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
return output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
|
return output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
|
}"
|
}"
|
[(set_attr "type" "dyncall")
|
[(set_attr "type" "dyncall")
|
(set (attr "length") (symbol_ref "attr_length_indirect_call (insn)"))])
|
(set (attr "length") (symbol_ref "attr_length_indirect_call (insn)"))])
|
|
|
;; This pattern is split if it is necessary to save and restore the
|
;; This pattern is split if it is necessary to save and restore the
|
;; PIC register.
|
;; PIC register.
|
(define_insn "call_val_reg_pic"
|
(define_insn "call_val_reg_pic"
|
[(set (match_operand:SI 2 "register_operand" "=&r") (reg:SI 19))
|
[(set (match_operand:SI 2 "register_operand" "=&r") (reg:SI 19))
|
(set (match_operand 0 "" "")
|
(set (match_operand 0 "" "")
|
(call (mem:SI (reg:SI 22))
|
(call (mem:SI (reg:SI 22))
|
(match_operand 1 "" "i")))
|
(match_operand 1 "" "i")))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 2))
|
(clobber (reg:SI 2))
|
(use (match_dup 2))
|
(use (match_dup 2))
|
(use (reg:SI 19))
|
(use (reg:SI 19))
|
(use (const_int 1))]
|
(use (const_int 1))]
|
"!TARGET_64BIT"
|
"!TARGET_64BIT"
|
"#")
|
"#")
|
|
|
;; Split out the PIC register save and restore after reload. As the
|
;; Split out the PIC register save and restore after reload. As the
|
;; split is done after reload, there are some situations in which we
|
;; split is done after reload, there are some situations in which we
|
;; unnecessarily save and restore %r4. This happens when there is a
|
;; unnecessarily save and restore %r4. This happens when there is a
|
;; single call and the PIC register is not used after the call.
|
;; single call and the PIC register is not used after the call.
|
;;
|
;;
|
;; The split has to be done since call_from_call_insn () can't handle
|
;; The split has to be done since call_from_call_insn () can't handle
|
;; the pattern as is. Noreturn calls are special because they have to
|
;; the pattern as is. Noreturn calls are special because they have to
|
;; terminate the basic block. The split has to contain more than one
|
;; terminate the basic block. The split has to contain more than one
|
;; insn.
|
;; insn.
|
(define_split
|
(define_split
|
[(parallel [(set (match_operand:SI 2 "register_operand" "") (reg:SI 19))
|
[(parallel [(set (match_operand:SI 2 "register_operand" "") (reg:SI 19))
|
(set (match_operand 0 "" "")
|
(set (match_operand 0 "" "")
|
(call (mem:SI (reg:SI 22))
|
(call (mem:SI (reg:SI 22))
|
(match_operand 1 "" "")))
|
(match_operand 1 "" "")))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 2))
|
(clobber (reg:SI 2))
|
(use (match_dup 2))
|
(use (match_dup 2))
|
(use (reg:SI 19))
|
(use (reg:SI 19))
|
(use (const_int 1))])]
|
(use (const_int 1))])]
|
"!TARGET_64BIT && reload_completed
|
"!TARGET_64BIT && reload_completed
|
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
|
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
|
[(set (match_dup 2) (reg:SI 19))
|
[(set (match_dup 2) (reg:SI 19))
|
(parallel [(set (match_dup 0)
|
(parallel [(set (match_dup 0)
|
(call (mem:SI (reg:SI 22))
|
(call (mem:SI (reg:SI 22))
|
(match_dup 1)))
|
(match_dup 1)))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 2))
|
(clobber (reg:SI 2))
|
(use (reg:SI 19))
|
(use (reg:SI 19))
|
(use (const_int 1))])]
|
(use (const_int 1))])]
|
"")
|
"")
|
|
|
(define_split
|
(define_split
|
[(parallel [(set (match_operand:SI 2 "register_operand" "") (reg:SI 19))
|
[(parallel [(set (match_operand:SI 2 "register_operand" "") (reg:SI 19))
|
(set (match_operand 0 "" "")
|
(set (match_operand 0 "" "")
|
(call (mem:SI (reg:SI 22))
|
(call (mem:SI (reg:SI 22))
|
(match_operand 1 "" "")))
|
(match_operand 1 "" "")))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 2))
|
(clobber (reg:SI 2))
|
(use (match_dup 2))
|
(use (match_dup 2))
|
(use (reg:SI 19))
|
(use (reg:SI 19))
|
(use (const_int 1))])]
|
(use (const_int 1))])]
|
"!TARGET_64BIT && reload_completed"
|
"!TARGET_64BIT && reload_completed"
|
[(set (match_dup 2) (reg:SI 19))
|
[(set (match_dup 2) (reg:SI 19))
|
(parallel [(set (match_dup 0)
|
(parallel [(set (match_dup 0)
|
(call (mem:SI (reg:SI 22))
|
(call (mem:SI (reg:SI 22))
|
(match_dup 1)))
|
(match_dup 1)))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 2))
|
(clobber (reg:SI 2))
|
(use (reg:SI 19))
|
(use (reg:SI 19))
|
(use (const_int 1))])
|
(use (const_int 1))])
|
(set (reg:SI 19) (match_dup 2))]
|
(set (reg:SI 19) (match_dup 2))]
|
"")
|
"")
|
|
|
(define_insn "*call_val_reg_pic_post_reload"
|
(define_insn "*call_val_reg_pic_post_reload"
|
[(set (match_operand 0 "" "")
|
[(set (match_operand 0 "" "")
|
(call (mem:SI (reg:SI 22))
|
(call (mem:SI (reg:SI 22))
|
(match_operand 1 "" "i")))
|
(match_operand 1 "" "i")))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 2))
|
(clobber (reg:SI 2))
|
(use (reg:SI 19))
|
(use (reg:SI 19))
|
(use (const_int 1))]
|
(use (const_int 1))]
|
"!TARGET_64BIT"
|
"!TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
return output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
|
return output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
|
}"
|
}"
|
[(set_attr "type" "dyncall")
|
[(set_attr "type" "dyncall")
|
(set (attr "length") (symbol_ref "attr_length_indirect_call (insn)"))])
|
(set (attr "length") (symbol_ref "attr_length_indirect_call (insn)"))])
|
|
|
;; This pattern is split if it is necessary to save and restore the
|
;; This pattern is split if it is necessary to save and restore the
|
;; PIC register.
|
;; PIC register.
|
(define_insn "call_val_reg_64bit"
|
(define_insn "call_val_reg_64bit"
|
[(set (match_operand:DI 3 "register_operand" "=&r") (reg:DI 27))
|
[(set (match_operand:DI 3 "register_operand" "=&r") (reg:DI 27))
|
(set (match_operand 0 "" "")
|
(set (match_operand 0 "" "")
|
(call (mem:SI (match_operand:DI 1 "register_operand" "r"))
|
(call (mem:SI (match_operand:DI 1 "register_operand" "r"))
|
(match_operand 2 "" "i")))
|
(match_operand 2 "" "i")))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 2))
|
(clobber (reg:DI 2))
|
(use (match_dup 3))
|
(use (match_dup 3))
|
(use (reg:DI 27))
|
(use (reg:DI 27))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(use (const_int 1))]
|
(use (const_int 1))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"#")
|
"#")
|
|
|
;; Split out the PIC register save and restore after reload. As the
|
;; Split out the PIC register save and restore after reload. As the
|
;; split is done after reload, there are some situations in which we
|
;; split is done after reload, there are some situations in which we
|
;; unnecessarily save and restore %r4. This happens when there is a
|
;; unnecessarily save and restore %r4. This happens when there is a
|
;; single call and the PIC register is not used after the call.
|
;; single call and the PIC register is not used after the call.
|
;;
|
;;
|
;; The split has to be done since call_from_call_insn () can't handle
|
;; The split has to be done since call_from_call_insn () can't handle
|
;; the pattern as is. Noreturn calls are special because they have to
|
;; the pattern as is. Noreturn calls are special because they have to
|
;; terminate the basic block. The split has to contain more than one
|
;; terminate the basic block. The split has to contain more than one
|
;; insn.
|
;; insn.
|
(define_split
|
(define_split
|
[(parallel [(set (match_operand:DI 3 "register_operand" "") (reg:DI 27))
|
[(parallel [(set (match_operand:DI 3 "register_operand" "") (reg:DI 27))
|
(set (match_operand 0 "" "")
|
(set (match_operand 0 "" "")
|
(call (mem:SI (match_operand:DI 1 "register_operand" ""))
|
(call (mem:SI (match_operand:DI 1 "register_operand" ""))
|
(match_operand 2 "" "")))
|
(match_operand 2 "" "")))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 2))
|
(clobber (reg:DI 2))
|
(use (match_dup 3))
|
(use (match_dup 3))
|
(use (reg:DI 27))
|
(use (reg:DI 27))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(use (const_int 1))])]
|
(use (const_int 1))])]
|
"TARGET_64BIT && reload_completed
|
"TARGET_64BIT && reload_completed
|
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
|
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
|
[(set (match_dup 3) (reg:DI 27))
|
[(set (match_dup 3) (reg:DI 27))
|
(parallel [(set (match_dup 0)
|
(parallel [(set (match_dup 0)
|
(call (mem:SI (match_dup 1))
|
(call (mem:SI (match_dup 1))
|
(match_dup 2)))
|
(match_dup 2)))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 2))
|
(clobber (reg:DI 2))
|
(use (reg:DI 27))
|
(use (reg:DI 27))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(use (const_int 1))])]
|
(use (const_int 1))])]
|
"")
|
"")
|
|
|
(define_split
|
(define_split
|
[(parallel [(set (match_operand:DI 3 "register_operand" "") (reg:DI 27))
|
[(parallel [(set (match_operand:DI 3 "register_operand" "") (reg:DI 27))
|
(set (match_operand 0 "" "")
|
(set (match_operand 0 "" "")
|
(call (mem:SI (match_operand:DI 1 "register_operand" ""))
|
(call (mem:SI (match_operand:DI 1 "register_operand" ""))
|
(match_operand 2 "" "")))
|
(match_operand 2 "" "")))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 2))
|
(clobber (reg:DI 2))
|
(use (match_dup 3))
|
(use (match_dup 3))
|
(use (reg:DI 27))
|
(use (reg:DI 27))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(use (const_int 1))])]
|
(use (const_int 1))])]
|
"TARGET_64BIT && reload_completed"
|
"TARGET_64BIT && reload_completed"
|
[(set (match_dup 3) (reg:DI 27))
|
[(set (match_dup 3) (reg:DI 27))
|
(parallel [(set (match_dup 0)
|
(parallel [(set (match_dup 0)
|
(call (mem:SI (match_dup 1))
|
(call (mem:SI (match_dup 1))
|
(match_dup 2)))
|
(match_dup 2)))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 2))
|
(clobber (reg:DI 2))
|
(use (reg:DI 27))
|
(use (reg:DI 27))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(use (const_int 1))])
|
(use (const_int 1))])
|
(set (reg:DI 27) (match_dup 3))]
|
(set (reg:DI 27) (match_dup 3))]
|
"")
|
"")
|
|
|
(define_insn "*call_val_reg_64bit_post_reload"
|
(define_insn "*call_val_reg_64bit_post_reload"
|
[(set (match_operand 0 "" "")
|
[(set (match_operand 0 "" "")
|
(call (mem:SI (match_operand:DI 1 "register_operand" "r"))
|
(call (mem:SI (match_operand:DI 1 "register_operand" "r"))
|
(match_operand 2 "" "i")))
|
(match_operand 2 "" "i")))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 2))
|
(clobber (reg:DI 2))
|
(use (reg:DI 27))
|
(use (reg:DI 27))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(use (const_int 1))]
|
(use (const_int 1))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
return output_indirect_call (insn, operands[1]);
|
return output_indirect_call (insn, operands[1]);
|
}"
|
}"
|
[(set_attr "type" "dyncall")
|
[(set_attr "type" "dyncall")
|
(set (attr "length") (symbol_ref "attr_length_indirect_call (insn)"))])
|
(set (attr "length") (symbol_ref "attr_length_indirect_call (insn)"))])
|
|
|
;; Call subroutine returning any type.
|
;; Call subroutine returning any type.
|
|
|
(define_expand "untyped_call"
|
(define_expand "untyped_call"
|
[(parallel [(call (match_operand 0 "" "")
|
[(parallel [(call (match_operand 0 "" "")
|
(const_int 0))
|
(const_int 0))
|
(match_operand 1 "" "")
|
(match_operand 1 "" "")
|
(match_operand 2 "" "")])]
|
(match_operand 2 "" "")])]
|
""
|
""
|
"
|
"
|
{
|
{
|
int i;
|
int i;
|
|
|
emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
|
emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
|
|
|
for (i = 0; i < XVECLEN (operands[2], 0); i++)
|
for (i = 0; i < XVECLEN (operands[2], 0); i++)
|
{
|
{
|
rtx set = XVECEXP (operands[2], 0, i);
|
rtx set = XVECEXP (operands[2], 0, i);
|
emit_move_insn (SET_DEST (set), SET_SRC (set));
|
emit_move_insn (SET_DEST (set), SET_SRC (set));
|
}
|
}
|
|
|
/* The optimizer does not know that the call sets the function value
|
/* The optimizer does not know that the call sets the function value
|
registers we stored in the result block. We avoid problems by
|
registers we stored in the result block. We avoid problems by
|
claiming that all hard registers are used and clobbered at this
|
claiming that all hard registers are used and clobbered at this
|
point. */
|
point. */
|
emit_insn (gen_blockage ());
|
emit_insn (gen_blockage ());
|
|
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
(define_expand "sibcall"
|
(define_expand "sibcall"
|
[(call (match_operand:SI 0 "" "")
|
[(call (match_operand:SI 0 "" "")
|
(match_operand 1 "" ""))]
|
(match_operand 1 "" ""))]
|
"!TARGET_PORTABLE_RUNTIME"
|
"!TARGET_PORTABLE_RUNTIME"
|
"
|
"
|
{
|
{
|
rtx op, call_insn;
|
rtx op, call_insn;
|
rtx nb = operands[1];
|
rtx nb = operands[1];
|
|
|
op = XEXP (operands[0], 0);
|
op = XEXP (operands[0], 0);
|
|
|
if (TARGET_64BIT)
|
if (TARGET_64BIT)
|
{
|
{
|
if (!virtuals_instantiated)
|
if (!virtuals_instantiated)
|
emit_move_insn (arg_pointer_rtx,
|
emit_move_insn (arg_pointer_rtx,
|
gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
|
gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
|
GEN_INT (64)));
|
GEN_INT (64)));
|
else
|
else
|
{
|
{
|
/* The loop pass can generate new libcalls after the virtual
|
/* The loop pass can generate new libcalls after the virtual
|
registers are instantiated when fpregs are disabled because
|
registers are instantiated when fpregs are disabled because
|
the only method that we have for doing DImode multiplication
|
the only method that we have for doing DImode multiplication
|
is with a libcall. This could be trouble if we haven't
|
is with a libcall. This could be trouble if we haven't
|
allocated enough space for the outgoing arguments. */
|
allocated enough space for the outgoing arguments. */
|
gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
|
gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
|
|
|
emit_move_insn (arg_pointer_rtx,
|
emit_move_insn (arg_pointer_rtx,
|
gen_rtx_PLUS (word_mode, stack_pointer_rtx,
|
gen_rtx_PLUS (word_mode, stack_pointer_rtx,
|
GEN_INT (STACK_POINTER_OFFSET + 64)));
|
GEN_INT (STACK_POINTER_OFFSET + 64)));
|
}
|
}
|
}
|
}
|
|
|
/* Indirect sibling calls are not allowed. */
|
/* Indirect sibling calls are not allowed. */
|
if (TARGET_64BIT)
|
if (TARGET_64BIT)
|
call_insn = gen_sibcall_internal_symref_64bit (op, operands[1]);
|
call_insn = gen_sibcall_internal_symref_64bit (op, operands[1]);
|
else
|
else
|
call_insn = gen_sibcall_internal_symref (op, operands[1]);
|
call_insn = gen_sibcall_internal_symref (op, operands[1]);
|
|
|
call_insn = emit_call_insn (call_insn);
|
call_insn = emit_call_insn (call_insn);
|
|
|
if (TARGET_64BIT)
|
if (TARGET_64BIT)
|
use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
|
use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
|
|
|
/* We don't have to restore the PIC register. */
|
/* We don't have to restore the PIC register. */
|
if (flag_pic)
|
if (flag_pic)
|
use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
|
use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
|
|
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
(define_insn "sibcall_internal_symref"
|
(define_insn "sibcall_internal_symref"
|
[(call (mem:SI (match_operand 0 "call_operand_address" ""))
|
[(call (mem:SI (match_operand 0 "call_operand_address" ""))
|
(match_operand 1 "" "i"))
|
(match_operand 1 "" "i"))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(use (reg:SI 2))
|
(use (reg:SI 2))
|
(use (const_int 0))]
|
(use (const_int 0))]
|
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
|
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
output_arg_descriptor (insn);
|
output_arg_descriptor (insn);
|
return output_call (insn, operands[0], 1);
|
return output_call (insn, operands[0], 1);
|
}"
|
}"
|
[(set_attr "type" "call")
|
[(set_attr "type" "call")
|
(set (attr "length") (symbol_ref "attr_length_call (insn, 1)"))])
|
(set (attr "length") (symbol_ref "attr_length_call (insn, 1)"))])
|
|
|
(define_insn "sibcall_internal_symref_64bit"
|
(define_insn "sibcall_internal_symref_64bit"
|
[(call (mem:SI (match_operand 0 "call_operand_address" ""))
|
[(call (mem:SI (match_operand 0 "call_operand_address" ""))
|
(match_operand 1 "" "i"))
|
(match_operand 1 "" "i"))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 1))
|
(use (reg:DI 2))
|
(use (reg:DI 2))
|
(use (const_int 0))]
|
(use (const_int 0))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
output_arg_descriptor (insn);
|
output_arg_descriptor (insn);
|
return output_call (insn, operands[0], 1);
|
return output_call (insn, operands[0], 1);
|
}"
|
}"
|
[(set_attr "type" "call")
|
[(set_attr "type" "call")
|
(set (attr "length") (symbol_ref "attr_length_call (insn, 1)"))])
|
(set (attr "length") (symbol_ref "attr_length_call (insn, 1)"))])
|
|
|
(define_expand "sibcall_value"
|
(define_expand "sibcall_value"
|
[(set (match_operand 0 "" "")
|
[(set (match_operand 0 "" "")
|
(call (match_operand:SI 1 "" "")
|
(call (match_operand:SI 1 "" "")
|
(match_operand 2 "" "")))]
|
(match_operand 2 "" "")))]
|
"!TARGET_PORTABLE_RUNTIME"
|
"!TARGET_PORTABLE_RUNTIME"
|
"
|
"
|
{
|
{
|
rtx op, call_insn;
|
rtx op, call_insn;
|
rtx nb = operands[1];
|
rtx nb = operands[1];
|
|
|
op = XEXP (operands[1], 0);
|
op = XEXP (operands[1], 0);
|
|
|
if (TARGET_64BIT)
|
if (TARGET_64BIT)
|
{
|
{
|
if (!virtuals_instantiated)
|
if (!virtuals_instantiated)
|
emit_move_insn (arg_pointer_rtx,
|
emit_move_insn (arg_pointer_rtx,
|
gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
|
gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
|
GEN_INT (64)));
|
GEN_INT (64)));
|
else
|
else
|
{
|
{
|
/* The loop pass can generate new libcalls after the virtual
|
/* The loop pass can generate new libcalls after the virtual
|
registers are instantiated when fpregs are disabled because
|
registers are instantiated when fpregs are disabled because
|
the only method that we have for doing DImode multiplication
|
the only method that we have for doing DImode multiplication
|
is with a libcall. This could be trouble if we haven't
|
is with a libcall. This could be trouble if we haven't
|
allocated enough space for the outgoing arguments. */
|
allocated enough space for the outgoing arguments. */
|
gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
|
gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
|
|
|
emit_move_insn (arg_pointer_rtx,
|
emit_move_insn (arg_pointer_rtx,
|
gen_rtx_PLUS (word_mode, stack_pointer_rtx,
|
gen_rtx_PLUS (word_mode, stack_pointer_rtx,
|
GEN_INT (STACK_POINTER_OFFSET + 64)));
|
GEN_INT (STACK_POINTER_OFFSET + 64)));
|
}
|
}
|
}
|
}
|
|
|
/* Indirect sibling calls are not allowed. */
|
/* Indirect sibling calls are not allowed. */
|
if (TARGET_64BIT)
|
if (TARGET_64BIT)
|
call_insn
|
call_insn
|
= gen_sibcall_value_internal_symref_64bit (operands[0], op, operands[2]);
|
= gen_sibcall_value_internal_symref_64bit (operands[0], op, operands[2]);
|
else
|
else
|
call_insn
|
call_insn
|
= gen_sibcall_value_internal_symref (operands[0], op, operands[2]);
|
= gen_sibcall_value_internal_symref (operands[0], op, operands[2]);
|
|
|
call_insn = emit_call_insn (call_insn);
|
call_insn = emit_call_insn (call_insn);
|
|
|
if (TARGET_64BIT)
|
if (TARGET_64BIT)
|
use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
|
use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
|
|
|
/* We don't have to restore the PIC register. */
|
/* We don't have to restore the PIC register. */
|
if (flag_pic)
|
if (flag_pic)
|
use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
|
use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
|
|
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
(define_insn "sibcall_value_internal_symref"
|
(define_insn "sibcall_value_internal_symref"
|
[(set (match_operand 0 "" "")
|
[(set (match_operand 0 "" "")
|
(call (mem:SI (match_operand 1 "call_operand_address" ""))
|
(call (mem:SI (match_operand 1 "call_operand_address" ""))
|
(match_operand 2 "" "i")))
|
(match_operand 2 "" "i")))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(use (reg:SI 2))
|
(use (reg:SI 2))
|
(use (const_int 0))]
|
(use (const_int 0))]
|
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
|
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
output_arg_descriptor (insn);
|
output_arg_descriptor (insn);
|
return output_call (insn, operands[1], 1);
|
return output_call (insn, operands[1], 1);
|
}"
|
}"
|
[(set_attr "type" "call")
|
[(set_attr "type" "call")
|
(set (attr "length") (symbol_ref "attr_length_call (insn, 1)"))])
|
(set (attr "length") (symbol_ref "attr_length_call (insn, 1)"))])
|
|
|
(define_insn "sibcall_value_internal_symref_64bit"
|
(define_insn "sibcall_value_internal_symref_64bit"
|
[(set (match_operand 0 "" "")
|
[(set (match_operand 0 "" "")
|
(call (mem:SI (match_operand 1 "call_operand_address" ""))
|
(call (mem:SI (match_operand 1 "call_operand_address" ""))
|
(match_operand 2 "" "i")))
|
(match_operand 2 "" "i")))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 1))
|
(use (reg:DI 2))
|
(use (reg:DI 2))
|
(use (const_int 0))]
|
(use (const_int 0))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
output_arg_descriptor (insn);
|
output_arg_descriptor (insn);
|
return output_call (insn, operands[1], 1);
|
return output_call (insn, operands[1], 1);
|
}"
|
}"
|
[(set_attr "type" "call")
|
[(set_attr "type" "call")
|
(set (attr "length") (symbol_ref "attr_length_call (insn, 1)"))])
|
(set (attr "length") (symbol_ref "attr_length_call (insn, 1)"))])
|
|
|
(define_insn "nop"
|
(define_insn "nop"
|
[(const_int 0)]
|
[(const_int 0)]
|
""
|
""
|
"nop"
|
"nop"
|
[(set_attr "type" "move")
|
[(set_attr "type" "move")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
;; These are just placeholders so we know where branch tables
|
;; These are just placeholders so we know where branch tables
|
;; begin and end.
|
;; begin and end.
|
(define_insn "begin_brtab"
|
(define_insn "begin_brtab"
|
[(const_int 1)]
|
[(const_int 1)]
|
""
|
""
|
"*
|
"*
|
{
|
{
|
/* Only GAS actually supports this pseudo-op. */
|
/* Only GAS actually supports this pseudo-op. */
|
if (TARGET_GAS)
|
if (TARGET_GAS)
|
return \".begin_brtab\";
|
return \".begin_brtab\";
|
else
|
else
|
return \"\";
|
return \"\";
|
}"
|
}"
|
[(set_attr "type" "move")
|
[(set_attr "type" "move")
|
(set_attr "length" "0")])
|
(set_attr "length" "0")])
|
|
|
(define_insn "end_brtab"
|
(define_insn "end_brtab"
|
[(const_int 2)]
|
[(const_int 2)]
|
""
|
""
|
"*
|
"*
|
{
|
{
|
/* Only GAS actually supports this pseudo-op. */
|
/* Only GAS actually supports this pseudo-op. */
|
if (TARGET_GAS)
|
if (TARGET_GAS)
|
return \".end_brtab\";
|
return \".end_brtab\";
|
else
|
else
|
return \"\";
|
return \"\";
|
}"
|
}"
|
[(set_attr "type" "move")
|
[(set_attr "type" "move")
|
(set_attr "length" "0")])
|
(set_attr "length" "0")])
|
|
|
;;; EH does longjmp's from and within the data section. Thus,
|
;;; EH does longjmp's from and within the data section. Thus,
|
;;; an interspace branch is required for the longjmp implementation.
|
;;; an interspace branch is required for the longjmp implementation.
|
;;; Registers r1 and r2 are used as scratch registers for the jump
|
;;; Registers r1 and r2 are used as scratch registers for the jump
|
;;; when necessary.
|
;;; when necessary.
|
(define_expand "interspace_jump"
|
(define_expand "interspace_jump"
|
[(parallel
|
[(parallel
|
[(set (pc) (match_operand 0 "pmode_register_operand" "a"))
|
[(set (pc) (match_operand 0 "pmode_register_operand" "a"))
|
(clobber (match_dup 1))])]
|
(clobber (match_dup 1))])]
|
""
|
""
|
"
|
"
|
{
|
{
|
operands[1] = gen_rtx_REG (word_mode, 2);
|
operands[1] = gen_rtx_REG (word_mode, 2);
|
}")
|
}")
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (pc) (match_operand 0 "pmode_register_operand" "a"))
|
[(set (pc) (match_operand 0 "pmode_register_operand" "a"))
|
(clobber (reg:SI 2))]
|
(clobber (reg:SI 2))]
|
"TARGET_PA_20 && !TARGET_64BIT"
|
"TARGET_PA_20 && !TARGET_64BIT"
|
"bve%* (%0)"
|
"bve%* (%0)"
|
[(set_attr "type" "branch")
|
[(set_attr "type" "branch")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (pc) (match_operand 0 "pmode_register_operand" "a"))
|
[(set (pc) (match_operand 0 "pmode_register_operand" "a"))
|
(clobber (reg:SI 2))]
|
(clobber (reg:SI 2))]
|
"TARGET_NO_SPACE_REGS && !TARGET_64BIT"
|
"TARGET_NO_SPACE_REGS && !TARGET_64BIT"
|
"be%* 0(%%sr4,%0)"
|
"be%* 0(%%sr4,%0)"
|
[(set_attr "type" "branch")
|
[(set_attr "type" "branch")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (pc) (match_operand 0 "pmode_register_operand" "a"))
|
[(set (pc) (match_operand 0 "pmode_register_operand" "a"))
|
(clobber (reg:SI 2))]
|
(clobber (reg:SI 2))]
|
"!TARGET_64BIT"
|
"!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 "type" "branch")
|
(set_attr "length" "12")])
|
(set_attr "length" "12")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (pc) (match_operand 0 "pmode_register_operand" "a"))
|
[(set (pc) (match_operand 0 "pmode_register_operand" "a"))
|
(clobber (reg:DI 2))]
|
(clobber (reg:DI 2))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"bve%* (%0)"
|
"bve%* (%0)"
|
[(set_attr "type" "branch")
|
[(set_attr "type" "branch")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_expand "builtin_longjmp"
|
(define_expand "builtin_longjmp"
|
[(unspec_volatile [(match_operand 0 "register_operand" "r")] UNSPECV_LONGJMP)]
|
[(unspec_volatile [(match_operand 0 "register_operand" "r")] UNSPECV_LONGJMP)]
|
""
|
""
|
"
|
"
|
{
|
{
|
/* The elements of the buffer are, in order: */
|
/* The elements of the buffer are, in order: */
|
rtx fp = gen_rtx_MEM (Pmode, operands[0]);
|
rtx fp = gen_rtx_MEM (Pmode, operands[0]);
|
rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0],
|
rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0],
|
POINTER_SIZE / BITS_PER_UNIT));
|
POINTER_SIZE / BITS_PER_UNIT));
|
rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0],
|
rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0],
|
(POINTER_SIZE * 2) / BITS_PER_UNIT));
|
(POINTER_SIZE * 2) / BITS_PER_UNIT));
|
rtx pv = gen_rtx_REG (Pmode, 1);
|
rtx pv = gen_rtx_REG (Pmode, 1);
|
|
|
emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
|
emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
|
emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
|
emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
|
|
|
/* Restore the frame pointer. The virtual_stack_vars_rtx is saved
|
/* Restore the frame pointer. The virtual_stack_vars_rtx is saved
|
instead of the hard_frame_pointer_rtx in the save area. We need
|
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
|
to adjust for the offset between these two values when we have
|
a nonlocal_goto pattern. When we don't have a nonlocal_goto
|
a nonlocal_goto pattern. When we don't have a nonlocal_goto
|
pattern, the receiver performs the adjustment. */
|
pattern, the receiver performs the adjustment. */
|
#ifdef HAVE_nonlocal_goto
|
#ifdef HAVE_nonlocal_goto
|
if (HAVE_nonlocal_goto)
|
if (HAVE_nonlocal_goto)
|
emit_move_insn (virtual_stack_vars_rtx, force_reg (Pmode, fp));
|
emit_move_insn (virtual_stack_vars_rtx, force_reg (Pmode, fp));
|
else
|
else
|
#endif
|
#endif
|
emit_move_insn (hard_frame_pointer_rtx, fp);
|
emit_move_insn (hard_frame_pointer_rtx, fp);
|
|
|
/* This bit is the same as expand_builtin_longjmp. */
|
/* This bit is the same as expand_builtin_longjmp. */
|
emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
|
emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
|
emit_use (hard_frame_pointer_rtx);
|
emit_use (hard_frame_pointer_rtx);
|
emit_use (stack_pointer_rtx);
|
emit_use (stack_pointer_rtx);
|
|
|
/* Load the label we are jumping through into r1 so that we know
|
/* Load the label we are jumping through into r1 so that we know
|
where to look for it when we get back to setjmp's function for
|
where to look for it when we get back to setjmp's function for
|
restoring the gp. */
|
restoring the gp. */
|
emit_move_insn (pv, lab);
|
emit_move_insn (pv, lab);
|
|
|
/* Prevent the insns above from being scheduled into the delay slot
|
/* Prevent the insns above from being scheduled into the delay slot
|
of the interspace jump because the space register could change. */
|
of the interspace jump because the space register could change. */
|
emit_insn (gen_blockage ());
|
emit_insn (gen_blockage ());
|
|
|
emit_jump_insn (gen_interspace_jump (pv));
|
emit_jump_insn (gen_interspace_jump (pv));
|
emit_barrier ();
|
emit_barrier ();
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
;;; Operands 2 and 3 are assumed to be CONST_INTs.
|
;;; Operands 2 and 3 are assumed to be CONST_INTs.
|
(define_expand "extzv"
|
(define_expand "extzv"
|
[(set (match_operand 0 "register_operand" "")
|
[(set (match_operand 0 "register_operand" "")
|
(zero_extract (match_operand 1 "register_operand" "")
|
(zero_extract (match_operand 1 "register_operand" "")
|
(match_operand 2 "uint32_operand" "")
|
(match_operand 2 "uint32_operand" "")
|
(match_operand 3 "uint32_operand" "")))]
|
(match_operand 3 "uint32_operand" "")))]
|
""
|
""
|
"
|
"
|
{
|
{
|
HOST_WIDE_INT len = INTVAL (operands[2]);
|
HOST_WIDE_INT len = INTVAL (operands[2]);
|
HOST_WIDE_INT pos = INTVAL (operands[3]);
|
HOST_WIDE_INT pos = INTVAL (operands[3]);
|
|
|
/* PA extraction insns don't support zero length bitfields or fields
|
/* PA extraction insns don't support zero length bitfields or fields
|
extending beyond the left or right-most bits. Also, we reject lengths
|
extending beyond the left or right-most bits. Also, we reject lengths
|
equal to a word as they are better handled by the move patterns. */
|
equal to a word as they are better handled by the move patterns. */
|
if (len <= 0 || len >= BITS_PER_WORD || pos < 0 || pos + len > BITS_PER_WORD)
|
if (len <= 0 || len >= BITS_PER_WORD || pos < 0 || pos + len > BITS_PER_WORD)
|
FAIL;
|
FAIL;
|
|
|
/* From mips.md: extract_bit_field doesn't verify that our source
|
/* From mips.md: extract_bit_field doesn't verify that our source
|
matches the predicate, so check it again here. */
|
matches the predicate, so check it again here. */
|
if (!register_operand (operands[1], VOIDmode))
|
if (!register_operand (operands[1], VOIDmode))
|
FAIL;
|
FAIL;
|
|
|
if (TARGET_64BIT)
|
if (TARGET_64BIT)
|
emit_insn (gen_extzv_64 (operands[0], operands[1],
|
emit_insn (gen_extzv_64 (operands[0], operands[1],
|
operands[2], operands[3]));
|
operands[2], operands[3]));
|
else
|
else
|
emit_insn (gen_extzv_32 (operands[0], operands[1],
|
emit_insn (gen_extzv_32 (operands[0], operands[1],
|
operands[2], operands[3]));
|
operands[2], operands[3]));
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
(define_insn "extzv_32"
|
(define_insn "extzv_32"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(zero_extract:SI (match_operand:SI 1 "register_operand" "r")
|
(zero_extract:SI (match_operand:SI 1 "register_operand" "r")
|
(match_operand:SI 2 "uint5_operand" "")
|
(match_operand:SI 2 "uint5_operand" "")
|
(match_operand:SI 3 "uint5_operand" "")))]
|
(match_operand:SI 3 "uint5_operand" "")))]
|
""
|
""
|
"{extru|extrw,u} %1,%3+%2-1,%2,%0"
|
"{extru|extrw,u} %1,%3+%2-1,%2,%0"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(zero_extract:SI (match_operand:SI 1 "register_operand" "r")
|
(zero_extract:SI (match_operand:SI 1 "register_operand" "r")
|
(const_int 1)
|
(const_int 1)
|
(match_operand:SI 2 "register_operand" "q")))]
|
(match_operand:SI 2 "register_operand" "q")))]
|
""
|
""
|
"{vextru %1,1,%0|extrw,u %1,%%sar,1,%0}"
|
"{vextru %1,1,%0|extrw,u %1,%%sar,1,%0}"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "extzv_64"
|
(define_insn "extzv_64"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(zero_extract:DI (match_operand:DI 1 "register_operand" "r")
|
(zero_extract:DI (match_operand:DI 1 "register_operand" "r")
|
(match_operand:DI 2 "uint32_operand" "")
|
(match_operand:DI 2 "uint32_operand" "")
|
(match_operand:DI 3 "uint32_operand" "")))]
|
(match_operand:DI 3 "uint32_operand" "")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"extrd,u %1,%3+%2-1,%2,%0"
|
"extrd,u %1,%3+%2-1,%2,%0"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(zero_extract:DI (match_operand:DI 1 "register_operand" "r")
|
(zero_extract:DI (match_operand:DI 1 "register_operand" "r")
|
(const_int 1)
|
(const_int 1)
|
(match_operand:DI 2 "register_operand" "q")))]
|
(match_operand:DI 2 "register_operand" "q")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"extrd,u %1,%%sar,1,%0"
|
"extrd,u %1,%%sar,1,%0"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
;;; Operands 2 and 3 are assumed to be CONST_INTs.
|
;;; Operands 2 and 3 are assumed to be CONST_INTs.
|
(define_expand "extv"
|
(define_expand "extv"
|
[(set (match_operand 0 "register_operand" "")
|
[(set (match_operand 0 "register_operand" "")
|
(sign_extract (match_operand 1 "register_operand" "")
|
(sign_extract (match_operand 1 "register_operand" "")
|
(match_operand 2 "uint32_operand" "")
|
(match_operand 2 "uint32_operand" "")
|
(match_operand 3 "uint32_operand" "")))]
|
(match_operand 3 "uint32_operand" "")))]
|
""
|
""
|
"
|
"
|
{
|
{
|
HOST_WIDE_INT len = INTVAL (operands[2]);
|
HOST_WIDE_INT len = INTVAL (operands[2]);
|
HOST_WIDE_INT pos = INTVAL (operands[3]);
|
HOST_WIDE_INT pos = INTVAL (operands[3]);
|
|
|
/* PA extraction insns don't support zero length bitfields or fields
|
/* PA extraction insns don't support zero length bitfields or fields
|
extending beyond the left or right-most bits. Also, we reject lengths
|
extending beyond the left or right-most bits. Also, we reject lengths
|
equal to a word as they are better handled by the move patterns. */
|
equal to a word as they are better handled by the move patterns. */
|
if (len <= 0 || len >= BITS_PER_WORD || pos < 0 || pos + len > BITS_PER_WORD)
|
if (len <= 0 || len >= BITS_PER_WORD || pos < 0 || pos + len > BITS_PER_WORD)
|
FAIL;
|
FAIL;
|
|
|
/* From mips.md: extract_bit_field doesn't verify that our source
|
/* From mips.md: extract_bit_field doesn't verify that our source
|
matches the predicate, so check it again here. */
|
matches the predicate, so check it again here. */
|
if (!register_operand (operands[1], VOIDmode))
|
if (!register_operand (operands[1], VOIDmode))
|
FAIL;
|
FAIL;
|
|
|
if (TARGET_64BIT)
|
if (TARGET_64BIT)
|
emit_insn (gen_extv_64 (operands[0], operands[1],
|
emit_insn (gen_extv_64 (operands[0], operands[1],
|
operands[2], operands[3]));
|
operands[2], operands[3]));
|
else
|
else
|
emit_insn (gen_extv_32 (operands[0], operands[1],
|
emit_insn (gen_extv_32 (operands[0], operands[1],
|
operands[2], operands[3]));
|
operands[2], operands[3]));
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
(define_insn "extv_32"
|
(define_insn "extv_32"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(sign_extract:SI (match_operand:SI 1 "register_operand" "r")
|
(sign_extract:SI (match_operand:SI 1 "register_operand" "r")
|
(match_operand:SI 2 "uint5_operand" "")
|
(match_operand:SI 2 "uint5_operand" "")
|
(match_operand:SI 3 "uint5_operand" "")))]
|
(match_operand:SI 3 "uint5_operand" "")))]
|
""
|
""
|
"{extrs|extrw,s} %1,%3+%2-1,%2,%0"
|
"{extrs|extrw,s} %1,%3+%2-1,%2,%0"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(sign_extract:SI (match_operand:SI 1 "register_operand" "r")
|
(sign_extract:SI (match_operand:SI 1 "register_operand" "r")
|
(const_int 1)
|
(const_int 1)
|
(match_operand:SI 2 "register_operand" "q")))]
|
(match_operand:SI 2 "register_operand" "q")))]
|
"!TARGET_64BIT"
|
"!TARGET_64BIT"
|
"{vextrs %1,1,%0|extrw,s %1,%%sar,1,%0}"
|
"{vextrs %1,1,%0|extrw,s %1,%%sar,1,%0}"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "extv_64"
|
(define_insn "extv_64"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(sign_extract:DI (match_operand:DI 1 "register_operand" "r")
|
(sign_extract:DI (match_operand:DI 1 "register_operand" "r")
|
(match_operand:DI 2 "uint32_operand" "")
|
(match_operand:DI 2 "uint32_operand" "")
|
(match_operand:DI 3 "uint32_operand" "")))]
|
(match_operand:DI 3 "uint32_operand" "")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"extrd,s %1,%3+%2-1,%2,%0"
|
"extrd,s %1,%3+%2-1,%2,%0"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(sign_extract:DI (match_operand:DI 1 "register_operand" "r")
|
(sign_extract:DI (match_operand:DI 1 "register_operand" "r")
|
(const_int 1)
|
(const_int 1)
|
(match_operand:DI 2 "register_operand" "q")))]
|
(match_operand:DI 2 "register_operand" "q")))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"extrd,s %1,%%sar,1,%0"
|
"extrd,s %1,%%sar,1,%0"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
;;; Operands 1 and 2 are assumed to be CONST_INTs.
|
;;; Operands 1 and 2 are assumed to be CONST_INTs.
|
(define_expand "insv"
|
(define_expand "insv"
|
[(set (zero_extract (match_operand 0 "register_operand" "")
|
[(set (zero_extract (match_operand 0 "register_operand" "")
|
(match_operand 1 "uint32_operand" "")
|
(match_operand 1 "uint32_operand" "")
|
(match_operand 2 "uint32_operand" ""))
|
(match_operand 2 "uint32_operand" ""))
|
(match_operand 3 "arith5_operand" ""))]
|
(match_operand 3 "arith5_operand" ""))]
|
""
|
""
|
"
|
"
|
{
|
{
|
HOST_WIDE_INT len = INTVAL (operands[1]);
|
HOST_WIDE_INT len = INTVAL (operands[1]);
|
HOST_WIDE_INT pos = INTVAL (operands[2]);
|
HOST_WIDE_INT pos = INTVAL (operands[2]);
|
|
|
/* PA insertion insns don't support zero length bitfields or fields
|
/* PA insertion insns don't support zero length bitfields or fields
|
extending beyond the left or right-most bits. Also, we reject lengths
|
extending beyond the left or right-most bits. Also, we reject lengths
|
equal to a word as they are better handled by the move patterns. */
|
equal to a word as they are better handled by the move patterns. */
|
if (len <= 0 || len >= BITS_PER_WORD || pos < 0 || pos + len > BITS_PER_WORD)
|
if (len <= 0 || len >= BITS_PER_WORD || pos < 0 || pos + len > BITS_PER_WORD)
|
FAIL;
|
FAIL;
|
|
|
/* From mips.md: insert_bit_field doesn't verify that our destination
|
/* From mips.md: insert_bit_field doesn't verify that our destination
|
matches the predicate, so check it again here. */
|
matches the predicate, so check it again here. */
|
if (!register_operand (operands[0], VOIDmode))
|
if (!register_operand (operands[0], VOIDmode))
|
FAIL;
|
FAIL;
|
|
|
if (TARGET_64BIT)
|
if (TARGET_64BIT)
|
emit_insn (gen_insv_64 (operands[0], operands[1],
|
emit_insn (gen_insv_64 (operands[0], operands[1],
|
operands[2], operands[3]));
|
operands[2], operands[3]));
|
else
|
else
|
emit_insn (gen_insv_32 (operands[0], operands[1],
|
emit_insn (gen_insv_32 (operands[0], operands[1],
|
operands[2], operands[3]));
|
operands[2], operands[3]));
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
(define_insn "insv_32"
|
(define_insn "insv_32"
|
[(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r")
|
[(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r")
|
(match_operand:SI 1 "uint5_operand" "")
|
(match_operand:SI 1 "uint5_operand" "")
|
(match_operand:SI 2 "uint5_operand" ""))
|
(match_operand:SI 2 "uint5_operand" ""))
|
(match_operand:SI 3 "arith5_operand" "r,L"))]
|
(match_operand:SI 3 "arith5_operand" "r,L"))]
|
""
|
""
|
"@
|
"@
|
{dep|depw} %3,%2+%1-1,%1,%0
|
{dep|depw} %3,%2+%1-1,%1,%0
|
{depi|depwi} %3,%2+%1-1,%1,%0"
|
{depi|depwi} %3,%2+%1-1,%1,%0"
|
[(set_attr "type" "shift,shift")
|
[(set_attr "type" "shift,shift")
|
(set_attr "length" "4,4")])
|
(set_attr "length" "4,4")])
|
|
|
;; Optimize insertion of const_int values of type 1...1xxxx.
|
;; Optimize insertion of const_int values of type 1...1xxxx.
|
(define_insn ""
|
(define_insn ""
|
[(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
|
[(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
|
(match_operand:SI 1 "uint5_operand" "")
|
(match_operand:SI 1 "uint5_operand" "")
|
(match_operand:SI 2 "uint5_operand" ""))
|
(match_operand:SI 2 "uint5_operand" ""))
|
(match_operand:SI 3 "const_int_operand" ""))]
|
(match_operand:SI 3 "const_int_operand" ""))]
|
"(INTVAL (operands[3]) & 0x10) != 0 &&
|
"(INTVAL (operands[3]) & 0x10) != 0 &&
|
(~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
|
(~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
|
"*
|
"*
|
{
|
{
|
operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
|
operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
|
return \"{depi|depwi} %3,%2+%1-1,%1,%0\";
|
return \"{depi|depwi} %3,%2+%1-1,%1,%0\";
|
}"
|
}"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "insv_64"
|
(define_insn "insv_64"
|
[(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r,r")
|
[(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r,r")
|
(match_operand:DI 1 "uint32_operand" "")
|
(match_operand:DI 1 "uint32_operand" "")
|
(match_operand:DI 2 "uint32_operand" ""))
|
(match_operand:DI 2 "uint32_operand" ""))
|
(match_operand:DI 3 "arith32_operand" "r,L"))]
|
(match_operand:DI 3 "arith32_operand" "r,L"))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"@
|
"@
|
depd %3,%2+%1-1,%1,%0
|
depd %3,%2+%1-1,%1,%0
|
depdi %3,%2+%1-1,%1,%0"
|
depdi %3,%2+%1-1,%1,%0"
|
[(set_attr "type" "shift,shift")
|
[(set_attr "type" "shift,shift")
|
(set_attr "length" "4,4")])
|
(set_attr "length" "4,4")])
|
|
|
;; Optimize insertion of const_int values of type 1...1xxxx.
|
;; Optimize insertion of const_int values of type 1...1xxxx.
|
(define_insn ""
|
(define_insn ""
|
[(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
|
[(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
|
(match_operand:DI 1 "uint32_operand" "")
|
(match_operand:DI 1 "uint32_operand" "")
|
(match_operand:DI 2 "uint32_operand" ""))
|
(match_operand:DI 2 "uint32_operand" ""))
|
(match_operand:DI 3 "const_int_operand" ""))]
|
(match_operand:DI 3 "const_int_operand" ""))]
|
"(INTVAL (operands[3]) & 0x10) != 0
|
"(INTVAL (operands[3]) & 0x10) != 0
|
&& TARGET_64BIT
|
&& TARGET_64BIT
|
&& (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
|
&& (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
|
"*
|
"*
|
{
|
{
|
operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
|
operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
|
return \"depdi %3,%2+%1-1,%1,%0\";
|
return \"depdi %3,%2+%1-1,%1,%0\";
|
}"
|
}"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
|
(ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
|
(const_int 32)))]
|
(const_int 32)))]
|
"TARGET_64BIT"
|
"TARGET_64BIT"
|
"depd,z %1,31,32,%0"
|
"depd,z %1,31,32,%0"
|
[(set_attr "type" "shift")
|
[(set_attr "type" "shift")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
;; This insn is used for some loop tests, typically loops reversed when
|
;; This insn is used for some loop tests, typically loops reversed when
|
;; strength reduction is used. It is actually created when the instruction
|
;; strength reduction is used. It is actually created when the instruction
|
;; combination phase combines the special loop test. Since this insn
|
;; combination phase combines the special loop test. Since this insn
|
;; is both a jump insn and has an output, it must deal with its own
|
;; is both a jump insn and has an output, it must deal with its own
|
;; reloads, hence the `m' constraints. The `!' constraints direct reload
|
;; reloads, hence the `m' constraints. The `!' constraints direct reload
|
;; to not choose the register alternatives in the event a reload is needed.
|
;; to not choose the register alternatives in the event a reload is needed.
|
(define_insn "decrement_and_branch_until_zero"
|
(define_insn "decrement_and_branch_until_zero"
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(match_operator 2 "comparison_operator"
|
(match_operator 2 "comparison_operator"
|
[(plus:SI
|
[(plus:SI
|
(match_operand:SI 0 "reg_before_reload_operand" "+!r,!*f,*m")
|
(match_operand:SI 0 "reg_before_reload_operand" "+!r,!*f,*m")
|
(match_operand:SI 1 "int5_operand" "L,L,L"))
|
(match_operand:SI 1 "int5_operand" "L,L,L"))
|
(const_int 0)])
|
(const_int 0)])
|
(label_ref (match_operand 3 "" ""))
|
(label_ref (match_operand 3 "" ""))
|
(pc)))
|
(pc)))
|
(set (match_dup 0)
|
(set (match_dup 0)
|
(plus:SI (match_dup 0) (match_dup 1)))
|
(plus:SI (match_dup 0) (match_dup 1)))
|
(clobber (match_scratch:SI 4 "=X,r,r"))]
|
(clobber (match_scratch:SI 4 "=X,r,r"))]
|
""
|
""
|
"* return output_dbra (operands, insn, which_alternative); "
|
"* return output_dbra (operands, insn, which_alternative); "
|
;; Do not expect to understand this the first time through.
|
;; Do not expect to understand this the first time through.
|
[(set_attr "type" "cbranch,multi,multi")
|
[(set_attr "type" "cbranch,multi,multi")
|
(set (attr "length")
|
(set (attr "length")
|
(if_then_else (eq_attr "alternative" "0")
|
(if_then_else (eq_attr "alternative" "0")
|
;; Loop counter in register case
|
;; Loop counter in register case
|
;; Short branch has length of 4
|
;; Short branch has length of 4
|
;; Long branch has length of 8, 20, 24 or 28
|
;; Long branch has length of 8, 20, 24 or 28
|
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 24)
|
(const_int 24)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 20)]
|
(const_int 20)]
|
(const_int 28))
|
(const_int 28))
|
|
|
;; Loop counter in FP reg case.
|
;; Loop counter in FP reg case.
|
;; Extra goo to deal with additional reload insns.
|
;; Extra goo to deal with additional reload insns.
|
(if_then_else (eq_attr "alternative" "1")
|
(if_then_else (eq_attr "alternative" "1")
|
(if_then_else (lt (match_dup 3) (pc))
|
(if_then_else (lt (match_dup 3) (pc))
|
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
|
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 24)
|
(const_int 24)
|
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
|
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 28)
|
(const_int 28)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 44)
|
(const_int 44)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 40)]
|
(const_int 40)]
|
(const_int 48))
|
(const_int 48))
|
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 24)
|
(const_int 24)
|
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 28)
|
(const_int 28)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 44)
|
(const_int 44)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 40)]
|
(const_int 40)]
|
(const_int 48)))
|
(const_int 48)))
|
|
|
;; Loop counter in memory case.
|
;; Loop counter in memory case.
|
;; Extra goo to deal with additional reload insns.
|
;; Extra goo to deal with additional reload insns.
|
(if_then_else (lt (match_dup 3) (pc))
|
(if_then_else (lt (match_dup 3) (pc))
|
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
|
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 12)
|
(const_int 12)
|
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
|
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 16)
|
(const_int 16)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 32)
|
(const_int 32)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 28)]
|
(const_int 28)]
|
(const_int 36))
|
(const_int 36))
|
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 12)
|
(const_int 12)
|
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 16)
|
(const_int 16)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 32)
|
(const_int 32)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 28)]
|
(const_int 28)]
|
(const_int 36))))))])
|
(const_int 36))))))])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(match_operator 2 "movb_comparison_operator"
|
(match_operator 2 "movb_comparison_operator"
|
[(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
|
[(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
|
(label_ref (match_operand 3 "" ""))
|
(label_ref (match_operand 3 "" ""))
|
(pc)))
|
(pc)))
|
(set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*m,!*q")
|
(set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*m,!*q")
|
(match_dup 1))]
|
(match_dup 1))]
|
""
|
""
|
"* return output_movb (operands, insn, which_alternative, 0); "
|
"* return output_movb (operands, insn, which_alternative, 0); "
|
;; Do not expect to understand this the first time through.
|
;; Do not expect to understand this the first time through.
|
[(set_attr "type" "cbranch,multi,multi,multi")
|
[(set_attr "type" "cbranch,multi,multi,multi")
|
(set (attr "length")
|
(set (attr "length")
|
(if_then_else (eq_attr "alternative" "0")
|
(if_then_else (eq_attr "alternative" "0")
|
;; Loop counter in register case
|
;; Loop counter in register case
|
;; Short branch has length of 4
|
;; Short branch has length of 4
|
;; Long branch has length of 8, 20, 24 or 28
|
;; Long branch has length of 8, 20, 24 or 28
|
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 24)
|
(const_int 24)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 20)]
|
(const_int 20)]
|
(const_int 28))
|
(const_int 28))
|
|
|
;; Loop counter in FP reg case.
|
;; Loop counter in FP reg case.
|
;; Extra goo to deal with additional reload insns.
|
;; Extra goo to deal with additional reload insns.
|
(if_then_else (eq_attr "alternative" "1")
|
(if_then_else (eq_attr "alternative" "1")
|
(if_then_else (lt (match_dup 3) (pc))
|
(if_then_else (lt (match_dup 3) (pc))
|
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
|
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 12)
|
(const_int 12)
|
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
|
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 16)
|
(const_int 16)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 32)
|
(const_int 32)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 28)]
|
(const_int 28)]
|
(const_int 36))
|
(const_int 36))
|
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 12)
|
(const_int 12)
|
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 16)
|
(const_int 16)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 32)
|
(const_int 32)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 28)]
|
(const_int 28)]
|
(const_int 36)))
|
(const_int 36)))
|
|
|
;; Loop counter in memory or sar case.
|
;; Loop counter in memory or sar case.
|
;; Extra goo to deal with additional reload insns.
|
;; Extra goo to deal with additional reload insns.
|
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 12)
|
(const_int 12)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 28)
|
(const_int 28)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 24)]
|
(const_int 24)]
|
(const_int 32)))))])
|
(const_int 32)))))])
|
|
|
;; Handle negated branch.
|
;; Handle negated branch.
|
(define_insn ""
|
(define_insn ""
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(match_operator 2 "movb_comparison_operator"
|
(match_operator 2 "movb_comparison_operator"
|
[(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
|
[(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
|
(pc)
|
(pc)
|
(label_ref (match_operand 3 "" ""))))
|
(label_ref (match_operand 3 "" ""))))
|
(set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*m,!*q")
|
(set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*m,!*q")
|
(match_dup 1))]
|
(match_dup 1))]
|
""
|
""
|
"* return output_movb (operands, insn, which_alternative, 1); "
|
"* return output_movb (operands, insn, which_alternative, 1); "
|
;; Do not expect to understand this the first time through.
|
;; Do not expect to understand this the first time through.
|
[(set_attr "type" "cbranch,multi,multi,multi")
|
[(set_attr "type" "cbranch,multi,multi,multi")
|
(set (attr "length")
|
(set (attr "length")
|
(if_then_else (eq_attr "alternative" "0")
|
(if_then_else (eq_attr "alternative" "0")
|
;; Loop counter in register case
|
;; Loop counter in register case
|
;; Short branch has length of 4
|
;; Short branch has length of 4
|
;; Long branch has length of 8
|
;; Long branch has length of 8
|
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 24)
|
(const_int 24)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 20)]
|
(const_int 20)]
|
(const_int 28))
|
(const_int 28))
|
|
|
;; Loop counter in FP reg case.
|
;; Loop counter in FP reg case.
|
;; Extra goo to deal with additional reload insns.
|
;; Extra goo to deal with additional reload insns.
|
(if_then_else (eq_attr "alternative" "1")
|
(if_then_else (eq_attr "alternative" "1")
|
(if_then_else (lt (match_dup 3) (pc))
|
(if_then_else (lt (match_dup 3) (pc))
|
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
|
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 12)
|
(const_int 12)
|
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
|
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 16)
|
(const_int 16)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 32)
|
(const_int 32)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 28)]
|
(const_int 28)]
|
(const_int 36))
|
(const_int 36))
|
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 12)
|
(const_int 12)
|
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 16)
|
(const_int 16)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 32)
|
(const_int 32)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 28)]
|
(const_int 28)]
|
(const_int 36)))
|
(const_int 36)))
|
|
|
;; Loop counter in memory or SAR case.
|
;; Loop counter in memory or SAR case.
|
;; Extra goo to deal with additional reload insns.
|
;; Extra goo to deal with additional reload insns.
|
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 12)
|
(const_int 12)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 28)
|
(const_int 28)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 24)]
|
(const_int 24)]
|
(const_int 32)))))])
|
(const_int 32)))))])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (pc) (label_ref (match_operand 3 "" "" )))
|
[(set (pc) (label_ref (match_operand 3 "" "" )))
|
(set (match_operand:SI 0 "ireg_operand" "=r")
|
(set (match_operand:SI 0 "ireg_operand" "=r")
|
(plus:SI (match_operand:SI 1 "ireg_operand" "r")
|
(plus:SI (match_operand:SI 1 "ireg_operand" "r")
|
(match_operand:SI 2 "ireg_or_int5_operand" "rL")))]
|
(match_operand:SI 2 "ireg_or_int5_operand" "rL")))]
|
"(reload_completed && operands[0] == operands[1]) || operands[0] == operands[2]"
|
"(reload_completed && operands[0] == operands[1]) || operands[0] == operands[2]"
|
"*
|
"*
|
{
|
{
|
return output_parallel_addb (operands, insn);
|
return output_parallel_addb (operands, insn);
|
}"
|
}"
|
[(set_attr "type" "parallel_branch")
|
[(set_attr "type" "parallel_branch")
|
(set (attr "length")
|
(set (attr "length")
|
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 24)
|
(const_int 24)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 20)]
|
(const_int 20)]
|
(const_int 28)))])
|
(const_int 28)))])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (pc) (label_ref (match_operand 2 "" "" )))
|
[(set (pc) (label_ref (match_operand 2 "" "" )))
|
(set (match_operand:SF 0 "ireg_operand" "=r")
|
(set (match_operand:SF 0 "ireg_operand" "=r")
|
(match_operand:SF 1 "ireg_or_int5_operand" "rL"))]
|
(match_operand:SF 1 "ireg_or_int5_operand" "rL"))]
|
"reload_completed"
|
"reload_completed"
|
"*
|
"*
|
{
|
{
|
return output_parallel_movb (operands, insn);
|
return output_parallel_movb (operands, insn);
|
}"
|
}"
|
[(set_attr "type" "parallel_branch")
|
[(set_attr "type" "parallel_branch")
|
(set (attr "length")
|
(set (attr "length")
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 24)
|
(const_int 24)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 20)]
|
(const_int 20)]
|
(const_int 28)))])
|
(const_int 28)))])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (pc) (label_ref (match_operand 2 "" "" )))
|
[(set (pc) (label_ref (match_operand 2 "" "" )))
|
(set (match_operand:SI 0 "ireg_operand" "=r")
|
(set (match_operand:SI 0 "ireg_operand" "=r")
|
(match_operand:SI 1 "ireg_or_int5_operand" "rL"))]
|
(match_operand:SI 1 "ireg_or_int5_operand" "rL"))]
|
"reload_completed"
|
"reload_completed"
|
"*
|
"*
|
{
|
{
|
return output_parallel_movb (operands, insn);
|
return output_parallel_movb (operands, insn);
|
}"
|
}"
|
[(set_attr "type" "parallel_branch")
|
[(set_attr "type" "parallel_branch")
|
(set (attr "length")
|
(set (attr "length")
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 24)
|
(const_int 24)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 20)]
|
(const_int 20)]
|
(const_int 28)))])
|
(const_int 28)))])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (pc) (label_ref (match_operand 2 "" "" )))
|
[(set (pc) (label_ref (match_operand 2 "" "" )))
|
(set (match_operand:HI 0 "ireg_operand" "=r")
|
(set (match_operand:HI 0 "ireg_operand" "=r")
|
(match_operand:HI 1 "ireg_or_int5_operand" "rL"))]
|
(match_operand:HI 1 "ireg_or_int5_operand" "rL"))]
|
"reload_completed"
|
"reload_completed"
|
"*
|
"*
|
{
|
{
|
return output_parallel_movb (operands, insn);
|
return output_parallel_movb (operands, insn);
|
}"
|
}"
|
[(set_attr "type" "parallel_branch")
|
[(set_attr "type" "parallel_branch")
|
(set (attr "length")
|
(set (attr "length")
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 24)
|
(const_int 24)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 20)]
|
(const_int 20)]
|
(const_int 28)))])
|
(const_int 28)))])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (pc) (label_ref (match_operand 2 "" "" )))
|
[(set (pc) (label_ref (match_operand 2 "" "" )))
|
(set (match_operand:QI 0 "ireg_operand" "=r")
|
(set (match_operand:QI 0 "ireg_operand" "=r")
|
(match_operand:QI 1 "ireg_or_int5_operand" "rL"))]
|
(match_operand:QI 1 "ireg_or_int5_operand" "rL"))]
|
"reload_completed"
|
"reload_completed"
|
"*
|
"*
|
{
|
{
|
return output_parallel_movb (operands, insn);
|
return output_parallel_movb (operands, insn);
|
}"
|
}"
|
[(set_attr "type" "parallel_branch")
|
[(set_attr "type" "parallel_branch")
|
(set (attr "length")
|
(set (attr "length")
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int MAX_12BIT_OFFSET))
|
(const_int 4)
|
(const_int 4)
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int MAX_17BIT_OFFSET))
|
(const_int 8)
|
(const_int 8)
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0))
|
(const_int 24)
|
(const_int 24)
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(eq (symbol_ref "flag_pic") (const_int 0))
|
(const_int 20)]
|
(const_int 20)]
|
(const_int 28)))])
|
(const_int 28)))])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand 0 "register_operand" "=f")
|
[(set (match_operand 0 "register_operand" "=f")
|
(mult (match_operand 1 "register_operand" "f")
|
(mult (match_operand 1 "register_operand" "f")
|
(match_operand 2 "register_operand" "f")))
|
(match_operand 2 "register_operand" "f")))
|
(set (match_operand 3 "register_operand" "+f")
|
(set (match_operand 3 "register_operand" "+f")
|
(plus (match_operand 4 "register_operand" "f")
|
(plus (match_operand 4 "register_operand" "f")
|
(match_operand 5 "register_operand" "f")))]
|
(match_operand 5 "register_operand" "f")))]
|
"TARGET_PA_11 && ! TARGET_SOFT_FLOAT
|
"TARGET_PA_11 && ! TARGET_SOFT_FLOAT
|
&& reload_completed && fmpyaddoperands (operands)"
|
&& reload_completed && fmpyaddoperands (operands)"
|
"*
|
"*
|
{
|
{
|
if (GET_MODE (operands[0]) == DFmode)
|
if (GET_MODE (operands[0]) == DFmode)
|
{
|
{
|
if (rtx_equal_p (operands[3], operands[5]))
|
if (rtx_equal_p (operands[3], operands[5]))
|
return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
|
return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
|
else
|
else
|
return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
|
return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
|
}
|
}
|
else
|
else
|
{
|
{
|
if (rtx_equal_p (operands[3], operands[5]))
|
if (rtx_equal_p (operands[3], operands[5]))
|
return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
|
return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
|
else
|
else
|
return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
|
return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
|
}
|
}
|
}"
|
}"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand 3 "register_operand" "+f")
|
[(set (match_operand 3 "register_operand" "+f")
|
(plus (match_operand 4 "register_operand" "f")
|
(plus (match_operand 4 "register_operand" "f")
|
(match_operand 5 "register_operand" "f")))
|
(match_operand 5 "register_operand" "f")))
|
(set (match_operand 0 "register_operand" "=f")
|
(set (match_operand 0 "register_operand" "=f")
|
(mult (match_operand 1 "register_operand" "f")
|
(mult (match_operand 1 "register_operand" "f")
|
(match_operand 2 "register_operand" "f")))]
|
(match_operand 2 "register_operand" "f")))]
|
"TARGET_PA_11 && ! TARGET_SOFT_FLOAT
|
"TARGET_PA_11 && ! TARGET_SOFT_FLOAT
|
&& reload_completed && fmpyaddoperands (operands)"
|
&& reload_completed && fmpyaddoperands (operands)"
|
"*
|
"*
|
{
|
{
|
if (GET_MODE (operands[0]) == DFmode)
|
if (GET_MODE (operands[0]) == DFmode)
|
{
|
{
|
if (rtx_equal_p (operands[3], operands[5]))
|
if (rtx_equal_p (operands[3], operands[5]))
|
return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
|
return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
|
else
|
else
|
return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
|
return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
|
}
|
}
|
else
|
else
|
{
|
{
|
if (rtx_equal_p (operands[3], operands[5]))
|
if (rtx_equal_p (operands[3], operands[5]))
|
return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
|
return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
|
else
|
else
|
return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
|
return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
|
}
|
}
|
}"
|
}"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand 0 "register_operand" "=f")
|
[(set (match_operand 0 "register_operand" "=f")
|
(mult (match_operand 1 "register_operand" "f")
|
(mult (match_operand 1 "register_operand" "f")
|
(match_operand 2 "register_operand" "f")))
|
(match_operand 2 "register_operand" "f")))
|
(set (match_operand 3 "register_operand" "+f")
|
(set (match_operand 3 "register_operand" "+f")
|
(minus (match_operand 4 "register_operand" "f")
|
(minus (match_operand 4 "register_operand" "f")
|
(match_operand 5 "register_operand" "f")))]
|
(match_operand 5 "register_operand" "f")))]
|
"TARGET_PA_11 && ! TARGET_SOFT_FLOAT
|
"TARGET_PA_11 && ! TARGET_SOFT_FLOAT
|
&& reload_completed && fmpysuboperands (operands)"
|
&& reload_completed && fmpysuboperands (operands)"
|
"*
|
"*
|
{
|
{
|
if (GET_MODE (operands[0]) == DFmode)
|
if (GET_MODE (operands[0]) == DFmode)
|
return \"fmpysub,dbl %1,%2,%0,%5,%3\";
|
return \"fmpysub,dbl %1,%2,%0,%5,%3\";
|
else
|
else
|
return \"fmpysub,sgl %1,%2,%0,%5,%3\";
|
return \"fmpysub,sgl %1,%2,%0,%5,%3\";
|
}"
|
}"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn ""
|
(define_insn ""
|
[(set (match_operand 3 "register_operand" "+f")
|
[(set (match_operand 3 "register_operand" "+f")
|
(minus (match_operand 4 "register_operand" "f")
|
(minus (match_operand 4 "register_operand" "f")
|
(match_operand 5 "register_operand" "f")))
|
(match_operand 5 "register_operand" "f")))
|
(set (match_operand 0 "register_operand" "=f")
|
(set (match_operand 0 "register_operand" "=f")
|
(mult (match_operand 1 "register_operand" "f")
|
(mult (match_operand 1 "register_operand" "f")
|
(match_operand 2 "register_operand" "f")))]
|
(match_operand 2 "register_operand" "f")))]
|
"TARGET_PA_11 && ! TARGET_SOFT_FLOAT
|
"TARGET_PA_11 && ! TARGET_SOFT_FLOAT
|
&& reload_completed && fmpysuboperands (operands)"
|
&& reload_completed && fmpysuboperands (operands)"
|
"*
|
"*
|
{
|
{
|
if (GET_MODE (operands[0]) == DFmode)
|
if (GET_MODE (operands[0]) == DFmode)
|
return \"fmpysub,dbl %1,%2,%0,%5,%3\";
|
return \"fmpysub,dbl %1,%2,%0,%5,%3\";
|
else
|
else
|
return \"fmpysub,sgl %1,%2,%0,%5,%3\";
|
return \"fmpysub,sgl %1,%2,%0,%5,%3\";
|
}"
|
}"
|
[(set_attr "type" "fpalu")
|
[(set_attr "type" "fpalu")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
;; The following two patterns are used by the trampoline code for nested
|
;; The following two patterns are used by the trampoline code for nested
|
;; functions. They flush the I and D cache lines from the start address
|
;; functions. They flush the I and D cache lines from the start address
|
;; (operand0) to the end address (operand1). No lines are flushed if the
|
;; (operand0) to the end address (operand1). No lines are flushed if the
|
;; end address is less than the start address (unsigned).
|
;; end address is less than the start address (unsigned).
|
;;
|
;;
|
;; Because the range of memory flushed is variable and the size of a MEM
|
;; 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
|
;; can only be a CONST_INT, the patterns specify that they perform an
|
;; unspecified volatile operation on all memory.
|
;; unspecified volatile operation on all memory.
|
;;
|
;;
|
;; The address range for an icache flush must lie within a single
|
;; The address range for an icache flush must lie within a single
|
;; space on targets with non-equivalent space registers.
|
;; space on targets with non-equivalent space registers.
|
;;
|
;;
|
;; Operand 0 contains the start address.
|
;; Operand 0 contains the start address.
|
;; Operand 1 contains the end address.
|
;; Operand 1 contains the end address.
|
;; Operand 2 contains the line length to use.
|
;; Operand 2 contains the line length to use.
|
(define_insn "dcacheflush"
|
(define_insn "dcacheflush"
|
[(const_int 1)
|
[(const_int 1)
|
(unspec_volatile [(mem:BLK (scratch))] UNSPECV_DCACHE)
|
(unspec_volatile [(mem:BLK (scratch))] UNSPECV_DCACHE)
|
(use (match_operand 0 "pmode_register_operand" "r"))
|
(use (match_operand 0 "pmode_register_operand" "r"))
|
(use (match_operand 1 "pmode_register_operand" "r"))
|
(use (match_operand 1 "pmode_register_operand" "r"))
|
(use (match_operand 2 "pmode_register_operand" "r"))
|
(use (match_operand 2 "pmode_register_operand" "r"))
|
(clobber (match_scratch:P 3 "=&0"))]
|
(clobber (match_scratch:P 3 "=&0"))]
|
""
|
""
|
"cmpb,<<=,n %3,%1,.\;fdc,m %2(%3)\;sync"
|
"cmpb,<<=,n %3,%1,.\;fdc,m %2(%3)\;sync"
|
[(set_attr "type" "multi")
|
[(set_attr "type" "multi")
|
(set_attr "length" "12")])
|
(set_attr "length" "12")])
|
|
|
(define_insn "icacheflush"
|
(define_insn "icacheflush"
|
[(const_int 2)
|
[(const_int 2)
|
(unspec_volatile [(mem:BLK (scratch))] UNSPECV_ICACHE)
|
(unspec_volatile [(mem:BLK (scratch))] UNSPECV_ICACHE)
|
(use (match_operand 0 "pmode_register_operand" "r"))
|
(use (match_operand 0 "pmode_register_operand" "r"))
|
(use (match_operand 1 "pmode_register_operand" "r"))
|
(use (match_operand 1 "pmode_register_operand" "r"))
|
(use (match_operand 2 "pmode_register_operand" "r"))
|
(use (match_operand 2 "pmode_register_operand" "r"))
|
(clobber (match_operand 3 "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:P 5 "=&0"))]
|
(clobber (match_scratch:P 5 "=&0"))]
|
""
|
""
|
"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"
|
"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 "type" "multi")
|
(set_attr "length" "52")])
|
(set_attr "length" "52")])
|
|
|
;; An out-of-line prologue.
|
;; An out-of-line prologue.
|
(define_insn "outline_prologue_call"
|
(define_insn "outline_prologue_call"
|
[(unspec_volatile [(const_int 0)] UNSPECV_OPC)
|
[(unspec_volatile [(const_int 0)] UNSPECV_OPC)
|
(clobber (reg:SI 31))
|
(clobber (reg:SI 31))
|
(clobber (reg:SI 22))
|
(clobber (reg:SI 22))
|
(clobber (reg:SI 21))
|
(clobber (reg:SI 21))
|
(clobber (reg:SI 20))
|
(clobber (reg:SI 20))
|
(clobber (reg:SI 19))
|
(clobber (reg:SI 19))
|
(clobber (reg:SI 1))]
|
(clobber (reg:SI 1))]
|
""
|
""
|
"*
|
"*
|
{
|
{
|
|
|
/* We need two different versions depending on whether or not we
|
/* We need two different versions depending on whether or not we
|
need a frame pointer. Also note that we return to the instruction
|
need a frame pointer. Also note that we return to the instruction
|
immediately after the branch rather than two instructions after the
|
immediately after the branch rather than two instructions after the
|
break as normally is the case. */
|
break as normally is the case. */
|
if (frame_pointer_needed)
|
if (frame_pointer_needed)
|
{
|
{
|
/* Must import the magic millicode routine(s). */
|
/* Must import the magic millicode routine(s). */
|
output_asm_insn (\".IMPORT __outline_prologue_fp,MILLICODE\", NULL);
|
output_asm_insn (\".IMPORT __outline_prologue_fp,MILLICODE\", NULL);
|
|
|
if (TARGET_PORTABLE_RUNTIME)
|
if (TARGET_PORTABLE_RUNTIME)
|
{
|
{
|
output_asm_insn (\"ldil L'__outline_prologue_fp,%%r31\", NULL);
|
output_asm_insn (\"ldil L'__outline_prologue_fp,%%r31\", NULL);
|
output_asm_insn (\"ble,n R'__outline_prologue_fp(%%sr0,%%r31)\",
|
output_asm_insn (\"ble,n R'__outline_prologue_fp(%%sr0,%%r31)\",
|
NULL);
|
NULL);
|
}
|
}
|
else
|
else
|
output_asm_insn (\"{bl|b,l},n __outline_prologue_fp,%%r31\", NULL);
|
output_asm_insn (\"{bl|b,l},n __outline_prologue_fp,%%r31\", NULL);
|
}
|
}
|
else
|
else
|
{
|
{
|
/* Must import the magic millicode routine(s). */
|
/* Must import the magic millicode routine(s). */
|
output_asm_insn (\".IMPORT __outline_prologue,MILLICODE\", NULL);
|
output_asm_insn (\".IMPORT __outline_prologue,MILLICODE\", NULL);
|
|
|
if (TARGET_PORTABLE_RUNTIME)
|
if (TARGET_PORTABLE_RUNTIME)
|
{
|
{
|
output_asm_insn (\"ldil L'__outline_prologue,%%r31\", NULL);
|
output_asm_insn (\"ldil L'__outline_prologue,%%r31\", NULL);
|
output_asm_insn (\"ble,n R'__outline_prologue(%%sr0,%%r31)\", NULL);
|
output_asm_insn (\"ble,n R'__outline_prologue(%%sr0,%%r31)\", NULL);
|
}
|
}
|
else
|
else
|
output_asm_insn (\"{bl|b,l},n __outline_prologue,%%r31\", NULL);
|
output_asm_insn (\"{bl|b,l},n __outline_prologue,%%r31\", NULL);
|
}
|
}
|
return \"\";
|
return \"\";
|
}"
|
}"
|
[(set_attr "type" "multi")
|
[(set_attr "type" "multi")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
;; An out-of-line epilogue.
|
;; An out-of-line epilogue.
|
(define_insn "outline_epilogue_call"
|
(define_insn "outline_epilogue_call"
|
[(unspec_volatile [(const_int 1)] UNSPECV_OEC)
|
[(unspec_volatile [(const_int 1)] UNSPECV_OEC)
|
(use (reg:SI 29))
|
(use (reg:SI 29))
|
(use (reg:SI 28))
|
(use (reg:SI 28))
|
(clobber (reg:SI 31))
|
(clobber (reg:SI 31))
|
(clobber (reg:SI 22))
|
(clobber (reg:SI 22))
|
(clobber (reg:SI 21))
|
(clobber (reg:SI 21))
|
(clobber (reg:SI 20))
|
(clobber (reg:SI 20))
|
(clobber (reg:SI 19))
|
(clobber (reg:SI 19))
|
(clobber (reg:SI 2))
|
(clobber (reg:SI 2))
|
(clobber (reg:SI 1))]
|
(clobber (reg:SI 1))]
|
""
|
""
|
"*
|
"*
|
{
|
{
|
|
|
/* We need two different versions depending on whether or not we
|
/* We need two different versions depending on whether or not we
|
need a frame pointer. Also note that we return to the instruction
|
need a frame pointer. Also note that we return to the instruction
|
immediately after the branch rather than two instructions after the
|
immediately after the branch rather than two instructions after the
|
break as normally is the case. */
|
break as normally is the case. */
|
if (frame_pointer_needed)
|
if (frame_pointer_needed)
|
{
|
{
|
/* Must import the magic millicode routine. */
|
/* Must import the magic millicode routine. */
|
output_asm_insn (\".IMPORT __outline_epilogue_fp,MILLICODE\", NULL);
|
output_asm_insn (\".IMPORT __outline_epilogue_fp,MILLICODE\", NULL);
|
|
|
/* The out-of-line prologue will make sure we return to the right
|
/* The out-of-line prologue will make sure we return to the right
|
instruction. */
|
instruction. */
|
if (TARGET_PORTABLE_RUNTIME)
|
if (TARGET_PORTABLE_RUNTIME)
|
{
|
{
|
output_asm_insn (\"ldil L'__outline_epilogue_fp,%%r31\", NULL);
|
output_asm_insn (\"ldil L'__outline_epilogue_fp,%%r31\", NULL);
|
output_asm_insn (\"ble,n R'__outline_epilogue_fp(%%sr0,%%r31)\",
|
output_asm_insn (\"ble,n R'__outline_epilogue_fp(%%sr0,%%r31)\",
|
NULL);
|
NULL);
|
}
|
}
|
else
|
else
|
output_asm_insn (\"{bl|b,l},n __outline_epilogue_fp,%%r31\", NULL);
|
output_asm_insn (\"{bl|b,l},n __outline_epilogue_fp,%%r31\", NULL);
|
}
|
}
|
else
|
else
|
{
|
{
|
/* Must import the magic millicode routine. */
|
/* Must import the magic millicode routine. */
|
output_asm_insn (\".IMPORT __outline_epilogue,MILLICODE\", NULL);
|
output_asm_insn (\".IMPORT __outline_epilogue,MILLICODE\", NULL);
|
|
|
/* The out-of-line prologue will make sure we return to the right
|
/* The out-of-line prologue will make sure we return to the right
|
instruction. */
|
instruction. */
|
if (TARGET_PORTABLE_RUNTIME)
|
if (TARGET_PORTABLE_RUNTIME)
|
{
|
{
|
output_asm_insn (\"ldil L'__outline_epilogue,%%r31\", NULL);
|
output_asm_insn (\"ldil L'__outline_epilogue,%%r31\", NULL);
|
output_asm_insn (\"ble,n R'__outline_epilogue(%%sr0,%%r31)\", NULL);
|
output_asm_insn (\"ble,n R'__outline_epilogue(%%sr0,%%r31)\", NULL);
|
}
|
}
|
else
|
else
|
output_asm_insn (\"{bl|b,l},n __outline_epilogue,%%r31\", NULL);
|
output_asm_insn (\"{bl|b,l},n __outline_epilogue,%%r31\", NULL);
|
}
|
}
|
return \"\";
|
return \"\";
|
}"
|
}"
|
[(set_attr "type" "multi")
|
[(set_attr "type" "multi")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
;; Given a function pointer, canonicalize it so it can be
|
;; Given a function pointer, canonicalize it so it can be
|
;; reliably compared to another function pointer. */
|
;; reliably compared to another function pointer. */
|
(define_expand "canonicalize_funcptr_for_compare"
|
(define_expand "canonicalize_funcptr_for_compare"
|
[(set (reg:SI 26) (match_operand:SI 1 "register_operand" ""))
|
[(set (reg:SI 26) (match_operand:SI 1 "register_operand" ""))
|
(parallel [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] UNSPEC_CFFC))
|
(parallel [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] UNSPEC_CFFC))
|
(clobber (match_dup 2))
|
(clobber (match_dup 2))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 22))
|
(clobber (reg:SI 22))
|
(clobber (reg:SI 31))])
|
(clobber (reg:SI 31))])
|
(set (match_operand:SI 0 "register_operand" "")
|
(set (match_operand:SI 0 "register_operand" "")
|
(reg:SI 29))]
|
(reg:SI 29))]
|
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
|
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
|
"
|
"
|
{
|
{
|
if (TARGET_ELF32)
|
if (TARGET_ELF32)
|
{
|
{
|
rtx canonicalize_funcptr_for_compare_libfunc
|
rtx canonicalize_funcptr_for_compare_libfunc
|
= init_one_libfunc (CANONICALIZE_FUNCPTR_FOR_COMPARE_LIBCALL);
|
= init_one_libfunc (CANONICALIZE_FUNCPTR_FOR_COMPARE_LIBCALL);
|
|
|
emit_library_call_value (canonicalize_funcptr_for_compare_libfunc,
|
emit_library_call_value (canonicalize_funcptr_for_compare_libfunc,
|
operands[0], LCT_NORMAL, Pmode,
|
operands[0], LCT_NORMAL, Pmode,
|
1, operands[1], Pmode);
|
1, operands[1], Pmode);
|
DONE;
|
DONE;
|
}
|
}
|
|
|
operands[2] = gen_reg_rtx (SImode);
|
operands[2] = gen_reg_rtx (SImode);
|
if (GET_CODE (operands[1]) != REG)
|
if (GET_CODE (operands[1]) != REG)
|
{
|
{
|
rtx tmp = gen_reg_rtx (Pmode);
|
rtx tmp = gen_reg_rtx (Pmode);
|
emit_move_insn (tmp, operands[1]);
|
emit_move_insn (tmp, operands[1]);
|
operands[1] = tmp;
|
operands[1] = tmp;
|
}
|
}
|
}")
|
}")
|
|
|
(define_insn "*$$sh_func_adrs"
|
(define_insn "*$$sh_func_adrs"
|
[(set (reg:SI 29) (unspec:SI [(reg:SI 26)] UNSPEC_CFFC))
|
[(set (reg:SI 29) (unspec:SI [(reg:SI 26)] UNSPEC_CFFC))
|
(clobber (match_operand:SI 0 "register_operand" "=a"))
|
(clobber (match_operand:SI 0 "register_operand" "=a"))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 26))
|
(clobber (reg:SI 22))
|
(clobber (reg:SI 22))
|
(clobber (reg:SI 31))]
|
(clobber (reg:SI 31))]
|
"!TARGET_64BIT"
|
"!TARGET_64BIT"
|
"*
|
"*
|
{
|
{
|
int length = get_attr_length (insn);
|
int length = get_attr_length (insn);
|
rtx xoperands[2];
|
rtx xoperands[2];
|
|
|
xoperands[0] = GEN_INT (length - 8);
|
xoperands[0] = GEN_INT (length - 8);
|
xoperands[1] = GEN_INT (length - 16);
|
xoperands[1] = GEN_INT (length - 16);
|
|
|
/* Must import the magic millicode routine. */
|
/* Must import the magic millicode routine. */
|
output_asm_insn (\".IMPORT $$sh_func_adrs,MILLICODE\", NULL);
|
output_asm_insn (\".IMPORT $$sh_func_adrs,MILLICODE\", NULL);
|
|
|
/* This is absolutely amazing.
|
/* This is absolutely amazing.
|
|
|
First, copy our input parameter into %r29 just in case we don't
|
First, copy our input parameter into %r29 just in case we don't
|
need to call $$sh_func_adrs. */
|
need to call $$sh_func_adrs. */
|
output_asm_insn (\"copy %%r26,%%r29\", NULL);
|
output_asm_insn (\"copy %%r26,%%r29\", NULL);
|
output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\", NULL);
|
output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\", NULL);
|
|
|
/* Next, examine the low two bits in %r26, if they aren't 0x2, then
|
/* Next, examine the low two bits in %r26, if they aren't 0x2, then
|
we use %r26 unchanged. */
|
we use %r26 unchanged. */
|
output_asm_insn (\"{comib|cmpib},<>,n 2,%%r31,.+%0\", xoperands);
|
output_asm_insn (\"{comib|cmpib},<>,n 2,%%r31,.+%0\", xoperands);
|
output_asm_insn (\"ldi 4096,%%r31\", NULL);
|
output_asm_insn (\"ldi 4096,%%r31\", NULL);
|
|
|
/* Next, compare %r26 with 4096, if %r26 is less than or equal to
|
/* Next, compare %r26 with 4096, if %r26 is less than or equal to
|
4096, then again we use %r26 unchanged. */
|
4096, then again we use %r26 unchanged. */
|
output_asm_insn (\"{comb|cmpb},<<,n %%r26,%%r31,.+%1\", xoperands);
|
output_asm_insn (\"{comb|cmpb},<<,n %%r26,%%r31,.+%1\", xoperands);
|
|
|
/* Finally, call $$sh_func_adrs to extract the function's real add24. */
|
/* Finally, call $$sh_func_adrs to extract the function's real add24. */
|
return output_millicode_call (insn,
|
return output_millicode_call (insn,
|
gen_rtx_SYMBOL_REF (SImode,
|
gen_rtx_SYMBOL_REF (SImode,
|
\"$$sh_func_adrs\"));
|
\"$$sh_func_adrs\"));
|
}"
|
}"
|
[(set_attr "type" "multi")
|
[(set_attr "type" "multi")
|
(set (attr "length")
|
(set (attr "length")
|
(plus (symbol_ref "attr_length_millicode_call (insn)")
|
(plus (symbol_ref "attr_length_millicode_call (insn)")
|
(const_int 20)))])
|
(const_int 20)))])
|
|
|
;; On the PA, the PIC register is call clobbered, so it must
|
;; On the PA, the PIC register is call clobbered, so it must
|
;; be saved & restored around calls by the caller. If the call
|
;; be saved & restored around calls by the caller. If the call
|
;; doesn't return normally (nonlocal goto, or an exception is
|
;; doesn't return normally (nonlocal goto, or an exception is
|
;; thrown), then the code at the exception handler label must
|
;; thrown), then the code at the exception handler label must
|
;; restore the PIC register.
|
;; restore the PIC register.
|
(define_expand "exception_receiver"
|
(define_expand "exception_receiver"
|
[(const_int 4)]
|
[(const_int 4)]
|
"flag_pic"
|
"flag_pic"
|
"
|
"
|
{
|
{
|
/* On the 64-bit port, we need a blockage because there is
|
/* On the 64-bit port, we need a blockage because there is
|
confusion regarding the dependence of the restore on the
|
confusion regarding the dependence of the restore on the
|
frame pointer. As a result, the frame pointer and pic
|
frame pointer. As a result, the frame pointer and pic
|
register restores sometimes are interchanged erroneously. */
|
register restores sometimes are interchanged erroneously. */
|
if (TARGET_64BIT)
|
if (TARGET_64BIT)
|
emit_insn (gen_blockage ());
|
emit_insn (gen_blockage ());
|
/* Restore the PIC register using hppa_pic_save_rtx (). The
|
/* Restore the PIC register using hppa_pic_save_rtx (). The
|
PIC register is not saved in the frame in 64-bit ABI. */
|
PIC register is not saved in the frame in 64-bit ABI. */
|
emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
|
emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
|
emit_insn (gen_blockage ());
|
emit_insn (gen_blockage ());
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
(define_expand "builtin_setjmp_receiver"
|
(define_expand "builtin_setjmp_receiver"
|
[(label_ref (match_operand 0 "" ""))]
|
[(label_ref (match_operand 0 "" ""))]
|
"flag_pic"
|
"flag_pic"
|
"
|
"
|
{
|
{
|
if (TARGET_64BIT)
|
if (TARGET_64BIT)
|
emit_insn (gen_blockage ());
|
emit_insn (gen_blockage ());
|
/* Restore the PIC register. Hopefully, this will always be from
|
/* Restore the PIC register. Hopefully, this will always be from
|
a stack slot. The only registers that are valid after a
|
a stack slot. The only registers that are valid after a
|
builtin_longjmp are the stack and frame pointers. */
|
builtin_longjmp are the stack and frame pointers. */
|
emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
|
emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
|
emit_insn (gen_blockage ());
|
emit_insn (gen_blockage ());
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
;; Allocate new stack space and update the saved stack pointer in the
|
;; Allocate new stack space and update the saved stack pointer in the
|
;; frame marker. The HP C compilers also copy additional words in the
|
;; frame marker. The HP C compilers also copy additional words in the
|
;; frame marker. The 64-bit compiler copies words at -48, -32 and -24.
|
;; frame marker. The 64-bit compiler copies words at -48, -32 and -24.
|
;; The 32-bit compiler copies the word at -16 (Static Link). We
|
;; The 32-bit compiler copies the word at -16 (Static Link). We
|
;; currently don't copy these values.
|
;; currently don't copy these values.
|
;;
|
;;
|
;; Since the copy of the frame marker can't be done atomically, I
|
;; Since the copy of the frame marker can't be done atomically, I
|
;; suspect that using it for unwind purposes may be somewhat unreliable.
|
;; suspect that using it for unwind purposes may be somewhat unreliable.
|
;; The HP compilers appear to raise the stack and copy the frame
|
;; The HP compilers appear to raise the stack and copy the frame
|
;; marker in a strict instruction sequence. This suggests that the
|
;; marker in a strict instruction sequence. This suggests that the
|
;; unwind library may check for an alloca sequence when ALLOCA_FRAME
|
;; unwind library may check for an alloca sequence when ALLOCA_FRAME
|
;; is set in the callinfo data. We currently don't set ALLOCA_FRAME
|
;; is set in the callinfo data. We currently don't set ALLOCA_FRAME
|
;; as GAS doesn't support it, or try to keep the instructions emitted
|
;; as GAS doesn't support it, or try to keep the instructions emitted
|
;; here in strict sequence.
|
;; here in strict sequence.
|
(define_expand "allocate_stack"
|
(define_expand "allocate_stack"
|
[(match_operand 0 "" "")
|
[(match_operand 0 "" "")
|
(match_operand 1 "" "")]
|
(match_operand 1 "" "")]
|
""
|
""
|
"
|
"
|
{
|
{
|
rtx addr;
|
rtx addr;
|
|
|
/* Since the stack grows upward, we need to store virtual_stack_dynamic_rtx
|
/* Since the stack grows upward, we need to store virtual_stack_dynamic_rtx
|
in operand 0 before adjusting the stack. */
|
in operand 0 before adjusting the stack. */
|
emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
|
emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
|
anti_adjust_stack (operands[1]);
|
anti_adjust_stack (operands[1]);
|
if (TARGET_HPUX_UNWIND_LIBRARY)
|
if (TARGET_HPUX_UNWIND_LIBRARY)
|
{
|
{
|
addr = gen_rtx_PLUS (word_mode, stack_pointer_rtx,
|
addr = gen_rtx_PLUS (word_mode, stack_pointer_rtx,
|
GEN_INT (TARGET_64BIT ? -8 : -4));
|
GEN_INT (TARGET_64BIT ? -8 : -4));
|
emit_move_insn (gen_rtx_MEM (word_mode, addr), frame_pointer_rtx);
|
emit_move_insn (gen_rtx_MEM (word_mode, addr), frame_pointer_rtx);
|
}
|
}
|
if (!TARGET_64BIT && flag_pic)
|
if (!TARGET_64BIT && flag_pic)
|
{
|
{
|
rtx addr = gen_rtx_PLUS (word_mode, stack_pointer_rtx, GEN_INT (-32));
|
rtx addr = gen_rtx_PLUS (word_mode, stack_pointer_rtx, GEN_INT (-32));
|
emit_move_insn (gen_rtx_MEM (word_mode, addr), pic_offset_table_rtx);
|
emit_move_insn (gen_rtx_MEM (word_mode, addr), pic_offset_table_rtx);
|
}
|
}
|
DONE;
|
DONE;
|
}")
|
}")
|
|
|
(define_expand "prefetch"
|
(define_expand "prefetch"
|
[(match_operand 0 "address_operand" "")
|
[(match_operand 0 "address_operand" "")
|
(match_operand 1 "const_int_operand" "")
|
(match_operand 1 "const_int_operand" "")
|
(match_operand 2 "const_int_operand" "")]
|
(match_operand 2 "const_int_operand" "")]
|
"TARGET_PA_20"
|
"TARGET_PA_20"
|
{
|
{
|
operands[0] = copy_addr_to_reg (operands[0]);
|
operands[0] = copy_addr_to_reg (operands[0]);
|
emit_insn (gen_prefetch_20 (operands[0], operands[1], operands[2]));
|
emit_insn (gen_prefetch_20 (operands[0], operands[1], operands[2]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_insn "prefetch_20"
|
(define_insn "prefetch_20"
|
[(prefetch (match_operand 0 "pmode_register_operand" "r")
|
[(prefetch (match_operand 0 "pmode_register_operand" "r")
|
(match_operand:SI 1 "const_int_operand" "n")
|
(match_operand:SI 1 "const_int_operand" "n")
|
(match_operand:SI 2 "const_int_operand" "n"))]
|
(match_operand:SI 2 "const_int_operand" "n"))]
|
"TARGET_PA_20"
|
"TARGET_PA_20"
|
{
|
{
|
/* The SL cache-control completer indicates good spatial locality but
|
/* The SL cache-control completer indicates good spatial locality but
|
poor temporal locality. The ldw instruction with a target of general
|
poor temporal locality. The ldw instruction with a target of general
|
register 0 prefetches a cache line for a read. The ldd instruction
|
register 0 prefetches a cache line for a read. The ldd instruction
|
prefetches a cache line for a write. */
|
prefetches a cache line for a write. */
|
static const char * const instr[2][2] = {
|
static const char * const instr[2][2] = {
|
{
|
{
|
"ldw,sl 0(%0),%%r0",
|
"ldw,sl 0(%0),%%r0",
|
"ldd,sl 0(%0),%%r0"
|
"ldd,sl 0(%0),%%r0"
|
},
|
},
|
{
|
{
|
"ldw 0(%0),%%r0",
|
"ldw 0(%0),%%r0",
|
"ldd 0(%0),%%r0"
|
"ldd 0(%0),%%r0"
|
}
|
}
|
};
|
};
|
int read_or_write = INTVAL (operands[1]) == 0 ? 0 : 1;
|
int read_or_write = INTVAL (operands[1]) == 0 ? 0 : 1;
|
int locality = INTVAL (operands[2]) == 0 ? 0 : 1;
|
int locality = INTVAL (operands[2]) == 0 ? 0 : 1;
|
|
|
return instr [locality][read_or_write];
|
return instr [locality][read_or_write];
|
}
|
}
|
[(set_attr "type" "load")
|
[(set_attr "type" "load")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
;; TLS Support
|
;; TLS Support
|
(define_insn "tgd_load"
|
(define_insn "tgd_load"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD))
|
(unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(use (reg:SI 27))]
|
(use (reg:SI 27))]
|
""
|
""
|
"*
|
"*
|
{
|
{
|
return \"addil LR'%1-$tls_gdidx$,%%r27\;ldo RR'%1-$tls_gdidx$(%%r1),%0\";
|
return \"addil LR'%1-$tls_gdidx$,%%r27\;ldo RR'%1-$tls_gdidx$(%%r1),%0\";
|
}"
|
}"
|
[(set_attr "type" "multi")
|
[(set_attr "type" "multi")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn "tgd_load_pic"
|
(define_insn "tgd_load_pic"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD_PIC))
|
(unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD_PIC))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(use (reg:SI 19))]
|
(use (reg:SI 19))]
|
""
|
""
|
"*
|
"*
|
{
|
{
|
return \"addil LT'%1-$tls_gdidx$,%%r19\;ldo RT'%1-$tls_gdidx$(%%r1),%0\";
|
return \"addil LT'%1-$tls_gdidx$,%%r19\;ldo RT'%1-$tls_gdidx$(%%r1),%0\";
|
}"
|
}"
|
[(set_attr "type" "multi")
|
[(set_attr "type" "multi")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn "tld_load"
|
(define_insn "tld_load"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM))
|
(unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(use (reg:SI 27))]
|
(use (reg:SI 27))]
|
""
|
""
|
"*
|
"*
|
{
|
{
|
return \"addil LR'%1-$tls_ldidx$,%%r27\;ldo RR'%1-$tls_ldidx$(%%r1),%0\";
|
return \"addil LR'%1-$tls_ldidx$,%%r27\;ldo RR'%1-$tls_ldidx$(%%r1),%0\";
|
}"
|
}"
|
[(set_attr "type" "multi")
|
[(set_attr "type" "multi")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn "tld_load_pic"
|
(define_insn "tld_load_pic"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM_PIC))
|
(unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM_PIC))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(use (reg:SI 19))]
|
(use (reg:SI 19))]
|
""
|
""
|
"*
|
"*
|
{
|
{
|
return \"addil LT'%1-$tls_ldidx$,%%r19\;ldo RT'%1-$tls_ldidx$(%%r1),%0\";
|
return \"addil LT'%1-$tls_ldidx$,%%r19\;ldo RT'%1-$tls_ldidx$(%%r1),%0\";
|
}"
|
}"
|
[(set_attr "type" "multi")
|
[(set_attr "type" "multi")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn "tld_offset_load"
|
(define_insn "tld_offset_load"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(plus:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
|
(plus:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
|
UNSPEC_TLSLDO)
|
UNSPEC_TLSLDO)
|
(match_operand:SI 2 "register_operand" "r")))
|
(match_operand:SI 2 "register_operand" "r")))
|
(clobber (reg:SI 1))]
|
(clobber (reg:SI 1))]
|
""
|
""
|
"*
|
"*
|
{
|
{
|
return \"addil LR'%1-$tls_dtpoff$,%2\;ldo RR'%1-$tls_dtpoff$(%%r1),%0\";
|
return \"addil LR'%1-$tls_dtpoff$,%2\;ldo RR'%1-$tls_dtpoff$(%%r1),%0\";
|
}"
|
}"
|
[(set_attr "type" "multi")
|
[(set_attr "type" "multi")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn "tp_load"
|
(define_insn "tp_load"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(unspec:SI [(const_int 0)] UNSPEC_TP))]
|
(unspec:SI [(const_int 0)] UNSPEC_TP))]
|
""
|
""
|
"mfctl %%cr27,%0"
|
"mfctl %%cr27,%0"
|
[(set_attr "type" "multi")
|
[(set_attr "type" "multi")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "tie_load"
|
(define_insn "tie_load"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE))
|
(unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(use (reg:SI 27))]
|
(use (reg:SI 27))]
|
""
|
""
|
"*
|
"*
|
{
|
{
|
return \"addil LR'%1-$tls_ieoff$,%%r27\;ldw RR'%1-$tls_ieoff$(%%r1),%0\";
|
return \"addil LR'%1-$tls_ieoff$,%%r27\;ldw RR'%1-$tls_ieoff$(%%r1),%0\";
|
}"
|
}"
|
[(set_attr "type" "multi")
|
[(set_attr "type" "multi")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn "tie_load_pic"
|
(define_insn "tie_load_pic"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE_PIC))
|
(unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE_PIC))
|
(clobber (reg:SI 1))
|
(clobber (reg:SI 1))
|
(use (reg:SI 19))]
|
(use (reg:SI 19))]
|
""
|
""
|
"*
|
"*
|
{
|
{
|
return \"addil LT'%1-$tls_ieoff$,%%r19\;ldw RT'%1-$tls_ieoff$(%%r1),%0\";
|
return \"addil LT'%1-$tls_ieoff$,%%r19\;ldw RT'%1-$tls_ieoff$(%%r1),%0\";
|
}"
|
}"
|
[(set_attr "type" "multi")
|
[(set_attr "type" "multi")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn "tle_load"
|
(define_insn "tle_load"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(plus:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
|
(plus:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
|
UNSPEC_TLSLE)
|
UNSPEC_TLSLE)
|
(match_operand:SI 2 "register_operand" "r")))
|
(match_operand:SI 2 "register_operand" "r")))
|
(clobber (reg:SI 1))]
|
(clobber (reg:SI 1))]
|
""
|
""
|
"addil LR'%1-$tls_leoff$,%2\;ldo RR'%1-$tls_leoff$(%%r1),%0"
|
"addil LR'%1-$tls_leoff$,%2\;ldo RR'%1-$tls_leoff$(%%r1),%0"
|
[(set_attr "type" "multi")
|
[(set_attr "type" "multi")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|