diff options
Diffstat (limited to 'gcc-4.8.1/gcc/config/pa/pa.md')
-rw-r--r-- | gcc-4.8.1/gcc/config/pa/pa.md | 9861 |
1 files changed, 0 insertions, 9861 deletions
diff --git a/gcc-4.8.1/gcc/config/pa/pa.md b/gcc-4.8.1/gcc/config/pa/pa.md deleted file mode 100644 index 5e6d5652e..000000000 --- a/gcc-4.8.1/gcc/config/pa/pa.md +++ /dev/null @@ -1,9861 +0,0 @@ -;;- Machine description for HP PA-RISC architecture for GCC compiler -;; Copyright (C) 1992-2013 Free Software Foundation, Inc. -;; Contributed by the Center for Software Science at the University -;; of Utah. - -;; This file is part of GCC. - -;; GCC is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. - -;; GCC is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - -;; This machine description is inspired by sparc.md and to a lesser -;; extent mips.md. - -;; Possible improvements: -;; -;; * With PA1.1, most computational instructions can conditionally nullify -;; the execution of the following instruction. A nullified instruction -;; does not cause the instruction pipeline to stall, making it a very -;; efficient alternative to e.g. branching or conditional moves. -;; -;; Nullification is performed conditionally based on the outcome of a -;; test specified in the opcode. The test result is stored in PSW[N] -;; and can only be used to nullify the instruction following immediately -;; after the test. For example: -;; -;; ldi 10,%r26 -;; ldi 5,%r25 -;; sub,< %r26,%r25,%r28 -;; sub %r28,%r25,%r28 ; %r28 == 0 -;; sub,> %r26,%r25,%r29 -;; sub %r29,%r25,%r29 ; %r29 == 5 -;; -;; This could be tricky to implement because the result of the test has -;; to be propagated one instruction forward, which, in the worst case, -;; would involve (1) adding a fake register for PSW[N]; (2) adding the -;; variants of the computational instructions that set or consume this -;; fake register. The cond_exec infrastructure is probably not helpful -;; for this. -;; -;; * PA-RISC includes a set of conventions for branch instruction usage -;; to indicate whether a particular branch is more likely to be taken -;; or not taken. For example, the prediction for CMPB instructions -;; (CMPB,cond,n r1,r2,target) depends on the direction of the branch -;; (forward or backward) and on the order of the operands: -;; -;; | branch | operand | branch | -;; | direction | compare | prediction | -;; +-----------+----------+------------+ -;; | backward | r1 < r2 | taken | -;; | backward | r1 >= r2 | not taken | -;; | forward | r1 < r2 | not taken | -;; | forward | r1 >= r2 | taken | -;; -;; By choosing instructions and operand order carefully, the compiler -;; could give the CPU branch predictor some help. -;; - -;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. - -;; Uses of UNSPEC in this file: - -(define_c_enum "unspec" - [UNSPEC_CFFC ; canonicalize_funcptr_for_compare - UNSPEC_GOTO ; indirect_goto - UNSPEC_DLTIND14R - UNSPEC_TP - UNSPEC_TLSGD - UNSPEC_TLSLDM - UNSPEC_TLSLDO - UNSPEC_TLSLDBASE - UNSPEC_TLSIE - UNSPEC_TLSLE - UNSPEC_TLSGD_PIC - UNSPEC_TLSLDM_PIC - UNSPEC_TLSIE_PIC - ]) - -;; UNSPEC_VOLATILE: - -(define_c_enum "unspecv" - [UNSPECV_BLOCKAGE ; blockage - UNSPECV_DCACHE ; dcacheflush - UNSPECV_ICACHE ; icacheflush - UNSPECV_OPC ; outline_prologue_call - UNSPECV_OEC ; outline_epilogue_call - UNSPECV_LONGJMP ; builtin_longjmp - ]) - -;; Maximum pc-relative branch offsets. - -;; These numbers are a bit smaller than the maximum allowable offsets -;; so that a few instructions may be inserted before the actual branch. - -(define_constants - [(MAX_12BIT_OFFSET 8184) ; 12-bit branch - (MAX_17BIT_OFFSET 262100) ; 17-bit branch - ]) - -;; Mode and code iterators - -;; This mode iterator allows :P to be used for patterns that operate on -;; pointer-sized quantities. Exactly one of the two alternatives will match. -(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")]) - -;; This attribute defines the condition prefix for word and double word -;; add, compare, subtract and logical instructions. -(define_mode_attr dwc [(SI "") (DI "*")]) - -;; Insn type. Used to default other attribute values. - -;; type "unary" insns have one input operand (1) and one output operand (0) -;; type "binary" insns have two input operands (1,2) and one output (0) - -(define_attr "type" - "move,unary,binary,shift,nullshift,compare,load,store,uncond_branch,btable_branch,branch,cbranch,fbranch,call,sibcall,dyncall,fpload,fpstore,fpalu,fpcc,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,multi,milli,sh_func_adrs,parallel_branch,fpstore_load,store_fpload" - (const_string "binary")) - -(define_attr "pa_combine_type" - "fmpy,faddsub,uncond_branch,addmove,none" - (const_string "none")) - -;; Processor type (for scheduling, not code generation) -- this attribute -;; must exactly match the processor_type enumeration in pa.h. -;; -;; FIXME: Add 800 scheduling for completeness? - -(define_attr "cpu" "700,7100,7100LC,7200,7300,8000" (const (symbol_ref "pa_cpu_attr"))) - -;; Length (in # of bytes). -(define_attr "length" "" - (cond [(eq_attr "type" "load,fpload") - (if_then_else (match_operand 1 "symbolic_memory_operand" "") - (const_int 8) (const_int 4)) - - (eq_attr "type" "store,fpstore") - (if_then_else (match_operand 0 "symbolic_memory_operand" "") - (const_int 8) (const_int 4)) - - (eq_attr "type" "binary,shift,nullshift") - (if_then_else (match_operand 2 "arith14_operand" "") - (const_int 4) (const_int 12)) - - (eq_attr "type" "move,unary,shift,nullshift") - (if_then_else (match_operand 1 "arith14_operand" "") - (const_int 4) (const_int 8))] - - (const_int 4))) - -(define_asm_attributes - [(set_attr "length" "4") - (set_attr "type" "multi")]) - -;; Attributes for instruction and branch scheduling - -;; For conditional branches. Frame related instructions are not allowed -;; because they confuse the unwind support. -(define_attr "in_branch_delay" "false,true" - (if_then_else (and (eq_attr "type" "!uncond_branch,btable_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch") - (eq_attr "length" "4") - (not (match_test "RTX_FRAME_RELATED_P (insn)"))) - (const_string "true") - (const_string "false"))) - -;; Disallow instructions which use the FPU since they will tie up the FPU -;; even if the instruction is nullified. -(define_attr "in_nullified_branch_delay" "false,true" - (if_then_else (and (eq_attr "type" "!uncond_branch,btable_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,parallel_branch") - (eq_attr "length" "4") - (not (match_test "RTX_FRAME_RELATED_P (insn)"))) - (const_string "true") - (const_string "false"))) - -;; For calls and millicode calls. Allow unconditional branches in the -;; delay slot. -(define_attr "in_call_delay" "false,true" - (cond [(and (eq_attr "type" "!uncond_branch,btable_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch") - (eq_attr "length" "4") - (not (match_test "RTX_FRAME_RELATED_P (insn)"))) - (const_string "true") - (eq_attr "type" "uncond_branch") - (if_then_else (match_test "TARGET_JUMP_IN_DELAY") - (const_string "true") - (const_string "false"))] - (const_string "false"))) - - -;; Call delay slot description. -(define_delay (eq_attr "type" "call") - [(eq_attr "in_call_delay" "true") (nil) (nil)]) - -;; Sibcall delay slot description. -(define_delay (eq_attr "type" "sibcall") - [(eq_attr "in_call_delay" "true") (nil) (nil)]) - -;; Millicode call delay slot description. -(define_delay (eq_attr "type" "milli") - [(eq_attr "in_call_delay" "true") (nil) (nil)]) - -;; Return and other similar instructions. -(define_delay (eq_attr "type" "btable_branch,branch,parallel_branch") - [(eq_attr "in_branch_delay" "true") (nil) (nil)]) - -;; Floating point conditional branch delay slot description. -(define_delay (eq_attr "type" "fbranch") - [(eq_attr "in_branch_delay" "true") - (eq_attr "in_nullified_branch_delay" "true") - (nil)]) - -;; Integer conditional branch delay slot description. -;; Nullification of conditional branches on the PA is dependent on the -;; direction of the branch. Forward branches nullify true and -;; backward branches nullify false. If the direction is unknown -;; then nullification is not allowed. -(define_delay (eq_attr "type" "cbranch") - [(eq_attr "in_branch_delay" "true") - (and (eq_attr "in_nullified_branch_delay" "true") - (attr_flag "forward")) - (and (eq_attr "in_nullified_branch_delay" "true") - (attr_flag "backward"))]) - -(define_delay (and (eq_attr "type" "uncond_branch") - (not (match_test "pa_following_call (insn)"))) - [(eq_attr "in_branch_delay" "true") (nil) (nil)]) - -;; Memory. Disregarding Cache misses, the Mustang memory times are: -;; load: 2, fpload: 3 -;; store, fpstore: 3, no D-cache operations should be scheduled. - -;; The Timex (aka 700) has two floating-point units: ALU, and MUL/DIV/SQRT. -;; Timings: -;; Instruction Time Unit Minimum Distance (unit contention) -;; fcpy 3 ALU 2 -;; fabs 3 ALU 2 -;; fadd 3 ALU 2 -;; fsub 3 ALU 2 -;; fcmp 3 ALU 2 -;; fcnv 3 ALU 2 -;; fmpyadd 3 ALU,MPY 2 -;; fmpysub 3 ALU,MPY 2 -;; fmpycfxt 3 ALU,MPY 2 -;; fmpy 3 MPY 2 -;; fmpyi 3 MPY 2 -;; fdiv,sgl 10 MPY 10 -;; fdiv,dbl 12 MPY 12 -;; fsqrt,sgl 14 MPY 14 -;; fsqrt,dbl 18 MPY 18 -;; -;; We don't model fmpyadd/fmpysub properly as those instructions -;; keep both the FP ALU and MPY units busy. Given that these -;; processors are obsolete, I'm not going to spend the time to -;; model those instructions correctly. - -(define_automaton "pa700") -(define_cpu_unit "dummy_700,mem_700,fpalu_700,fpmpy_700" "pa700") - -(define_insn_reservation "W0" 4 - (and (eq_attr "type" "fpcc") - (eq_attr "cpu" "700")) - "fpalu_700*2") - -(define_insn_reservation "W1" 3 - (and (eq_attr "type" "fpalu") - (eq_attr "cpu" "700")) - "fpalu_700*2") - -(define_insn_reservation "W2" 3 - (and (eq_attr "type" "fpmulsgl,fpmuldbl") - (eq_attr "cpu" "700")) - "fpmpy_700*2") - -(define_insn_reservation "W3" 10 - (and (eq_attr "type" "fpdivsgl") - (eq_attr "cpu" "700")) - "fpmpy_700*10") - -(define_insn_reservation "W4" 12 - (and (eq_attr "type" "fpdivdbl") - (eq_attr "cpu" "700")) - "fpmpy_700*12") - -(define_insn_reservation "W5" 14 - (and (eq_attr "type" "fpsqrtsgl") - (eq_attr "cpu" "700")) - "fpmpy_700*14") - -(define_insn_reservation "W6" 18 - (and (eq_attr "type" "fpsqrtdbl") - (eq_attr "cpu" "700")) - "fpmpy_700*18") - -(define_insn_reservation "W7" 2 - (and (eq_attr "type" "load") - (eq_attr "cpu" "700")) - "mem_700") - -(define_insn_reservation "W8" 2 - (and (eq_attr "type" "fpload") - (eq_attr "cpu" "700")) - "mem_700") - -(define_insn_reservation "W9" 3 - (and (eq_attr "type" "store") - (eq_attr "cpu" "700")) - "mem_700*3") - -(define_insn_reservation "W10" 3 - (and (eq_attr "type" "fpstore") - (eq_attr "cpu" "700")) - "mem_700*3") - -(define_insn_reservation "W11" 5 - (and (eq_attr "type" "fpstore_load") - (eq_attr "cpu" "700")) - "mem_700*5") - -(define_insn_reservation "W12" 6 - (and (eq_attr "type" "store_fpload") - (eq_attr "cpu" "700")) - "mem_700*6") - -(define_insn_reservation "W13" 1 - (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,load,fpload,store,fpstore,fpstore_load,store_fpload") - (eq_attr "cpu" "700")) - "dummy_700") - -;; We have a bypass for all computations in the FP unit which feed an -;; FP store as long as the sizes are the same. -(define_bypass 2 "W1,W2" "W10,W11" "pa_fpstore_bypass_p") -(define_bypass 9 "W3" "W10,W11" "pa_fpstore_bypass_p") -(define_bypass 11 "W4" "W10,W11" "pa_fpstore_bypass_p") -(define_bypass 13 "W5" "W10,W11" "pa_fpstore_bypass_p") -(define_bypass 17 "W6" "W10,W11" "pa_fpstore_bypass_p") - -;; We have an "anti-bypass" for FP loads which feed an FP store. -(define_bypass 4 "W8,W12" "W10,W11" "pa_fpstore_bypass_p") - -;; Function units for the 7100 and 7150. The 7100/7150 can dual-issue -;; floating point computations with non-floating point computations (fp loads -;; and stores are not fp computations). -;; -;; Memory. Disregarding Cache misses, memory loads take two cycles; stores also -;; 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 -;; all have the same memory characteristics if one disregards cache misses. -;; -;; The 7100/7150 has three floating-point units: ALU, MUL, and DIV. -;; There's no value in modeling the ALU and MUL separately though -;; since there can never be a functional unit conflict given the -;; latency and issue rates for those units. -;; -;; Timings: -;; Instruction Time Unit Minimum Distance (unit contention) -;; fcpy 2 ALU 1 -;; fabs 2 ALU 1 -;; fadd 2 ALU 1 -;; fsub 2 ALU 1 -;; fcmp 2 ALU 1 -;; fcnv 2 ALU 1 -;; fmpyadd 2 ALU,MPY 1 -;; fmpysub 2 ALU,MPY 1 -;; fmpycfxt 2 ALU,MPY 1 -;; fmpy 2 MPY 1 -;; fmpyi 2 MPY 1 -;; fdiv,sgl 8 DIV 8 -;; fdiv,dbl 15 DIV 15 -;; fsqrt,sgl 8 DIV 8 -;; fsqrt,dbl 15 DIV 15 - -(define_automaton "pa7100") -(define_cpu_unit "i_7100, f_7100,fpmac_7100,fpdivsqrt_7100,mem_7100" "pa7100") - -(define_insn_reservation "X0" 2 - (and (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl") - (eq_attr "cpu" "7100")) - "f_7100,fpmac_7100") - -(define_insn_reservation "X1" 8 - (and (eq_attr "type" "fpdivsgl,fpsqrtsgl") - (eq_attr "cpu" "7100")) - "f_7100+fpdivsqrt_7100,fpdivsqrt_7100*7") - -(define_insn_reservation "X2" 15 - (and (eq_attr "type" "fpdivdbl,fpsqrtdbl") - (eq_attr "cpu" "7100")) - "f_7100+fpdivsqrt_7100,fpdivsqrt_7100*14") - -(define_insn_reservation "X3" 2 - (and (eq_attr "type" "load") - (eq_attr "cpu" "7100")) - "i_7100+mem_7100") - -(define_insn_reservation "X4" 2 - (and (eq_attr "type" "fpload") - (eq_attr "cpu" "7100")) - "i_7100+mem_7100") - -(define_insn_reservation "X5" 2 - (and (eq_attr "type" "store") - (eq_attr "cpu" "7100")) - "i_7100+mem_7100,mem_7100") - -(define_insn_reservation "X6" 2 - (and (eq_attr "type" "fpstore") - (eq_attr "cpu" "7100")) - "i_7100+mem_7100,mem_7100") - -(define_insn_reservation "X7" 4 - (and (eq_attr "type" "fpstore_load") - (eq_attr "cpu" "7100")) - "i_7100+mem_7100,mem_7100*3") - -(define_insn_reservation "X8" 4 - (and (eq_attr "type" "store_fpload") - (eq_attr "cpu" "7100")) - "i_7100+mem_7100,mem_7100*3") - -(define_insn_reservation "X9" 1 - (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,fpstore_load,store_fpload") - (eq_attr "cpu" "7100")) - "i_7100") - -;; We have a bypass for all computations in the FP unit which feed an -;; FP store as long as the sizes are the same. -(define_bypass 1 "X0" "X6,X7" "pa_fpstore_bypass_p") -(define_bypass 7 "X1" "X6,X7" "pa_fpstore_bypass_p") -(define_bypass 14 "X2" "X6,X7" "pa_fpstore_bypass_p") - -;; We have an "anti-bypass" for FP loads which feed an FP store. -(define_bypass 3 "X4,X8" "X6,X7" "pa_fpstore_bypass_p") - -;; The 7100LC has three floating-point units: ALU, MUL, and DIV. -;; There's no value in modeling the ALU and MUL separately though -;; since there can never be a functional unit conflict that -;; can be avoided given the latency, issue rates and mandatory -;; one cycle cpu-wide lock for a double precision fp multiply. -;; -;; Timings: -;; Instruction Time Unit Minimum Distance (unit contention) -;; fcpy 2 ALU 1 -;; fabs 2 ALU 1 -;; fadd 2 ALU 1 -;; fsub 2 ALU 1 -;; fcmp 2 ALU 1 -;; fcnv 2 ALU 1 -;; fmpyadd,sgl 2 ALU,MPY 1 -;; fmpyadd,dbl 3 ALU,MPY 2 -;; fmpysub,sgl 2 ALU,MPY 1 -;; fmpysub,dbl 3 ALU,MPY 2 -;; fmpycfxt,sgl 2 ALU,MPY 1 -;; fmpycfxt,dbl 3 ALU,MPY 2 -;; fmpy,sgl 2 MPY 1 -;; fmpy,dbl 3 MPY 2 -;; fmpyi 3 MPY 2 -;; fdiv,sgl 8 DIV 8 -;; fdiv,dbl 15 DIV 15 -;; fsqrt,sgl 8 DIV 8 -;; fsqrt,dbl 15 DIV 15 -;; -;; The PA7200 is just like the PA7100LC except that there is -;; no store-store penalty. -;; -;; The PA7300 is just like the PA7200 except that there is -;; no store-load penalty. -;; -;; Note there are some aspects of the 7100LC we are not modeling -;; at the moment. I'll be reviewing the 7100LC scheduling info -;; shortly and updating this description. -;; -;; load-load pairs -;; store-store pairs -;; other issue modeling - -(define_automaton "pa7100lc") -(define_cpu_unit "i0_7100lc, i1_7100lc, f_7100lc" "pa7100lc") -(define_cpu_unit "fpmac_7100lc" "pa7100lc") -(define_cpu_unit "mem_7100lc" "pa7100lc") - -;; Double precision multiplies lock the entire CPU for one -;; cycle. There is no way to avoid this lock and trying to -;; schedule around the lock is pointless and thus there is no -;; value in trying to model this lock. -;; -;; Not modeling the lock allows us to treat fp multiplies just -;; like any other FP alu instruction. It allows for a smaller -;; DFA and may reduce register pressure. -(define_insn_reservation "Y0" 2 - (and (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl") - (eq_attr "cpu" "7100LC,7200,7300")) - "f_7100lc,fpmac_7100lc") - -;; fp division and sqrt instructions lock the entire CPU for -;; 7 cycles (single precision) or 14 cycles (double precision). -;; There is no way to avoid this lock and trying to schedule -;; around the lock is pointless and thus there is no value in -;; trying to model this lock. Not modeling the lock allows -;; for a smaller DFA and may reduce register pressure. -(define_insn_reservation "Y1" 1 - (and (eq_attr "type" "fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl") - (eq_attr "cpu" "7100LC,7200,7300")) - "f_7100lc") - -(define_insn_reservation "Y2" 2 - (and (eq_attr "type" "load") - (eq_attr "cpu" "7100LC,7200,7300")) - "i1_7100lc+mem_7100lc") - -(define_insn_reservation "Y3" 2 - (and (eq_attr "type" "fpload") - (eq_attr "cpu" "7100LC,7200,7300")) - "i1_7100lc+mem_7100lc") - -(define_insn_reservation "Y4" 2 - (and (eq_attr "type" "store") - (eq_attr "cpu" "7100LC")) - "i1_7100lc+mem_7100lc,mem_7100lc") - -(define_insn_reservation "Y5" 2 - (and (eq_attr "type" "fpstore") - (eq_attr "cpu" "7100LC")) - "i1_7100lc+mem_7100lc,mem_7100lc") - -(define_insn_reservation "Y6" 4 - (and (eq_attr "type" "fpstore_load") - (eq_attr "cpu" "7100LC")) - "i1_7100lc+mem_7100lc,mem_7100lc*3") - -(define_insn_reservation "Y7" 4 - (and (eq_attr "type" "store_fpload") - (eq_attr "cpu" "7100LC")) - "i1_7100lc+mem_7100lc,mem_7100lc*3") - -(define_insn_reservation "Y8" 1 - (and (eq_attr "type" "shift,nullshift") - (eq_attr "cpu" "7100LC,7200,7300")) - "i1_7100lc") - -(define_insn_reservation "Y9" 1 - (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,shift,nullshift") - (eq_attr "cpu" "7100LC,7200,7300")) - "(i0_7100lc|i1_7100lc)") - -;; The 7200 has a store-load penalty -(define_insn_reservation "Y10" 2 - (and (eq_attr "type" "store") - (eq_attr "cpu" "7200")) - "i1_7100lc,mem_7100lc") - -(define_insn_reservation "Y11" 2 - (and (eq_attr "type" "fpstore") - (eq_attr "cpu" "7200")) - "i1_7100lc,mem_7100lc") - -(define_insn_reservation "Y12" 4 - (and (eq_attr "type" "fpstore_load") - (eq_attr "cpu" "7200")) - "i1_7100lc,mem_7100lc,i1_7100lc+mem_7100lc") - -(define_insn_reservation "Y13" 4 - (and (eq_attr "type" "store_fpload") - (eq_attr "cpu" "7200")) - "i1_7100lc,mem_7100lc,i1_7100lc+mem_7100lc") - -;; The 7300 has no penalty for store-store or store-load -(define_insn_reservation "Y14" 2 - (and (eq_attr "type" "store") - (eq_attr "cpu" "7300")) - "i1_7100lc") - -(define_insn_reservation "Y15" 2 - (and (eq_attr "type" "fpstore") - (eq_attr "cpu" "7300")) - "i1_7100lc") - -(define_insn_reservation "Y16" 4 - (and (eq_attr "type" "fpstore_load") - (eq_attr "cpu" "7300")) - "i1_7100lc,i1_7100lc+mem_7100lc") - -(define_insn_reservation "Y17" 4 - (and (eq_attr "type" "store_fpload") - (eq_attr "cpu" "7300")) - "i1_7100lc,i1_7100lc+mem_7100lc") - -;; We have an "anti-bypass" for FP loads which feed an FP store. -(define_bypass 3 "Y3,Y7,Y13,Y17" "Y5,Y6,Y11,Y12,Y15,Y16" "pa_fpstore_bypass_p") - -;; Scheduling for the PA8000 is somewhat different than scheduling for a -;; traditional architecture. -;; -;; The PA8000 has a large (56) entry reorder buffer that is split between -;; memory and non-memory operations. -;; -;; 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 -;; 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. -;; -;; Given the large reorder buffer, the processor can hide most latencies. -;; According to HP, they've got the best results by scheduling for retirement -;; bandwidth with limited latency scheduling for floating point operations. -;; Latency for integer operations and memory references is ignored. -;; -;; -;; We claim floating point operations have a 2 cycle latency and are -;; fully pipelined, except for div and sqrt which are not pipelined and -;; take from 17 to 31 cycles to complete. -;; -;; 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. - -(define_automaton "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 "store_8000" "pa8000") -(define_cpu_unit "f0_8000, f1_8000" "pa8000") -(define_cpu_unit "fdivsqrt0_8000, fdivsqrt1_8000" "pa8000") -(define_reservation "inm_8000" "inm0_8000 | inm1_8000") -(define_reservation "im_8000" "im0_8000 | im1_8000") -(define_reservation "rnm_8000" "rnm0_8000 | rnm1_8000") -(define_reservation "rm_8000" "rm0_8000 | rm1_8000") -(define_reservation "f_8000" "f0_8000 | f1_8000") -(define_reservation "fdivsqrt_8000" "fdivsqrt0_8000 | fdivsqrt1_8000") - -;; We can issue any two memops per cycle, but we can only retire -;; one memory store per cycle. We assume that the reorder buffer -;; will hide any memory latencies per HP's recommendation. -(define_insn_reservation "Z0" 0 - (and - (eq_attr "type" "load,fpload") - (eq_attr "cpu" "8000")) - "im_8000,rm_8000") - -(define_insn_reservation "Z1" 0 - (and - (eq_attr "type" "store,fpstore") - (eq_attr "cpu" "8000")) - "im_8000,rm_8000+store_8000") - -(define_insn_reservation "Z2" 0 - (and (eq_attr "type" "fpstore_load,store_fpload") - (eq_attr "cpu" "8000")) - "im_8000,rm_8000+store_8000,im_8000,rm_8000") - -;; We can issue and retire two non-memory operations per cycle with -;; a few exceptions (branches). This group catches those we want -;; to assume have zero latency. -(define_insn_reservation "Z3" 0 - (and - (eq_attr "type" "!load,fpload,store,fpstore,uncond_branch,btable_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch,fpcc,fpalu,fpmulsgl,fpmuldbl,fpsqrtsgl,fpsqrtdbl,fpdivsgl,fpdivdbl,fpstore_load,store_fpload") - (eq_attr "cpu" "8000")) - "inm_8000,rnm_8000") - -;; Branches use both slots in the non-memory issue and -;; retirement unit. -(define_insn_reservation "Z4" 0 - (and - (eq_attr "type" "uncond_branch,btable_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch") - (eq_attr "cpu" "8000")) - "inm0_8000+inm1_8000,rnm0_8000+rnm1_8000") - -;; We partial latency schedule the floating point units. -;; They can issue/retire two at a time in the non-memory -;; units. We fix their latency at 2 cycles and they -;; are fully pipelined. -(define_insn_reservation "Z5" 1 - (and - (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl") - (eq_attr "cpu" "8000")) - "inm_8000,f_8000,rnm_8000") - -;; The fdivsqrt units are not pipelined and have a very long latency. -;; To keep the DFA from exploding, we do not show all the -;; reservations for the divsqrt unit. -(define_insn_reservation "Z6" 17 - (and - (eq_attr "type" "fpdivsgl,fpsqrtsgl") - (eq_attr "cpu" "8000")) - "inm_8000,fdivsqrt_8000*6,rnm_8000") - -(define_insn_reservation "Z7" 31 - (and - (eq_attr "type" "fpdivdbl,fpsqrtdbl") - (eq_attr "cpu" "8000")) - "inm_8000,fdivsqrt_8000*6,rnm_8000") - -;; Operand and operator predicates and constraints - -(include "predicates.md") -(include "constraints.md") - -;; Atomic instructions - -;; All memory loads and stores access storage atomically except -;; for one exception. The STORE BYTES, STORE DOUBLE BYTES, and -;; doubleword loads and stores are not guaranteed to be atomic -;; when referencing the I/O address space. - -;; Implement atomic DImode load using 64-bit floating point load and copy. - -(define_expand "atomic_loaddi" - [(match_operand:DI 0 "register_operand") ;; val out - (match_operand:DI 1 "memory_operand") ;; memory - (match_operand:SI 2 "const_int_operand")] ;; model - "!TARGET_64BIT && !TARGET_SOFT_FLOAT" -{ - enum memmodel model = (enum memmodel) INTVAL (operands[2]); - operands[1] = force_reg (SImode, XEXP (operands[1], 0)); - operands[2] = gen_reg_rtx (DImode); - expand_mem_thread_fence (model); - emit_insn (gen_atomic_loaddi_1 (operands[0], operands[1], operands[2])); - if ((model & MEMMODEL_MASK) == MEMMODEL_SEQ_CST) - expand_mem_thread_fence (model); - DONE; -}) - -(define_insn "atomic_loaddi_1" - [(set (match_operand:DI 0 "register_operand" "=r") - (mem:DI (match_operand:SI 1 "register_operand" "r"))) - (clobber (match_operand:DI 2 "register_operand" "=&f"))] - "!TARGET_64BIT && !TARGET_SOFT_FLOAT" - "{fldds|fldd} 0(%1),%2\;{fstds|fstd} %2,-16(%%sp)\;{ldws|ldw} -16(%%sp),%0\;{ldws|ldw} -12(%%sp),%R0" - [(set_attr "type" "move") - (set_attr "length" "16")]) - -;; Implement atomic DImode store using copy and 64-bit floating point store. - -(define_expand "atomic_storedi" - [(match_operand:DI 0 "memory_operand") ;; memory - (match_operand:DI 1 "register_operand") ;; val out - (match_operand:SI 2 "const_int_operand")] ;; model - "!TARGET_64BIT && !TARGET_SOFT_FLOAT" -{ - enum memmodel model = (enum memmodel) INTVAL (operands[2]); - operands[0] = force_reg (SImode, XEXP (operands[0], 0)); - operands[2] = gen_reg_rtx (DImode); - expand_mem_thread_fence (model); - emit_insn (gen_atomic_storedi_1 (operands[0], operands[1], operands[2])); - if ((model & MEMMODEL_MASK) == MEMMODEL_SEQ_CST) - expand_mem_thread_fence (model); - DONE; -}) - -(define_insn "atomic_storedi_1" - [(set (mem:DI (match_operand:SI 0 "register_operand" "r")) - (match_operand:DI 1 "register_operand" "r")) - (clobber (match_operand:DI 2 "register_operand" "=&f"))] - "!TARGET_64BIT && !TARGET_SOFT_FLOAT" - "{stws|stw} %1,-16(%%sp)\;{stws|stw} %R1,-12(%%sp)\;{fldds|fldd} -16(%%sp),%2\;{fstds|fstd} %2,0(%0)" - [(set_attr "type" "move") - (set_attr "length" "16")]) - -;; Compare instructions. -;; This controls RTL generation and register allocation. - -(define_insn "" - [(set (reg:CCFP 0) - (match_operator:CCFP 2 "comparison_operator" - [(match_operand:SF 0 "reg_or_0_operand" "fG") - (match_operand:SF 1 "reg_or_0_operand" "fG")]))] - "! TARGET_SOFT_FLOAT" - "fcmp,sgl,%Y2 %f0,%f1" - [(set_attr "length" "4") - (set_attr "type" "fpcc")]) - -(define_insn "" - [(set (reg:CCFP 0) - (match_operator:CCFP 2 "comparison_operator" - [(match_operand:DF 0 "reg_or_0_operand" "fG") - (match_operand:DF 1 "reg_or_0_operand" "fG")]))] - "! TARGET_SOFT_FLOAT" - "fcmp,dbl,%Y2 %f0,%f1" - [(set_attr "length" "4") - (set_attr "type" "fpcc")]) - -;; Provide a means to emit the movccfp0 and movccfp1 optimization -;; placeholders. This is necessary in rare situations when a -;; placeholder is re-emitted (see PR 8705). - -(define_expand "movccfp" - [(set (reg:CCFP 0) - (match_operand 0 "const_int_operand" ""))] - "! TARGET_SOFT_FLOAT" - " -{ - if ((unsigned HOST_WIDE_INT) INTVAL (operands[0]) > 1) - FAIL; -}") - -;; The following patterns are optimization placeholders. In almost -;; all cases, the user of the condition code will be simplified and the -;; original condition code setting insn should be eliminated. - -(define_insn "*movccfp0" - [(set (reg:CCFP 0) - (const_int 0))] - "! TARGET_SOFT_FLOAT" - "fcmp,dbl,= %%fr0,%%fr0" - [(set_attr "length" "4") - (set_attr "type" "fpcc")]) - -(define_insn "*movccfp1" - [(set (reg:CCFP 0) - (const_int 1))] - "! TARGET_SOFT_FLOAT" - "fcmp,dbl,!= %%fr0,%%fr0" - [(set_attr "length" "4") - (set_attr "type" "fpcc")]) - -;; scc insns. - -(define_expand "cstoresi4" - [(set (match_operand:SI 0 "register_operand") - (match_operator:SI 1 "ordered_comparison_operator" - [(match_operand:SI 2 "reg_or_0_operand" "") - (match_operand:SI 3 "arith5_operand" "")]))] - "!TARGET_64BIT" - "") - -;; Instruction canonicalization puts immediate operands second, which -;; is the reverse of what we want. - -(define_insn "scc" - [(set (match_operand:SI 0 "register_operand" "=r") - (match_operator:SI 3 "comparison_operator" - [(match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "arith11_operand" "rI")]))] - "" - "{com%I2clr|cmp%I2clr},%B3 %2,%1,%0\;ldi 1,%0" - [(set_attr "type" "binary") - (set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (match_operator:DI 3 "comparison_operator" - [(match_operand:DI 1 "register_operand" "r") - (match_operand:DI 2 "arith11_operand" "rI")]))] - "TARGET_64BIT" - "cmp%I2clr,*%B3 %2,%1,%0\;ldi 1,%0" - [(set_attr "type" "binary") - (set_attr "length" "8")]) - -(define_insn "iorscc" - [(set (match_operand:SI 0 "register_operand" "=r") - (ior:SI (match_operator:SI 3 "comparison_operator" - [(match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "arith11_operand" "rI")]) - (match_operator:SI 6 "comparison_operator" - [(match_operand:SI 4 "register_operand" "r") - (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" - [(set_attr "type" "binary") - (set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (ior:DI (match_operator:DI 3 "comparison_operator" - [(match_operand:DI 1 "register_operand" "r") - (match_operand:DI 2 "arith11_operand" "rI")]) - (match_operator:DI 6 "comparison_operator" - [(match_operand:DI 4 "register_operand" "r") - (match_operand:DI 5 "arith11_operand" "rI")])))] - "TARGET_64BIT" - "cmp%I2clr,*%S3 %2,%1,%%r0\;cmp%I5clr,*%B6 %5,%4,%0\;ldi 1,%0" - [(set_attr "type" "binary") - (set_attr "length" "12")]) - -;; Combiner patterns for common operations performed with the output -;; from an scc insn (negscc and incscc). -(define_insn "negscc" - [(set (match_operand:SI 0 "register_operand" "=r") - (neg:SI (match_operator:SI 3 "comparison_operator" - [(match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "arith11_operand" "rI")])))] - "" - "{com%I2clr|cmp%I2clr},%B3 %2,%1,%0\;ldi -1,%0" - [(set_attr "type" "binary") - (set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (neg:DI (match_operator:DI 3 "comparison_operator" - [(match_operand:DI 1 "register_operand" "r") - (match_operand:DI 2 "arith11_operand" "rI")])))] - "TARGET_64BIT" - "cmp%I2clr,*%B3 %2,%1,%0\;ldi -1,%0" - [(set_attr "type" "binary") - (set_attr "length" "8")]) - -;; Patterns for adding/subtracting the result of a boolean expression from -;; 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 -;; general do in two instructions, the incscc pattern at the end outputs -;; two or three instructions. - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (plus:SI (leu:SI (match_operand:SI 2 "register_operand" "r") - (match_operand:SI 3 "arith11_operand" "rI")) - (match_operand:SI 1 "register_operand" "r")))] - "" - "sub%I3 %3,%2,%%r0\;{addc|add,c} %%r0,%1,%0" - [(set_attr "type" "binary") - (set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (plus:DI (leu:DI (match_operand:DI 2 "register_operand" "r") - (match_operand:DI 3 "arith11_operand" "rI")) - (match_operand:DI 1 "register_operand" "r")))] - "TARGET_64BIT" - "sub%I3 %3,%2,%%r0\;add,dc %%r0,%1,%0" - [(set_attr "type" "binary") - (set_attr "length" "8")]) - -; This need only accept registers for op3, since canonicalization -; replaces geu with gtu when op3 is an integer. -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (plus:SI (geu:SI (match_operand:SI 2 "register_operand" "r") - (match_operand:SI 3 "register_operand" "r")) - (match_operand:SI 1 "register_operand" "r")))] - "" - "sub %2,%3,%%r0\;{addc|add,c} %%r0,%1,%0" - [(set_attr "type" "binary") - (set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (plus:DI (geu:DI (match_operand:DI 2 "register_operand" "r") - (match_operand:DI 3 "register_operand" "r")) - (match_operand:DI 1 "register_operand" "r")))] - "TARGET_64BIT" - "sub %2,%3,%%r0\;add,dc %%r0,%1,%0" - [(set_attr "type" "binary") - (set_attr "length" "8")]) - -; 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 -; make better code than the general incscc pattern. -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (plus:SI (gtu:SI (match_operand:SI 2 "register_operand" "r") - (match_operand:SI 3 "int11_operand" "I")) - (match_operand:SI 1 "register_operand" "r")))] - "" - "addi %k3,%2,%%r0\;{addc|add,c} %%r0,%1,%0" - [(set_attr "type" "binary") - (set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (plus:DI (gtu:DI (match_operand:DI 2 "register_operand" "r") - (match_operand:DI 3 "int11_operand" "I")) - (match_operand:DI 1 "register_operand" "r")))] - "TARGET_64BIT" - "addi %k3,%2,%%r0\;add,dc %%r0,%1,%0" - [(set_attr "type" "binary") - (set_attr "length" "8")]) - -(define_insn "incscc" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (plus:SI (match_operator:SI 4 "comparison_operator" - [(match_operand:SI 2 "register_operand" "r,r") - (match_operand:SI 3 "arith11_operand" "rI,rI")]) - (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,tr 1,%1,%0\;copy %1,%0" - [(set_attr "type" "binary,binary") - (set_attr "length" "8,12")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r,r") - (plus:DI (match_operator:DI 4 "comparison_operator" - [(match_operand:DI 2 "register_operand" "r,r") - (match_operand:DI 3 "arith11_operand" "rI,rI")]) - (match_operand:DI 1 "register_operand" "0,?r")))] - "TARGET_64BIT" - "@ - cmp%I3clr,*%B4 %3,%2,%%r0\;addi 1,%0,%0 - cmp%I3clr,*%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0" - [(set_attr "type" "binary,binary") - (set_attr "length" "8,12")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (minus:SI (match_operand:SI 1 "register_operand" "r") - (gtu:SI (match_operand:SI 2 "register_operand" "r") - (match_operand:SI 3 "arith11_operand" "rI"))))] - "" - "sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0" - [(set_attr "type" "binary") - (set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (minus:DI (match_operand:DI 1 "register_operand" "r") - (gtu:DI (match_operand:DI 2 "register_operand" "r") - (match_operand:DI 3 "arith11_operand" "rI"))))] - "TARGET_64BIT" - "sub%I3 %3,%2,%%r0\;sub,db %1,%%r0,%0" - [(set_attr "type" "binary") - (set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r") - (gtu:SI (match_operand:SI 2 "register_operand" "r") - (match_operand:SI 3 "arith11_operand" "rI"))) - (match_operand:SI 4 "register_operand" "r")))] - "" - "sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%4,%0" - [(set_attr "type" "binary") - (set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r") - (gtu:DI (match_operand:DI 2 "register_operand" "r") - (match_operand:DI 3 "arith11_operand" "rI"))) - (match_operand:DI 4 "register_operand" "r")))] - "TARGET_64BIT" - "sub%I3 %3,%2,%%r0\;sub,db %1,%4,%0" - [(set_attr "type" "binary") - (set_attr "length" "8")]) - -; This need only accept registers for op3, since canonicalization -; replaces ltu with leu when op3 is an integer. -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (minus:SI (match_operand:SI 1 "register_operand" "r") - (ltu:SI (match_operand:SI 2 "register_operand" "r") - (match_operand:SI 3 "register_operand" "r"))))] - "" - "sub %2,%3,%%r0\;{subb|sub,b} %1,%%r0,%0" - [(set_attr "type" "binary") - (set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (minus:DI (match_operand:DI 1 "register_operand" "r") - (ltu:DI (match_operand:DI 2 "register_operand" "r") - (match_operand:DI 3 "register_operand" "r"))))] - "TARGET_64BIT" - "sub %2,%3,%%r0\;sub,db %1,%%r0,%0" - [(set_attr "type" "binary") - (set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r") - (ltu:SI (match_operand:SI 2 "register_operand" "r") - (match_operand:SI 3 "register_operand" "r"))) - (match_operand:SI 4 "register_operand" "r")))] - "" - "sub %2,%3,%%r0\;{subb|sub,b} %1,%4,%0" - [(set_attr "type" "binary") - (set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r") - (ltu:DI (match_operand:DI 2 "register_operand" "r") - (match_operand:DI 3 "register_operand" "r"))) - (match_operand:DI 4 "register_operand" "r")))] - "TARGET_64BIT" - "sub %2,%3,%%r0\;sub,db %1,%4,%0" - [(set_attr "type" "binary") - (set_attr "length" "8")]) - -; 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 -; make better code than the general incscc pattern. -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (minus:SI (match_operand:SI 1 "register_operand" "r") - (leu:SI (match_operand:SI 2 "register_operand" "r") - (match_operand:SI 3 "int11_operand" "I"))))] - "" - "addi %k3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0" - [(set_attr "type" "binary") - (set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (minus:DI (match_operand:DI 1 "register_operand" "r") - (leu:DI (match_operand:DI 2 "register_operand" "r") - (match_operand:DI 3 "int11_operand" "I"))))] - "TARGET_64BIT" - "addi %k3,%2,%%r0\;sub,db %1,%%r0,%0" - [(set_attr "type" "binary") - (set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r") - (leu:SI (match_operand:SI 2 "register_operand" "r") - (match_operand:SI 3 "int11_operand" "I"))) - (match_operand:SI 4 "register_operand" "r")))] - "" - "addi %k3,%2,%%r0\;{subb|sub,b} %1,%4,%0" - [(set_attr "type" "binary") - (set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r") - (leu:DI (match_operand:DI 2 "register_operand" "r") - (match_operand:DI 3 "int11_operand" "I"))) - (match_operand:DI 4 "register_operand" "r")))] - "TARGET_64BIT" - "addi %k3,%2,%%r0\;sub,db %1,%4,%0" - [(set_attr "type" "binary") - (set_attr "length" "8")]) - -(define_insn "decscc" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (minus:SI (match_operand:SI 1 "register_operand" "0,?r") - (match_operator:SI 4 "comparison_operator" - [(match_operand:SI 2 "register_operand" "r,r") - (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,tr -1,%1,%0\;copy %1,%0" - [(set_attr "type" "binary,binary") - (set_attr "length" "8,12")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r,r") - (minus:DI (match_operand:DI 1 "register_operand" "0,?r") - (match_operator:DI 4 "comparison_operator" - [(match_operand:DI 2 "register_operand" "r,r") - (match_operand:DI 3 "arith11_operand" "rI,rI")])))] - "TARGET_64BIT" - "@ - cmp%I3clr,*%B4 %3,%2,%%r0\;addi -1,%0,%0 - cmp%I3clr,*%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0" - [(set_attr "type" "binary,binary") - (set_attr "length" "8,12")]) - -; 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.) - -(define_insn "sminsi3" - [(set (match_operand:SI 0 "register_operand" "=r,r,r") - (smin:SI (match_operand:SI 1 "register_operand" "%0,0,r") - (match_operand:SI 2 "arith11_operand" "r,I,M")))] - "" - "@ - {comclr|cmpclr},> %2,%0,%%r0\;copy %2,%0 - {comiclr|cmpiclr},> %2,%0,%%r0\;ldi %2,%0 - {comclr|cmpclr},> %1,%r2,%0\;copy %1,%0" -[(set_attr "type" "multi,multi,multi") - (set_attr "length" "8,8,8")]) - -(define_insn "smindi3" - [(set (match_operand:DI 0 "register_operand" "=r,r,r") - (smin:DI (match_operand:DI 1 "register_operand" "%0,0,r") - (match_operand:DI 2 "arith11_operand" "r,I,M")))] - "TARGET_64BIT" - "@ - cmpclr,*> %2,%0,%%r0\;copy %2,%0 - cmpiclr,*> %2,%0,%%r0\;ldi %2,%0 - cmpclr,*> %1,%r2,%0\;copy %1,%0" -[(set_attr "type" "multi,multi,multi") - (set_attr "length" "8,8,8")]) - -(define_insn "uminsi3" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (umin:SI (match_operand:SI 1 "register_operand" "%0,0") - (match_operand:SI 2 "arith11_operand" "r,I")))] - "" - "@ - {comclr|cmpclr},>> %2,%0,%%r0\;copy %2,%0 - {comiclr|cmpiclr},>> %2,%0,%%r0\;ldi %2,%0" -[(set_attr "type" "multi,multi") - (set_attr "length" "8,8")]) - -(define_insn "umindi3" - [(set (match_operand:DI 0 "register_operand" "=r,r") - (umin:DI (match_operand:DI 1 "register_operand" "%0,0") - (match_operand:DI 2 "arith11_operand" "r,I")))] - "TARGET_64BIT" - "@ - cmpclr,*>> %2,%0,%%r0\;copy %2,%0 - cmpiclr,*>> %2,%0,%%r0\;ldi %2,%0" -[(set_attr "type" "multi,multi") - (set_attr "length" "8,8")]) - -(define_insn "smaxsi3" - [(set (match_operand:SI 0 "register_operand" "=r,r,r") - (smax:SI (match_operand:SI 1 "register_operand" "%0,0,r") - (match_operand:SI 2 "arith11_operand" "r,I,M")))] - "" - "@ - {comclr|cmpclr},< %2,%0,%%r0\;copy %2,%0 - {comiclr|cmpiclr},< %2,%0,%%r0\;ldi %2,%0 - {comclr|cmpclr},< %1,%r2,%0\;copy %1,%0" -[(set_attr "type" "multi,multi,multi") - (set_attr "length" "8,8,8")]) - -(define_insn "smaxdi3" - [(set (match_operand:DI 0 "register_operand" "=r,r,r") - (smax:DI (match_operand:DI 1 "register_operand" "%0,0,r") - (match_operand:DI 2 "arith11_operand" "r,I,M")))] - "TARGET_64BIT" - "@ - cmpclr,*< %2,%0,%%r0\;copy %2,%0 - cmpiclr,*< %2,%0,%%r0\;ldi %2,%0 - cmpclr,*< %1,%r2,%0\;copy %1,%0" -[(set_attr "type" "multi,multi,multi") - (set_attr "length" "8,8,8")]) - -(define_insn "umaxsi3" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (umax:SI (match_operand:SI 1 "register_operand" "%0,0") - (match_operand:SI 2 "arith11_operand" "r,I")))] - "" - "@ - {comclr|cmpclr},<< %2,%0,%%r0\;copy %2,%0 - {comiclr|cmpiclr},<< %2,%0,%%r0\;ldi %2,%0" -[(set_attr "type" "multi,multi") - (set_attr "length" "8,8")]) - -(define_insn "umaxdi3" - [(set (match_operand:DI 0 "register_operand" "=r,r") - (umax:DI (match_operand:DI 1 "register_operand" "%0,0") - (match_operand:DI 2 "arith11_operand" "r,I")))] - "TARGET_64BIT" - "@ - cmpclr,*<< %2,%0,%%r0\;copy %2,%0 - cmpiclr,*<< %2,%0,%%r0\;ldi %2,%0" -[(set_attr "type" "multi,multi") - (set_attr "length" "8,8")]) - -(define_insn "abssi2" - [(set (match_operand:SI 0 "register_operand" "=r") - (abs:SI (match_operand:SI 1 "register_operand" "r")))] - "" - "or,>= %%r0,%1,%0\;subi 0,%0,%0" - [(set_attr "type" "multi") - (set_attr "length" "8")]) - -(define_insn "absdi2" - [(set (match_operand:DI 0 "register_operand" "=r") - (abs:DI (match_operand:DI 1 "register_operand" "r")))] - "TARGET_64BIT" - "or,*>= %%r0,%1,%0\;subi 0,%0,%0" - [(set_attr "type" "multi") - (set_attr "length" "8")]) - -;;; Experimental conditional move patterns - -(define_expand "movsicc" - [(set (match_operand:SI 0 "register_operand" "") - (if_then_else:SI - (match_operand 1 "comparison_operator" "") - (match_operand:SI 2 "reg_or_cint_move_operand" "") - (match_operand:SI 3 "reg_or_cint_move_operand" "")))] - "" - " -{ - if (GET_MODE (XEXP (operands[1], 0)) != SImode - || GET_MODE (XEXP (operands[1], 0)) != GET_MODE (XEXP (operands[1], 1))) - FAIL; -}") - -;; We used to accept any register for op1. -;; -;; However, it loses sometimes because the compiler will end up using -;; 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. -;; -;; If/when global register allocation supports tying we should allow any -;; register for op1 again. -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") - (if_then_else:SI - (match_operator 2 "comparison_operator" - [(match_operand:SI 3 "register_operand" "r,r,r,r") - (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI")]) - (match_operand:SI 1 "reg_or_cint_move_operand" "0,J,N,K") - (const_int 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\;ldil L'%1,%0 - {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;{zdepi|depwi,z} %Z1,%0" - [(set_attr "type" "multi,multi,multi,nullshift") - (set_attr "length" "8,8,8,8")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r") - (if_then_else:SI - (match_operator 5 "comparison_operator" - [(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 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")))] - "" - "@ - {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\;ldil L'%2,%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\;ldi %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" - [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift") - (set_attr "length" "8,8,8,8,8,8,8,8")]) - -(define_expand "movdicc" - [(set (match_operand:DI 0 "register_operand" "") - (if_then_else:DI - (match_operand 1 "comparison_operator" "") - (match_operand:DI 2 "reg_or_cint_move_operand" "") - (match_operand:DI 3 "reg_or_cint_move_operand" "")))] - "TARGET_64BIT" - " -{ - if (GET_MODE (XEXP (operands[1], 0)) != DImode - || GET_MODE (XEXP (operands[1], 0)) != GET_MODE (XEXP (operands[1], 1))) - FAIL; -}") - -; We need the first constraint alternative in order to avoid -; earlyclobbers on all other alternatives. -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r") - (if_then_else:DI - (match_operator 2 "comparison_operator" - [(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 1 "reg_or_cint_move_operand" "0,r,J,N,K") - (const_int 0)))] - "TARGET_64BIT" - "@ - cmp%I4clr,*%S2 %4,%3,%%r0\;ldi 0,%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\;ldil L'%1,%0 - cmp%I4clr,*%B2 %4,%3,%0\;depdi,z %z1,%0" - [(set_attr "type" "multi,multi,multi,multi,nullshift") - (set_attr "length" "8,8,8,8,8")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r,r") - (if_then_else:DI - (match_operator 5 "comparison_operator" - [(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 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")))] - "TARGET_64BIT" - "@ - cmp%I4clr,*%S5 %4,%3,%%r0\;copy %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\;depdi,z %z2,%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\;ldil L'%1,%0 - cmp%I4clr,*%B5 %4,%3,%%r0\;depdi,z %z1,%0" - [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift") - (set_attr "length" "8,8,8,8,8,8,8,8")]) - -;; Conditional Branches - -(define_expand "cbranchdi4" - [(set (pc) - (if_then_else (match_operator 0 "ordered_comparison_operator" - [(match_operand:DI 1 "reg_or_0_operand" "") - (match_operand:DI 2 "register_operand" "")]) - (label_ref (match_operand 3 "" "")) - (pc)))] - "TARGET_64BIT" - "") - -(define_expand "cbranchsi4" - [(set (pc) - (if_then_else (match_operator 0 "ordered_comparison_operator" - [(match_operand:SI 1 "reg_or_0_operand" "") - (match_operand:SI 2 "arith5_operand" "")]) - (label_ref (match_operand 3 "" "")) - (pc)))] - "" - "") - -(define_expand "cbranchsf4" - [(set (pc) - (if_then_else (match_operator 0 "comparison_operator" - [(match_operand:SF 1 "reg_or_0_operand" "") - (match_operand:SF 2 "reg_or_0_operand" "")]) - (label_ref (match_operand 3 "" "")) - (pc)))] - "" - " -{ - pa_emit_bcond_fp (operands); - DONE; -}") - - -(define_expand "cbranchdf4" - [(set (pc) - (if_then_else (match_operator 0 "comparison_operator" - [(match_operand:DF 1 "reg_or_0_operand" "") - (match_operand:DF 2 "reg_or_0_operand" "")]) - (label_ref (match_operand 3 "" "")) - (pc)))] - "" - " -{ - pa_emit_bcond_fp (operands); - DONE; -}") - -;; Match the branch patterns. - - -;; Note a long backward conditional branch with an annulled delay slot -;; has a length of 12. -(define_insn "" - [(set (pc) - (if_then_else - (match_operator 3 "comparison_operator" - [(match_operand:SI 1 "reg_or_0_operand" "rM") - (match_operand:SI 2 "arith5_operand" "rL")]) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - return pa_output_cbranch (operands, 0, insn); -}" -[(set_attr "type" "cbranch") - (set (attr "length") - (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 24) - (not (match_test "flag_pic")) - (const_int 20)] - (const_int 28)))]) - -;; Match the negated branch. - -(define_insn "" - [(set (pc) - (if_then_else - (match_operator 3 "comparison_operator" - [(match_operand:SI 1 "reg_or_0_operand" "rM") - (match_operand:SI 2 "arith5_operand" "rL")]) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -{ - return pa_output_cbranch (operands, 1, insn); -}" -[(set_attr "type" "cbranch") - (set (attr "length") - (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 24) - (not (match_test "flag_pic")) - (const_int 20)] - (const_int 28)))]) - -(define_insn "" - [(set (pc) - (if_then_else - (match_operator 3 "comparison_operator" - [(match_operand:DI 1 "reg_or_0_operand" "rM") - (match_operand:DI 2 "reg_or_0_operand" "rM")]) - (label_ref (match_operand 0 "" "")) - (pc)))] - "TARGET_64BIT" - "* -{ - return pa_output_cbranch (operands, 0, insn); -}" -[(set_attr "type" "cbranch") - (set (attr "length") - (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 24) - (not (match_test "flag_pic")) - (const_int 20)] - (const_int 28)))]) - -;; Match the negated branch. - -(define_insn "" - [(set (pc) - (if_then_else - (match_operator 3 "comparison_operator" - [(match_operand:DI 1 "reg_or_0_operand" "rM") - (match_operand:DI 2 "reg_or_0_operand" "rM")]) - (pc) - (label_ref (match_operand 0 "" ""))))] - "TARGET_64BIT" - "* -{ - return pa_output_cbranch (operands, 1, insn); -}" -[(set_attr "type" "cbranch") - (set (attr "length") - (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 24) - (not (match_test "flag_pic")) - (const_int 20)] - (const_int 28)))]) -(define_insn "" - [(set (pc) - (if_then_else - (match_operator 3 "cmpib_comparison_operator" - [(match_operand:DI 1 "reg_or_0_operand" "rM") - (match_operand:DI 2 "arith5_operand" "rL")]) - (label_ref (match_operand 0 "" "")) - (pc)))] - "TARGET_64BIT" - "* -{ - return pa_output_cbranch (operands, 0, insn); -}" -[(set_attr "type" "cbranch") - (set (attr "length") - (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 24) - (not (match_test "flag_pic")) - (const_int 20)] - (const_int 28)))]) - -;; Match the negated branch. - -(define_insn "" - [(set (pc) - (if_then_else - (match_operator 3 "cmpib_comparison_operator" - [(match_operand:DI 1 "reg_or_0_operand" "rM") - (match_operand:DI 2 "arith5_operand" "rL")]) - (pc) - (label_ref (match_operand 0 "" ""))))] - "TARGET_64BIT" - "* -{ - return pa_output_cbranch (operands, 1, insn); -}" -[(set_attr "type" "cbranch") - (set (attr "length") - (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 24) - (not (match_test "flag_pic")) - (const_int 20)] - (const_int 28)))]) - -;; Branch on Bit patterns. -(define_insn "" - [(set (pc) - (if_then_else - (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r") - (const_int 1) - (match_operand:SI 1 "uint5_operand" "")) - (const_int 0)) - (label_ref (match_operand 2 "" "")) - (pc)))] - "" - "* -{ - return pa_output_bb (operands, 0, insn, 0); -}" -[(set_attr "type" "cbranch") - (set (attr "length") - (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 24) - (not (match_test "flag_pic")) - (const_int 20)] - (const_int 28)))]) - -(define_insn "" - [(set (pc) - (if_then_else - (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r") - (const_int 1) - (match_operand:DI 1 "uint32_operand" "")) - (const_int 0)) - (label_ref (match_operand 2 "" "")) - (pc)))] - "TARGET_64BIT" - "* -{ - return pa_output_bb (operands, 0, insn, 0); -}" -[(set_attr "type" "cbranch") - (set (attr "length") - (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 24) - (not (match_test "flag_pic")) - (const_int 20)] - (const_int 28)))]) - -(define_insn "" - [(set (pc) - (if_then_else - (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r") - (const_int 1) - (match_operand:SI 1 "uint5_operand" "")) - (const_int 0)) - (pc) - (label_ref (match_operand 2 "" ""))))] - "" - "* -{ - return pa_output_bb (operands, 1, insn, 0); -}" -[(set_attr "type" "cbranch") - (set (attr "length") - (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 24) - (not (match_test "flag_pic")) - (const_int 20)] - (const_int 28)))]) - -(define_insn "" - [(set (pc) - (if_then_else - (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r") - (const_int 1) - (match_operand:DI 1 "uint32_operand" "")) - (const_int 0)) - (pc) - (label_ref (match_operand 2 "" ""))))] - "TARGET_64BIT" - "* -{ - return pa_output_bb (operands, 1, insn, 0); -}" -[(set_attr "type" "cbranch") - (set (attr "length") - (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 24) - (not (match_test "flag_pic")) - (const_int 20)] - (const_int 28)))]) - -(define_insn "" - [(set (pc) - (if_then_else - (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r") - (const_int 1) - (match_operand:SI 1 "uint5_operand" "")) - (const_int 0)) - (label_ref (match_operand 2 "" "")) - (pc)))] - "" - "* -{ - return pa_output_bb (operands, 0, insn, 1); -}" -[(set_attr "type" "cbranch") - (set (attr "length") - (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 24) - (not (match_test "flag_pic")) - (const_int 20)] - (const_int 28)))]) - -(define_insn "" - [(set (pc) - (if_then_else - (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r") - (const_int 1) - (match_operand:DI 1 "uint32_operand" "")) - (const_int 0)) - (label_ref (match_operand 2 "" "")) - (pc)))] - "TARGET_64BIT" - "* -{ - return pa_output_bb (operands, 0, insn, 1); -}" -[(set_attr "type" "cbranch") - (set (attr "length") - (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 24) - (not (match_test "flag_pic")) - (const_int 20)] - (const_int 28)))]) - -(define_insn "" - [(set (pc) - (if_then_else - (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r") - (const_int 1) - (match_operand:SI 1 "uint5_operand" "")) - (const_int 0)) - (pc) - (label_ref (match_operand 2 "" ""))))] - "" - "* -{ - return pa_output_bb (operands, 1, insn, 1); -}" -[(set_attr "type" "cbranch") - (set (attr "length") - (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 24) - (not (match_test "flag_pic")) - (const_int 20)] - (const_int 28)))]) - -(define_insn "" - [(set (pc) - (if_then_else - (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r") - (const_int 1) - (match_operand:DI 1 "uint32_operand" "")) - (const_int 0)) - (pc) - (label_ref (match_operand 2 "" ""))))] - "TARGET_64BIT" - "* -{ - return pa_output_bb (operands, 1, insn, 1); -}" -[(set_attr "type" "cbranch") - (set (attr "length") - (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 24) - (not (match_test "flag_pic")) - (const_int 20)] - (const_int 28)))]) - -;; Branch on Variable Bit patterns. -(define_insn "" - [(set (pc) - (if_then_else - (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r") - (const_int 1) - (match_operand:SI 1 "register_operand" "q")) - (const_int 0)) - (label_ref (match_operand 2 "" "")) - (pc)))] - "" - "* -{ - return pa_output_bvb (operands, 0, insn, 0); -}" -[(set_attr "type" "cbranch") - (set (attr "length") - (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 24) - (not (match_test "flag_pic")) - (const_int 20)] - (const_int 28)))]) - -(define_insn "" - [(set (pc) - (if_then_else - (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r") - (const_int 1) - (match_operand:DI 1 "register_operand" "q")) - (const_int 0)) - (label_ref (match_operand 2 "" "")) - (pc)))] - "TARGET_64BIT" - "* -{ - return pa_output_bvb (operands, 0, insn, 0); -}" -[(set_attr "type" "cbranch") - (set (attr "length") - (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 24) - (not (match_test "flag_pic")) - (const_int 20)] - (const_int 28)))]) - -(define_insn "" - [(set (pc) - (if_then_else - (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r") - (const_int 1) - (match_operand:SI 1 "register_operand" "q")) - (const_int 0)) - (pc) - (label_ref (match_operand 2 "" ""))))] - "" - "* -{ - return pa_output_bvb (operands, 1, insn, 0); -}" -[(set_attr "type" "cbranch") - (set (attr "length") - (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 24) - (not (match_test "flag_pic")) - (const_int 20)] - (const_int 28)))]) - -(define_insn "" - [(set (pc) - (if_then_else - (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r") - (const_int 1) - (match_operand:DI 1 "register_operand" "q")) - (const_int 0)) - (pc) - (label_ref (match_operand 2 "" ""))))] - "TARGET_64BIT" - "* -{ - return pa_output_bvb (operands, 1, insn, 0); -}" -[(set_attr "type" "cbranch") - (set (attr "length") - (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 24) - (not (match_test "flag_pic")) - (const_int 20)] - (const_int 28)))]) - -(define_insn "" - [(set (pc) - (if_then_else - (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r") - (const_int 1) - (match_operand:SI 1 "register_operand" "q")) - (const_int 0)) - (label_ref (match_operand 2 "" "")) - (pc)))] - "" - "* -{ - return pa_output_bvb (operands, 0, insn, 1); -}" -[(set_attr "type" "cbranch") - (set (attr "length") - (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 24) - (not (match_test "flag_pic")) - (const_int 20)] - (const_int 28)))]) - -(define_insn "" - [(set (pc) - (if_then_else - (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r") - (const_int 1) - (match_operand:DI 1 "register_operand" "q")) - (const_int 0)) - (label_ref (match_operand 2 "" "")) - (pc)))] - "TARGET_64BIT" - "* -{ - return pa_output_bvb (operands, 0, insn, 1); -}" -[(set_attr "type" "cbranch") - (set (attr "length") - (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 24) - (not (match_test "flag_pic")) - (const_int 20)] - (const_int 28)))]) - -(define_insn "" - [(set (pc) - (if_then_else - (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r") - (const_int 1) - (match_operand:SI 1 "register_operand" "q")) - (const_int 0)) - (pc) - (label_ref (match_operand 2 "" ""))))] - "" - "* -{ - return pa_output_bvb (operands, 1, insn, 1); -}" -[(set_attr "type" "cbranch") - (set (attr "length") - (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 24) - (not (match_test "flag_pic")) - (const_int 20)] - (const_int 28)))]) - -(define_insn "" - [(set (pc) - (if_then_else - (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r") - (const_int 1) - (match_operand:DI 1 "register_operand" "q")) - (const_int 0)) - (pc) - (label_ref (match_operand 2 "" ""))))] - "TARGET_64BIT" - "* -{ - return pa_output_bvb (operands, 1, insn, 1); -}" -[(set_attr "type" "cbranch") - (set (attr "length") - (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 24) - (not (match_test "flag_pic")) - (const_int 20)] - (const_int 28)))]) - -;; Floating point branches - -;; ??? Nullification is handled differently from other branches. -;; If nullification is specified, the delay slot is nullified on any -;; taken branch regardless of branch direction. -(define_insn "" - [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "!TARGET_SOFT_FLOAT" - "* -{ - int length = get_attr_length (insn); - rtx xoperands[1]; - int nullify, xdelay; - - if (length < 16) - return \"ftest\;b%* %l0\"; - - if (dbr_sequence_length () == 0 || INSN_ANNULLED_BRANCH_P (insn)) - { - nullify = 1; - xdelay = 0; - xoperands[0] = GEN_INT (length - 8); - } - else - { - nullify = 0; - xdelay = 1; - xoperands[0] = GEN_INT (length - 4); - } - - if (nullify) - output_asm_insn (\"ftest\;add,tr %%r0,%%r0,%%r0\;b,n .+%0\", xoperands); - else - output_asm_insn (\"ftest\;add,tr %%r0,%%r0,%%r0\;b .+%0\", xoperands); - return pa_output_lbranch (operands[0], insn, xdelay); -}" -[(set_attr "type" "fbranch") - (set (attr "length") - (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 32) - (not (match_test "flag_pic")) - (const_int 28)] - (const_int 36)))]) - -(define_insn "" - [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "!TARGET_SOFT_FLOAT" - "* -{ - int length = get_attr_length (insn); - rtx xoperands[1]; - int nullify, xdelay; - - if (length < 16) - return \"ftest\;add,tr %%r0,%%r0,%%r0\;b%* %0\"; - - if (dbr_sequence_length () == 0 || INSN_ANNULLED_BRANCH_P (insn)) - { - nullify = 1; - xdelay = 0; - xoperands[0] = GEN_INT (length - 4); - } - else - { - nullify = 0; - xdelay = 1; - xoperands[0] = GEN_INT (length); - } - - if (nullify) - output_asm_insn (\"ftest\;b,n .+%0\", xoperands); - else - output_asm_insn (\"ftest\;b .+%0\", xoperands); - return pa_output_lbranch (operands[0], insn, xdelay); -}" -[(set_attr "type" "fbranch") - (set (attr "length") - (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 12) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 28) - (not (match_test "flag_pic")) - (const_int 24)] - (const_int 32)))]) - -;; Move instructions - -(define_expand "movsi" - [(set (match_operand:SI 0 "general_operand" "") - (match_operand:SI 1 "general_operand" ""))] - "" - " -{ - if (pa_emit_move_sequence (operands, SImode, 0)) - DONE; -}") - -;; Handle SImode input reloads requiring %r1 as a scratch register. -(define_expand "reload_insi_r1" - [(set (match_operand:SI 0 "register_operand" "=Z") - (match_operand:SI 1 "non_hard_reg_operand" "")) - (clobber (match_operand:SI 2 "register_operand" "=&a"))] - "" - " -{ - if (pa_emit_move_sequence (operands, SImode, operands[2])) - DONE; - - /* We don't want the clobber emitted, so handle this ourselves. */ - emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); - DONE; -}") - -;; Handle SImode input reloads requiring a general register as a -;; scratch register. -(define_expand "reload_insi" - [(set (match_operand:SI 0 "register_operand" "=Z") - (match_operand:SI 1 "non_hard_reg_operand" "")) - (clobber (match_operand:SI 2 "register_operand" "=&r"))] - "" - " -{ - if (pa_emit_move_sequence (operands, SImode, operands[2])) - DONE; - - /* We don't want the clobber emitted, so handle this ourselves. */ - emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); - DONE; -}") - -;; Handle SImode output reloads requiring a general register as a -;; scratch register. -(define_expand "reload_outsi" - [(set (match_operand:SI 0 "non_hard_reg_operand" "") - (match_operand:SI 1 "register_operand" "Z")) - (clobber (match_operand:SI 2 "register_operand" "=&r"))] - "" - " -{ - if (pa_emit_move_sequence (operands, SImode, operands[2])) - DONE; - - /* We don't want the clobber emitted, so handle this ourselves. */ - emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); - DONE; -}") - -(define_insn "" - [(set (match_operand:SI 0 "move_dest_operand" - "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T,?r,?*f") - (match_operand:SI 1 "move_src_operand" - "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f,*f,r"))] - "(register_operand (operands[0], SImode) - || reg_or_0_operand (operands[1], SImode)) - && !TARGET_SOFT_FLOAT - && !TARGET_64BIT" - "@ - ldw RT'%A1,%0 - copy %1,%0 - ldi %1,%0 - ldil L'%1,%0 - {zdepi|depwi,z} %Z1,%0 - ldw%M1 %1,%0 - stw%M0 %r1,%0 - mtsar %r1 - {mfctl|mfctl,w} %%sar,%0 - fcpy,sgl %f1,%0 - fldw%F1 %1,%0 - fstw%F0 %1,%0 - {fstws|fstw} %1,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0 - {stws|stw} %1,-16(%%sp)\n\t{fldws|fldw} -16(%%sp),%0" - [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore,fpstore_load,store_fpload") - (set_attr "pa_combine_type" "addmove") - (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,8,8")]) - -(define_insn "" - [(set (match_operand:SI 0 "move_dest_operand" - "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T") - (match_operand:SI 1 "move_src_operand" - "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f"))] - "(register_operand (operands[0], SImode) - || reg_or_0_operand (operands[1], SImode)) - && !TARGET_SOFT_FLOAT - && TARGET_64BIT" - "@ - ldw RT'%A1,%0 - copy %1,%0 - ldi %1,%0 - ldil L'%1,%0 - {zdepi|depwi,z} %Z1,%0 - ldw%M1 %1,%0 - stw%M0 %r1,%0 - mtsar %r1 - {mfctl|mfctl,w} %%sar,%0 - fcpy,sgl %f1,%0 - fldw%F1 %1,%0 - fstw%F0 %1,%0" - [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore") - (set_attr "pa_combine_type" "addmove") - (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4")]) - -(define_insn "" - [(set (match_operand:SI 0 "indexed_memory_operand" "=R") - (match_operand:SI 1 "register_operand" "f"))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && reload_completed" - "fstw%F0 %1,%0" - [(set_attr "type" "fpstore") - (set_attr "pa_combine_type" "addmove") - (set_attr "length" "4")]) - -; 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. -(define_peephole2 - [(set (match_operand:SI 0 "register_operand" "") - (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "") - (const_int 4)) - (match_operand:SI 2 "register_operand" ""))) - (set (mem:SI (match_dup 0)) - (match_operand:SI 3 "register_operand" ""))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && REG_OK_FOR_BASE_P (operands[2]) - && FP_REGNO_P (REGNO (operands[3]))" - [(set (mem:SI (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2))) - (match_dup 3)) - (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4)) - (match_dup 2)))] - "") - -(define_peephole2 - [(set (match_operand:SI 0 "register_operand" "") - (plus:SI (match_operand:SI 2 "register_operand" "") - (mult:SI (match_operand:SI 1 "register_operand" "") - (const_int 4)))) - (set (mem:SI (match_dup 0)) - (match_operand:SI 3 "register_operand" ""))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && REG_OK_FOR_BASE_P (operands[2]) - && FP_REGNO_P (REGNO (operands[3]))" - [(set (mem:SI (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2))) - (match_dup 3)) - (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4)) - (match_dup 2)))] - "") - -(define_peephole2 - [(set (match_operand:DI 0 "register_operand" "") - (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "") - (const_int 4)) - (match_operand:DI 2 "register_operand" ""))) - (set (mem:SI (match_dup 0)) - (match_operand:SI 3 "register_operand" ""))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && TARGET_64BIT - && REG_OK_FOR_BASE_P (operands[2]) - && FP_REGNO_P (REGNO (operands[3]))" - [(set (mem:SI (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2))) - (match_dup 3)) - (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4)) - (match_dup 2)))] - "") - -(define_peephole2 - [(set (match_operand:DI 0 "register_operand" "") - (plus:DI (match_operand:DI 2 "register_operand" "") - (mult:DI (match_operand:DI 1 "register_operand" "") - (const_int 4)))) - (set (mem:SI (match_dup 0)) - (match_operand:SI 3 "register_operand" ""))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && TARGET_64BIT - && REG_OK_FOR_BASE_P (operands[2]) - && FP_REGNO_P (REGNO (operands[3]))" - [(set (mem:SI (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2))) - (match_dup 3)) - (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4)) - (match_dup 2)))] - "") - -(define_peephole2 - [(set (match_operand:SI 0 "register_operand" "") - (plus:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "register_operand" ""))) - (set (mem:SI (match_dup 0)) - (match_operand:SI 3 "register_operand" ""))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && TARGET_NO_SPACE_REGS - && REG_OK_FOR_INDEX_P (operands[1]) - && REG_OK_FOR_BASE_P (operands[2]) - && FP_REGNO_P (REGNO (operands[3]))" - [(set (mem:SI (plus:SI (match_dup 1) (match_dup 2))) - (match_dup 3)) - (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))] - "") - -(define_peephole2 - [(set (match_operand:SI 0 "register_operand" "") - (plus:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "register_operand" ""))) - (set (mem:SI (match_dup 0)) - (match_operand:SI 3 "register_operand" ""))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && TARGET_NO_SPACE_REGS - && REG_OK_FOR_BASE_P (operands[1]) - && REG_OK_FOR_INDEX_P (operands[2]) - && FP_REGNO_P (REGNO (operands[3]))" - [(set (mem:SI (plus:SI (match_dup 2) (match_dup 1))) - (match_dup 3)) - (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))] - "") - -(define_peephole2 - [(set (match_operand:DI 0 "register_operand" "") - (plus:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "register_operand" ""))) - (set (mem:SI (match_dup 0)) - (match_operand:SI 3 "register_operand" ""))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && TARGET_64BIT - && TARGET_NO_SPACE_REGS - && REG_OK_FOR_INDEX_P (operands[1]) - && REG_OK_FOR_BASE_P (operands[2]) - && FP_REGNO_P (REGNO (operands[3]))" - [(set (mem:SI (plus:DI (match_dup 1) (match_dup 2))) - (match_dup 3)) - (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))] - "") - -(define_peephole2 - [(set (match_operand:DI 0 "register_operand" "") - (plus:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "register_operand" ""))) - (set (mem:SI (match_dup 0)) - (match_operand:SI 3 "register_operand" ""))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && TARGET_64BIT - && TARGET_NO_SPACE_REGS - && REG_OK_FOR_BASE_P (operands[1]) - && REG_OK_FOR_INDEX_P (operands[2]) - && FP_REGNO_P (REGNO (operands[3]))" - [(set (mem:SI (plus:DI (match_dup 2) (match_dup 1))) - (match_dup 3)) - (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))] - "") - -(define_insn "" - [(set (match_operand:SI 0 "move_dest_operand" - "=r,r,r,r,r,r,Q,!*q,!r") - (match_operand:SI 1 "move_src_operand" - "A,r,J,N,K,RQ,rM,!rM,!*q"))] - "(register_operand (operands[0], SImode) - || reg_or_0_operand (operands[1], SImode)) - && TARGET_SOFT_FLOAT" - "@ - ldw RT'%A1,%0 - copy %1,%0 - ldi %1,%0 - ldil L'%1,%0 - {zdepi|depwi,z} %Z1,%0 - ldw%M1 %1,%0 - stw%M0 %r1,%0 - mtsar %r1 - {mfctl|mfctl,w} %%sar,%0" - [(set_attr "type" "load,move,move,move,move,load,store,move,move") - (set_attr "pa_combine_type" "addmove") - (set_attr "length" "4,4,4,4,4,4,4,4,4")]) - -;; Load or store with base-register modification. -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (mem:SI (plus:DI (match_operand:DI 1 "register_operand" "+r") - (match_operand:DI 2 "int5_operand" "L")))) - (set (match_dup 1) - (plus:DI (match_dup 1) (match_dup 2)))] - "TARGET_64BIT" - "ldw,mb %2(%1),%0" - [(set_attr "type" "load") - (set_attr "length" "4")]) - -; And a zero extended variant. -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (zero_extend:DI (mem:SI - (plus:DI - (match_operand:DI 1 "register_operand" "+r") - (match_operand:DI 2 "int5_operand" "L"))))) - (set (match_dup 1) - (plus:DI (match_dup 1) (match_dup 2)))] - "TARGET_64BIT" - "ldw,mb %2(%1),%0" - [(set_attr "type" "load") - (set_attr "length" "4")]) - -(define_expand "pre_load" - [(parallel [(set (match_operand:SI 0 "register_operand" "") - (mem (plus (match_operand 1 "register_operand" "") - (match_operand 2 "pre_cint_operand" "")))) - (set (match_dup 1) - (plus (match_dup 1) (match_dup 2)))])] - "" - " -{ - if (TARGET_64BIT) - { - emit_insn (gen_pre_ldd (operands[0], operands[1], operands[2])); - DONE; - } - emit_insn (gen_pre_ldw (operands[0], operands[1], operands[2])); - DONE; -}") - -(define_insn "pre_ldw" - [(set (match_operand:SI 0 "register_operand" "=r") - (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "+r") - (match_operand:SI 2 "pre_cint_operand" "")))) - (set (match_dup 1) - (plus:SI (match_dup 1) (match_dup 2)))] - "" - "* -{ - if (INTVAL (operands[2]) < 0) - return \"{ldwm|ldw,mb} %2(%1),%0\"; - return \"{ldws|ldw},mb %2(%1),%0\"; -}" - [(set_attr "type" "load") - (set_attr "length" "4")]) - -(define_insn "pre_ldd" - [(set (match_operand:DI 0 "register_operand" "=r") - (mem:DI (plus:DI (match_operand:DI 1 "register_operand" "+r") - (match_operand:DI 2 "pre_cint_operand" "")))) - (set (match_dup 1) - (plus:DI (match_dup 1) (match_dup 2)))] - "TARGET_64BIT" - "ldd,mb %2(%1),%0" - [(set_attr "type" "load") - (set_attr "length" "4")]) - -(define_insn "" - [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "+r") - (match_operand:SI 1 "pre_cint_operand" ""))) - (match_operand:SI 2 "reg_or_0_operand" "rM")) - (set (match_dup 0) - (plus:SI (match_dup 0) (match_dup 1)))] - "" - "* -{ - if (INTVAL (operands[1]) < 0) - return \"{stwm|stw,mb} %r2,%1(%0)\"; - return \"{stws|stw},mb %r2,%1(%0)\"; -}" - [(set_attr "type" "store") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (mem:SI (match_operand:SI 1 "register_operand" "+r"))) - (set (match_dup 1) - (plus:SI (match_dup 1) - (match_operand:SI 2 "post_cint_operand" "")))] - "" - "* -{ - if (INTVAL (operands[2]) > 0) - return \"{ldwm|ldw,ma} %2(%1),%0\"; - return \"{ldws|ldw},ma %2(%1),%0\"; -}" - [(set_attr "type" "load") - (set_attr "length" "4")]) - -(define_expand "post_store" - [(parallel [(set (mem (match_operand 0 "register_operand" "")) - (match_operand 1 "reg_or_0_operand" "")) - (set (match_dup 0) - (plus (match_dup 0) - (match_operand 2 "post_cint_operand" "")))])] - "" - " -{ - if (TARGET_64BIT) - { - emit_insn (gen_post_std (operands[0], operands[1], operands[2])); - DONE; - } - emit_insn (gen_post_stw (operands[0], operands[1], operands[2])); - DONE; -}") - -(define_insn "post_stw" - [(set (mem:SI (match_operand:SI 0 "register_operand" "+r")) - (match_operand:SI 1 "reg_or_0_operand" "rM")) - (set (match_dup 0) - (plus:SI (match_dup 0) - (match_operand:SI 2 "post_cint_operand" "")))] - "" - "* -{ - if (INTVAL (operands[2]) > 0) - return \"{stwm|stw,ma} %r1,%2(%0)\"; - return \"{stws|stw},ma %r1,%2(%0)\"; -}" - [(set_attr "type" "store") - (set_attr "length" "4")]) - -(define_insn "post_std" - [(set (mem:DI (match_operand:DI 0 "register_operand" "+r")) - (match_operand:DI 1 "reg_or_0_operand" "rM")) - (set (match_dup 0) - (plus:DI (match_dup 0) - (match_operand:DI 2 "post_cint_operand" "")))] - "TARGET_64BIT" - "std,ma %r1,%2(%0)" - [(set_attr "type" "store") - (set_attr "length" "4")]) - -;; For loading the address of a label while generating PIC code. -;; Note since this pattern can be created at reload time (via movsi), all -;; the same rules for movsi apply here. (no new pseudos, no temporaries). -(define_insn "" - [(set (match_operand 0 "pmode_register_operand" "=a") - (match_operand 1 "pic_label_operand" ""))] - "TARGET_PA_20" - "* -{ - rtx xoperands[3]; - - xoperands[0] = operands[0]; - xoperands[1] = operands[1]; - xoperands[2] = gen_label_rtx (); - - (*targetm.asm_out.internal_label) (asm_out_file, \"L\", - CODE_LABEL_NUMBER (xoperands[2])); - output_asm_insn (\"mfia %0\", xoperands); - - /* If we're trying to load the address of a label that happens to be - close, then we can use a shorter sequence. */ - if (GET_CODE (operands[1]) == LABEL_REF - && !LABEL_REF_NONLOCAL_P (operands[1]) - && INSN_ADDRESSES_SET_P () - && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0))) - - INSN_ADDRESSES (INSN_UID (insn))) < 8100) - output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands); - else - { - output_asm_insn (\"addil L%%%1-%2,%0\", xoperands); - output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands); - } - return \"\"; -}" - [(set_attr "type" "multi") - (set_attr "length" "12")]) ; 8 or 12 - -(define_insn "" - [(set (match_operand 0 "pmode_register_operand" "=a") - (match_operand 1 "pic_label_operand" ""))] - "!TARGET_PA_20" - "* -{ - rtx xoperands[3]; - - xoperands[0] = operands[0]; - xoperands[1] = operands[1]; - xoperands[2] = gen_label_rtx (); - - output_asm_insn (\"bl .+8,%0\", xoperands); - output_asm_insn (\"depi 0,31,2,%0\", xoperands); - (*targetm.asm_out.internal_label) (asm_out_file, \"L\", - CODE_LABEL_NUMBER (xoperands[2])); - - /* If we're trying to load the address of a label that happens to be - close, then we can use a shorter sequence. */ - if (GET_CODE (operands[1]) == LABEL_REF - && !LABEL_REF_NONLOCAL_P (operands[1]) - && INSN_ADDRESSES_SET_P () - && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0))) - - INSN_ADDRESSES (INSN_UID (insn))) < 8100) - output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands); - else - { - output_asm_insn (\"addil L%%%1-%2,%0\", xoperands); - output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands); - } - return \"\"; -}" - [(set_attr "type" "multi") - (set_attr "length" "16")]) ; 12 or 16 - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=a") - (plus:SI (match_operand:SI 1 "register_operand" "r") - (high:SI (match_operand 2 "" ""))))] - "symbolic_operand (operands[2], Pmode) - && ! function_label_operand (operands[2], Pmode) - && flag_pic" - "addil LT'%G2,%1" - [(set_attr "type" "binary") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=a") - (plus:DI (match_operand:DI 1 "register_operand" "r") - (high:DI (match_operand 2 "" ""))))] - "symbolic_operand (operands[2], Pmode) - && ! function_label_operand (operands[2], Pmode) - && TARGET_64BIT - && flag_pic" - "addil LT'%G2,%1" - [(set_attr "type" "binary") - (set_attr "length" "4")]) - -;; Always use addil rather than ldil;add sequences. This allows the -;; HP linker to eliminate the dp relocation if the symbolic operand -;; lives in the TEXT space. -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=a") - (high:SI (match_operand 1 "" "")))] - "symbolic_operand (operands[1], Pmode) - && ! function_label_operand (operands[1], Pmode) - && ! read_only_operand (operands[1], Pmode) - && ! flag_pic" - "* -{ - if (TARGET_LONG_LOAD_STORE) - return \"addil NLR'%H1,%%r27\;ldo N'%H1(%%r1),%%r1\"; - else - return \"addil LR'%H1,%%r27\"; -}" - [(set_attr "type" "binary") - (set (attr "length") - (if_then_else (not (match_test "TARGET_LONG_LOAD_STORE")) - (const_int 4) - (const_int 8)))]) - - -;; This is for use in the prologue/epilogue code. We need it -;; to add large constants to a stack pointer or frame pointer. -;; Because of the additional %r1 pressure, we probably do not -;; want to use this in general code, so make it available -;; only after reload. -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=!a,*r") - (plus:SI (match_operand:SI 1 "register_operand" "r,r") - (high:SI (match_operand 2 "const_int_operand" ""))))] - "reload_completed" - "@ - addil L'%G2,%1 - ldil L'%G2,%0\;{addl|add,l} %0,%1,%0" - [(set_attr "type" "binary,binary") - (set_attr "length" "4,8")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=!a,*r") - (plus:DI (match_operand:DI 1 "register_operand" "r,r") - (high:DI (match_operand 2 "const_int_operand" ""))))] - "reload_completed && TARGET_64BIT" - "@ - addil L'%G2,%1 - ldil L'%G2,%0\;{addl|add,l} %0,%1,%0" - [(set_attr "type" "binary,binary") - (set_attr "length" "4,8")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (high:SI (match_operand 1 "" "")))] - "(!flag_pic || !symbolic_operand (operands[1], Pmode)) - && !pa_is_function_label_plus_const (operands[1])" - "* -{ - if (symbolic_operand (operands[1], Pmode)) - return \"ldil LR'%H1,%0\"; - else - return \"ldil L'%G1,%0\"; -}" - [(set_attr "type" "move") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (high:DI (match_operand 1 "const_int_operand" "")))] - "TARGET_64BIT" - "ldil L'%G1,%0"; - [(set_attr "type" "move") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (lo_sum:DI (match_operand:DI 1 "register_operand" "r") - (match_operand:DI 2 "const_int_operand" "i")))] - "TARGET_64BIT" - "ldo R'%G2(%1),%0"; - [(set_attr "type" "move") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (lo_sum:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "immediate_operand" "i")))] - "!pa_is_function_label_plus_const (operands[2])" - "* -{ - gcc_assert (!flag_pic || !symbolic_operand (operands[2], Pmode)); - - if (symbolic_operand (operands[2], Pmode)) - return \"ldo RR'%G2(%1),%0\"; - else - return \"ldo R'%G2(%1),%0\"; -}" - [(set_attr "type" "move") - (set_attr "length" "4")]) - -;; Now that a symbolic_address plus a constant is broken up early -;; in the compilation phase (for better CSE) we need a special -;; combiner pattern to load the symbolic address plus the constant -;; in only 2 instructions. (For cases where the symbolic address -;; was not a common subexpression.) -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (match_operand:SI 1 "symbolic_operand" "")) - (clobber (match_operand:SI 2 "register_operand" ""))] - "! (flag_pic && pic_label_operand (operands[1], SImode))" - [(set (match_dup 2) (high:SI (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 -;; create addresses which use indexing. In some cases, this -;; is a lose because there isn't any store instructions which -;; allow indexed addresses (with integer register source). -;; -;; These define_splits try to turn a 3 insn store into -;; a 2 insn store with some creative RTL rewriting. -(define_split - [(set (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "") - (match_operand:SI 1 "shadd_operand" "")) - (plus:SI (match_operand:SI 2 "register_operand" "") - (match_operand:SI 3 "const_int_operand" "")))) - (match_operand:SI 4 "register_operand" "")) - (clobber (match_operand:SI 5 "register_operand" ""))] - "" - [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1)) - (match_dup 2))) - (set (mem:SI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))] - "") - -(define_split - [(set (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "") - (match_operand:SI 1 "shadd_operand" "")) - (plus:SI (match_operand:SI 2 "register_operand" "") - (match_operand:SI 3 "const_int_operand" "")))) - (match_operand:HI 4 "register_operand" "")) - (clobber (match_operand:SI 5 "register_operand" ""))] - "" - [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1)) - (match_dup 2))) - (set (mem:HI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))] - "") - -(define_split - [(set (mem:QI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "") - (match_operand:SI 1 "shadd_operand" "")) - (plus:SI (match_operand:SI 2 "register_operand" "") - (match_operand:SI 3 "const_int_operand" "")))) - (match_operand:QI 4 "register_operand" "")) - (clobber (match_operand:SI 5 "register_operand" ""))] - "" - [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1)) - (match_dup 2))) - (set (mem:QI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))] - "") - -(define_expand "movhi" - [(set (match_operand:HI 0 "general_operand" "") - (match_operand:HI 1 "general_operand" ""))] - "" - " -{ - if (pa_emit_move_sequence (operands, HImode, 0)) - DONE; -}") - -;; Handle HImode input reloads requiring a general register as a -;; scratch register. -(define_expand "reload_inhi" - [(set (match_operand:HI 0 "register_operand" "=Z") - (match_operand:HI 1 "non_hard_reg_operand" "")) - (clobber (match_operand:HI 2 "register_operand" "=&r"))] - "" - " -{ - if (pa_emit_move_sequence (operands, HImode, operands[2])) - DONE; - - /* We don't want the clobber emitted, so handle this ourselves. */ - emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); - DONE; -}") - -;; Handle HImode output reloads requiring a general register as a -;; scratch register. -(define_expand "reload_outhi" - [(set (match_operand:HI 0 "non_hard_reg_operand" "") - (match_operand:HI 1 "register_operand" "Z")) - (clobber (match_operand:HI 2 "register_operand" "=&r"))] - "" - " -{ - if (pa_emit_move_sequence (operands, HImode, operands[2])) - DONE; - - /* We don't want the clobber emitted, so handle this ourselves. */ - emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); - DONE; -}") - -(define_insn "" - [(set (match_operand:HI 0 "move_dest_operand" - "=r,r,r,r,r,Q,!*q,!r") - (match_operand:HI 1 "move_src_operand" - "r,J,N,K,RQ,rM,!rM,!*q"))] - "(register_operand (operands[0], HImode) - || reg_or_0_operand (operands[1], HImode))" - "@ - copy %1,%0 - ldi %1,%0 - ldil L'%1,%0 - {zdepi|depwi,z} %Z1,%0 - ldh%M1 %1,%0 - sth%M0 %r1,%0 - mtsar %r1 - {mfctl|mfctl,w} %sar,%0" - [(set_attr "type" "move,move,move,shift,load,store,move,move") - (set_attr "pa_combine_type" "addmove") - (set_attr "length" "4,4,4,4,4,4,4,4")]) - -(define_insn "" - [(set (match_operand:HI 0 "register_operand" "=r") - (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "+r") - (match_operand:SI 2 "int5_operand" "L")))) - (set (match_dup 1) - (plus:SI (match_dup 1) (match_dup 2)))] - "" - "{ldhs|ldh},mb %2(%1),%0" - [(set_attr "type" "load") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:HI 0 "register_operand" "=r") - (mem:HI (plus:DI (match_operand:DI 1 "register_operand" "+r") - (match_operand:DI 2 "int5_operand" "L")))) - (set (match_dup 1) - (plus:DI (match_dup 1) (match_dup 2)))] - "TARGET_64BIT" - "ldh,mb %2(%1),%0" - [(set_attr "type" "load") - (set_attr "length" "4")]) - -; And a zero extended variant. -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (zero_extend:DI (mem:HI - (plus:DI - (match_operand:DI 1 "register_operand" "+r") - (match_operand:DI 2 "int5_operand" "L"))))) - (set (match_dup 1) - (plus:DI (match_dup 1) (match_dup 2)))] - "TARGET_64BIT" - "ldh,mb %2(%1),%0" - [(set_attr "type" "load") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (zero_extend:SI (mem:HI - (plus:SI - (match_operand:SI 1 "register_operand" "+r") - (match_operand:SI 2 "int5_operand" "L"))))) - (set (match_dup 1) - (plus:SI (match_dup 1) (match_dup 2)))] - "" - "{ldhs|ldh},mb %2(%1),%0" - [(set_attr "type" "load") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (zero_extend:SI (mem:HI - (plus:DI - (match_operand:DI 1 "register_operand" "+r") - (match_operand:DI 2 "int5_operand" "L"))))) - (set (match_dup 1) - (plus:DI (match_dup 1) (match_dup 2)))] - "TARGET_64BIT" - "ldh,mb %2(%1),%0" - [(set_attr "type" "load") - (set_attr "length" "4")]) - -(define_insn "" - [(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "+r") - (match_operand:SI 1 "int5_operand" "L"))) - (match_operand:HI 2 "reg_or_0_operand" "rM")) - (set (match_dup 0) - (plus:SI (match_dup 0) (match_dup 1)))] - "" - "{sths|sth},mb %r2,%1(%0)" - [(set_attr "type" "store") - (set_attr "length" "4")]) - -(define_insn "" - [(set (mem:HI (plus:DI (match_operand:DI 0 "register_operand" "+r") - (match_operand:DI 1 "int5_operand" "L"))) - (match_operand:HI 2 "reg_or_0_operand" "rM")) - (set (match_dup 0) - (plus:DI (match_dup 0) (match_dup 1)))] - "TARGET_64BIT" - "sth,mb %r2,%1(%0)" - [(set_attr "type" "store") - (set_attr "length" "4")]) - -(define_insn "addhi3" - [(set (match_operand:HI 0 "register_operand" "=r,r") - (plus:HI (match_operand:HI 1 "register_operand" "%r,r") - (match_operand:HI 2 "arith14_operand" "r,J")))] - "" - "@ - {addl|add,l} %1,%2,%0 - ldo %2(%1),%0" - [(set_attr "type" "binary,binary") - (set_attr "pa_combine_type" "addmove") - (set_attr "length" "4,4")]) - -(define_expand "movqi" - [(set (match_operand:QI 0 "general_operand" "") - (match_operand:QI 1 "general_operand" ""))] - "" - " -{ - if (pa_emit_move_sequence (operands, QImode, 0)) - DONE; -}") - -;; Handle QImode input reloads requiring a general register as a -;; scratch register. -(define_expand "reload_inqi" - [(set (match_operand:QI 0 "register_operand" "=Z") - (match_operand:QI 1 "non_hard_reg_operand" "")) - (clobber (match_operand:QI 2 "register_operand" "=&r"))] - "" - " -{ - if (pa_emit_move_sequence (operands, QImode, operands[2])) - DONE; - - /* We don't want the clobber emitted, so handle this ourselves. */ - emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); - DONE; -}") - -;; Handle QImode output reloads requiring a general register as a -;; scratch register. -(define_expand "reload_outqi" - [(set (match_operand:QI 0 "non_hard_reg_operand" "") - (match_operand:QI 1 "register_operand" "Z")) - (clobber (match_operand:QI 2 "register_operand" "=&r"))] - "" - " -{ - if (pa_emit_move_sequence (operands, QImode, operands[2])) - DONE; - - /* We don't want the clobber emitted, so handle this ourselves. */ - emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); - DONE; -}") - -(define_insn "" - [(set (match_operand:QI 0 "move_dest_operand" - "=r,r,r,r,r,Q,!*q,!r") - (match_operand:QI 1 "move_src_operand" - "r,J,N,K,RQ,rM,!rM,!*q"))] - "(register_operand (operands[0], QImode) - || reg_or_0_operand (operands[1], QImode))" - "@ - copy %1,%0 - ldi %1,%0 - ldil L'%1,%0 - {zdepi|depwi,z} %Z1,%0 - ldb%M1 %1,%0 - stb%M0 %r1,%0 - mtsar %r1 - {mfctl|mfctl,w} %%sar,%0" - [(set_attr "type" "move,move,move,shift,load,store,move,move") - (set_attr "pa_combine_type" "addmove") - (set_attr "length" "4,4,4,4,4,4,4,4")]) - -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=r") - (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "+r") - (match_operand:SI 2 "int5_operand" "L")))) - (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))] - "" - "{ldbs|ldb},mb %2(%1),%0" - [(set_attr "type" "load") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=r") - (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "+r") - (match_operand:DI 2 "int5_operand" "L")))) - (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))] - "TARGET_64BIT" - "ldb,mb %2(%1),%0" - [(set_attr "type" "load") - (set_attr "length" "4")]) - -; Now the same thing with zero extensions. -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (zero_extend:DI (mem:QI (plus:DI - (match_operand:DI 1 "register_operand" "+r") - (match_operand:DI 2 "int5_operand" "L"))))) - (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))] - "TARGET_64BIT" - "ldb,mb %2(%1),%0" - [(set_attr "type" "load") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (zero_extend:SI (mem:QI (plus:SI - (match_operand:SI 1 "register_operand" "+r") - (match_operand:SI 2 "int5_operand" "L"))))) - (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))] - "" - "{ldbs|ldb},mb %2(%1),%0" - [(set_attr "type" "load") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (zero_extend:SI (mem:QI (plus:DI - (match_operand:DI 1 "register_operand" "+r") - (match_operand:DI 2 "int5_operand" "L"))))) - (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))] - "TARGET_64BIT" - "ldb,mb %2(%1),%0" - [(set_attr "type" "load") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:HI 0 "register_operand" "=r") - (zero_extend:HI (mem:QI (plus:SI - (match_operand:SI 1 "register_operand" "+r") - (match_operand:SI 2 "int5_operand" "L"))))) - (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))] - "" - "{ldbs|ldb},mb %2(%1),%0" - [(set_attr "type" "load") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:HI 0 "register_operand" "=r") - (zero_extend:HI (mem:QI (plus:DI - (match_operand:DI 1 "register_operand" "+r") - (match_operand:DI 2 "int5_operand" "L"))))) - (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))] - "TARGET_64BIT" - "ldb,mb %2(%1),%0" - [(set_attr "type" "load") - (set_attr "length" "4")]) - -(define_insn "" - [(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "+r") - (match_operand:SI 1 "int5_operand" "L"))) - (match_operand:QI 2 "reg_or_0_operand" "rM")) - (set (match_dup 0) - (plus:SI (match_dup 0) (match_dup 1)))] - "" - "{stbs|stb},mb %r2,%1(%0)" - [(set_attr "type" "store") - (set_attr "length" "4")]) - -(define_insn "" - [(set (mem:QI (plus:DI (match_operand:DI 0 "register_operand" "+r") - (match_operand:DI 1 "int5_operand" "L"))) - (match_operand:QI 2 "reg_or_0_operand" "rM")) - (set (match_dup 0) - (plus:DI (match_dup 0) (match_dup 1)))] - "TARGET_64BIT" - "stb,mb %r2,%1(%0)" - [(set_attr "type" "store") - (set_attr "length" "4")]) - -;; The definition of this insn does not really explain what it does, -;; but it should suffice that anything generated as this insn will be -;; recognized as a movmemsi operation, and that it will not successfully -;; combine with anything. -(define_expand "movmemsi" - [(parallel [(set (match_operand:BLK 0 "" "") - (match_operand:BLK 1 "" "")) - (clobber (match_dup 4)) - (clobber (match_dup 5)) - (clobber (match_dup 6)) - (clobber (match_dup 7)) - (clobber (match_dup 8)) - (use (match_operand:SI 2 "arith14_operand" "")) - (use (match_operand:SI 3 "const_int_operand" ""))])] - "!TARGET_64BIT && optimize > 0" - " -{ - int size, align; - - /* HP provides very fast block move library routine for the PA; - this routine includes: - - 4x4 byte at a time block moves, - 1x4 byte at a time with alignment checked at runtime with - attempts to align the source and destination as needed - 1x1 byte loop - - With that in mind, here's the heuristics to try and guess when - the inlined block move will be better than the library block - move: - - 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 - the library routines. - - If the size is small in respect to the known alignment, then open - code the copy (since that will lead to better scheduling). - - Else use the block move pattern. */ - - /* Undetermined size, use the library routine. */ - if (GET_CODE (operands[2]) != CONST_INT) - FAIL; - - size = INTVAL (operands[2]); - align = INTVAL (operands[3]); - align = align > 4 ? 4 : (align ? align : 1); - - /* If size/alignment is large, then use the library routines. */ - if (size / align > 16) - FAIL; - - /* This does happen, but not often enough to worry much about. */ - if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ())) - FAIL; - - /* Fall through means we're going to use our block move pattern. */ - operands[0] - = replace_equiv_address (operands[0], - copy_to_mode_reg (SImode, XEXP (operands[0], 0))); - operands[1] - = replace_equiv_address (operands[1], - copy_to_mode_reg (SImode, XEXP (operands[1], 0))); - operands[4] = gen_reg_rtx (SImode); - operands[5] = gen_reg_rtx (SImode); - operands[6] = gen_reg_rtx (SImode); - operands[7] = gen_reg_rtx (SImode); - operands[8] = gen_reg_rtx (SImode); -}") - -;; The operand constraints are written like this to support both compile-time -;; and run-time determined byte counts. The expander and pa_output_block_move -;; only support compile-time determined counts at this time. -;; -;; 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. -;; -;; 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 -;; 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 -;; forced to internally copy operands 0 and 1 to operands 7 and 8, -;; respectively. We then split or peephole optimize after reload. -(define_insn "movmemsi_prereload" - [(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r")) - (mem:BLK (match_operand:SI 1 "register_operand" "r,r"))) - (clobber (match_operand:SI 2 "register_operand" "=&r,&r")) ;loop cnt/tmp - (clobber (match_operand:SI 3 "register_operand" "=&r,&r")) ;item tmp1 - (clobber (match_operand:SI 6 "register_operand" "=&r,&r")) ;item tmp2 - (clobber (match_operand:SI 7 "register_operand" "=&r,&r")) ;item tmp3 - (clobber (match_operand:SI 8 "register_operand" "=&r,&r")) ;item tmp4 - (use (match_operand:SI 4 "arith14_operand" "J,2")) ;byte count - (use (match_operand:SI 5 "const_int_operand" "n,n"))] ;alignment - "!TARGET_64BIT" - "#" - [(set_attr "type" "multi,multi")]) - -(define_split - [(parallel [(set (match_operand:BLK 0 "memory_operand" "") - (match_operand:BLK 1 "memory_operand" "")) - (clobber (match_operand:SI 2 "register_operand" "")) - (clobber (match_operand:SI 3 "register_operand" "")) - (clobber (match_operand:SI 6 "register_operand" "")) - (clobber (match_operand:SI 7 "register_operand" "")) - (clobber (match_operand:SI 8 "register_operand" "")) - (use (match_operand:SI 4 "arith14_operand" "")) - (use (match_operand:SI 5 "const_int_operand" ""))])] - "!TARGET_64BIT && reload_completed && !flag_peephole2 - && GET_CODE (operands[0]) == MEM - && register_operand (XEXP (operands[0], 0), SImode) - && GET_CODE (operands[1]) == MEM - && register_operand (XEXP (operands[1], 0), SImode)" - [(set (match_dup 7) (match_dup 9)) - (set (match_dup 8) (match_dup 10)) - (parallel [(set (match_dup 0) (match_dup 1)) - (clobber (match_dup 2)) - (clobber (match_dup 3)) - (clobber (match_dup 6)) - (clobber (match_dup 7)) - (clobber (match_dup 8)) - (use (match_dup 4)) - (use (match_dup 5)) - (const_int 0)])] - " -{ - operands[9] = XEXP (operands[0], 0); - operands[10] = XEXP (operands[1], 0); - operands[0] = replace_equiv_address (operands[0], operands[7]); - operands[1] = replace_equiv_address (operands[1], operands[8]); -}") - -(define_peephole2 - [(parallel [(set (match_operand:BLK 0 "memory_operand" "") - (match_operand:BLK 1 "memory_operand" "")) - (clobber (match_operand:SI 2 "register_operand" "")) - (clobber (match_operand:SI 3 "register_operand" "")) - (clobber (match_operand:SI 6 "register_operand" "")) - (clobber (match_operand:SI 7 "register_operand" "")) - (clobber (match_operand:SI 8 "register_operand" "")) - (use (match_operand:SI 4 "arith14_operand" "")) - (use (match_operand:SI 5 "const_int_operand" ""))])] - "!TARGET_64BIT - && GET_CODE (operands[0]) == MEM - && register_operand (XEXP (operands[0], 0), SImode) - && GET_CODE (operands[1]) == MEM - && register_operand (XEXP (operands[1], 0), SImode)" - [(parallel [(set (match_dup 0) (match_dup 1)) - (clobber (match_dup 2)) - (clobber (match_dup 3)) - (clobber (match_dup 6)) - (clobber (match_dup 7)) - (clobber (match_dup 8)) - (use (match_dup 4)) - (use (match_dup 5)) - (const_int 0)])] - " -{ - rtx addr = XEXP (operands[0], 0); - if (dead_or_set_p (curr_insn, addr)) - operands[7] = addr; - else - { - emit_insn (gen_rtx_SET (VOIDmode, operands[7], addr)); - operands[0] = replace_equiv_address (operands[0], operands[7]); - } - - addr = XEXP (operands[1], 0); - if (dead_or_set_p (curr_insn, addr)) - operands[8] = addr; - else - { - emit_insn (gen_rtx_SET (VOIDmode, operands[8], addr)); - operands[1] = replace_equiv_address (operands[1], operands[8]); - } -}") - -(define_insn "movmemsi_postreload" - [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r")) - (mem:BLK (match_operand:SI 1 "register_operand" "+r,r"))) - (clobber (match_operand:SI 2 "register_operand" "=&r,&r")) ;loop cnt/tmp - (clobber (match_operand:SI 3 "register_operand" "=&r,&r")) ;item tmp1 - (clobber (match_operand:SI 6 "register_operand" "=&r,&r")) ;item tmp2 - (clobber (match_dup 0)) - (clobber (match_dup 1)) - (use (match_operand:SI 4 "arith14_operand" "J,2")) ;byte count - (use (match_operand:SI 5 "const_int_operand" "n,n")) ;alignment - (const_int 0)] - "!TARGET_64BIT && reload_completed" - "* return pa_output_block_move (operands, !which_alternative);" - [(set_attr "type" "multi,multi")]) - -(define_expand "movmemdi" - [(parallel [(set (match_operand:BLK 0 "" "") - (match_operand:BLK 1 "" "")) - (clobber (match_dup 4)) - (clobber (match_dup 5)) - (clobber (match_dup 6)) - (clobber (match_dup 7)) - (clobber (match_dup 8)) - (use (match_operand:DI 2 "arith14_operand" "")) - (use (match_operand:DI 3 "const_int_operand" ""))])] - "TARGET_64BIT && optimize > 0" - " -{ - int size, align; - - /* HP provides very fast block move library routine for the PA; - this routine includes: - - 4x4 byte at a time block moves, - 1x4 byte at a time with alignment checked at runtime with - attempts to align the source and destination as needed - 1x1 byte loop - - With that in mind, here's the heuristics to try and guess when - the inlined block move will be better than the library block - move: - - 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 - the library routines. - - If the size is small in respect to the known alignment, then open - code the copy (since that will lead to better scheduling). - - Else use the block move pattern. */ - - /* Undetermined size, use the library routine. */ - if (GET_CODE (operands[2]) != CONST_INT) - FAIL; - - size = INTVAL (operands[2]); - align = INTVAL (operands[3]); - align = align > 8 ? 8 : (align ? align : 1); - - /* If size/alignment is large, then use the library routines. */ - if (size / align > 16) - FAIL; - - /* This does happen, but not often enough to worry much about. */ - if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ())) - FAIL; - - /* Fall through means we're going to use our block move pattern. */ - operands[0] - = replace_equiv_address (operands[0], - copy_to_mode_reg (DImode, XEXP (operands[0], 0))); - operands[1] - = replace_equiv_address (operands[1], - copy_to_mode_reg (DImode, XEXP (operands[1], 0))); - operands[4] = gen_reg_rtx (DImode); - operands[5] = gen_reg_rtx (DImode); - operands[6] = gen_reg_rtx (DImode); - operands[7] = gen_reg_rtx (DImode); - operands[8] = gen_reg_rtx (DImode); -}") - -;; The operand constraints are written like this to support both compile-time -;; and run-time determined byte counts. The expander and pa_output_block_move -;; only support compile-time determined counts at this time. -;; -;; 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. -;; -;; 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 -;; 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 -;; forced to internally copy operands 0 and 1 to operands 7 and 8, -;; respectively. We then split or peephole optimize after reload. -(define_insn "movmemdi_prereload" - [(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r")) - (mem:BLK (match_operand:DI 1 "register_operand" "r,r"))) - (clobber (match_operand:DI 2 "register_operand" "=&r,&r")) ;loop cnt/tmp - (clobber (match_operand:DI 3 "register_operand" "=&r,&r")) ;item tmp1 - (clobber (match_operand:DI 6 "register_operand" "=&r,&r")) ;item tmp2 - (clobber (match_operand:DI 7 "register_operand" "=&r,&r")) ;item tmp3 - (clobber (match_operand:DI 8 "register_operand" "=&r,&r")) ;item tmp4 - (use (match_operand:DI 4 "arith14_operand" "J,2")) ;byte count - (use (match_operand:DI 5 "const_int_operand" "n,n"))] ;alignment - "TARGET_64BIT" - "#" - [(set_attr "type" "multi,multi")]) - -(define_split - [(parallel [(set (match_operand:BLK 0 "memory_operand" "") - (match_operand:BLK 1 "memory_operand" "")) - (clobber (match_operand:DI 2 "register_operand" "")) - (clobber (match_operand:DI 3 "register_operand" "")) - (clobber (match_operand:DI 6 "register_operand" "")) - (clobber (match_operand:DI 7 "register_operand" "")) - (clobber (match_operand:DI 8 "register_operand" "")) - (use (match_operand:DI 4 "arith14_operand" "")) - (use (match_operand:DI 5 "const_int_operand" ""))])] - "TARGET_64BIT && reload_completed && !flag_peephole2 - && GET_CODE (operands[0]) == MEM - && register_operand (XEXP (operands[0], 0), DImode) - && GET_CODE (operands[1]) == MEM - && register_operand (XEXP (operands[1], 0), DImode)" - [(set (match_dup 7) (match_dup 9)) - (set (match_dup 8) (match_dup 10)) - (parallel [(set (match_dup 0) (match_dup 1)) - (clobber (match_dup 2)) - (clobber (match_dup 3)) - (clobber (match_dup 6)) - (clobber (match_dup 7)) - (clobber (match_dup 8)) - (use (match_dup 4)) - (use (match_dup 5)) - (const_int 0)])] - " -{ - operands[9] = XEXP (operands[0], 0); - operands[10] = XEXP (operands[1], 0); - operands[0] = replace_equiv_address (operands[0], operands[7]); - operands[1] = replace_equiv_address (operands[1], operands[8]); -}") - -(define_peephole2 - [(parallel [(set (match_operand:BLK 0 "memory_operand" "") - (match_operand:BLK 1 "memory_operand" "")) - (clobber (match_operand:DI 2 "register_operand" "")) - (clobber (match_operand:DI 3 "register_operand" "")) - (clobber (match_operand:DI 6 "register_operand" "")) - (clobber (match_operand:DI 7 "register_operand" "")) - (clobber (match_operand:DI 8 "register_operand" "")) - (use (match_operand:DI 4 "arith14_operand" "")) - (use (match_operand:DI 5 "const_int_operand" ""))])] - "TARGET_64BIT - && GET_CODE (operands[0]) == MEM - && register_operand (XEXP (operands[0], 0), DImode) - && GET_CODE (operands[1]) == MEM - && register_operand (XEXP (operands[1], 0), DImode)" - [(parallel [(set (match_dup 0) (match_dup 1)) - (clobber (match_dup 2)) - (clobber (match_dup 3)) - (clobber (match_dup 6)) - (clobber (match_dup 7)) - (clobber (match_dup 8)) - (use (match_dup 4)) - (use (match_dup 5)) - (const_int 0)])] - " -{ - rtx addr = XEXP (operands[0], 0); - if (dead_or_set_p (curr_insn, addr)) - operands[7] = addr; - else - { - emit_insn (gen_rtx_SET (VOIDmode, operands[7], addr)); - operands[0] = replace_equiv_address (operands[0], operands[7]); - } - - addr = XEXP (operands[1], 0); - if (dead_or_set_p (curr_insn, addr)) - operands[8] = addr; - else - { - emit_insn (gen_rtx_SET (VOIDmode, operands[8], addr)); - operands[1] = replace_equiv_address (operands[1], operands[8]); - } -}") - -(define_insn "movmemdi_postreload" - [(set (mem:BLK (match_operand:DI 0 "register_operand" "+r,r")) - (mem:BLK (match_operand:DI 1 "register_operand" "+r,r"))) - (clobber (match_operand:DI 2 "register_operand" "=&r,&r")) ;loop cnt/tmp - (clobber (match_operand:DI 3 "register_operand" "=&r,&r")) ;item tmp1 - (clobber (match_operand:DI 6 "register_operand" "=&r,&r")) ;item tmp2 - (clobber (match_dup 0)) - (clobber (match_dup 1)) - (use (match_operand:DI 4 "arith14_operand" "J,2")) ;byte count - (use (match_operand:DI 5 "const_int_operand" "n,n")) ;alignment - (const_int 0)] - "TARGET_64BIT && reload_completed" - "* return pa_output_block_move (operands, !which_alternative);" - [(set_attr "type" "multi,multi")]) - -(define_expand "setmemsi" - [(parallel [(set (match_operand:BLK 0 "" "") - (match_operand 2 "const_int_operand" "")) - (clobber (match_dup 4)) - (clobber (match_dup 5)) - (use (match_operand:SI 1 "arith14_operand" "")) - (use (match_operand:SI 3 "const_int_operand" ""))])] - "!TARGET_64BIT && optimize > 0" - " -{ - int size, align; - - /* If value to set is not zero, use the library routine. */ - if (operands[2] != const0_rtx) - FAIL; - - /* Undetermined size, use the library routine. */ - if (GET_CODE (operands[1]) != CONST_INT) - FAIL; - - size = INTVAL (operands[1]); - align = INTVAL (operands[3]); - align = align > 4 ? 4 : align; - - /* If size/alignment is large, then use the library routines. */ - if (size / align > 16) - FAIL; - - /* This does happen, but not often enough to worry much about. */ - if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ())) - FAIL; - - /* Fall through means we're going to use our block clear pattern. */ - operands[0] - = replace_equiv_address (operands[0], - copy_to_mode_reg (SImode, XEXP (operands[0], 0))); - operands[4] = gen_reg_rtx (SImode); - operands[5] = gen_reg_rtx (SImode); -}") - -(define_insn "clrmemsi_prereload" - [(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r")) - (const_int 0)) - (clobber (match_operand:SI 1 "register_operand" "=&r,&r")) ;loop cnt/tmp - (clobber (match_operand:SI 4 "register_operand" "=&r,&r")) ;tmp1 - (use (match_operand:SI 2 "arith14_operand" "J,1")) ;byte count - (use (match_operand:SI 3 "const_int_operand" "n,n"))] ;alignment - "!TARGET_64BIT" - "#" - [(set_attr "type" "multi,multi")]) - -(define_split - [(parallel [(set (match_operand:BLK 0 "memory_operand" "") - (const_int 0)) - (clobber (match_operand:SI 1 "register_operand" "")) - (clobber (match_operand:SI 4 "register_operand" "")) - (use (match_operand:SI 2 "arith14_operand" "")) - (use (match_operand:SI 3 "const_int_operand" ""))])] - "!TARGET_64BIT && reload_completed && !flag_peephole2 - && GET_CODE (operands[0]) == MEM - && register_operand (XEXP (operands[0], 0), SImode)" - [(set (match_dup 4) (match_dup 5)) - (parallel [(set (match_dup 0) (const_int 0)) - (clobber (match_dup 1)) - (clobber (match_dup 4)) - (use (match_dup 2)) - (use (match_dup 3)) - (const_int 0)])] - " -{ - operands[5] = XEXP (operands[0], 0); - operands[0] = replace_equiv_address (operands[0], operands[4]); -}") - -(define_peephole2 - [(parallel [(set (match_operand:BLK 0 "memory_operand" "") - (const_int 0)) - (clobber (match_operand:SI 1 "register_operand" "")) - (clobber (match_operand:SI 4 "register_operand" "")) - (use (match_operand:SI 2 "arith14_operand" "")) - (use (match_operand:SI 3 "const_int_operand" ""))])] - "!TARGET_64BIT - && GET_CODE (operands[0]) == MEM - && register_operand (XEXP (operands[0], 0), SImode)" - [(parallel [(set (match_dup 0) (const_int 0)) - (clobber (match_dup 1)) - (clobber (match_dup 4)) - (use (match_dup 2)) - (use (match_dup 3)) - (const_int 0)])] - " -{ - rtx addr = XEXP (operands[0], 0); - if (dead_or_set_p (curr_insn, addr)) - operands[4] = addr; - else - { - emit_insn (gen_rtx_SET (VOIDmode, operands[4], addr)); - operands[0] = replace_equiv_address (operands[0], operands[4]); - } -}") - -(define_insn "clrmemsi_postreload" - [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r")) - (const_int 0)) - (clobber (match_operand:SI 1 "register_operand" "=&r,&r")) ;loop cnt/tmp - (clobber (match_dup 0)) - (use (match_operand:SI 2 "arith14_operand" "J,1")) ;byte count - (use (match_operand:SI 3 "const_int_operand" "n,n")) ;alignment - (const_int 0)] - "!TARGET_64BIT && reload_completed" - "* return pa_output_block_clear (operands, !which_alternative);" - [(set_attr "type" "multi,multi")]) - -(define_expand "setmemdi" - [(parallel [(set (match_operand:BLK 0 "" "") - (match_operand 2 "const_int_operand" "")) - (clobber (match_dup 4)) - (clobber (match_dup 5)) - (use (match_operand:DI 1 "arith14_operand" "")) - (use (match_operand:DI 3 "const_int_operand" ""))])] - "TARGET_64BIT && optimize > 0" - " -{ - int size, align; - - /* If value to set is not zero, use the library routine. */ - if (operands[2] != const0_rtx) - FAIL; - - /* Undetermined size, use the library routine. */ - if (GET_CODE (operands[1]) != CONST_INT) - FAIL; - - size = INTVAL (operands[1]); - align = INTVAL (operands[3]); - align = align > 8 ? 8 : align; - - /* If size/alignment is large, then use the library routines. */ - if (size / align > 16) - FAIL; - - /* This does happen, but not often enough to worry much about. */ - if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ())) - FAIL; - - /* Fall through means we're going to use our block clear pattern. */ - operands[0] - = replace_equiv_address (operands[0], - copy_to_mode_reg (DImode, XEXP (operands[0], 0))); - operands[4] = gen_reg_rtx (DImode); - operands[5] = gen_reg_rtx (DImode); -}") - -(define_insn "clrmemdi_prereload" - [(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r")) - (const_int 0)) - (clobber (match_operand:DI 1 "register_operand" "=&r,&r")) ;loop cnt/tmp - (clobber (match_operand:DI 4 "register_operand" "=&r,&r")) ;item tmp1 - (use (match_operand:DI 2 "arith14_operand" "J,1")) ;byte count - (use (match_operand:DI 3 "const_int_operand" "n,n"))] ;alignment - "TARGET_64BIT" - "#" - [(set_attr "type" "multi,multi")]) - -(define_split - [(parallel [(set (match_operand:BLK 0 "memory_operand" "") - (const_int 0)) - (clobber (match_operand:DI 1 "register_operand" "")) - (clobber (match_operand:DI 4 "register_operand" "")) - (use (match_operand:DI 2 "arith14_operand" "")) - (use (match_operand:DI 3 "const_int_operand" ""))])] - "TARGET_64BIT && reload_completed && !flag_peephole2 - && GET_CODE (operands[0]) == MEM - && register_operand (XEXP (operands[0], 0), DImode)" - [(set (match_dup 4) (match_dup 5)) - (parallel [(set (match_dup 0) (const_int 0)) - (clobber (match_dup 1)) - (clobber (match_dup 4)) - (use (match_dup 2)) - (use (match_dup 3)) - (const_int 0)])] - " -{ - operands[5] = XEXP (operands[0], 0); - operands[0] = replace_equiv_address (operands[0], operands[4]); -}") - -(define_peephole2 - [(parallel [(set (match_operand:BLK 0 "memory_operand" "") - (const_int 0)) - (clobber (match_operand:DI 1 "register_operand" "")) - (clobber (match_operand:DI 4 "register_operand" "")) - (use (match_operand:DI 2 "arith14_operand" "")) - (use (match_operand:DI 3 "const_int_operand" ""))])] - "TARGET_64BIT - && GET_CODE (operands[0]) == MEM - && register_operand (XEXP (operands[0], 0), DImode)" - [(parallel [(set (match_dup 0) (const_int 0)) - (clobber (match_dup 1)) - (clobber (match_dup 4)) - (use (match_dup 2)) - (use (match_dup 3)) - (const_int 0)])] - " -{ - rtx addr = XEXP (operands[0], 0); - if (dead_or_set_p (curr_insn, addr)) - operands[4] = addr; - else - { - emit_insn (gen_rtx_SET (VOIDmode, operands[4], addr)); - operands[0] = replace_equiv_address (operands[0], operands[4]); - } -}") - -(define_insn "clrmemdi_postreload" - [(set (mem:BLK (match_operand:DI 0 "register_operand" "+r,r")) - (const_int 0)) - (clobber (match_operand:DI 1 "register_operand" "=&r,&r")) ;loop cnt/tmp - (clobber (match_dup 0)) - (use (match_operand:DI 2 "arith14_operand" "J,1")) ;byte count - (use (match_operand:DI 3 "const_int_operand" "n,n")) ;alignment - (const_int 0)] - "TARGET_64BIT && reload_completed" - "* return pa_output_block_clear (operands, !which_alternative);" - [(set_attr "type" "multi,multi")]) - -;; Floating point move insns - -(define_expand "movdf" - [(set (match_operand:DF 0 "general_operand" "") - (match_operand:DF 1 "general_operand" ""))] - "" - " -{ - if (pa_emit_move_sequence (operands, DFmode, 0)) - DONE; -}") - -;; Handle DFmode input reloads requiring %r1 as a scratch register. -(define_expand "reload_indf_r1" - [(set (match_operand:DF 0 "register_operand" "=Z") - (match_operand:DF 1 "non_hard_reg_operand" "")) - (clobber (match_operand:SI 2 "register_operand" "=&a"))] - "" - " -{ - if (pa_emit_move_sequence (operands, DFmode, operands[2])) - DONE; - - /* We don't want the clobber emitted, so handle this ourselves. */ - emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); - DONE; -}") - -;; Handle DFmode input reloads requiring a general register as a -;; scratch register. -(define_expand "reload_indf" - [(set (match_operand:DF 0 "register_operand" "=Z") - (match_operand:DF 1 "non_hard_reg_operand" "")) - (clobber (match_operand:DF 2 "register_operand" "=&r"))] - "" - " -{ - if (pa_emit_move_sequence (operands, DFmode, operands[2])) - DONE; - - /* We don't want the clobber emitted, so handle this ourselves. */ - emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); - DONE; -}") - -;; Handle DFmode output reloads requiring a general register as a -;; scratch register. -(define_expand "reload_outdf" - [(set (match_operand:DF 0 "non_hard_reg_operand" "") - (match_operand:DF 1 "register_operand" "Z")) - (clobber (match_operand:DF 2 "register_operand" "=&r"))] - "" - " -{ - if (pa_emit_move_sequence (operands, DFmode, operands[2])) - DONE; - - /* We don't want the clobber emitted, so handle this ourselves. */ - emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); - DONE; -}") - -(define_insn "" - [(set (match_operand:DF 0 "move_dest_operand" - "=f,*r,T,?o,?Q,f,*r,*r,?*r,?f") - (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand" - "fG,*rG,f,*r,*r,RT,o,RQ,f,*r"))] - "(register_operand (operands[0], DFmode) - || reg_or_0_operand (operands[1], DFmode)) - && !(GET_CODE (operands[1]) == CONST_DOUBLE - && GET_CODE (operands[0]) == MEM) - && !TARGET_64BIT - && !TARGET_SOFT_FLOAT" - "* -{ - if ((FP_REG_P (operands[0]) || FP_REG_P (operands[1]) - || operands[1] == CONST0_RTX (DFmode)) - && !(REG_P (operands[0]) && REG_P (operands[1]) - && FP_REG_P (operands[0]) ^ FP_REG_P (operands[1]))) - return pa_output_fp_move_double (operands); - return pa_output_move_double (operands); -}" - [(set_attr "type" "fpalu,move,fpstore,store,store,fpload,load,load,fpstore_load,store_fpload") - (set_attr "length" "4,8,4,8,16,4,8,16,12,12")]) - -(define_insn "" - [(set (match_operand:DF 0 "indexed_memory_operand" "=R") - (match_operand:DF 1 "reg_or_0_operand" "f"))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && reload_completed" - "fstd%F0 %1,%0" - [(set_attr "type" "fpstore") - (set_attr "pa_combine_type" "addmove") - (set_attr "length" "4")]) - -(define_peephole2 - [(set (match_operand:SI 0 "register_operand" "") - (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "") - (const_int 8)) - (match_operand:SI 2 "register_operand" ""))) - (set (mem:DF (match_dup 0)) - (match_operand:DF 3 "register_operand" ""))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && REG_OK_FOR_BASE_P (operands[2]) - && FP_REGNO_P (REGNO (operands[3]))" - [(set (mem:DF (plus:SI (mult:SI (match_dup 1) (const_int 8)) (match_dup 2))) - (match_dup 3)) - (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 8)) - (match_dup 2)))] - "") - -(define_peephole2 - [(set (match_operand:SI 0 "register_operand" "") - (plus:SI (match_operand:SI 2 "register_operand" "") - (mult:SI (match_operand:SI 1 "register_operand" "") - (const_int 8)))) - (set (mem:DF (match_dup 0)) - (match_operand:DF 3 "register_operand" ""))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && REG_OK_FOR_BASE_P (operands[2]) - && FP_REGNO_P (REGNO (operands[3]))" - [(set (mem:DF (plus:SI (mult:SI (match_dup 1) (const_int 8)) (match_dup 2))) - (match_dup 3)) - (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 8)) - (match_dup 2)))] - "") - -(define_peephole2 - [(set (match_operand:DI 0 "register_operand" "") - (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "") - (const_int 8)) - (match_operand:DI 2 "register_operand" ""))) - (set (mem:DF (match_dup 0)) - (match_operand:DF 3 "register_operand" ""))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && TARGET_64BIT - && REG_OK_FOR_BASE_P (operands[2]) - && FP_REGNO_P (REGNO (operands[3]))" - [(set (mem:DF (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2))) - (match_dup 3)) - (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8)) - (match_dup 2)))] - "") - -(define_peephole2 - [(set (match_operand:DI 0 "register_operand" "") - (plus:DI (match_operand:DI 2 "register_operand" "") - (mult:DI (match_operand:DI 1 "register_operand" "") - (const_int 8)))) - (set (mem:DF (match_dup 0)) - (match_operand:DF 3 "register_operand" ""))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && TARGET_64BIT - && REG_OK_FOR_BASE_P (operands[2]) - && FP_REGNO_P (REGNO (operands[3]))" - [(set (mem:DF (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2))) - (match_dup 3)) - (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8)) - (match_dup 2)))] - "") - -(define_peephole2 - [(set (match_operand:SI 0 "register_operand" "") - (plus:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "register_operand" ""))) - (set (mem:DF (match_dup 0)) - (match_operand:DF 3 "register_operand" ""))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && TARGET_NO_SPACE_REGS - && REG_OK_FOR_INDEX_P (operands[1]) - && REG_OK_FOR_BASE_P (operands[2]) - && FP_REGNO_P (REGNO (operands[3]))" - [(set (mem:DF (plus:SI (match_dup 1) (match_dup 2))) - (match_dup 3)) - (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))] - "") - -(define_peephole2 - [(set (match_operand:SI 0 "register_operand" "") - (plus:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "register_operand" ""))) - (set (mem:DF (match_dup 0)) - (match_operand:DF 3 "register_operand" ""))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && TARGET_NO_SPACE_REGS - && REG_OK_FOR_BASE_P (operands[1]) - && REG_OK_FOR_INDEX_P (operands[2]) - && FP_REGNO_P (REGNO (operands[3]))" - [(set (mem:DF (plus:SI (match_dup 2) (match_dup 1))) - (match_dup 3)) - (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))] - "") - -(define_peephole2 - [(set (match_operand:DI 0 "register_operand" "") - (plus:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "register_operand" ""))) - (set (mem:DF (match_dup 0)) - (match_operand:DF 3 "register_operand" ""))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && TARGET_64BIT - && TARGET_NO_SPACE_REGS - && REG_OK_FOR_INDEX_P (operands[1]) - && REG_OK_FOR_BASE_P (operands[2]) - && FP_REGNO_P (REGNO (operands[3]))" - [(set (mem:DF (plus:DI (match_dup 1) (match_dup 2))) - (match_dup 3)) - (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))] - "") - -(define_peephole2 - [(set (match_operand:DI 0 "register_operand" "") - (plus:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "register_operand" ""))) - (set (mem:DF (match_dup 0)) - (match_operand:DF 3 "register_operand" ""))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && TARGET_64BIT - && TARGET_NO_SPACE_REGS - && REG_OK_FOR_BASE_P (operands[1]) - && REG_OK_FOR_INDEX_P (operands[2]) - && FP_REGNO_P (REGNO (operands[3]))" - [(set (mem:DF (plus:DI (match_dup 2) (match_dup 1))) - (match_dup 3)) - (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))] - "") - -(define_insn "" - [(set (match_operand:DF 0 "move_dest_operand" - "=r,?o,?Q,r,r") - (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand" - "rG,r,r,o,RQ"))] - "(register_operand (operands[0], DFmode) - || reg_or_0_operand (operands[1], DFmode)) - && !TARGET_64BIT - && TARGET_SOFT_FLOAT" - "* -{ - return pa_output_move_double (operands); -}" - [(set_attr "type" "move,store,store,load,load") - (set_attr "length" "8,8,16,8,16")]) - -(define_insn "" - [(set (match_operand:DF 0 "move_dest_operand" - "=!*r,*r,*r,*r,*r,Q,f,f,T") - (match_operand:DF 1 "move_src_operand" - "!*r,J,N,K,RQ,*rG,fG,RT,f"))] - "(register_operand (operands[0], DFmode) - || reg_or_0_operand (operands[1], DFmode)) - && !TARGET_SOFT_FLOAT && TARGET_64BIT" - "@ - copy %1,%0 - ldi %1,%0 - ldil L'%1,%0 - depdi,z %z1,%0 - ldd%M1 %1,%0 - std%M0 %r1,%0 - fcpy,dbl %f1,%0 - fldd%F1 %1,%0 - fstd%F0 %1,%0" - [(set_attr "type" "move,move,move,shift,load,store,fpalu,fpload,fpstore") - (set_attr "pa_combine_type" "addmove") - (set_attr "length" "4,4,4,4,4,4,4,4,4")]) - - -(define_expand "movdi" - [(set (match_operand:DI 0 "general_operand" "") - (match_operand:DI 1 "general_operand" ""))] - "" - " -{ - if (pa_emit_move_sequence (operands, DImode, 0)) - DONE; -}") - -;; Handle DImode input reloads requiring %r1 as a scratch register. -(define_expand "reload_indi_r1" - [(set (match_operand:DI 0 "register_operand" "=Z") - (match_operand:DI 1 "non_hard_reg_operand" "")) - (clobber (match_operand:SI 2 "register_operand" "=&a"))] - "" - " -{ - if (pa_emit_move_sequence (operands, DImode, operands[2])) - DONE; - - /* We don't want the clobber emitted, so handle this ourselves. */ - emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); - DONE; -}") - -;; Handle DImode input reloads requiring a general register as a -;; scratch register. -(define_expand "reload_indi" - [(set (match_operand:DI 0 "register_operand" "=Z") - (match_operand:DI 1 "non_hard_reg_operand" "")) - (clobber (match_operand:SI 2 "register_operand" "=&r"))] - "" - " -{ - if (pa_emit_move_sequence (operands, DImode, operands[2])) - DONE; - - /* We don't want the clobber emitted, so handle this ourselves. */ - emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); - DONE; -}") - -;; Handle DImode output reloads requiring a general register as a -;; scratch register. -(define_expand "reload_outdi" - [(set (match_operand:DI 0 "non_hard_reg_operand" "") - (match_operand:DI 1 "register_operand" "Z")) - (clobber (match_operand:SI 2 "register_operand" "=&r"))] - "" - " -{ - if (pa_emit_move_sequence (operands, DImode, operands[2])) - DONE; - - /* We don't want the clobber emitted, so handle this ourselves. */ - emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); - DONE; -}") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (high:DI (match_operand 1 "" "")))] - "!TARGET_64BIT" - "* -{ - rtx op0 = operands[0]; - rtx op1 = operands[1]; - - switch (GET_CODE (op1)) - { - case CONST_INT: -#if HOST_BITS_PER_WIDE_INT <= 32 - operands[0] = operand_subword (op0, 1, 0, DImode); - output_asm_insn (\"ldil L'%1,%0\", operands); - - operands[0] = operand_subword (op0, 0, 0, DImode); - if (INTVAL (op1) < 0) - output_asm_insn (\"ldi -1,%0\", operands); - else - output_asm_insn (\"ldi 0,%0\", operands); -#else - operands[0] = operand_subword (op0, 1, 0, DImode); - operands[1] = GEN_INT (INTVAL (op1) & 0xffffffff); - output_asm_insn (\"ldil L'%1,%0\", operands); - - operands[0] = operand_subword (op0, 0, 0, DImode); - operands[1] = GEN_INT (INTVAL (op1) >> 32); - output_asm_insn (pa_singlemove_string (operands), operands); -#endif - break; - - case CONST_DOUBLE: - operands[0] = operand_subword (op0, 1, 0, DImode); - operands[1] = GEN_INT (CONST_DOUBLE_LOW (op1)); - output_asm_insn (\"ldil L'%1,%0\", operands); - - operands[0] = operand_subword (op0, 0, 0, DImode); - operands[1] = GEN_INT (CONST_DOUBLE_HIGH (op1)); - output_asm_insn (pa_singlemove_string (operands), operands); - break; - - default: - gcc_unreachable (); - } - return \"\"; -}" - [(set_attr "type" "move") - (set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:DI 0 "move_dest_operand" - "=r,o,Q,r,r,r,*f,*f,T,?r,?*f") - (match_operand:DI 1 "move_src_operand" - "rM,r,r,o*R,Q,i,*fM,RT,*f,*f,r"))] - "(register_operand (operands[0], DImode) - || reg_or_0_operand (operands[1], DImode)) - && !TARGET_64BIT - && !TARGET_SOFT_FLOAT" - "* -{ - if ((FP_REG_P (operands[0]) || FP_REG_P (operands[1]) - || operands[1] == CONST0_RTX (DFmode)) - && !(REG_P (operands[0]) && REG_P (operands[1]) - && FP_REG_P (operands[0]) ^ FP_REG_P (operands[1]))) - return pa_output_fp_move_double (operands); - return pa_output_move_double (operands); -}" - [(set_attr "type" - "move,store,store,load,load,multi,fpalu,fpload,fpstore,fpstore_load,store_fpload") - (set_attr "length" "8,8,16,8,16,16,4,4,4,12,12")]) - -(define_insn "" - [(set (match_operand:DI 0 "move_dest_operand" - "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T") - (match_operand:DI 1 "move_src_operand" - "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f"))] - "(register_operand (operands[0], DImode) - || reg_or_0_operand (operands[1], DImode)) - && !TARGET_SOFT_FLOAT && TARGET_64BIT" - "@ - ldd RT'%A1,%0 - copy %1,%0 - ldi %1,%0 - ldil L'%1,%0 - depdi,z %z1,%0 - ldd%M1 %1,%0 - std%M0 %r1,%0 - mtsar %r1 - {mfctl|mfctl,w} %%sar,%0 - fcpy,dbl %f1,%0 - fldd%F1 %1,%0 - fstd%F0 %1,%0" - [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore") - (set_attr "pa_combine_type" "addmove") - (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4")]) - -(define_insn "" - [(set (match_operand:DI 0 "indexed_memory_operand" "=R") - (match_operand:DI 1 "register_operand" "f"))] - "!TARGET_SOFT_FLOAT - && TARGET_64BIT - && !TARGET_DISABLE_INDEXING - && reload_completed" - "fstd%F0 %1,%0" - [(set_attr "type" "fpstore") - (set_attr "pa_combine_type" "addmove") - (set_attr "length" "4")]) - -(define_peephole2 - [(set (match_operand:DI 0 "register_operand" "") - (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "") - (const_int 8)) - (match_operand:DI 2 "register_operand" ""))) - (set (mem:DI (match_dup 0)) - (match_operand:DI 3 "register_operand" ""))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && TARGET_64BIT - && REG_OK_FOR_BASE_P (operands[2]) - && FP_REGNO_P (REGNO (operands[3]))" - [(set (mem:DI (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2))) - (match_dup 3)) - (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8)) - (match_dup 2)))] - "") - -(define_peephole2 - [(set (match_operand:DI 0 "register_operand" "") - (plus:DI (match_operand:DI 2 "register_operand" "") - (mult:DI (match_operand:DI 1 "register_operand" "") - (const_int 8)))) - (set (mem:DI (match_dup 0)) - (match_operand:DI 3 "register_operand" ""))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && TARGET_64BIT - && REG_OK_FOR_BASE_P (operands[2]) - && FP_REGNO_P (REGNO (operands[3]))" - [(set (mem:DI (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2))) - (match_dup 3)) - (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8)) - (match_dup 2)))] - "") - -(define_peephole2 - [(set (match_operand:DI 0 "register_operand" "") - (plus:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "register_operand" ""))) - (set (mem:DI (match_dup 0)) - (match_operand:DI 3 "register_operand" ""))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && TARGET_64BIT - && TARGET_NO_SPACE_REGS - && REG_OK_FOR_INDEX_P (operands[1]) - && REG_OK_FOR_BASE_P (operands[2]) - && FP_REGNO_P (REGNO (operands[3]))" - [(set (mem:DI (plus:DI (match_dup 1) (match_dup 2))) - (match_dup 3)) - (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))] - "") - -(define_peephole2 - [(set (match_operand:DI 0 "register_operand" "") - (plus:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "register_operand" ""))) - (set (mem:DI (match_dup 0)) - (match_operand:DI 3 "register_operand" ""))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && TARGET_64BIT - && TARGET_NO_SPACE_REGS - && REG_OK_FOR_BASE_P (operands[1]) - && REG_OK_FOR_INDEX_P (operands[2]) - && FP_REGNO_P (REGNO (operands[3]))" - [(set (mem:DI (plus:DI (match_dup 2) (match_dup 1))) - (match_dup 3)) - (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))] - "") - -(define_insn "" - [(set (match_operand:DI 0 "move_dest_operand" - "=r,o,Q,r,r,r") - (match_operand:DI 1 "general_operand" - "rM,r,r,o,Q,i"))] - "(register_operand (operands[0], DImode) - || reg_or_0_operand (operands[1], DImode)) - && !TARGET_64BIT - && TARGET_SOFT_FLOAT" - "* -{ - return pa_output_move_double (operands); -}" - [(set_attr "type" "move,store,store,load,load,multi") - (set_attr "length" "8,8,16,8,16,16")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r,&r") - (lo_sum:DI (match_operand:DI 1 "register_operand" "0,r") - (match_operand:DI 2 "immediate_operand" "i,i")))] - "!TARGET_64BIT" - "* -{ - /* Don't output a 64-bit constant, since we can't trust the assembler to - handle it correctly. */ - if (GET_CODE (operands[2]) == CONST_DOUBLE) - operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[2])); - else if (HOST_BITS_PER_WIDE_INT > 32 - && GET_CODE (operands[2]) == CONST_INT) - operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffffffff); - if (which_alternative == 1) - output_asm_insn (\"copy %1,%0\", operands); - return \"ldo R'%G2(%R1),%R0\"; -}" - [(set_attr "type" "move,move") - (set_attr "length" "4,8")]) - -(define_expand "movsf" - [(set (match_operand:SF 0 "general_operand" "") - (match_operand:SF 1 "general_operand" ""))] - "" - " -{ - if (pa_emit_move_sequence (operands, SFmode, 0)) - DONE; -}") - -;; Handle SFmode input reloads requiring %r1 as a scratch register. -(define_expand "reload_insf_r1" - [(set (match_operand:SF 0 "register_operand" "=Z") - (match_operand:SF 1 "non_hard_reg_operand" "")) - (clobber (match_operand:SI 2 "register_operand" "=&a"))] - "" - " -{ - if (pa_emit_move_sequence (operands, SFmode, operands[2])) - DONE; - - /* We don't want the clobber emitted, so handle this ourselves. */ - emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); - DONE; -}") - -;; Handle SFmode input reloads requiring a general register as a -;; scratch register. -(define_expand "reload_insf" - [(set (match_operand:SF 0 "register_operand" "=Z") - (match_operand:SF 1 "non_hard_reg_operand" "")) - (clobber (match_operand:SF 2 "register_operand" "=&r"))] - "" - " -{ - if (pa_emit_move_sequence (operands, SFmode, operands[2])) - DONE; - - /* We don't want the clobber emitted, so handle this ourselves. */ - emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); - DONE; -}") - -;; Handle SFmode output reloads requiring a general register as a -;; scratch register. -(define_expand "reload_outsf" - [(set (match_operand:SF 0 "non_hard_reg_operand" "") - (match_operand:SF 1 "register_operand" "Z")) - (clobber (match_operand:SF 2 "register_operand" "=&r"))] - "" - " -{ - if (pa_emit_move_sequence (operands, SFmode, operands[2])) - DONE; - - /* We don't want the clobber emitted, so handle this ourselves. */ - emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); - DONE; -}") - -(define_insn "" - [(set (match_operand:SF 0 "move_dest_operand" - "=f,!*r,f,*r,T,Q,?*r,?f") - (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand" - "fG,!*rG,RT,RQ,f,*rG,f,*r"))] - "(register_operand (operands[0], SFmode) - || reg_or_0_operand (operands[1], SFmode)) - && !TARGET_SOFT_FLOAT - && !TARGET_64BIT" - "@ - fcpy,sgl %f1,%0 - copy %r1,%0 - fldw%F1 %1,%0 - ldw%M1 %1,%0 - fstw%F0 %1,%0 - stw%M0 %r1,%0 - {fstws|fstw} %1,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0 - {stws|stw} %1,-16(%%sp)\n\t{fldws|fldw} -16(%%sp),%0" - [(set_attr "type" "fpalu,move,fpload,load,fpstore,store,fpstore_load,store_fpload") - (set_attr "pa_combine_type" "addmove") - (set_attr "length" "4,4,4,4,4,4,8,8")]) - -(define_insn "" - [(set (match_operand:SF 0 "move_dest_operand" - "=f,!*r,f,*r,T,Q") - (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand" - "fG,!*rG,RT,RQ,f,*rG"))] - "(register_operand (operands[0], SFmode) - || reg_or_0_operand (operands[1], SFmode)) - && !TARGET_SOFT_FLOAT - && TARGET_64BIT" - "@ - fcpy,sgl %f1,%0 - copy %r1,%0 - fldw%F1 %1,%0 - ldw%M1 %1,%0 - fstw%F0 %1,%0 - stw%M0 %r1,%0" - [(set_attr "type" "fpalu,move,fpload,load,fpstore,store") - (set_attr "pa_combine_type" "addmove") - (set_attr "length" "4,4,4,4,4,4")]) - -(define_insn "" - [(set (match_operand:SF 0 "indexed_memory_operand" "=R") - (match_operand:SF 1 "register_operand" "f"))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && reload_completed" - "fstw%F0 %1,%0" - [(set_attr "type" "fpstore") - (set_attr "pa_combine_type" "addmove") - (set_attr "length" "4")]) - -(define_peephole2 - [(set (match_operand:SI 0 "register_operand" "") - (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "") - (const_int 4)) - (match_operand:SI 2 "register_operand" ""))) - (set (mem:SF (match_dup 0)) - (match_operand:SF 3 "register_operand" ""))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && REG_OK_FOR_BASE_P (operands[2]) - && FP_REGNO_P (REGNO (operands[3]))" - [(set (mem:SF (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2))) - (match_dup 3)) - (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4)) - (match_dup 2)))] - "") - -(define_peephole2 - [(set (match_operand:SI 0 "register_operand" "") - (plus:SI (match_operand:SI 2 "register_operand" "") - (mult:SI (match_operand:SI 1 "register_operand" "") - (const_int 4)))) - (set (mem:SF (match_dup 0)) - (match_operand:SF 3 "register_operand" ""))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && REG_OK_FOR_BASE_P (operands[2]) - && FP_REGNO_P (REGNO (operands[3]))" - [(set (mem:SF (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2))) - (match_dup 3)) - (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4)) - (match_dup 2)))] - "") - -(define_peephole2 - [(set (match_operand:DI 0 "register_operand" "") - (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "") - (const_int 4)) - (match_operand:DI 2 "register_operand" ""))) - (set (mem:SF (match_dup 0)) - (match_operand:SF 3 "register_operand" ""))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && TARGET_64BIT - && REG_OK_FOR_BASE_P (operands[2]) - && FP_REGNO_P (REGNO (operands[3]))" - [(set (mem:SF (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2))) - (match_dup 3)) - (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4)) - (match_dup 2)))] - "") - -(define_peephole2 - [(set (match_operand:DI 0 "register_operand" "") - (plus:DI (match_operand:DI 2 "register_operand" "") - (mult:DI (match_operand:DI 1 "register_operand" "") - (const_int 4)))) - (set (mem:SF (match_dup 0)) - (match_operand:SF 3 "register_operand" ""))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && TARGET_64BIT - && REG_OK_FOR_BASE_P (operands[2]) - && FP_REGNO_P (REGNO (operands[3]))" - [(set (mem:SF (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2))) - (match_dup 3)) - (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4)) - (match_dup 2)))] - "") - -(define_peephole2 - [(set (match_operand:SI 0 "register_operand" "") - (plus:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "register_operand" ""))) - (set (mem:SF (match_dup 0)) - (match_operand:SF 3 "register_operand" ""))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && TARGET_NO_SPACE_REGS - && REG_OK_FOR_INDEX_P (operands[1]) - && REG_OK_FOR_BASE_P (operands[2]) - && FP_REGNO_P (REGNO (operands[3]))" - [(set (mem:SF (plus:SI (match_dup 1) (match_dup 2))) - (match_dup 3)) - (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))] - "") - -(define_peephole2 - [(set (match_operand:SI 0 "register_operand" "") - (plus:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "register_operand" ""))) - (set (mem:SF (match_dup 0)) - (match_operand:SF 3 "register_operand" ""))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && TARGET_NO_SPACE_REGS - && REG_OK_FOR_BASE_P (operands[1]) - && REG_OK_FOR_INDEX_P (operands[2]) - && FP_REGNO_P (REGNO (operands[3]))" - [(set (mem:SF (plus:SI (match_dup 2) (match_dup 1))) - (match_dup 3)) - (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))] - "") - -(define_peephole2 - [(set (match_operand:DI 0 "register_operand" "") - (plus:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "register_operand" ""))) - (set (mem:SF (match_dup 0)) - (match_operand:SF 3 "register_operand" ""))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && TARGET_64BIT - && TARGET_NO_SPACE_REGS - && REG_OK_FOR_INDEX_P (operands[1]) - && REG_OK_FOR_BASE_P (operands[2]) - && FP_REGNO_P (REGNO (operands[3]))" - [(set (mem:SF (plus:DI (match_dup 1) (match_dup 2))) - (match_dup 3)) - (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))] - "") - -(define_peephole2 - [(set (match_operand:DI 0 "register_operand" "") - (plus:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "register_operand" ""))) - (set (mem:SF (match_dup 0)) - (match_operand:SF 3 "register_operand" ""))] - "!TARGET_SOFT_FLOAT - && !TARGET_DISABLE_INDEXING - && TARGET_64BIT - && TARGET_NO_SPACE_REGS - && REG_OK_FOR_BASE_P (operands[1]) - && REG_OK_FOR_INDEX_P (operands[2]) - && FP_REGNO_P (REGNO (operands[3]))" - [(set (mem:SF (plus:DI (match_dup 2) (match_dup 1))) - (match_dup 3)) - (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))] - "") - -(define_insn "" - [(set (match_operand:SF 0 "move_dest_operand" - "=r,r,Q") - (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand" - "rG,RQ,rG"))] - "(register_operand (operands[0], SFmode) - || reg_or_0_operand (operands[1], SFmode)) - && TARGET_SOFT_FLOAT" - "@ - copy %r1,%0 - ldw%M1 %1,%0 - stw%M0 %r1,%0" - [(set_attr "type" "move,load,store") - (set_attr "pa_combine_type" "addmove") - (set_attr "length" "4,4,4")]) - - - -;;- zero extension instructions -;; We have define_expand for zero extension patterns to make sure the -;; operands get loaded into registers. The define_insns accept -;; memory operands. This gives us better overall code than just -;; having a pattern that does or does not accept memory operands. - -(define_expand "zero_extendqihi2" - [(set (match_operand:HI 0 "register_operand" "") - (zero_extend:HI - (match_operand:QI 1 "register_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:HI 0 "register_operand" "=r,r") - (zero_extend:HI - (match_operand:QI 1 "move_src_operand" "r,RQ")))] - "GET_CODE (operands[1]) != CONST_INT" - "@ - {extru|extrw,u} %1,31,8,%0 - ldb%M1 %1,%0" - [(set_attr "type" "shift,load") - (set_attr "length" "4,4")]) - -(define_expand "zero_extendqisi2" - [(set (match_operand:SI 0 "register_operand" "") - (zero_extend:SI - (match_operand:QI 1 "register_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (zero_extend:SI - (match_operand:QI 1 "move_src_operand" "r,RQ")))] - "GET_CODE (operands[1]) != CONST_INT" - "@ - {extru|extrw,u} %1,31,8,%0 - ldb%M1 %1,%0" - [(set_attr "type" "shift,load") - (set_attr "length" "4,4")]) - -(define_expand "zero_extendhisi2" - [(set (match_operand:SI 0 "register_operand" "") - (zero_extend:SI - (match_operand:HI 1 "register_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (zero_extend:SI - (match_operand:HI 1 "move_src_operand" "r,RQ")))] - "GET_CODE (operands[1]) != CONST_INT" - "@ - {extru|extrw,u} %1,31,16,%0 - ldh%M1 %1,%0" - [(set_attr "type" "shift,load") - (set_attr "length" "4,4")]) - -(define_expand "zero_extendqidi2" - [(set (match_operand:DI 0 "register_operand" "") - (zero_extend:DI - (match_operand:QI 1 "register_operand" "")))] - "TARGET_64BIT" - "") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r,r") - (zero_extend:DI - (match_operand:QI 1 "move_src_operand" "r,RQ")))] - "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT" - "@ - extrd,u %1,63,8,%0 - ldb%M1 %1,%0" - [(set_attr "type" "shift,load") - (set_attr "length" "4,4")]) - -(define_expand "zero_extendhidi2" - [(set (match_operand:DI 0 "register_operand" "") - (zero_extend:DI - (match_operand:HI 1 "register_operand" "")))] - "TARGET_64BIT" - "") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r,r") - (zero_extend:DI - (match_operand:HI 1 "move_src_operand" "r,RQ")))] - "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT" - "@ - extrd,u %1,63,16,%0 - ldh%M1 %1,%0" - [(set_attr "type" "shift,load") - (set_attr "length" "4,4")]) - -(define_expand "zero_extendsidi2" - [(set (match_operand:DI 0 "register_operand" "") - (zero_extend:DI - (match_operand:SI 1 "register_operand" "")))] - "TARGET_64BIT" - "") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r,r") - (zero_extend:DI - (match_operand:SI 1 "move_src_operand" "r,RQ")))] - "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT" - "@ - extrd,u %1,63,32,%0 - ldw%M1 %1,%0" - [(set_attr "type" "shift,load") - (set_attr "length" "4,4")]) - -;;- sign extension instructions - -(define_insn "extendhisi2" - [(set (match_operand:SI 0 "register_operand" "=r") - (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))] - "" - "{extrs|extrw,s} %1,31,16,%0" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -(define_insn "extendqihi2" - [(set (match_operand:HI 0 "register_operand" "=r") - (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))] - "" - "{extrs|extrw,s} %1,31,8,%0" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -(define_insn "extendqisi2" - [(set (match_operand:SI 0 "register_operand" "=r") - (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))] - "" - "{extrs|extrw,s} %1,31,8,%0" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -(define_insn "extendqidi2" - [(set (match_operand:DI 0 "register_operand" "=r") - (sign_extend:DI (match_operand:QI 1 "register_operand" "r")))] - "TARGET_64BIT" - "extrd,s %1,63,8,%0" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -(define_insn "extendhidi2" - [(set (match_operand:DI 0 "register_operand" "=r") - (sign_extend:DI (match_operand:HI 1 "register_operand" "r")))] - "TARGET_64BIT" - "extrd,s %1,63,16,%0" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -(define_insn "extendsidi2" - [(set (match_operand:DI 0 "register_operand" "=r") - (sign_extend:DI (match_operand:SI 1 "register_operand" "r")))] - "TARGET_64BIT" - "extrd,s %1,63,32,%0" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - - -;; Conversions between float and double. - -(define_insn "extendsfdf2" - [(set (match_operand:DF 0 "register_operand" "=f") - (float_extend:DF - (match_operand:SF 1 "register_operand" "f")))] - "! TARGET_SOFT_FLOAT" - "{fcnvff|fcnv},sgl,dbl %1,%0" - [(set_attr "type" "fpalu") - (set_attr "length" "4")]) - -(define_insn "truncdfsf2" - [(set (match_operand:SF 0 "register_operand" "=f") - (float_truncate:SF - (match_operand:DF 1 "register_operand" "f")))] - "! TARGET_SOFT_FLOAT" - "{fcnvff|fcnv},dbl,sgl %1,%0" - [(set_attr "type" "fpalu") - (set_attr "length" "4")]) - -;; Conversion between fixed point and floating point. -;; Note that among the fix-to-float insns -;; the ones that start with SImode come first. -;; That is so that an operand that is a CONST_INT -;; (and therefore lacks a specific machine mode). -;; will be recognized as SImode (which is always valid) -;; rather than as QImode or HImode. - -;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...))) -;; to be reloaded by putting the constant into memory. -;; It must come before the more general floatsisf2 pattern. -(define_insn "" - [(set (match_operand:SF 0 "register_operand" "=f") - (float:SF (match_operand:SI 1 "const_int_operand" "m")))] - "! TARGET_SOFT_FLOAT" - "fldw%F1 %1,%0\;{fcnvxf,sgl,sgl|fcnv,w,sgl} %0,%0" - [(set_attr "type" "fpalu") - (set_attr "length" "8")]) - -(define_insn "floatsisf2" - [(set (match_operand:SF 0 "register_operand" "=f") - (float:SF (match_operand:SI 1 "register_operand" "f")))] - "! TARGET_SOFT_FLOAT" - "{fcnvxf,sgl,sgl|fcnv,w,sgl} %1,%0" - [(set_attr "type" "fpalu") - (set_attr "length" "4")]) - -;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...))) -;; to be reloaded by putting the constant into memory. -;; It must come before the more general floatsidf2 pattern. -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f") - (float:DF (match_operand:SI 1 "const_int_operand" "m")))] - "! TARGET_SOFT_FLOAT" - "fldw%F1 %1,%0\;{fcnvxf,sgl,dbl|fcnv,w,dbl} %0,%0" - [(set_attr "type" "fpalu") - (set_attr "length" "8")]) - -(define_insn "floatsidf2" - [(set (match_operand:DF 0 "register_operand" "=f") - (float:DF (match_operand:SI 1 "register_operand" "f")))] - "! TARGET_SOFT_FLOAT" - "{fcnvxf,sgl,dbl|fcnv,w,dbl} %1,%0" - [(set_attr "type" "fpalu") - (set_attr "length" "4")]) - -(define_expand "floatunssisf2" - [(set (subreg:SI (match_dup 2) 4) - (match_operand:SI 1 "register_operand" "")) - (set (subreg:SI (match_dup 2) 0) - (const_int 0)) - (set (match_operand:SF 0 "register_operand" "") - (float:SF (match_dup 2)))] - "TARGET_PA_11 && ! TARGET_SOFT_FLOAT" - " -{ - if (TARGET_PA_20) - { - emit_insn (gen_floatunssisf2_pa20 (operands[0], operands[1])); - DONE; - } - operands[2] = gen_reg_rtx (DImode); -}") - -(define_expand "floatunssidf2" - [(set (subreg:SI (match_dup 2) 4) - (match_operand:SI 1 "register_operand" "")) - (set (subreg:SI (match_dup 2) 0) - (const_int 0)) - (set (match_operand:DF 0 "register_operand" "") - (float:DF (match_dup 2)))] - "TARGET_PA_11 && ! TARGET_SOFT_FLOAT" - " -{ - if (TARGET_PA_20) - { - emit_insn (gen_floatunssidf2_pa20 (operands[0], operands[1])); - DONE; - } - operands[2] = gen_reg_rtx (DImode); -}") - -(define_insn "floatdisf2" - [(set (match_operand:SF 0 "register_operand" "=f") - (float:SF (match_operand:DI 1 "register_operand" "f")))] - "TARGET_PA_11 && ! TARGET_SOFT_FLOAT" - "{fcnvxf,dbl,sgl|fcnv,dw,sgl} %1,%0" - [(set_attr "type" "fpalu") - (set_attr "length" "4")]) - -(define_insn "floatdidf2" - [(set (match_operand:DF 0 "register_operand" "=f") - (float:DF (match_operand:DI 1 "register_operand" "f")))] - "TARGET_PA_11 && ! TARGET_SOFT_FLOAT" - "{fcnvxf,dbl,dbl|fcnv,dw,dbl} %1,%0" - [(set_attr "type" "fpalu") - (set_attr "length" "4")]) - -;; Convert a float to an actual integer. -;; Truncation is performed as part of the conversion. - -(define_insn "fix_truncsfsi2" - [(set (match_operand:SI 0 "register_operand" "=f") - (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))] - "! TARGET_SOFT_FLOAT" - "{fcnvfxt,sgl,sgl|fcnv,t,sgl,w} %1,%0" - [(set_attr "type" "fpalu") - (set_attr "length" "4")]) - -(define_insn "fix_truncdfsi2" - [(set (match_operand:SI 0 "register_operand" "=f") - (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))] - "! TARGET_SOFT_FLOAT" - "{fcnvfxt,dbl,sgl|fcnv,t,dbl,w} %1,%0" - [(set_attr "type" "fpalu") - (set_attr "length" "4")]) - -(define_insn "fix_truncsfdi2" - [(set (match_operand:DI 0 "register_operand" "=f") - (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))] - "TARGET_PA_11 && ! TARGET_SOFT_FLOAT" - "{fcnvfxt,sgl,dbl|fcnv,t,sgl,dw} %1,%0" - [(set_attr "type" "fpalu") - (set_attr "length" "4")]) - -(define_insn "fix_truncdfdi2" - [(set (match_operand:DI 0 "register_operand" "=f") - (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))] - "TARGET_PA_11 && ! TARGET_SOFT_FLOAT" - "{fcnvfxt,dbl,dbl|fcnv,t,dbl,dw} %1,%0" - [(set_attr "type" "fpalu") - (set_attr "length" "4")]) - -(define_insn "floatunssidf2_pa20" - [(set (match_operand:DF 0 "register_operand" "=f") - (unsigned_float:DF (match_operand:SI 1 "register_operand" "f")))] - "! TARGET_SOFT_FLOAT && TARGET_PA_20" - "fcnv,uw,dbl %1,%0" - [(set_attr "type" "fpalu") - (set_attr "length" "4")]) - -(define_insn "floatunssisf2_pa20" - [(set (match_operand:SF 0 "register_operand" "=f") - (unsigned_float:SF (match_operand:SI 1 "register_operand" "f")))] - "! TARGET_SOFT_FLOAT && TARGET_PA_20" - "fcnv,uw,sgl %1,%0" - [(set_attr "type" "fpalu") - (set_attr "length" "4")]) - -(define_insn "floatunsdisf2" - [(set (match_operand:SF 0 "register_operand" "=f") - (unsigned_float:SF (match_operand:DI 1 "register_operand" "f")))] - "! TARGET_SOFT_FLOAT && TARGET_PA_20" - "fcnv,udw,sgl %1,%0" - [(set_attr "type" "fpalu") - (set_attr "length" "4")]) - -(define_insn "floatunsdidf2" - [(set (match_operand:DF 0 "register_operand" "=f") - (unsigned_float:DF (match_operand:DI 1 "register_operand" "f")))] - "! TARGET_SOFT_FLOAT && TARGET_PA_20" - "fcnv,udw,dbl %1,%0" - [(set_attr "type" "fpalu") - (set_attr "length" "4")]) - -(define_insn "fixuns_truncsfsi2" - [(set (match_operand:SI 0 "register_operand" "=f") - (unsigned_fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))] - "! TARGET_SOFT_FLOAT && TARGET_PA_20" - "fcnv,t,sgl,uw %1,%0" - [(set_attr "type" "fpalu") - (set_attr "length" "4")]) - -(define_insn "fixuns_truncdfsi2" - [(set (match_operand:SI 0 "register_operand" "=f") - (unsigned_fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))] - "! TARGET_SOFT_FLOAT && TARGET_PA_20" - "fcnv,t,dbl,uw %1,%0" - [(set_attr "type" "fpalu") - (set_attr "length" "4")]) - -(define_insn "fixuns_truncsfdi2" - [(set (match_operand:DI 0 "register_operand" "=f") - (unsigned_fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))] - "! TARGET_SOFT_FLOAT && TARGET_PA_20" - "fcnv,t,sgl,udw %1,%0" - [(set_attr "type" "fpalu") - (set_attr "length" "4")]) - -(define_insn "fixuns_truncdfdi2" - [(set (match_operand:DI 0 "register_operand" "=f") - (unsigned_fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))] - "! TARGET_SOFT_FLOAT && TARGET_PA_20" - "fcnv,t,dbl,udw %1,%0" - [(set_attr "type" "fpalu") - (set_attr "length" "4")]) - -;;- arithmetic instructions - -(define_expand "adddi3" - [(set (match_operand:DI 0 "register_operand" "") - (plus:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "adddi3_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (plus:DI (match_operand:DI 1 "register_operand" "%r") - (match_operand:DI 2 "arith11_operand" "rI")))] - "!TARGET_64BIT" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT) - { - if (INTVAL (operands[2]) >= 0) - return \"addi %2,%R1,%R0\;{addc|add,c} %1,%%r0,%0\"; - else - return \"addi %2,%R1,%R0\;{subb|sub,b} %1,%%r0,%0\"; - } - else - return \"add %R2,%R1,%R0\;{addc|add,c} %2,%1,%0\"; -}" - [(set_attr "type" "binary") - (set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r,r") - (plus:DI (match_operand:DI 1 "register_operand" "%r,r") - (match_operand:DI 2 "arith14_operand" "r,J")))] - "TARGET_64BIT" - "@ - add,l %1,%2,%0 - ldo %2(%1),%0" - [(set_attr "type" "binary,binary") - (set_attr "pa_combine_type" "addmove") - (set_attr "length" "4,4")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (plus:DI (not:DI (match_operand:DI 1 "register_operand" "r")) - (match_operand:DI 2 "register_operand" "r")))] - "TARGET_64BIT" - "uaddcm %2,%1,%0" - [(set_attr "type" "binary") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (plus:SI (not:SI (match_operand:SI 1 "register_operand" "r")) - (match_operand:SI 2 "register_operand" "r")))] - "" - "uaddcm %2,%1,%0" - [(set_attr "type" "binary") - (set_attr "length" "4")]) - -(define_expand "addvdi3" - [(parallel [(set (match_operand:DI 0 "register_operand" "") - (plus:DI (match_operand:DI 1 "reg_or_0_operand" "") - (match_operand:DI 2 "arith11_operand" ""))) - (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1)) - (sign_extend:TI (match_dup 2))) - (sign_extend:TI (plus:DI (match_dup 1) - (match_dup 2)))) - (const_int 0))])] - "" - "") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r,r") - (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rM,rM") - (match_operand:DI 2 "arith11_operand" "r,I"))) - (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1)) - (sign_extend:TI (match_dup 2))) - (sign_extend:TI (plus:DI (match_dup 1) - (match_dup 2)))) - (const_int 0))] - "TARGET_64BIT" - "@ - add,tsv,* %2,%1,%0 - addi,tsv,* %2,%1,%0" - [(set_attr "type" "binary,binary") - (set_attr "length" "4,4")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rM") - (match_operand:DI 2 "arith11_operand" "rI"))) - (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1)) - (sign_extend:TI (match_dup 2))) - (sign_extend:TI (plus:DI (match_dup 1) - (match_dup 2)))) - (const_int 0))] - "!TARGET_64BIT" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT) - { - if (INTVAL (operands[2]) >= 0) - return \"addi %2,%R1,%R0\;{addco|add,c,tsv} %1,%%r0,%0\"; - else - return \"addi %2,%R1,%R0\;{subbo|sub,b,tsv} %1,%%r0,%0\"; - } - else - return \"add %R2,%R1,%R0\;{addco|add,c,tsv} %2,%1,%0\"; -}" - [(set_attr "type" "binary") - (set_attr "length" "8")]) - -;; define_splits to optimize cases of adding a constant integer -;; to a register when the constant does not fit in 14 bits. */ -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (plus:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "const_int_operand" ""))) - (clobber (match_operand:SI 4 "register_operand" ""))] - "! pa_cint_ok_for_move (INTVAL (operands[2])) - && VAL_14_BITS_P (INTVAL (operands[2]) >> 1)" - [(set (match_dup 4) (plus:SI (match_dup 1) (match_dup 2))) - (set (match_dup 0) (plus:SI (match_dup 4) (match_dup 3)))] - " -{ - int val = INTVAL (operands[2]); - int low = (val < 0) ? -0x2000 : 0x1fff; - int rest = val - low; - - operands[2] = GEN_INT (rest); - operands[3] = GEN_INT (low); -}") - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (plus:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "const_int_operand" ""))) - (clobber (match_operand:SI 4 "register_operand" ""))] - "! pa_cint_ok_for_move (INTVAL (operands[2]))" - [(set (match_dup 4) (match_dup 2)) - (set (match_dup 0) (plus:SI (mult:SI (match_dup 4) (match_dup 3)) - (match_dup 1)))] - " -{ - HOST_WIDE_INT intval = INTVAL (operands[2]); - - /* 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 - in a single instruction (pa_cint_ok_for_move). - - If that fails, try to negate the constant and subtract it - from our input operand. */ - if (intval % 2 == 0 && pa_cint_ok_for_move (intval / 2)) - { - operands[2] = GEN_INT (intval / 2); - operands[3] = const2_rtx; - } - else if (intval % 4 == 0 && pa_cint_ok_for_move (intval / 4)) - { - operands[2] = GEN_INT (intval / 4); - operands[3] = GEN_INT (4); - } - else if (intval % 8 == 0 && pa_cint_ok_for_move (intval / 8)) - { - operands[2] = GEN_INT (intval / 8); - operands[3] = GEN_INT (8); - } - else if (pa_cint_ok_for_move (-intval)) - { - emit_insn (gen_rtx_SET (VOIDmode, operands[4], GEN_INT (-intval))); - emit_insn (gen_subsi3 (operands[0], operands[1], operands[4])); - DONE; - } - else - FAIL; -}") - -(define_insn "addsi3" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (plus:SI (match_operand:SI 1 "register_operand" "%r,r") - (match_operand:SI 2 "arith14_operand" "r,J")))] - "" - "@ - {addl|add,l} %1,%2,%0 - ldo %2(%1),%0" - [(set_attr "type" "binary,binary") - (set_attr "pa_combine_type" "addmove") - (set_attr "length" "4,4")]) - -(define_insn "addvsi3" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rM,rM") - (match_operand:SI 2 "arith11_operand" "r,I"))) - (trap_if (ne (plus:DI (sign_extend:DI (match_dup 1)) - (sign_extend:DI (match_dup 2))) - (sign_extend:DI (plus:SI (match_dup 1) - (match_dup 2)))) - (const_int 0))] - "" - "@ - {addo|add,tsv} %2,%1,%0 - {addio|addi,tsv} %2,%1,%0" - [(set_attr "type" "binary,binary") - (set_attr "length" "4,4")]) - -(define_expand "subdi3" - [(set (match_operand:DI 0 "register_operand" "") - (minus:DI (match_operand:DI 1 "arith11_operand" "") - (match_operand:DI 2 "reg_or_0_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r,r,!q") - (minus:DI (match_operand:DI 1 "arith11_operand" "r,I,!U") - (match_operand:DI 2 "reg_or_0_operand" "rM,rM,!rM")))] - "TARGET_64BIT" - "@ - sub %1,%2,%0 - subi %1,%2,%0 - mtsarcm %2" - [(set_attr "type" "binary,binary,move") - (set_attr "length" "4,4,4")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r,&r") - (minus:DI (match_operand:DI 1 "arith11_operand" "r,I") - (match_operand:DI 2 "reg_or_0_operand" "rM,rM")))] - "!TARGET_64BIT" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT) - { - if (INTVAL (operands[1]) >= 0) - return \"subi %1,%R2,%R0\;{subb|sub,b} %%r0,%2,%0\"; - else - return \"ldi -1,%0\;subi %1,%R2,%R0\;{subb|sub,b} %0,%2,%0\"; - } - else - return \"sub %R1,%R2,%R0\;{subb|sub,b} %1,%2,%0\"; -}" - [(set_attr "type" "binary") - (set (attr "length") - (if_then_else (eq_attr "alternative" "0") - (const_int 8) - (if_then_else (ge (symbol_ref "INTVAL (operands[1])") - (const_int 0)) - (const_int 8) - (const_int 12))))]) - -(define_expand "subvdi3" - [(parallel [(set (match_operand:DI 0 "register_operand" "") - (minus:DI (match_operand:DI 1 "arith11_operand" "") - (match_operand:DI 2 "reg_or_0_operand" ""))) - (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1)) - (sign_extend:TI (match_dup 2))) - (sign_extend:TI (minus:DI (match_dup 1) - (match_dup 2)))) - (const_int 0))])] - "" - "") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r,r") - (minus:DI (match_operand:DI 1 "arith11_operand" "r,I") - (match_operand:DI 2 "reg_or_0_operand" "rM,rM"))) - (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1)) - (sign_extend:TI (match_dup 2))) - (sign_extend:TI (minus:DI (match_dup 1) - (match_dup 2)))) - (const_int 0))] - "TARGET_64BIT" - "@ - {subo|sub,tsv} %1,%2,%0 - {subio|subi,tsv} %1,%2,%0" - [(set_attr "type" "binary,binary") - (set_attr "length" "4,4")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r,&r") - (minus:DI (match_operand:DI 1 "arith11_operand" "r,I") - (match_operand:DI 2 "reg_or_0_operand" "rM,rM"))) - (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1)) - (sign_extend:TI (match_dup 2))) - (sign_extend:TI (minus:DI (match_dup 1) - (match_dup 2)))) - (const_int 0))] - "!TARGET_64BIT" - "* -{ - if (GET_CODE (operands[1]) == CONST_INT) - { - if (INTVAL (operands[1]) >= 0) - return \"subi %1,%R2,%R0\;{subbo|sub,b,tsv} %%r0,%2,%0\"; - else - return \"ldi -1,%0\;subi %1,%R2,%R0\;{subbo|sub,b,tsv} %0,%2,%0\"; - } - else - return \"sub %R1,%R2,%R0\;{subbo|sub,b,tsv} %1,%2,%0\"; -}" - [(set_attr "type" "binary,binary") - (set (attr "length") - (if_then_else (eq_attr "alternative" "0") - (const_int 8) - (if_then_else (ge (symbol_ref "INTVAL (operands[1])") - (const_int 0)) - (const_int 8) - (const_int 12))))]) - -(define_expand "subsi3" - [(set (match_operand:SI 0 "register_operand" "") - (minus:SI (match_operand:SI 1 "arith11_operand" "") - (match_operand:SI 2 "register_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (minus:SI (match_operand:SI 1 "arith11_operand" "r,I") - (match_operand:SI 2 "register_operand" "r,r")))] - "!TARGET_PA_20" - "@ - sub %1,%2,%0 - subi %1,%2,%0" - [(set_attr "type" "binary,binary") - (set_attr "length" "4,4")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r,r,!q") - (minus:SI (match_operand:SI 1 "arith11_operand" "r,I,!S") - (match_operand:SI 2 "register_operand" "r,r,!r")))] - "TARGET_PA_20" - "@ - sub %1,%2,%0 - subi %1,%2,%0 - mtsarcm %2" - [(set_attr "type" "binary,binary,move") - (set_attr "length" "4,4,4")]) - -(define_insn "subvsi3" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (minus:SI (match_operand:SI 1 "arith11_operand" "rM,I") - (match_operand:SI 2 "reg_or_0_operand" "rM,rM"))) - (trap_if (ne (minus:DI (sign_extend:DI (match_dup 1)) - (sign_extend:DI (match_dup 2))) - (sign_extend:DI (minus:SI (match_dup 1) - (match_dup 2)))) - (const_int 0))] - "" - "@ - {subo|sub,tsv} %1,%2,%0 - {subio|subi,tsv} %1,%2,%0" - [(set_attr "type" "binary,binary") - (set_attr "length" "4,4")]) - -;; Clobbering a "register_operand" instead of a match_scratch -;; in operand3 of millicode calls avoids spilling %r1 and -;; produces better code. - -;; The mulsi3 insns set up registers for the millicode call. -(define_expand "mulsi3" - [(set (reg:SI 26) (match_operand:SI 1 "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))) - (clobber (match_dup 3)) - (clobber (reg:SI 26)) - (clobber (reg:SI 25)) - (clobber (match_dup 4))]) - (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))] - "" - " -{ - operands[4] = gen_rtx_REG (SImode, TARGET_64BIT ? 2 : 31); - if (TARGET_PA_11 && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT) - { - rtx scratch = gen_reg_rtx (DImode); - operands[1] = force_reg (SImode, operands[1]); - operands[2] = force_reg (SImode, operands[2]); - emit_insn (gen_umulsidi3 (scratch, operands[1], operands[2])); - emit_insn (gen_movsi (operands[0], - gen_rtx_SUBREG (SImode, scratch, - GET_MODE_SIZE (SImode)))); - DONE; - } - operands[3] = gen_reg_rtx (SImode); -}") - -(define_insn "umulsidi3" - [(set (match_operand:DI 0 "register_operand" "=f") - (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f")) - (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "f"))))] - "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT" - "xmpyu %1,%2,%0" - [(set_attr "type" "fpmuldbl") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=f") - (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f")) - (match_operand:DI 2 "uint32_operand" "f")))] - "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT && !TARGET_64BIT" - "xmpyu %1,%R2,%0" - [(set_attr "type" "fpmuldbl") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=f") - (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f")) - (match_operand:DI 2 "uint32_operand" "f")))] - "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT && TARGET_64BIT" - "xmpyu %1,%2R,%0" - [(set_attr "type" "fpmuldbl") - (set_attr "length" "4")]) - -(define_insn "" - [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25))) - (clobber (match_operand:SI 0 "register_operand" "=a")) - (clobber (reg:SI 26)) - (clobber (reg:SI 25)) - (clobber (reg:SI 31))] - "!TARGET_64BIT" - "* return pa_output_mul_insn (0, insn);" - [(set_attr "type" "milli") - (set (attr "length") - (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)] - (symbol_ref "pa_attr_length_millicode_call (insn)")))]) - -(define_insn "" - [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25))) - (clobber (match_operand:SI 0 "register_operand" "=a")) - (clobber (reg:SI 26)) - (clobber (reg:SI 25)) - (clobber (reg:SI 2))] - "TARGET_64BIT" - "* return pa_output_mul_insn (0, insn);" - [(set_attr "type" "milli") - (set (attr "length") - (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)] - (symbol_ref "pa_attr_length_millicode_call (insn)")))]) - -(define_expand "muldi3" - [(set (match_operand:DI 0 "register_operand" "") - (mult:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "register_operand" "")))] - "TARGET_64BIT && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT" - " -{ - rtx low_product = gen_reg_rtx (DImode); - rtx cross_product1 = gen_reg_rtx (DImode); - rtx cross_product2 = gen_reg_rtx (DImode); - rtx cross_scratch = gen_reg_rtx (DImode); - rtx cross_product = gen_reg_rtx (DImode); - rtx op1l, op1r, op2l, op2r; - rtx op1shifted, op2shifted; - - op1shifted = gen_reg_rtx (DImode); - op2shifted = gen_reg_rtx (DImode); - op1l = gen_reg_rtx (SImode); - op1r = gen_reg_rtx (SImode); - op2l = gen_reg_rtx (SImode); - op2r = gen_reg_rtx (SImode); - - emit_move_insn (op1shifted, gen_rtx_LSHIFTRT (DImode, operands[1], - GEN_INT (32))); - emit_move_insn (op2shifted, gen_rtx_LSHIFTRT (DImode, operands[2], - GEN_INT (32))); - op1r = force_reg (SImode, gen_rtx_SUBREG (SImode, operands[1], 4)); - op2r = force_reg (SImode, gen_rtx_SUBREG (SImode, operands[2], 4)); - op1l = force_reg (SImode, gen_rtx_SUBREG (SImode, op1shifted, 4)); - op2l = force_reg (SImode, gen_rtx_SUBREG (SImode, op2shifted, 4)); - - /* Emit multiplies for the cross products. */ - emit_insn (gen_umulsidi3 (cross_product1, op2r, op1l)); - emit_insn (gen_umulsidi3 (cross_product2, op2l, op1r)); - - /* Emit a multiply for the low sub-word. */ - emit_insn (gen_umulsidi3 (low_product, copy_rtx (op2r), copy_rtx (op1r))); - - /* Sum the cross products and shift them into proper position. */ - emit_insn (gen_adddi3 (cross_scratch, cross_product1, cross_product2)); - emit_insn (gen_ashldi3 (cross_product, cross_scratch, GEN_INT (32))); - - /* Add the cross product to the low product and store the result - into the output operand . */ - emit_insn (gen_adddi3 (operands[0], cross_product, low_product)); - DONE; -}") - -;;; Division and mod. -(define_expand "divsi3" - [(set (reg:SI 26) (match_operand:SI 1 "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))) - (clobber (match_dup 3)) - (clobber (match_dup 4)) - (clobber (reg:SI 26)) - (clobber (reg:SI 25)) - (clobber (match_dup 5))]) - (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))] - "" - " -{ - operands[3] = gen_reg_rtx (SImode); - if (TARGET_64BIT) - { - operands[5] = gen_rtx_REG (SImode, 2); - operands[4] = operands[5]; - } - else - { - operands[5] = gen_rtx_REG (SImode, 31); - operands[4] = gen_reg_rtx (SImode); - } - if (GET_CODE (operands[2]) == CONST_INT && pa_emit_hpdiv_const (operands, 0)) - DONE; -}") - -(define_insn "" - [(set (reg:SI 29) - (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" ""))) - (clobber (match_operand:SI 1 "register_operand" "=a")) - (clobber (match_operand:SI 2 "register_operand" "=&r")) - (clobber (reg:SI 26)) - (clobber (reg:SI 25)) - (clobber (reg:SI 31))] - "!TARGET_64BIT" - "* - return pa_output_div_insn (operands, 0, insn);" - [(set_attr "type" "milli") - (set (attr "length") - (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)] - (symbol_ref "pa_attr_length_millicode_call (insn)")))]) - -(define_insn "" - [(set (reg:SI 29) - (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" ""))) - (clobber (match_operand:SI 1 "register_operand" "=a")) - (clobber (match_operand:SI 2 "register_operand" "=&r")) - (clobber (reg:SI 26)) - (clobber (reg:SI 25)) - (clobber (reg:SI 2))] - "TARGET_64BIT" - "* - return pa_output_div_insn (operands, 0, insn);" - [(set_attr "type" "milli") - (set (attr "length") - (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)] - (symbol_ref "pa_attr_length_millicode_call (insn)")))]) - -(define_expand "udivsi3" - [(set (reg:SI 26) (match_operand:SI 1 "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))) - (clobber (match_dup 3)) - (clobber (match_dup 4)) - (clobber (reg:SI 26)) - (clobber (reg:SI 25)) - (clobber (match_dup 5))]) - (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))] - "" - " -{ - operands[3] = gen_reg_rtx (SImode); - - if (TARGET_64BIT) - { - operands[5] = gen_rtx_REG (SImode, 2); - operands[4] = operands[5]; - } - else - { - operands[5] = gen_rtx_REG (SImode, 31); - operands[4] = gen_reg_rtx (SImode); - } - if (GET_CODE (operands[2]) == CONST_INT && pa_emit_hpdiv_const (operands, 1)) - DONE; -}") - -(define_insn "" - [(set (reg:SI 29) - (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" ""))) - (clobber (match_operand:SI 1 "register_operand" "=a")) - (clobber (match_operand:SI 2 "register_operand" "=&r")) - (clobber (reg:SI 26)) - (clobber (reg:SI 25)) - (clobber (reg:SI 31))] - "!TARGET_64BIT" - "* - return pa_output_div_insn (operands, 1, insn);" - [(set_attr "type" "milli") - (set (attr "length") - (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)] - (symbol_ref "pa_attr_length_millicode_call (insn)")))]) - -(define_insn "" - [(set (reg:SI 29) - (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" ""))) - (clobber (match_operand:SI 1 "register_operand" "=a")) - (clobber (match_operand:SI 2 "register_operand" "=&r")) - (clobber (reg:SI 26)) - (clobber (reg:SI 25)) - (clobber (reg:SI 2))] - "TARGET_64BIT" - "* - return pa_output_div_insn (operands, 1, insn);" - [(set_attr "type" "milli") - (set (attr "length") - (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)] - (symbol_ref "pa_attr_length_millicode_call (insn)")))]) - -(define_expand "modsi3" - [(set (reg:SI 26) (match_operand:SI 1 "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))) - (clobber (match_dup 3)) - (clobber (match_dup 4)) - (clobber (reg:SI 26)) - (clobber (reg:SI 25)) - (clobber (match_dup 5))]) - (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))] - "" - " -{ - if (TARGET_64BIT) - { - operands[5] = gen_rtx_REG (SImode, 2); - operands[4] = operands[5]; - } - else - { - operands[5] = gen_rtx_REG (SImode, 31); - operands[4] = gen_reg_rtx (SImode); - } - operands[3] = gen_reg_rtx (SImode); -}") - -(define_insn "" - [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25))) - (clobber (match_operand:SI 0 "register_operand" "=a")) - (clobber (match_operand:SI 1 "register_operand" "=&r")) - (clobber (reg:SI 26)) - (clobber (reg:SI 25)) - (clobber (reg:SI 31))] - "!TARGET_64BIT" - "* - return pa_output_mod_insn (0, insn);" - [(set_attr "type" "milli") - (set (attr "length") - (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)] - (symbol_ref "pa_attr_length_millicode_call (insn)")))]) - -(define_insn "" - [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25))) - (clobber (match_operand:SI 0 "register_operand" "=a")) - (clobber (match_operand:SI 1 "register_operand" "=&r")) - (clobber (reg:SI 26)) - (clobber (reg:SI 25)) - (clobber (reg:SI 2))] - "TARGET_64BIT" - "* - return pa_output_mod_insn (0, insn);" - [(set_attr "type" "milli") - (set (attr "length") - (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)] - (symbol_ref "pa_attr_length_millicode_call (insn)")))]) - -(define_expand "umodsi3" - [(set (reg:SI 26) (match_operand:SI 1 "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))) - (clobber (match_dup 3)) - (clobber (match_dup 4)) - (clobber (reg:SI 26)) - (clobber (reg:SI 25)) - (clobber (match_dup 5))]) - (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))] - "" - " -{ - if (TARGET_64BIT) - { - operands[5] = gen_rtx_REG (SImode, 2); - operands[4] = operands[5]; - } - else - { - operands[5] = gen_rtx_REG (SImode, 31); - operands[4] = gen_reg_rtx (SImode); - } - operands[3] = gen_reg_rtx (SImode); -}") - -(define_insn "" - [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25))) - (clobber (match_operand:SI 0 "register_operand" "=a")) - (clobber (match_operand:SI 1 "register_operand" "=&r")) - (clobber (reg:SI 26)) - (clobber (reg:SI 25)) - (clobber (reg:SI 31))] - "!TARGET_64BIT" - "* - return pa_output_mod_insn (1, insn);" - [(set_attr "type" "milli") - (set (attr "length") - (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)] - (symbol_ref "pa_attr_length_millicode_call (insn)")))]) - -(define_insn "" - [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25))) - (clobber (match_operand:SI 0 "register_operand" "=a")) - (clobber (match_operand:SI 1 "register_operand" "=&r")) - (clobber (reg:SI 26)) - (clobber (reg:SI 25)) - (clobber (reg:SI 2))] - "TARGET_64BIT" - "* - return pa_output_mod_insn (1, insn);" - [(set_attr "type" "milli") - (set (attr "length") - (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)] - (symbol_ref "pa_attr_length_millicode_call (insn)")))]) - -;;- and instructions -;; We define DImode `and` so with DImode `not` we can get -;; DImode `andn`. Other combinations are possible. - -(define_expand "anddi3" - [(set (match_operand:DI 0 "register_operand" "") - (and:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "and_operand" "")))] - "TARGET_64BIT" - "") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r,r") - (and:DI (match_operand:DI 1 "register_operand" "%?r,0") - (match_operand:DI 2 "and_operand" "rO,P")))] - "TARGET_64BIT" - "* return pa_output_64bit_and (operands); " - [(set_attr "type" "binary") - (set_attr "length" "4")]) - -; The ? for op1 makes reload prefer zdepi instead of loading a huge -; constant with ldil;ldo. -(define_insn "andsi3" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (and:SI (match_operand:SI 1 "register_operand" "%?r,0") - (match_operand:SI 2 "and_operand" "rO,P")))] - "" - "* return pa_output_and (operands); " - [(set_attr "type" "binary,shift") - (set_attr "length" "4,4")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (and:DI (not:DI (match_operand:DI 1 "register_operand" "r")) - (match_operand:DI 2 "register_operand" "r")))] - "TARGET_64BIT" - "andcm %2,%1,%0" - [(set_attr "type" "binary") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (and:SI (not:SI (match_operand:SI 1 "register_operand" "r")) - (match_operand:SI 2 "register_operand" "r")))] - "" - "andcm %2,%1,%0" - [(set_attr "type" "binary") - (set_attr "length" "4")]) - -(define_expand "iordi3" - [(set (match_operand:DI 0 "register_operand" "") - (ior:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "reg_or_cint_ior_operand" "")))] - "TARGET_64BIT" - "") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r,r") - (ior:DI (match_operand:DI 1 "register_operand" "0,0") - (match_operand:DI 2 "cint_ior_operand" "M,i")))] - "TARGET_64BIT" - "* return pa_output_64bit_ior (operands); " - [(set_attr "type" "binary,shift") - (set_attr "length" "4,4")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (ior:DI (match_operand:DI 1 "register_operand" "%r") - (match_operand:DI 2 "register_operand" "r")))] - "TARGET_64BIT" - "or %1,%2,%0" - [(set_attr "type" "binary") - (set_attr "length" "4")]) - -;; Need a define_expand because we've run out of CONST_OK... characters. -(define_expand "iorsi3" - [(set (match_operand:SI 0 "register_operand" "") - (ior:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "reg_or_cint_ior_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (ior:SI (match_operand:SI 1 "register_operand" "0,0") - (match_operand:SI 2 "cint_ior_operand" "M,i")))] - "" - "* return pa_output_ior (operands); " - [(set_attr "type" "binary,shift") - (set_attr "length" "4,4")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (ior:SI (match_operand:SI 1 "register_operand" "%r") - (match_operand:SI 2 "register_operand" "r")))] - "" - "or %1,%2,%0" - [(set_attr "type" "binary") - (set_attr "length" "4")]) - -(define_expand "xordi3" - [(set (match_operand:DI 0 "register_operand" "") - (xor:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "register_operand" "")))] - "TARGET_64BIT" - "") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (xor:DI (match_operand:DI 1 "register_operand" "%r") - (match_operand:DI 2 "register_operand" "r")))] - "TARGET_64BIT" - "xor %1,%2,%0" - [(set_attr "type" "binary") - (set_attr "length" "4")]) - -(define_insn "xorsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (xor:SI (match_operand:SI 1 "register_operand" "%r") - (match_operand:SI 2 "register_operand" "r")))] - "" - "xor %1,%2,%0" - [(set_attr "type" "binary") - (set_attr "length" "4")]) - -(define_expand "negdi2" - [(set (match_operand:DI 0 "register_operand" "") - (neg:DI (match_operand:DI 1 "register_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (neg:DI (match_operand:DI 1 "register_operand" "r")))] - "!TARGET_64BIT" - "sub %%r0,%R1,%R0\;{subb|sub,b} %%r0,%1,%0" - [(set_attr "type" "unary") - (set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (neg:DI (match_operand:DI 1 "register_operand" "r")))] - "TARGET_64BIT" - "sub %%r0,%1,%0" - [(set_attr "type" "unary") - (set_attr "length" "4")]) - -(define_expand "negvdi2" - [(parallel [(set (match_operand:DI 0 "register_operand" "") - (neg:DI (match_operand:DI 1 "register_operand" ""))) - (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1))) - (sign_extend:TI (neg:DI (match_dup 1)))) - (const_int 0))])] - "" - "") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (neg:DI (match_operand:DI 1 "register_operand" "r"))) - (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1))) - (sign_extend:TI (neg:DI (match_dup 1)))) - (const_int 0))] - "!TARGET_64BIT" - "sub %%r0,%R1,%R0\;{subbo|sub,b,tsv} %%r0,%1,%0" - [(set_attr "type" "unary") - (set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (neg:DI (match_operand:DI 1 "register_operand" "r"))) - (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1))) - (sign_extend:TI (neg:DI (match_dup 1)))) - (const_int 0))] - "TARGET_64BIT" - "sub,tsv %%r0,%1,%0" - [(set_attr "type" "unary") - (set_attr "length" "4")]) - -(define_insn "negsi2" - [(set (match_operand:SI 0 "register_operand" "=r") - (neg:SI (match_operand:SI 1 "register_operand" "r")))] - "" - "sub %%r0,%1,%0" - [(set_attr "type" "unary") - (set_attr "length" "4")]) - -(define_insn "negvsi2" - [(set (match_operand:SI 0 "register_operand" "=r") - (neg:SI (match_operand:SI 1 "register_operand" "r"))) - (trap_if (ne (neg:DI (sign_extend:DI (match_dup 1))) - (sign_extend:DI (neg:SI (match_dup 1)))) - (const_int 0))] - "" - "{subo|sub,tsv} %%r0,%1,%0" - [(set_attr "type" "unary") - (set_attr "length" "4")]) - -(define_expand "one_cmpldi2" - [(set (match_operand:DI 0 "register_operand" "") - (not:DI (match_operand:DI 1 "register_operand" "")))] - "" - " -{ -}") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (not:DI (match_operand:DI 1 "register_operand" "r")))] - "!TARGET_64BIT" - "uaddcm %%r0,%1,%0\;uaddcm %%r0,%R1,%R0" - [(set_attr "type" "unary") - (set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (not:DI (match_operand:DI 1 "register_operand" "r")))] - "TARGET_64BIT" - "uaddcm %%r0,%1,%0" - [(set_attr "type" "unary") - (set_attr "length" "4")]) - -(define_insn "one_cmplsi2" - [(set (match_operand:SI 0 "register_operand" "=r") - (not:SI (match_operand:SI 1 "register_operand" "r")))] - "" - "uaddcm %%r0,%1,%0" - [(set_attr "type" "unary") - (set_attr "length" "4")]) - -;; Floating point arithmetic instructions. - -(define_insn "adddf3" - [(set (match_operand:DF 0 "register_operand" "=f") - (plus:DF (match_operand:DF 1 "register_operand" "f") - (match_operand:DF 2 "register_operand" "f")))] - "! TARGET_SOFT_FLOAT" - "fadd,dbl %1,%2,%0" - [(set_attr "type" "fpalu") - (set_attr "pa_combine_type" "faddsub") - (set_attr "length" "4")]) - -(define_insn "addsf3" - [(set (match_operand:SF 0 "register_operand" "=f") - (plus:SF (match_operand:SF 1 "register_operand" "f") - (match_operand:SF 2 "register_operand" "f")))] - "! TARGET_SOFT_FLOAT" - "fadd,sgl %1,%2,%0" - [(set_attr "type" "fpalu") - (set_attr "pa_combine_type" "faddsub") - (set_attr "length" "4")]) - -(define_insn "subdf3" - [(set (match_operand:DF 0 "register_operand" "=f") - (minus:DF (match_operand:DF 1 "register_operand" "f") - (match_operand:DF 2 "register_operand" "f")))] - "! TARGET_SOFT_FLOAT" - "fsub,dbl %1,%2,%0" - [(set_attr "type" "fpalu") - (set_attr "pa_combine_type" "faddsub") - (set_attr "length" "4")]) - -(define_insn "subsf3" - [(set (match_operand:SF 0 "register_operand" "=f") - (minus:SF (match_operand:SF 1 "register_operand" "f") - (match_operand:SF 2 "register_operand" "f")))] - "! TARGET_SOFT_FLOAT" - "fsub,sgl %1,%2,%0" - [(set_attr "type" "fpalu") - (set_attr "pa_combine_type" "faddsub") - (set_attr "length" "4")]) - -(define_insn "muldf3" - [(set (match_operand:DF 0 "register_operand" "=f") - (mult:DF (match_operand:DF 1 "register_operand" "f") - (match_operand:DF 2 "register_operand" "f")))] - "! TARGET_SOFT_FLOAT" - "fmpy,dbl %1,%2,%0" - [(set_attr "type" "fpmuldbl") - (set_attr "pa_combine_type" "fmpy") - (set_attr "length" "4")]) - -(define_insn "mulsf3" - [(set (match_operand:SF 0 "register_operand" "=f") - (mult:SF (match_operand:SF 1 "register_operand" "f") - (match_operand:SF 2 "register_operand" "f")))] - "! TARGET_SOFT_FLOAT" - "fmpy,sgl %1,%2,%0" - [(set_attr "type" "fpmulsgl") - (set_attr "pa_combine_type" "fmpy") - (set_attr "length" "4")]) - -(define_insn "divdf3" - [(set (match_operand:DF 0 "register_operand" "=f") - (div:DF (match_operand:DF 1 "register_operand" "f") - (match_operand:DF 2 "register_operand" "f")))] - "! TARGET_SOFT_FLOAT" - "fdiv,dbl %1,%2,%0" - [(set_attr "type" "fpdivdbl") - (set_attr "length" "4")]) - -(define_insn "divsf3" - [(set (match_operand:SF 0 "register_operand" "=f") - (div:SF (match_operand:SF 1 "register_operand" "f") - (match_operand:SF 2 "register_operand" "f")))] - "! TARGET_SOFT_FLOAT" - "fdiv,sgl %1,%2,%0" - [(set_attr "type" "fpdivsgl") - (set_attr "length" "4")]) - -;; Processors prior to PA 2.0 don't have a fneg instruction. Fast -;; negation can be done by subtracting from plus zero. However, this -;; violates the IEEE standard when negating plus and minus zero. -;; The slow path toggles the sign bit in the general registers. -(define_expand "negdf2" - [(set (match_operand:DF 0 "register_operand" "") - (neg:DF (match_operand:DF 1 "register_operand" "")))] - "!TARGET_SOFT_FLOAT" -{ - if (TARGET_PA_20 || !flag_signed_zeros) - emit_insn (gen_negdf2_fast (operands[0], operands[1])); - else - emit_insn (gen_negdf2_slow (operands[0], operands[1])); - DONE; -}) - -(define_insn "negdf2_slow" - [(set (match_operand:DF 0 "register_operand" "=r") - (neg:DF (match_operand:DF 1 "register_operand" "r")))] - "!TARGET_SOFT_FLOAT && !TARGET_PA_20" - "* -{ - if (rtx_equal_p (operands[0], operands[1])) - return \"and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0\"; - else - 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 "length") - (if_then_else (match_test "rtx_equal_p (operands[0], operands[1])") - (const_int 12) - (const_int 16)))]) - -(define_insn "negdf2_fast" - [(set (match_operand:DF 0 "register_operand" "=f") - (neg:DF (match_operand:DF 1 "register_operand" "f")))] - "!TARGET_SOFT_FLOAT" - "* -{ - if (TARGET_PA_20) - return \"fneg,dbl %1,%0\"; - else - return \"fsub,dbl %%fr0,%1,%0\"; -}" - [(set_attr "type" "fpalu") - (set_attr "length" "4")]) - -(define_expand "negsf2" - [(set (match_operand:SF 0 "register_operand" "") - (neg:SF (match_operand:SF 1 "register_operand" "")))] - "!TARGET_SOFT_FLOAT" -{ - if (TARGET_PA_20 || !flag_signed_zeros) - emit_insn (gen_negsf2_fast (operands[0], operands[1])); - else - emit_insn (gen_negsf2_slow (operands[0], operands[1])); - DONE; -}) - -(define_insn "negsf2_slow" - [(set (match_operand:SF 0 "register_operand" "=r") - (neg:SF (match_operand:SF 1 "register_operand" "r")))] - "!TARGET_SOFT_FLOAT && !TARGET_PA_20" - "and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0" - [(set_attr "type" "multi") - (set_attr "length" "12")]) - -(define_insn "negsf2_fast" - [(set (match_operand:SF 0 "register_operand" "=f") - (neg:SF (match_operand:SF 1 "register_operand" "f")))] - "!TARGET_SOFT_FLOAT" - "* -{ - if (TARGET_PA_20) - return \"fneg,sgl %1,%0\"; - else - return \"fsub,sgl %%fr0,%1,%0\"; -}" - [(set_attr "type" "fpalu") - (set_attr "length" "4")]) - -(define_insn "absdf2" - [(set (match_operand:DF 0 "register_operand" "=f") - (abs:DF (match_operand:DF 1 "register_operand" "f")))] - "! TARGET_SOFT_FLOAT" - "fabs,dbl %1,%0" - [(set_attr "type" "fpalu") - (set_attr "length" "4")]) - -(define_insn "abssf2" - [(set (match_operand:SF 0 "register_operand" "=f") - (abs:SF (match_operand:SF 1 "register_operand" "f")))] - "! TARGET_SOFT_FLOAT" - "fabs,sgl %1,%0" - [(set_attr "type" "fpalu") - (set_attr "length" "4")]) - -(define_insn "sqrtdf2" - [(set (match_operand:DF 0 "register_operand" "=f") - (sqrt:DF (match_operand:DF 1 "register_operand" "f")))] - "! TARGET_SOFT_FLOAT" - "fsqrt,dbl %1,%0" - [(set_attr "type" "fpsqrtdbl") - (set_attr "length" "4")]) - -(define_insn "sqrtsf2" - [(set (match_operand:SF 0 "register_operand" "=f") - (sqrt:SF (match_operand:SF 1 "register_operand" "f")))] - "! TARGET_SOFT_FLOAT" - "fsqrt,sgl %1,%0" - [(set_attr "type" "fpsqrtsgl") - (set_attr "length" "4")]) - -;; PA 2.0 floating point instructions - -; fmpyfadd patterns -(define_insn "fmadf4" - [(set (match_operand:DF 0 "register_operand" "=f") - (fma:DF (match_operand:DF 1 "register_operand" "f") - (match_operand:DF 2 "register_operand" "f") - (match_operand:DF 3 "register_operand" "f")))] - "TARGET_PA_20 && ! TARGET_SOFT_FLOAT" - "fmpyfadd,dbl %1,%2,%3,%0" - [(set_attr "type" "fpmuldbl") - (set_attr "length" "4")]) - -(define_insn "fmasf4" - [(set (match_operand:SF 0 "register_operand" "=f") - (fma:SF (match_operand:SF 1 "register_operand" "f") - (match_operand:SF 2 "register_operand" "f") - (match_operand:SF 3 "register_operand" "f")))] - "TARGET_PA_20 && ! TARGET_SOFT_FLOAT" - "fmpyfadd,sgl %1,%2,%3,%0" - [(set_attr "type" "fpmulsgl") - (set_attr "length" "4")]) - -; fmpynfadd patterns -(define_insn "fnmadf4" - [(set (match_operand:DF 0 "register_operand" "=f") - (fma:DF (neg:DF (match_operand:DF 1 "register_operand" "f")) - (match_operand:DF 2 "register_operand" "f") - (match_operand:DF 3 "register_operand" "f")))] - "TARGET_PA_20 && ! TARGET_SOFT_FLOAT" - "fmpynfadd,dbl %1,%2,%3,%0" - [(set_attr "type" "fpmuldbl") - (set_attr "length" "4")]) - -(define_insn "fnmasf4" - [(set (match_operand:SF 0 "register_operand" "=f") - (fma:SF (neg:SF (match_operand:SF 1 "register_operand" "f")) - (match_operand:SF 2 "register_operand" "f") - (match_operand:SF 3 "register_operand" "f")))] - "TARGET_PA_20 && ! TARGET_SOFT_FLOAT" - "fmpynfadd,sgl %1,%2,%3,%0" - [(set_attr "type" "fpmulsgl") - (set_attr "length" "4")]) - -; fnegabs patterns -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f") - (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))] - "TARGET_PA_20 && ! TARGET_SOFT_FLOAT" - "fnegabs,dbl %1,%0" - [(set_attr "type" "fpalu") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:SF 0 "register_operand" "=f") - (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))] - "TARGET_PA_20 && ! TARGET_SOFT_FLOAT" - "fnegabs,sgl %1,%0" - [(set_attr "type" "fpalu") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:DF 0 "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)))] - "(! TARGET_SOFT_FLOAT && TARGET_PA_20 - && ! reg_overlap_mentioned_p (operands[2], operands[1]))" - "#" - [(set_attr "type" "fpalu") - (set_attr "length" "8")]) - -(define_split - [(set (match_operand:DF 0 "register_operand" "") - (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "")))) - (set (match_operand:DF 2 "register_operand" "") (abs:DF (match_dup 1)))] - "! TARGET_SOFT_FLOAT && TARGET_PA_20" - [(set (match_dup 2) (abs:DF (match_dup 1))) - (set (match_dup 0) (neg:DF (abs:DF (match_dup 1))))] - "") - -(define_insn "" - [(set (match_operand:SF 0 "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)))] - "(! TARGET_SOFT_FLOAT && TARGET_PA_20 - && ! reg_overlap_mentioned_p (operands[2], operands[1]))" - "#" - [(set_attr "type" "fpalu") - (set_attr "length" "8")]) - -(define_split - [(set (match_operand:SF 0 "register_operand" "") - (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "")))) - (set (match_operand:SF 2 "register_operand" "") (abs:SF (match_dup 1)))] - "! TARGET_SOFT_FLOAT && TARGET_PA_20" - [(set (match_dup 2) (abs:SF (match_dup 1))) - (set (match_dup 0) (neg:SF (abs:SF (match_dup 1))))] - "") - -;; Negating a multiply can be faked by adding zero in a fused multiply-add -;; instruction if we can ignore the sign of zero. -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f") - (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f") - (match_operand:DF 2 "register_operand" "f"))))] - "!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros" - "fmpynfadd,dbl %1,%2,%%fr0,%0" - [(set_attr "type" "fpmuldbl") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:SF 0 "register_operand" "=f") - (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f") - (match_operand:SF 2 "register_operand" "f"))))] - "!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros" - "fmpynfadd,sgl %1,%2,%%fr0,%0" - [(set_attr "type" "fpmuldbl") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f") - (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f") - (match_operand:DF 2 "register_operand" "f")))) - (set (match_operand:DF 3 "register_operand" "=&f") - (mult:DF (match_dup 1) (match_dup 2)))] - "(!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros - && ! (reg_overlap_mentioned_p (operands[3], operands[1]) - || reg_overlap_mentioned_p (operands[3], operands[2])))" - "#" - [(set_attr "type" "fpmuldbl") - (set_attr "length" "8")]) - -(define_split - [(set (match_operand:DF 0 "register_operand" "") - (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "") - (match_operand:DF 2 "register_operand" "")))) - (set (match_operand:DF 3 "register_operand" "") - (mult:DF (match_dup 1) (match_dup 2)))] - "!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros" - [(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))))] - "") - -(define_insn "" - [(set (match_operand:SF 0 "register_operand" "=f") - (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f") - (match_operand:SF 2 "register_operand" "f")))) - (set (match_operand:SF 3 "register_operand" "=&f") - (mult:SF (match_dup 1) (match_dup 2)))] - "(!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros - && ! (reg_overlap_mentioned_p (operands[3], operands[1]) - || reg_overlap_mentioned_p (operands[3], operands[2])))" - "#" - [(set_attr "type" "fpmuldbl") - (set_attr "length" "8")]) - -(define_split - [(set (match_operand:SF 0 "register_operand" "") - (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "") - (match_operand:SF 2 "register_operand" "")))) - (set (match_operand:SF 3 "register_operand" "") - (mult:SF (match_dup 1) (match_dup 2)))] - "!TARGET_SOFT_FLOAT && TARGET_PA_20&& !flag_signed_zeros" - [(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))))] - "") - -;;- Shift instructions - -;; Optimized special case of shifting. - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m") - (const_int 24)))] - "" - "ldb%M1 %1,%0" - [(set_attr "type" "load") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m") - (const_int 16)))] - "" - "ldh%M1 %1,%0" - [(set_attr "type" "load") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r") - (match_operand:SI 3 "shadd_operand" "")) - (match_operand:SI 1 "register_operand" "r")))] - "" - "{sh%O3addl %2,%1,%0|shladd,l %2,%O3,%1,%0} " - [(set_attr "type" "binary") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (plus:DI (mult:DI (match_operand:DI 2 "register_operand" "r") - (match_operand:DI 3 "shadd_operand" "")) - (match_operand:DI 1 "register_operand" "r")))] - "TARGET_64BIT" - "shladd,l %2,%O3,%1,%0" - [(set_attr "type" "binary") - (set_attr "length" "4")]) - -(define_expand "ashlsi3" - [(set (match_operand:SI 0 "register_operand" "") - (ashift:SI (match_operand:SI 1 "lhs_lshift_operand" "") - (match_operand:SI 2 "arith32_operand" "")))] - "" - " -{ - if (GET_CODE (operands[2]) != CONST_INT) - { - rtx temp = gen_reg_rtx (SImode); - emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2])); - if (GET_CODE (operands[1]) == CONST_INT) - emit_insn (gen_zvdep_imm32 (operands[0], operands[1], temp)); - else - emit_insn (gen_zvdep32 (operands[0], operands[1], temp)); - DONE; - } - /* Make sure both inputs are not constants, - there are no patterns for that. */ - operands[1] = force_reg (SImode, operands[1]); -}") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (ashift:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "const_int_operand" "n")))] - "" - "{zdep|depw,z} %1,%P2,%L2,%0" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -; 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 -; replace a register with a known value in range -16..15 with a -; constant. Ideally, we would like to merge zvdep32 and zvdep_imm32, -; but since we have no more CONST_OK... characters, that is not -; possible. -(define_insn "zvdep32" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (ashift:SI (match_operand:SI 1 "arith5_operand" "r,L") - (minus:SI (const_int 31) - (match_operand:SI 2 "register_operand" "q,q"))))] - "" - "@ - {zvdep %1,32,%0|depw,z %1,%%sar,32,%0} - {zvdepi %1,32,%0|depwi,z %1,%%sar,32,%0}" - [(set_attr "type" "shift,shift") - (set_attr "length" "4,4")]) - -(define_insn "zvdep_imm32" - [(set (match_operand:SI 0 "register_operand" "=r") - (ashift:SI (match_operand:SI 1 "lhs_lshift_cint_operand" "") - (minus:SI (const_int 31) - (match_operand:SI 2 "register_operand" "q"))))] - "" - "* -{ - unsigned HOST_WIDE_INT x = UINTVAL (operands[1]); - operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1)); - operands[1] = GEN_INT ((x & 0xf) - 0x10); - return \"{zvdepi %1,%2,%0|depwi,z %1,%%sar,%2,%0}\"; -}" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -(define_insn "vdepi_ior" - [(set (match_operand:SI 0 "register_operand" "=r") - (ior:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "") - (minus:SI (const_int 31) - (match_operand:SI 2 "register_operand" "q"))) - (match_operand:SI 3 "register_operand" "0")))] - ; accept ...0001...1, can this be generalized? - "exact_log2 (INTVAL (operands[1]) + 1) > 0" - "* -{ - HOST_WIDE_INT x = INTVAL (operands[1]); - operands[2] = GEN_INT (exact_log2 (x + 1)); - return \"{vdepi -1,%2,%0|depwi -1,%%sar,%2,%0}\"; -}" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -(define_insn "vdepi_and" - [(set (match_operand:SI 0 "register_operand" "=r") - (and:SI (rotate:SI (match_operand:SI 1 "const_int_operand" "") - (minus:SI (const_int 31) - (match_operand:SI 2 "register_operand" "q"))) - (match_operand:SI 3 "register_operand" "0")))] - ; this can be generalized...! - "INTVAL (operands[1]) == -2" - "* -{ - HOST_WIDE_INT x = INTVAL (operands[1]); - operands[2] = GEN_INT (exact_log2 ((~x) + 1)); - return \"{vdepi 0,%2,%0|depwi 0,%%sar,%2,%0}\"; -}" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -(define_expand "ashldi3" - [(set (match_operand:DI 0 "register_operand" "") - (ashift:DI (match_operand:DI 1 "lhs_lshift_operand" "") - (match_operand:DI 2 "arith32_operand" "")))] - "TARGET_64BIT" - " -{ - if (GET_CODE (operands[2]) != CONST_INT) - { - rtx temp = gen_reg_rtx (DImode); - emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2])); - if (GET_CODE (operands[1]) == CONST_INT) - emit_insn (gen_zvdep_imm64 (operands[0], operands[1], temp)); - else - emit_insn (gen_zvdep64 (operands[0], operands[1], temp)); - DONE; - } - /* Make sure both inputs are not constants, - there are no patterns for that. */ - operands[1] = force_reg (DImode, operands[1]); -}") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (ashift:DI (match_operand:DI 1 "register_operand" "r") - (match_operand:DI 2 "const_int_operand" "n")))] - "TARGET_64BIT" - "depd,z %1,%p2,%Q2,%0" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -; 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 -; replace a register with a known value in range -16..15 with a -; constant. Ideally, we would like to merge zvdep64 and zvdep_imm64, -; but since we have no more CONST_OK... characters, that is not -; possible. -(define_insn "zvdep64" - [(set (match_operand:DI 0 "register_operand" "=r,r") - (ashift:DI (match_operand:DI 1 "arith5_operand" "r,L") - (minus:DI (const_int 63) - (match_operand:DI 2 "register_operand" "q,q"))))] - "TARGET_64BIT" - "@ - depd,z %1,%%sar,64,%0 - depdi,z %1,%%sar,64,%0" - [(set_attr "type" "shift,shift") - (set_attr "length" "4,4")]) - -(define_insn "zvdep_imm64" - [(set (match_operand:DI 0 "register_operand" "=r") - (ashift:DI (match_operand:DI 1 "lhs_lshift_cint_operand" "") - (minus:DI (const_int 63) - (match_operand:DI 2 "register_operand" "q"))))] - "TARGET_64BIT" - "* -{ - unsigned HOST_WIDE_INT x = UINTVAL (operands[1]); - operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1)); - operands[1] = GEN_INT ((x & 0x1f) - 0x20); - return \"depdi,z %1,%%sar,%2,%0\"; -}" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (ior:DI (ashift:DI (match_operand:DI 1 "const_int_operand" "") - (minus:DI (const_int 63) - (match_operand:DI 2 "register_operand" "q"))) - (match_operand:DI 3 "register_operand" "0")))] - ; accept ...0001...1, can this be generalized? - "TARGET_64BIT && exact_log2 (INTVAL (operands[1]) + 1) > 0" - "* -{ - HOST_WIDE_INT x = INTVAL (operands[1]); - operands[2] = GEN_INT (exact_log2 (x + 1)); - return \"depdi -1,%%sar,%2,%0\"; -}" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (and:DI (rotate:DI (match_operand:DI 1 "const_int_operand" "") - (minus:DI (const_int 63) - (match_operand:DI 2 "register_operand" "q"))) - (match_operand:DI 3 "register_operand" "0")))] - ; this can be generalized...! - "TARGET_64BIT && INTVAL (operands[1]) == -2" - "* -{ - HOST_WIDE_INT x = INTVAL (operands[1]); - operands[2] = GEN_INT (exact_log2 ((~x) + 1)); - return \"depdi 0,%%sar,%2,%0\"; -}" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -(define_expand "ashrsi3" - [(set (match_operand:SI 0 "register_operand" "") - (ashiftrt:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "arith32_operand" "")))] - "" - " -{ - if (GET_CODE (operands[2]) != CONST_INT) - { - rtx temp = gen_reg_rtx (SImode); - emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2])); - emit_insn (gen_vextrs32 (operands[0], operands[1], temp)); - DONE; - } -}") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "const_int_operand" "n")))] - "" - "{extrs|extrw,s} %1,%P2,%L2,%0" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -(define_insn "vextrs32" - [(set (match_operand:SI 0 "register_operand" "=r") - (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") - (minus:SI (const_int 31) - (match_operand:SI 2 "register_operand" "q"))))] - "" - "{vextrs %1,32,%0|extrw,s %1,%%sar,32,%0}" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -(define_expand "ashrdi3" - [(set (match_operand:DI 0 "register_operand" "") - (ashiftrt:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "arith32_operand" "")))] - "TARGET_64BIT" - " -{ - if (GET_CODE (operands[2]) != CONST_INT) - { - rtx temp = gen_reg_rtx (DImode); - emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2])); - emit_insn (gen_vextrs64 (operands[0], operands[1], temp)); - DONE; - } -}") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (ashiftrt:DI (match_operand:DI 1 "register_operand" "r") - (match_operand:DI 2 "const_int_operand" "n")))] - "TARGET_64BIT" - "extrd,s %1,%p2,%Q2,%0" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -(define_insn "vextrs64" - [(set (match_operand:DI 0 "register_operand" "=r") - (ashiftrt:DI (match_operand:DI 1 "register_operand" "r") - (minus:DI (const_int 63) - (match_operand:DI 2 "register_operand" "q"))))] - "TARGET_64BIT" - "extrd,s %1,%%sar,64,%0" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -(define_insn "lshrsi3" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r") - (match_operand:SI 2 "shift5_operand" "q,n")))] - "" - "@ - {vshd %%r0,%1,%0|shrpw %%r0,%1,%%sar,%0} - {extru|extrw,u} %1,%P2,%L2,%0" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -(define_insn "lshrdi3" - [(set (match_operand:DI 0 "register_operand" "=r,r") - (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r") - (match_operand:DI 2 "shift6_operand" "q,n")))] - "TARGET_64BIT" - "@ - shrpd %%r0,%1,%%sar,%0 - extrd,u %1,%p2,%Q2,%0" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -; Shift right pair word 0 to 31 bits. -(define_insn "shrpsi4" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r,r") - (minus:SI (const_int 32) - (match_operand:SI 3 "shift5_operand" "q,n"))) - (lshiftrt:SI (match_operand:SI 2 "register_operand" "r,r") - (match_dup 3))))] - "" - "@ - {vshd %1,%2,%0|shrpw %1,%2,%%sar,%0} - {shd|shrpw} %1,%2,%3,%0" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -; Shift right pair doubleword 0 to 63 bits. -(define_insn "shrpdi4" - [(set (match_operand:DI 0 "register_operand" "=r,r") - (ior:DI (ashift:DI (match_operand:SI 1 "register_operand" "r,r") - (minus:DI (const_int 64) - (match_operand:DI 3 "shift6_operand" "q,n"))) - (lshiftrt:DI (match_operand:DI 2 "register_operand" "r,r") - (match_dup 3))))] - "TARGET_64BIT" - "@ - shrpd %1,%2,%%sar,%0 - shrpd %1,%2,%3,%0" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -(define_insn "rotrsi3" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (rotatert:SI (match_operand:SI 1 "register_operand" "r,r") - (match_operand:SI 2 "shift5_operand" "q,n")))] - "" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT) - { - operands[2] = GEN_INT (INTVAL (operands[2]) & 31); - return \"{shd|shrpw} %1,%1,%2,%0\"; - } - else - return \"{vshd %1,%1,%0|shrpw %1,%1,%%sar,%0}\"; -}" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -(define_expand "rotlsi3" - [(set (match_operand:SI 0 "register_operand" "") - (rotate:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "arith32_operand" "")))] - "" - " -{ - if (GET_CODE (operands[2]) != CONST_INT) - { - rtx temp = gen_reg_rtx (SImode); - emit_insn (gen_subsi3 (temp, GEN_INT (32), operands[2])); - emit_insn (gen_rotrsi3 (operands[0], operands[1], temp)); - DONE; - } - /* Else expand normally. */ -}") - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (rotate:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "const_int_operand" "n")))] - "" - "* -{ - operands[2] = GEN_INT ((32 - INTVAL (operands[2])) & 31); - return \"{shd|shrpw} %1,%1,%2,%0\"; -}" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (match_operator:SI 5 "plus_xor_ior_operator" - [(ashift:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 3 "const_int_operand" "n")) - (lshiftrt:SI (match_operand:SI 2 "register_operand" "r") - (match_operand:SI 4 "const_int_operand" "n"))]))] - "INTVAL (operands[3]) + INTVAL (operands[4]) == 32" - "{shd|shrpw} %1,%2,%4,%0" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (match_operator:SI 5 "plus_xor_ior_operator" - [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r") - (match_operand:SI 4 "const_int_operand" "n")) - (ashift:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 3 "const_int_operand" "n"))]))] - "INTVAL (operands[3]) + INTVAL (operands[4]) == 32" - "{shd|shrpw} %1,%2,%4,%0" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "const_int_operand" "")) - (match_operand:SI 3 "const_int_operand" "")))] - "exact_log2 (1 + (INTVAL (operands[3]) >> (INTVAL (operands[2]) & 31))) > 0" - "* -{ - int cnt = INTVAL (operands[2]) & 31; - operands[3] = GEN_INT (exact_log2 (1 + (INTVAL (operands[3]) >> cnt))); - operands[2] = GEN_INT (31 - cnt); - return \"{zdep|depw,z} %1,%2,%3,%0\"; -}" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -;; Unconditional and other jump instructions. - -;; Trivial return used when no epilogue is needed. -(define_insn "return" - [(return) - (use (reg:SI 2))] - "pa_can_use_return_insn ()" - "* -{ - if (TARGET_PA_20) - return \"bve%* (%%r2)\"; - return \"bv%* %%r0(%%r2)\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -;; This is used for most returns. -(define_insn "return_internal" - [(return) - (use (reg:SI 2))] - "" - "* -{ - if (TARGET_PA_20) - return \"bve%* (%%r2)\"; - return \"bv%* %%r0(%%r2)\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -;; This is used for eh returns which bypass the return stub. -(define_insn "return_external_pic" - [(return) - (clobber (reg:SI 1)) - (use (reg:SI 2))] - "!TARGET_NO_SPACE_REGS - && !TARGET_PA_20 - && flag_pic && crtl->calls_eh_return" - "ldsid (%%sr0,%%r2),%%r1\;mtsp %%r1,%%sr0\;be%* 0(%%sr0,%%r2)" - [(set_attr "type" "branch") - (set_attr "length" "12")]) - -(define_expand "prologue" - [(const_int 0)] - "" - "pa_expand_prologue ();DONE;") - -(define_expand "sibcall_epilogue" - [(return)] - "" - " -{ - pa_expand_epilogue (); - DONE; -}") - -(define_expand "epilogue" - [(return)] - "" - " -{ - rtx x; - - /* Try to use the trivial return first. Else use the full epilogue. */ - if (pa_can_use_return_insn ()) - x = gen_return (); - else - { - pa_expand_epilogue (); - - /* EH returns bypass the normal return stub. Thus, we must do an - interspace branch to return from functions that call eh_return. - This is only a problem for returns from shared code on ports - using space registers. */ - if (!TARGET_NO_SPACE_REGS - && !TARGET_PA_20 - && flag_pic && crtl->calls_eh_return) - x = gen_return_external_pic (); - else - x = gen_return_internal (); - } - emit_jump_insn (x); - DONE; -}") - -; 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 -(define_insn "load_offset_label_address" - [(set (match_operand:SI 0 "register_operand" "=r") - (plus:SI (match_operand:SI 1 "register_operand" "r") - (minus:SI (match_operand:SI 2 "" "") - (label_ref:SI (match_operand 3 "" "")))))] - "" - "ldo %2-%l3(%1),%0" - [(set_attr "type" "multi") - (set_attr "length" "4")]) - -; Output a code label and load its address. -(define_insn "lcla1" - [(set (match_operand:SI 0 "register_operand" "=r") - (label_ref:SI (match_operand 1 "" ""))) - (const_int 0)] - "!TARGET_PA_20" - "* -{ - output_asm_insn (\"bl .+8,%0\;depi 0,31,2,%0\", operands); - (*targetm.asm_out.internal_label) (asm_out_file, \"L\", - CODE_LABEL_NUMBER (operands[1])); - return \"\"; -}" - [(set_attr "type" "multi") - (set_attr "length" "8")]) - -(define_insn "lcla2" - [(set (match_operand:SI 0 "register_operand" "=r") - (label_ref:SI (match_operand 1 "" ""))) - (const_int 0)] - "TARGET_PA_20" - "* -{ - (*targetm.asm_out.internal_label) (asm_out_file, \"L\", - CODE_LABEL_NUMBER (operands[1])); - return \"mfia %0\"; -}" - [(set_attr "type" "move") - (set_attr "length" "4")]) - -(define_insn "blockage" - [(unspec_volatile [(const_int 2)] UNSPECV_BLOCKAGE)] - "" - "" - [(set_attr "length" "0")]) - -(define_insn "jump" - [(set (pc) (label_ref (match_operand 0 "" "")))] - "" - "* -{ - /* An unconditional branch which can reach its target. */ - if (get_attr_length (insn) < 16) - return \"b%* %l0\"; - - return pa_output_lbranch (operands[0], insn, 1); -}" - [(set_attr "type" "uncond_branch") - (set_attr "pa_combine_type" "uncond_branch") - (set (attr "length") - (cond [(match_test "pa_jump_in_call_delay (insn)") - (if_then_else (lt (abs (minus (match_dup 0) - (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (const_int 8)) - (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 4) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 20) - (not (match_test "flag_pic")) - (const_int 16)] - (const_int 24)))]) - -;;; Hope this is only within a function... -(define_insn "indirect_jump" - [(set (pc) (match_operand 0 "register_operand" "r"))] - "GET_MODE (operands[0]) == word_mode" - "bv%* %%r0(%0)" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -;;; An indirect jump can be optimized to a direct jump. GAS for the -;;; SOM target doesn't allow branching to a label inside a function. -;;; We also don't correctly compute branch distances for labels -;;; outside the current function. Thus, we use an indirect jump can't -;;; be optimized to a direct jump for all targets. We assume that -;;; the branch target is in the same space (i.e., nested function -;;; jumping to a label in an outer function in the same translation -;;; unit). -(define_expand "nonlocal_goto" - [(use (match_operand 0 "general_operand" "")) - (use (match_operand 1 "general_operand" "")) - (use (match_operand 2 "general_operand" "")) - (use (match_operand 3 "general_operand" ""))] - "" -{ - rtx lab = operands[1]; - rtx stack = operands[2]; - rtx fp = operands[3]; - - lab = copy_to_reg (lab); - - emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode))); - emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx)); - - /* Restore the frame pointer. The virtual_stack_vars_rtx is saved - instead of the hard_frame_pointer_rtx in the save area. As a - result, an extra instruction is needed to adjust for the offset - of the virtual stack variables and the hard frame pointer. */ - if (GET_CODE (fp) != REG) - fp = force_reg (Pmode, fp); - emit_move_insn (hard_frame_pointer_rtx, plus_constant (Pmode, fp, -8)); - - emit_stack_restore (SAVE_NONLOCAL, stack); - - emit_use (hard_frame_pointer_rtx); - emit_use (stack_pointer_rtx); - - /* Nonlocal goto jumps are only used between functions in the same - translation unit. Thus, we can avoid the extra overhead of an - interspace jump. */ - emit_jump_insn (gen_indirect_goto (lab)); - emit_barrier (); - DONE; -}) - -(define_insn "indirect_goto" - [(unspec [(match_operand 0 "register_operand" "=r")] UNSPEC_GOTO)] - "GET_MODE (operands[0]) == word_mode" - "bv%* %%r0(%0)" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -;;; This jump is used in branch tables where the insn length is fixed. -;;; The length of this insn is adjusted if the delay slot is not filled. -(define_insn "short_jump" - [(set (pc) (label_ref (match_operand 0 "" ""))) - (const_int 0)] - "" - "b%* %l0%#" - [(set_attr "type" "btable_branch") - (set_attr "length" "4")]) - -;; Subroutines of "casesi". -;; operand 0 is index -;; operand 1 is the minimum bound -;; operand 2 is the maximum bound - minimum bound + 1 -;; operand 3 is CODE_LABEL for the table; -;; operand 4 is the CODE_LABEL to go to if index out of range. - -(define_expand "casesi" - [(match_operand:SI 0 "general_operand" "") - (match_operand:SI 1 "const_int_operand" "") - (match_operand:SI 2 "const_int_operand" "") - (match_operand 3 "" "") - (match_operand 4 "" "")] - "" - " -{ - if (GET_CODE (operands[0]) != REG) - operands[0] = force_reg (SImode, operands[0]); - - if (operands[1] != const0_rtx) - { - rtx index = gen_reg_rtx (SImode); - - operands[1] = gen_int_mode (-INTVAL (operands[1]), SImode); - if (!INT_14_BITS (operands[1])) - operands[1] = force_reg (SImode, operands[1]); - emit_insn (gen_addsi3 (index, operands[0], operands[1])); - operands[0] = index; - } - - if (!INT_5_BITS (operands[2])) - operands[2] = force_reg (SImode, operands[2]); - - /* This branch prevents us finding an insn for the delay slot of the - 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 - 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 - 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 - then be worthwhile to split the casesi patterns to improve scheduling. - However, it's not clear that all this extra complexity is worth - the effort. */ - { - rtx test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]); - 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 - just in case the addition overflowed or we had random bits in the - high part of the register. */ - if (TARGET_64BIT) - { - rtx index = gen_reg_rtx (DImode); - - emit_insn (gen_extendsidi2 (index, operands[0])); - operands[0] = index; - } - - if (TARGET_BIG_SWITCH) - { - if (TARGET_64BIT) - emit_jump_insn (gen_casesi64p (operands[0], operands[3])); - else if (flag_pic) - emit_jump_insn (gen_casesi32p (operands[0], operands[3])); - else - emit_jump_insn (gen_casesi32 (operands[0], operands[3])); - } - else - emit_jump_insn (gen_casesi0 (operands[0], operands[3])); - DONE; -}") - -;;; The rtl for this pattern doesn't accurately describe what the insn -;;; actually does, particularly when case-vector elements are exploded -;;; in pa_reorg. However, the initial SET in these patterns must show -;;; the connection of the insn to the following jump table. -(define_insn "casesi0" - [(set (pc) (mem:SI (plus:SI - (mult:SI (match_operand:SI 0 "register_operand" "r") - (const_int 4)) - (label_ref (match_operand 1 "" "")))))] - "" - "blr,n %0,%%r0\;nop" - [(set_attr "type" "multi") - (set_attr "length" "8")]) - -;;; 32-bit code, absolute branch table. -(define_insn "casesi32" - [(set (pc) (mem:SI (plus:SI - (mult:SI (match_operand:SI 0 "register_operand" "r") - (const_int 4)) - (label_ref (match_operand 1 "" ""))))) - (clobber (match_scratch:SI 2 "=&r"))] - "!flag_pic" - "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 "length" "16")]) - -;;; 32-bit code, relative branch table. -(define_insn "casesi32p" - [(set (pc) (mem:SI (plus:SI - (mult:SI (match_operand:SI 0 "register_operand" "r") - (const_int 4)) - (label_ref (match_operand 1 "" ""))))) - (clobber (match_scratch:SI 2 "=&r")) - (clobber (match_scratch:SI 3 "=&r"))] - "flag_pic" - "{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)" - [(set_attr "type" "multi") - (set (attr "length") - (if_then_else (match_test "TARGET_PA_20") - (const_int 20) - (const_int 24)))]) - -;;; 64-bit code, 32-bit relative branch table. -(define_insn "casesi64p" - [(set (pc) (mem:DI (plus:DI - (mult:DI (match_operand:DI 0 "register_operand" "r") - (const_int 8)) - (label_ref (match_operand 1 "" ""))))) - (clobber (match_scratch:DI 2 "=&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\;\ -add,l %2,%3,%3\;bv,n %%r0(%3)" - [(set_attr "type" "multi") - (set_attr "length" "24")]) - - -;; Call patterns. -;;- jump to subroutine - -(define_expand "call" - [(parallel [(call (match_operand:SI 0 "" "") - (match_operand 1 "" "")) - (clobber (reg:SI 2))])] - "" - " -{ - rtx op; - rtx nb = operands[1]; - - if (TARGET_PORTABLE_RUNTIME) - op = force_reg (SImode, XEXP (operands[0], 0)); - else - op = XEXP (operands[0], 0); - - if (TARGET_64BIT) - { - if (!virtuals_instantiated) - emit_move_insn (arg_pointer_rtx, - gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx, - GEN_INT (64))); - else - { - /* The loop pass can generate new libcalls after the virtual - registers are instantiated when fpregs are disabled because - the only method that we have for doing DImode multiplication - is with a libcall. This could be trouble if we haven't - allocated enough space for the outgoing arguments. */ - gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size); - - emit_move_insn (arg_pointer_rtx, - gen_rtx_PLUS (word_mode, stack_pointer_rtx, - GEN_INT (STACK_POINTER_OFFSET + 64))); - } - } - - /* Use two different patterns for calls to explicitly named functions - and calls through function pointers. This is necessary as these two - types of calls use different calling conventions, and CSE might try - to change the named call into an indirect call in some cases (using - two patterns keeps CSE from performing this optimization). - - 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 - move insn. During reload, a instruction involving a pseudo register - with no explicit dependence on the PIC register can be converted - 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 - generation, then it can potentially be repositioned during scheduling. - and an instruction that eventually uses the PIC register may end up - between the call and the PIC register restore. - - This only worked because there is a post call group of instructions - that are scheduled with the call. These instructions are included - 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 - can throw. This results in the PIC register restore being scheduled - independently from the call. So, we now hide the save and restore - 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 - need to have a use of the PIC register in the return pattern and - the final save/restore operation is not needed. - - 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. - This might have required a new register class and constraint. It - was also simpler to just handle the restore from a register than a - generic pseudo. */ - if (TARGET_64BIT) - { - rtx r4 = gen_rtx_REG (word_mode, 4); - if (GET_CODE (op) == SYMBOL_REF) - emit_call_insn (gen_call_symref_64bit (op, nb, r4)); - else - { - op = force_reg (word_mode, op); - emit_call_insn (gen_call_reg_64bit (op, nb, r4)); - } - } - else - { - if (GET_CODE (op) == SYMBOL_REF) - { - if (flag_pic) - { - rtx r4 = gen_rtx_REG (word_mode, 4); - emit_call_insn (gen_call_symref_pic (op, nb, r4)); - } - else - emit_call_insn (gen_call_symref (op, nb)); - } - else - { - rtx tmpreg = gen_rtx_REG (word_mode, 22); - emit_move_insn (tmpreg, force_reg (word_mode, op)); - if (flag_pic) - { - rtx r4 = gen_rtx_REG (word_mode, 4); - emit_call_insn (gen_call_reg_pic (nb, r4)); - } - else - emit_call_insn (gen_call_reg (nb)); - } - } - - DONE; -}") - -;; 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. -;; Implementing the calculation in rtl is difficult as well as ugly. As -;; we need the same calculation in several places, maintenance becomes a -;; nightmare. -;; -;; However, this has a subtle impact on branch shortening. When the -;; expression used to set the length attribute of an instruction depends -;; 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 -;; 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 -;; 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 -;; 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 -;; code sequence than necessary. However, the length of any given call -;; will still reflect its final code location and it may be shorter than -;; the initial length estimate. - -;; 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 -;; 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 -;; calls to participate in branch shortening would be to make the call to -;; insn_default_length a target option. Then, we could massage unknown -;; 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. - -(define_insn "call_symref" - [(call (mem:SI (match_operand 0 "call_operand_address" "")) - (match_operand 1 "" "i")) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (use (const_int 0))] - "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT" - "* -{ - pa_output_arg_descriptor (insn); - return pa_output_call (insn, operands[0], 0); -}" - [(set_attr "type" "call") - (set (attr "length") - (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)] - (symbol_ref "pa_attr_length_call (insn, 0)")))]) - -(define_insn "call_symref_pic" - [(call (mem:SI (match_operand 0 "call_operand_address" "")) - (match_operand 1 "" "i")) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (clobber (match_operand 2)) - (use (reg:SI 19)) - (use (const_int 0))] - "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT" - "#") - -;; Split out the PIC register save and restore after reload. As the -;; split is done after reload, there are some situations in which we -;; unnecessarily save and restore %r4. This happens when there is a -;; 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 pattern as is. Noreturn calls are special because they have to -;; terminate the basic block. The split has to contain more than one -;; insn. -(define_split - [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" "")) - (match_operand 1 "" "")) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (clobber (match_operand 2)) - (use (reg:SI 19)) - (use (const_int 0))])] - "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed - && find_reg_note (insn, REG_NORETURN, NULL_RTX)" - [(set (match_dup 2) (reg:SI 19)) - (parallel [(call (mem:SI (match_dup 0)) - (match_dup 1)) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (use (reg:SI 19)) - (use (const_int 0))])] - "") - -(define_split - [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" "")) - (match_operand 1 "" "")) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (clobber (match_operand 2)) - (use (reg:SI 19)) - (use (const_int 0))])] - "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed" - [(set (match_dup 2) (reg:SI 19)) - (parallel [(call (mem:SI (match_dup 0)) - (match_dup 1)) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (use (reg:SI 19)) - (use (const_int 0))]) - (set (reg:SI 19) (match_dup 2))] - "") - -(define_insn "*call_symref_pic_post_reload" - [(call (mem:SI (match_operand 0 "call_operand_address" "")) - (match_operand 1 "" "i")) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (use (reg:SI 19)) - (use (const_int 0))] - "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT" - "* -{ - pa_output_arg_descriptor (insn); - return pa_output_call (insn, operands[0], 0); -}" - [(set_attr "type" "call") - (set (attr "length") - (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)] - (symbol_ref "pa_attr_length_call (insn, 0)")))]) - -;; This pattern is split if it is necessary to save and restore the -;; PIC register. -(define_insn "call_symref_64bit" - [(call (mem:SI (match_operand 0 "call_operand_address" "")) - (match_operand 1 "" "i")) - (clobber (reg:DI 1)) - (clobber (reg:DI 2)) - (clobber (match_operand 2)) - (use (reg:DI 27)) - (use (reg:DI 29)) - (use (const_int 0))] - "TARGET_64BIT" - "#") - -;; Split out the PIC register save and restore after reload. As the -;; split is done after reload, there are some situations in which we -;; unnecessarily save and restore %r4. This happens when there is a -;; 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 pattern as is. Noreturn calls are special because they have to -;; terminate the basic block. The split has to contain more than one -;; insn. -(define_split - [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" "")) - (match_operand 1 "" "")) - (clobber (reg:DI 1)) - (clobber (reg:DI 2)) - (clobber (match_operand 2)) - (use (reg:DI 27)) - (use (reg:DI 29)) - (use (const_int 0))])] - "TARGET_64BIT && reload_completed - && find_reg_note (insn, REG_NORETURN, NULL_RTX)" - [(set (match_dup 2) (reg:DI 27)) - (parallel [(call (mem:SI (match_dup 0)) - (match_dup 1)) - (clobber (reg:DI 1)) - (clobber (reg:DI 2)) - (use (reg:DI 27)) - (use (reg:DI 29)) - (use (const_int 0))])] - "") - -(define_split - [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" "")) - (match_operand 1 "" "")) - (clobber (reg:DI 1)) - (clobber (reg:DI 2)) - (clobber (match_operand 2)) - (use (reg:DI 27)) - (use (reg:DI 29)) - (use (const_int 0))])] - "TARGET_64BIT && reload_completed" - [(set (match_dup 2) (reg:DI 27)) - (parallel [(call (mem:SI (match_dup 0)) - (match_dup 1)) - (clobber (reg:DI 1)) - (clobber (reg:DI 2)) - (use (reg:DI 27)) - (use (reg:DI 29)) - (use (const_int 0))]) - (set (reg:DI 27) (match_dup 2))] - "") - -(define_insn "*call_symref_64bit_post_reload" - [(call (mem:SI (match_operand 0 "call_operand_address" "")) - (match_operand 1 "" "i")) - (clobber (reg:DI 1)) - (clobber (reg:DI 2)) - (use (reg:DI 27)) - (use (reg:DI 29)) - (use (const_int 0))] - "TARGET_64BIT" - "* -{ - pa_output_arg_descriptor (insn); - return pa_output_call (insn, operands[0], 0); -}" - [(set_attr "type" "call") - (set (attr "length") - (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)] - (symbol_ref "pa_attr_length_call (insn, 0)")))]) - -(define_insn "call_reg" - [(call (mem:SI (reg:SI 22)) - (match_operand 0 "" "i")) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (use (const_int 1))] - "!TARGET_64BIT" - "* -{ - return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22)); -}" - [(set_attr "type" "dyncall") - (set (attr "length") - (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)] - (symbol_ref "pa_attr_length_indirect_call (insn)")))]) - -;; This pattern is split if it is necessary to save and restore the -;; PIC register. -(define_insn "call_reg_pic" - [(call (mem:SI (reg:SI 22)) - (match_operand 0 "" "i")) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (clobber (match_operand 1)) - (use (reg:SI 19)) - (use (const_int 1))] - "!TARGET_64BIT" - "#") - -;; Split out the PIC register save and restore after reload. As the -;; split is done after reload, there are some situations in which we -;; unnecessarily save and restore %r4. This happens when there is a -;; 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 pattern as is. Noreturn calls are special because they have to -;; terminate the basic block. The split has to contain more than one -;; insn. -(define_split - [(parallel [(call (mem:SI (reg:SI 22)) - (match_operand 0 "" "")) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (clobber (match_operand 1)) - (use (reg:SI 19)) - (use (const_int 1))])] - "!TARGET_64BIT && reload_completed - && find_reg_note (insn, REG_NORETURN, NULL_RTX)" - [(set (match_dup 1) (reg:SI 19)) - (parallel [(call (mem:SI (reg:SI 22)) - (match_dup 0)) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (use (reg:SI 19)) - (use (const_int 1))])] - "") - -(define_split - [(parallel [(call (mem:SI (reg:SI 22)) - (match_operand 0 "" "")) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (clobber (match_operand 1)) - (use (reg:SI 19)) - (use (const_int 1))])] - "!TARGET_64BIT && reload_completed" - [(set (match_dup 1) (reg:SI 19)) - (parallel [(call (mem:SI (reg:SI 22)) - (match_dup 0)) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (use (reg:SI 19)) - (use (const_int 1))]) - (set (reg:SI 19) (match_dup 1))] - "") - -(define_insn "*call_reg_pic_post_reload" - [(call (mem:SI (reg:SI 22)) - (match_operand 0 "" "i")) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (use (reg:SI 19)) - (use (const_int 1))] - "!TARGET_64BIT" - "* -{ - return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22)); -}" - [(set_attr "type" "dyncall") - (set (attr "length") - (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)] - (symbol_ref "pa_attr_length_indirect_call (insn)")))]) - -;; This pattern is split if it is necessary to save and restore the -;; PIC register. -(define_insn "call_reg_64bit" - [(call (mem:SI (match_operand:DI 0 "register_operand" "r")) - (match_operand 1 "" "i")) - (clobber (reg:DI 1)) - (clobber (reg:DI 2)) - (clobber (match_operand 2)) - (use (reg:DI 27)) - (use (reg:DI 29)) - (use (const_int 1))] - "TARGET_64BIT" - "#") - -;; Split out the PIC register save and restore after reload. As the -;; split is done after reload, there are some situations in which we -;; unnecessarily save and restore %r4. This happens when there is a -;; 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 pattern as is. Noreturn calls are special because they have to -;; terminate the basic block. The split has to contain more than one -;; insn. -(define_split - [(parallel [(call (mem:SI (match_operand 0 "register_operand" "")) - (match_operand 1 "" "")) - (clobber (reg:DI 1)) - (clobber (reg:DI 2)) - (clobber (match_operand 2)) - (use (reg:DI 27)) - (use (reg:DI 29)) - (use (const_int 1))])] - "TARGET_64BIT && reload_completed - && find_reg_note (insn, REG_NORETURN, NULL_RTX)" - [(set (match_dup 2) (reg:DI 27)) - (parallel [(call (mem:SI (match_dup 0)) - (match_dup 1)) - (clobber (reg:DI 1)) - (clobber (reg:DI 2)) - (use (reg:DI 27)) - (use (reg:DI 29)) - (use (const_int 1))])] - "") - -(define_split - [(parallel [(call (mem:SI (match_operand 0 "register_operand" "")) - (match_operand 1 "" "")) - (clobber (reg:DI 1)) - (clobber (reg:DI 2)) - (clobber (match_operand 2)) - (use (reg:DI 27)) - (use (reg:DI 29)) - (use (const_int 1))])] - "TARGET_64BIT && reload_completed" - [(set (match_dup 2) (reg:DI 27)) - (parallel [(call (mem:SI (match_dup 0)) - (match_dup 1)) - (clobber (reg:DI 1)) - (clobber (reg:DI 2)) - (use (reg:DI 27)) - (use (reg:DI 29)) - (use (const_int 1))]) - (set (reg:DI 27) (match_dup 2))] - "") - -(define_insn "*call_reg_64bit_post_reload" - [(call (mem:SI (match_operand:DI 0 "register_operand" "r")) - (match_operand 1 "" "i")) - (clobber (reg:DI 1)) - (clobber (reg:DI 2)) - (use (reg:DI 27)) - (use (reg:DI 29)) - (use (const_int 1))] - "TARGET_64BIT" - "* -{ - return pa_output_indirect_call (insn, operands[0]); -}" - [(set_attr "type" "dyncall") - (set (attr "length") - (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 12)] - (symbol_ref "pa_attr_length_indirect_call (insn)")))]) - -(define_expand "call_value" - [(parallel [(set (match_operand 0 "" "") - (call (match_operand:SI 1 "" "") - (match_operand 2 "" ""))) - (clobber (reg:SI 2))])] - "" -{ - rtx op; - rtx dst = operands[0]; - rtx nb = operands[2]; - - if (TARGET_PORTABLE_RUNTIME) - op = force_reg (SImode, XEXP (operands[1], 0)); - else - op = XEXP (operands[1], 0); - - if (TARGET_64BIT) - { - if (!virtuals_instantiated) - emit_move_insn (arg_pointer_rtx, - gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx, - GEN_INT (64))); - else - { - /* The loop pass can generate new libcalls after the virtual - registers are instantiated when fpregs are disabled because - the only method that we have for doing DImode multiplication - is with a libcall. This could be trouble if we haven't - allocated enough space for the outgoing arguments. */ - gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size); - - emit_move_insn (arg_pointer_rtx, - gen_rtx_PLUS (word_mode, stack_pointer_rtx, - GEN_INT (STACK_POINTER_OFFSET + 64))); - } - } - - /* Use two different patterns for calls to explicitly named functions - and calls through function pointers. This is necessary as these two - types of calls use different calling conventions, and CSE might try - to change the named call into an indirect call in some cases (using - two patterns keeps CSE from performing this optimization). - - 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 - move insn. During reload, a instruction involving a pseudo register - with no explicit dependence on the PIC register can be converted - 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 - generation, then it can potentially be repositioned during scheduling. - and an instruction that eventually uses the PIC register may end up - between the call and the PIC register restore. - - This only worked because there is a post call group of instructions - that are scheduled with the call. These instructions are included - 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 - can throw. This results in the PIC register restore being scheduled - independently from the call. So, we now hide the save and restore - 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 - need to have a use of the PIC register in the return pattern and - the final save/restore operation is not needed. - - 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. - This might have required a new register class and constraint. It - was also simpler to just handle the restore from a register than a - generic pseudo. */ - if (TARGET_64BIT) - { - rtx r4 = gen_rtx_REG (word_mode, 4); - if (GET_CODE (op) == SYMBOL_REF) - { - if (TARGET_HPUX && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT - && !strcmp (targetm.strip_name_encoding (XSTR (op, 0)), "powf")) - emit_call_insn (gen_call_val_powf_64bit (dst, op, nb, r4)); - else - emit_call_insn (gen_call_val_symref_64bit (dst, op, nb, r4)); - } - else - { - op = force_reg (word_mode, op); - emit_call_insn (gen_call_val_reg_64bit (dst, op, nb, r4)); - } - } - else - { - if (GET_CODE (op) == SYMBOL_REF) - { - if (flag_pic) - { - rtx r4 = gen_rtx_REG (word_mode, 4); - - if (TARGET_HPUX && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT - && !strcmp (targetm.strip_name_encoding (XSTR (op, 0)), - "powf")) - emit_call_insn (gen_call_val_powf_pic (dst, op, nb, r4)); - else - emit_call_insn (gen_call_val_symref_pic (dst, op, nb, r4)); - } - else - { - if (TARGET_HPUX && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT - && !strcmp (targetm.strip_name_encoding (XSTR (op, 0)), - "powf")) - emit_call_insn (gen_call_val_powf (dst, op, nb)); - else - emit_call_insn (gen_call_val_symref (dst, op, nb)); - } - } - else - { - rtx tmpreg = gen_rtx_REG (word_mode, 22); - emit_move_insn (tmpreg, force_reg (word_mode, op)); - if (flag_pic) - { - rtx r4 = gen_rtx_REG (word_mode, 4); - emit_call_insn (gen_call_val_reg_pic (dst, nb, r4)); - } - else - emit_call_insn (gen_call_val_reg (dst, nb)); - } - } - - DONE; -}) - -(define_insn "call_val_symref" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand 1 "call_operand_address" "")) - (match_operand 2 "" "i"))) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (use (const_int 0))] - "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT" - "* -{ - pa_output_arg_descriptor (insn); - return pa_output_call (insn, operands[1], 0); -}" - [(set_attr "type" "call") - (set (attr "length") - (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)] - (symbol_ref "pa_attr_length_call (insn, 0)")))]) - -;; powf function clobbers %fr12 -(define_insn "call_val_powf" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand 1 "call_operand_address" "")) - (match_operand 2 "" "i"))) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (clobber (reg:DF 48)) - (use (const_int 1))] - "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT" - "* -{ - pa_output_arg_descriptor (insn); - return pa_output_call (insn, operands[1], 0); -}" - [(set_attr "type" "call") - (set (attr "length") - (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)] - (symbol_ref "pa_attr_length_call (insn, 0)")))]) - -(define_insn "call_val_symref_pic" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand 1 "call_operand_address" "")) - (match_operand 2 "" "i"))) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (clobber (match_operand 3)) - (use (reg:SI 19)) - (use (const_int 0))] - "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT" - "#") - -;; Split out the PIC register save and restore after reload. As the -;; split is done after reload, there are some situations in which we -;; unnecessarily save and restore %r4. This happens when there is a -;; 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 pattern as is. Noreturn calls are special because they have to -;; terminate the basic block. The split has to contain more than one -;; insn. -(define_split - [(parallel [(set (match_operand 0 "" "") - (call (mem:SI (match_operand 1 "call_operand_address" "")) - (match_operand 2 "" ""))) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (clobber (match_operand 3)) - (use (reg:SI 19)) - (use (const_int 0))])] - "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed - && find_reg_note (insn, REG_NORETURN, NULL_RTX)" - [(set (match_dup 3) (reg:SI 19)) - (parallel [(set (match_dup 0) - (call (mem:SI (match_dup 1)) - (match_dup 2))) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (use (reg:SI 19)) - (use (const_int 0))])] - "") - -(define_split - [(parallel [(set (match_operand 0 "" "") - (call (mem:SI (match_operand 1 "call_operand_address" "")) - (match_operand 2 "" ""))) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (clobber (match_operand 3)) - (use (reg:SI 19)) - (use (const_int 0))])] - "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed" - [(set (match_dup 3) (reg:SI 19)) - (parallel [(set (match_dup 0) - (call (mem:SI (match_dup 1)) - (match_dup 2))) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (use (reg:SI 19)) - (use (const_int 0))]) - (set (reg:SI 19) (match_dup 3))] - "") - -(define_insn "*call_val_symref_pic_post_reload" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand 1 "call_operand_address" "")) - (match_operand 2 "" "i"))) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (use (reg:SI 19)) - (use (const_int 0))] - "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT" - "* -{ - pa_output_arg_descriptor (insn); - return pa_output_call (insn, operands[1], 0); -}" - [(set_attr "type" "call") - (set (attr "length") - (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)] - (symbol_ref "pa_attr_length_call (insn, 0)")))]) - -;; powf function clobbers %fr12 -(define_insn "call_val_powf_pic" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand 1 "call_operand_address" "")) - (match_operand 2 "" "i"))) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (clobber (reg:DF 48)) - (clobber (match_operand 3)) - (use (reg:SI 19)) - (use (const_int 1))] - "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT" - "#") - -;; Split out the PIC register save and restore after reload. As the -;; split is done after reload, there are some situations in which we -;; unnecessarily save and restore %r4. This happens when there is a -;; 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 pattern as is. Noreturn calls are special because they have to -;; terminate the basic block. The split has to contain more than one -;; insn. -(define_split - [(parallel [(set (match_operand 0 "" "") - (call (mem:SI (match_operand 1 "call_operand_address" "")) - (match_operand 2 "" ""))) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (clobber (reg:DF 48)) - (clobber (match_operand 3)) - (use (reg:SI 19)) - (use (const_int 1))])] - "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed - && find_reg_note (insn, REG_NORETURN, NULL_RTX)" - [(set (match_dup 3) (reg:SI 19)) - (parallel [(set (match_dup 0) - (call (mem:SI (match_dup 1)) - (match_dup 2))) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (clobber (reg:DF 48)) - (use (reg:SI 19)) - (use (const_int 1))])] - "") - -(define_split - [(parallel [(set (match_operand 0 "" "") - (call (mem:SI (match_operand 1 "call_operand_address" "")) - (match_operand 2 "" ""))) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (clobber (reg:DF 48)) - (clobber (match_operand 3)) - (use (reg:SI 19)) - (use (const_int 1))])] - "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed" - [(set (match_dup 3) (reg:SI 19)) - (parallel [(set (match_dup 0) - (call (mem:SI (match_dup 1)) - (match_dup 2))) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (clobber (reg:DF 48)) - (use (reg:SI 19)) - (use (const_int 1))]) - (set (reg:SI 19) (match_dup 3))] - "") - -(define_insn "*call_val_powf_pic_post_reload" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand 1 "call_operand_address" "")) - (match_operand 2 "" "i"))) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (clobber (reg:DF 48)) - (use (reg:SI 19)) - (use (const_int 1))] - "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT" - "* -{ - pa_output_arg_descriptor (insn); - return pa_output_call (insn, operands[1], 0); -}" - [(set_attr "type" "call") - (set (attr "length") - (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)] - (symbol_ref "pa_attr_length_call (insn, 0)")))]) - -;; This pattern is split if it is necessary to save and restore the -;; PIC register. -(define_insn "call_val_symref_64bit" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand 1 "call_operand_address" "")) - (match_operand 2 "" "i"))) - (clobber (reg:DI 1)) - (clobber (reg:DI 2)) - (clobber (match_operand 3)) - (use (reg:DI 27)) - (use (reg:DI 29)) - (use (const_int 0))] - "TARGET_64BIT" - "#") - -;; Split out the PIC register save and restore after reload. As the -;; split is done after reload, there are some situations in which we -;; unnecessarily save and restore %r4. This happens when there is a -;; 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 pattern as is. Noreturn calls are special because they have to -;; terminate the basic block. The split has to contain more than one -;; insn. -(define_split - [(parallel [(set (match_operand 0 "" "") - (call (mem:SI (match_operand 1 "call_operand_address" "")) - (match_operand 2 "" ""))) - (clobber (reg:DI 1)) - (clobber (reg:DI 2)) - (clobber (match_operand 3)) - (use (reg:DI 27)) - (use (reg:DI 29)) - (use (const_int 0))])] - "TARGET_64BIT && reload_completed - && find_reg_note (insn, REG_NORETURN, NULL_RTX)" - [(set (match_dup 3) (reg:DI 27)) - (parallel [(set (match_dup 0) - (call (mem:SI (match_dup 1)) - (match_dup 2))) - (clobber (reg:DI 1)) - (clobber (reg:DI 2)) - (use (reg:DI 27)) - (use (reg:DI 29)) - (use (const_int 0))])] - "") - -(define_split - [(parallel [(set (match_operand 0 "" "") - (call (mem:SI (match_operand 1 "call_operand_address" "")) - (match_operand 2 "" ""))) - (clobber (reg:DI 1)) - (clobber (reg:DI 2)) - (clobber (match_operand 3)) - (use (reg:DI 27)) - (use (reg:DI 29)) - (use (const_int 0))])] - "TARGET_64BIT && reload_completed" - [(set (match_dup 3) (reg:DI 27)) - (parallel [(set (match_dup 0) - (call (mem:SI (match_dup 1)) - (match_dup 2))) - (clobber (reg:DI 1)) - (clobber (reg:DI 2)) - (use (reg:DI 27)) - (use (reg:DI 29)) - (use (const_int 0))]) - (set (reg:DI 27) (match_dup 3))] - "") - -(define_insn "*call_val_symref_64bit_post_reload" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand 1 "call_operand_address" "")) - (match_operand 2 "" "i"))) - (clobber (reg:DI 1)) - (clobber (reg:DI 2)) - (use (reg:DI 27)) - (use (reg:DI 29)) - (use (const_int 0))] - "TARGET_64BIT" - "* -{ - pa_output_arg_descriptor (insn); - return pa_output_call (insn, operands[1], 0); -}" - [(set_attr "type" "call") - (set (attr "length") - (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)] - (symbol_ref "pa_attr_length_call (insn, 0)")))]) - -;; powf function clobbers %fr12 -(define_insn "call_val_powf_64bit" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand 1 "call_operand_address" "")) - (match_operand 2 "" "i"))) - (clobber (reg:DI 1)) - (clobber (reg:DI 2)) - (clobber (reg:DF 40)) - (clobber (match_operand 3)) - (use (reg:DI 27)) - (use (reg:DI 29)) - (use (const_int 1))] - "TARGET_64BIT && TARGET_HPUX" - "#") - -;; Split out the PIC register save and restore after reload. As the -;; split is done after reload, there are some situations in which we -;; unnecessarily save and restore %r4. This happens when there is a -;; 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 pattern as is. Noreturn calls are special because they have to -;; terminate the basic block. The split has to contain more than one -;; insn. -(define_split - [(parallel [(set (match_operand 0 "" "") - (call (mem:SI (match_operand 1 "call_operand_address" "")) - (match_operand 2 "" ""))) - (clobber (reg:DI 1)) - (clobber (reg:DI 2)) - (clobber (reg:DF 40)) - (clobber (match_operand 3)) - (use (reg:DI 27)) - (use (reg:DI 29)) - (use (const_int 1))])] - "TARGET_64BIT && TARGET_HPUX && reload_completed - && find_reg_note (insn, REG_NORETURN, NULL_RTX)" - [(set (match_dup 3) (reg:DI 27)) - (parallel [(set (match_dup 0) - (call (mem:SI (match_dup 1)) - (match_dup 2))) - (clobber (reg:DI 1)) - (clobber (reg:DI 2)) - (clobber (reg:DF 40)) - (use (reg:DI 27)) - (use (reg:DI 29)) - (use (const_int 1))])] - "") - -(define_split - [(parallel [(set (match_operand 0 "" "") - (call (mem:SI (match_operand 1 "call_operand_address" "")) - (match_operand 2 "" ""))) - (clobber (reg:DI 1)) - (clobber (reg:DI 2)) - (clobber (reg:DF 40)) - (clobber (match_operand 3)) - (use (reg:DI 27)) - (use (reg:DI 29)) - (use (const_int 1))])] - "TARGET_64BIT && TARGET_HPUX && reload_completed" - [(set (match_dup 3) (reg:DI 27)) - (parallel [(set (match_dup 0) - (call (mem:SI (match_dup 1)) - (match_dup 2))) - (clobber (reg:DI 1)) - (clobber (reg:DI 2)) - (clobber (reg:DF 40)) - (use (reg:DI 27)) - (use (reg:DI 29)) - (use (const_int 1))]) - (set (reg:DI 27) (match_dup 3))] - "") - -(define_insn "*call_val_powf_64bit_post_reload" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand 1 "call_operand_address" "")) - (match_operand 2 "" "i"))) - (clobber (reg:DI 1)) - (clobber (reg:DI 2)) - (clobber (reg:DF 40)) - (use (reg:DI 27)) - (use (reg:DI 29)) - (use (const_int 1))] - "TARGET_64BIT && TARGET_HPUX" - "* -{ - pa_output_arg_descriptor (insn); - return pa_output_call (insn, operands[1], 0); -}" - [(set_attr "type" "call") - (set (attr "length") - (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)] - (symbol_ref "pa_attr_length_call (insn, 0)")))]) - -(define_insn "call_val_reg" - [(set (match_operand 0 "" "") - (call (mem:SI (reg:SI 22)) - (match_operand 1 "" "i"))) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (use (const_int 1))] - "!TARGET_64BIT" - "* -{ - return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22)); -}" - [(set_attr "type" "dyncall") - (set (attr "length") - (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)] - (symbol_ref "pa_attr_length_indirect_call (insn)")))]) - -;; This pattern is split if it is necessary to save and restore the -;; PIC register. -(define_insn "call_val_reg_pic" - [(set (match_operand 0 "" "") - (call (mem:SI (reg:SI 22)) - (match_operand 1 "" "i"))) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (clobber (match_operand 2)) - (use (reg:SI 19)) - (use (const_int 1))] - "!TARGET_64BIT" - "#") - -;; Split out the PIC register save and restore after reload. As the -;; split is done after reload, there are some situations in which we -;; unnecessarily save and restore %r4. This happens when there is a -;; 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 pattern as is. Noreturn calls are special because they have to -;; terminate the basic block. The split has to contain more than one -;; insn. -(define_split - [(parallel [(set (match_operand 0 "" "") - (call (mem:SI (reg:SI 22)) - (match_operand 1 "" ""))) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (clobber (match_operand 2)) - (use (reg:SI 19)) - (use (const_int 1))])] - "!TARGET_64BIT && reload_completed - && find_reg_note (insn, REG_NORETURN, NULL_RTX)" - [(set (match_dup 2) (reg:SI 19)) - (parallel [(set (match_dup 0) - (call (mem:SI (reg:SI 22)) - (match_dup 1))) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (use (reg:SI 19)) - (use (const_int 1))])] - "") - -(define_split - [(parallel [(set (match_operand 0 "" "") - (call (mem:SI (reg:SI 22)) - (match_operand 1 "" ""))) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (clobber (match_operand 2)) - (use (reg:SI 19)) - (use (const_int 1))])] - "!TARGET_64BIT && reload_completed" - [(set (match_dup 2) (reg:SI 19)) - (parallel [(set (match_dup 0) - (call (mem:SI (reg:SI 22)) - (match_dup 1))) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (use (reg:SI 19)) - (use (const_int 1))]) - (set (reg:SI 19) (match_dup 2))] - "") - -(define_insn "*call_val_reg_pic_post_reload" - [(set (match_operand 0 "" "") - (call (mem:SI (reg:SI 22)) - (match_operand 1 "" "i"))) - (clobber (reg:SI 1)) - (clobber (reg:SI 2)) - (use (reg:SI 19)) - (use (const_int 1))] - "!TARGET_64BIT" - "* -{ - return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22)); -}" - [(set_attr "type" "dyncall") - (set (attr "length") - (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)] - (symbol_ref "pa_attr_length_indirect_call (insn)")))]) - -;; This pattern is split if it is necessary to save and restore the -;; PIC register. -(define_insn "call_val_reg_64bit" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:DI 1 "register_operand" "r")) - (match_operand 2 "" "i"))) - (clobber (reg:DI 1)) - (clobber (reg:DI 2)) - (clobber (match_operand 3)) - (use (reg:DI 27)) - (use (reg:DI 29)) - (use (const_int 1))] - "TARGET_64BIT" - "#") - -;; Split out the PIC register save and restore after reload. As the -;; split is done after reload, there are some situations in which we -;; unnecessarily save and restore %r4. This happens when there is a -;; 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 pattern as is. Noreturn calls are special because they have to -;; terminate the basic block. The split has to contain more than one -;; insn. -(define_split - [(parallel [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:DI 1 "register_operand" "")) - (match_operand 2 "" ""))) - (clobber (reg:DI 1)) - (clobber (reg:DI 2)) - (clobber (match_operand 3)) - (use (reg:DI 27)) - (use (reg:DI 29)) - (use (const_int 1))])] - "TARGET_64BIT && reload_completed - && find_reg_note (insn, REG_NORETURN, NULL_RTX)" - [(set (match_dup 3) (reg:DI 27)) - (parallel [(set (match_dup 0) - (call (mem:SI (match_dup 1)) - (match_dup 2))) - (clobber (reg:DI 1)) - (clobber (reg:DI 2)) - (use (reg:DI 27)) - (use (reg:DI 29)) - (use (const_int 1))])] - "") - -(define_split - [(parallel [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:DI 1 "register_operand" "")) - (match_operand 2 "" ""))) - (clobber (reg:DI 1)) - (clobber (reg:DI 2)) - (clobber (match_operand 3)) - (use (reg:DI 27)) - (use (reg:DI 29)) - (use (const_int 1))])] - "TARGET_64BIT && reload_completed" - [(set (match_dup 3) (reg:DI 27)) - (parallel [(set (match_dup 0) - (call (mem:SI (match_dup 1)) - (match_dup 2))) - (clobber (reg:DI 1)) - (clobber (reg:DI 2)) - (use (reg:DI 27)) - (use (reg:DI 29)) - (use (const_int 1))]) - (set (reg:DI 27) (match_dup 3))] - "") - -(define_insn "*call_val_reg_64bit_post_reload" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:DI 1 "register_operand" "r")) - (match_operand 2 "" "i"))) - (clobber (reg:DI 1)) - (clobber (reg:DI 2)) - (use (reg:DI 27)) - (use (reg:DI 29)) - (use (const_int 1))] - "TARGET_64BIT" - "* -{ - return pa_output_indirect_call (insn, operands[1]); -}" - [(set_attr "type" "dyncall") - (set (attr "length") - (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 12)] - (symbol_ref "pa_attr_length_indirect_call (insn)")))]) - -;; Call subroutine returning any type. - -(define_expand "untyped_call" - [(parallel [(call (match_operand 0 "" "") - (const_int 0)) - (match_operand 1 "" "") - (match_operand 2 "" "")])] - "" - " -{ - int i; - - emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx)); - - for (i = 0; i < XVECLEN (operands[2], 0); i++) - { - rtx set = XVECEXP (operands[2], 0, i); - emit_move_insn (SET_DEST (set), SET_SRC (set)); - } - - /* The optimizer does not know that the call sets the function value - registers we stored in the result block. We avoid problems by - claiming that all hard registers are used and clobbered at this - point. */ - emit_insn (gen_blockage ()); - - DONE; -}") - -(define_expand "sibcall" - [(call (match_operand:SI 0 "" "") - (match_operand 1 "" ""))] - "!TARGET_PORTABLE_RUNTIME" - " -{ - rtx op, call_insn; - rtx nb = operands[1]; - - op = XEXP (operands[0], 0); - - if (TARGET_64BIT) - { - if (!virtuals_instantiated) - emit_move_insn (arg_pointer_rtx, - gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx, - GEN_INT (64))); - else - { - /* The loop pass can generate new libcalls after the virtual - registers are instantiated when fpregs are disabled because - the only method that we have for doing DImode multiplication - is with a libcall. This could be trouble if we haven't - allocated enough space for the outgoing arguments. */ - gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size); - - emit_move_insn (arg_pointer_rtx, - gen_rtx_PLUS (word_mode, stack_pointer_rtx, - GEN_INT (STACK_POINTER_OFFSET + 64))); - } - } - - /* Indirect sibling calls are not allowed. */ - if (TARGET_64BIT) - call_insn = gen_sibcall_internal_symref_64bit (op, operands[1]); - else - call_insn = gen_sibcall_internal_symref (op, operands[1]); - - call_insn = emit_call_insn (call_insn); - - if (TARGET_64BIT) - use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx); - - /* We don't have to restore the PIC register. */ - if (flag_pic) - use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx); - - DONE; -}") - -(define_insn "sibcall_internal_symref" - [(call (mem:SI (match_operand 0 "call_operand_address" "")) - (match_operand 1 "" "i")) - (clobber (reg:SI 1)) - (use (reg:SI 2)) - (use (const_int 0))] - "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT" - "* -{ - pa_output_arg_descriptor (insn); - return pa_output_call (insn, operands[0], 1); -}" - [(set_attr "type" "sibcall") - (set (attr "length") - (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)] - (symbol_ref "pa_attr_length_call (insn, 1)")))]) - -(define_insn "sibcall_internal_symref_64bit" - [(call (mem:SI (match_operand 0 "call_operand_address" "")) - (match_operand 1 "" "i")) - (clobber (reg:DI 1)) - (use (reg:DI 2)) - (use (const_int 0))] - "TARGET_64BIT" - "* -{ - pa_output_arg_descriptor (insn); - return pa_output_call (insn, operands[0], 1); -}" - [(set_attr "type" "sibcall") - (set (attr "length") - (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)] - (symbol_ref "pa_attr_length_call (insn, 1)")))]) - -(define_expand "sibcall_value" - [(set (match_operand 0 "" "") - (call (match_operand:SI 1 "" "") - (match_operand 2 "" "")))] - "!TARGET_PORTABLE_RUNTIME" - " -{ - rtx op, call_insn; - rtx nb = operands[1]; - - op = XEXP (operands[1], 0); - - if (TARGET_64BIT) - { - if (!virtuals_instantiated) - emit_move_insn (arg_pointer_rtx, - gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx, - GEN_INT (64))); - else - { - /* The loop pass can generate new libcalls after the virtual - registers are instantiated when fpregs are disabled because - the only method that we have for doing DImode multiplication - is with a libcall. This could be trouble if we haven't - allocated enough space for the outgoing arguments. */ - gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size); - - emit_move_insn (arg_pointer_rtx, - gen_rtx_PLUS (word_mode, stack_pointer_rtx, - GEN_INT (STACK_POINTER_OFFSET + 64))); - } - } - - /* Indirect sibling calls are not allowed. */ - if (TARGET_64BIT) - call_insn - = gen_sibcall_value_internal_symref_64bit (operands[0], op, operands[2]); - else - call_insn - = gen_sibcall_value_internal_symref (operands[0], op, operands[2]); - - call_insn = emit_call_insn (call_insn); - - if (TARGET_64BIT) - use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx); - - /* We don't have to restore the PIC register. */ - if (flag_pic) - use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx); - - DONE; -}") - -(define_insn "sibcall_value_internal_symref" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand 1 "call_operand_address" "")) - (match_operand 2 "" "i"))) - (clobber (reg:SI 1)) - (use (reg:SI 2)) - (use (const_int 0))] - "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT" - "* -{ - pa_output_arg_descriptor (insn); - return pa_output_call (insn, operands[1], 1); -}" - [(set_attr "type" "sibcall") - (set (attr "length") - (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)] - (symbol_ref "pa_attr_length_call (insn, 1)")))]) - -(define_insn "sibcall_value_internal_symref_64bit" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand 1 "call_operand_address" "")) - (match_operand 2 "" "i"))) - (clobber (reg:DI 1)) - (use (reg:DI 2)) - (use (const_int 0))] - "TARGET_64BIT" - "* -{ - pa_output_arg_descriptor (insn); - return pa_output_call (insn, operands[1], 1); -}" - [(set_attr "type" "sibcall") - (set (attr "length") - (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)] - (symbol_ref "pa_attr_length_call (insn, 1)")))]) - -(define_insn "nop" - [(const_int 0)] - "" - "nop" - [(set_attr "type" "move") - (set_attr "length" "4")]) - -;; These are just placeholders so we know where branch tables -;; begin and end. -(define_insn "begin_brtab" - [(const_int 1)] - "" - "* -{ - /* Only GAS actually supports this pseudo-op. */ - if (TARGET_GAS) - return \".begin_brtab\"; - else - return \"\"; -}" - [(set_attr "type" "move") - (set_attr "length" "0")]) - -(define_insn "end_brtab" - [(const_int 2)] - "" - "* -{ - /* Only GAS actually supports this pseudo-op. */ - if (TARGET_GAS) - return \".end_brtab\"; - else - return \"\"; -}" - [(set_attr "type" "move") - (set_attr "length" "0")]) - -;;; EH does longjmp's from and within the data section. Thus, -;;; an interspace branch is required for the longjmp implementation. -;;; Registers r1 and r2 are used as scratch registers for the jump -;;; when necessary. -(define_expand "interspace_jump" - [(parallel - [(set (pc) (match_operand 0 "pmode_register_operand" "a")) - (clobber (match_dup 1))])] - "" - " -{ - operands[1] = gen_rtx_REG (word_mode, 2); -}") - -(define_insn "" - [(set (pc) (match_operand 0 "pmode_register_operand" "a")) - (clobber (reg:SI 2))] - "TARGET_PA_20 && !TARGET_64BIT" - "bve%* (%0)" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_insn "" - [(set (pc) (match_operand 0 "pmode_register_operand" "a")) - (clobber (reg:SI 2))] - "TARGET_NO_SPACE_REGS && !TARGET_64BIT" - "be%* 0(%%sr4,%0)" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_insn "" - [(set (pc) (match_operand 0 "pmode_register_operand" "a")) - (clobber (reg:SI 2))] - "!TARGET_64BIT" - "ldsid (%%sr0,%0),%%r2\;mtsp %%r2,%%sr0\;be%* 0(%%sr0,%0)" - [(set_attr "type" "branch") - (set_attr "length" "12")]) - -(define_insn "" - [(set (pc) (match_operand 0 "pmode_register_operand" "a")) - (clobber (reg:DI 2))] - "TARGET_64BIT" - "bve%* (%0)" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_expand "builtin_longjmp" - [(unspec_volatile [(match_operand 0 "register_operand" "r")] UNSPECV_LONGJMP)] - "" - " -{ - /* The elements of the buffer are, in order: */ - rtx fp = gen_rtx_MEM (Pmode, operands[0]); - rtx lab = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], - POINTER_SIZE / BITS_PER_UNIT)); - rtx stack = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], - (POINTER_SIZE * 2) / BITS_PER_UNIT)); - rtx pv = gen_rtx_REG (Pmode, 1); - - emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode))); - emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx)); - - /* Restore the frame pointer. The virtual_stack_vars_rtx is saved - instead of the hard_frame_pointer_rtx in the save area. We need - to adjust for the offset between these two values. */ - if (GET_CODE (fp) != REG) - fp = force_reg (Pmode, fp); - emit_move_insn (hard_frame_pointer_rtx, plus_constant (Pmode, fp, -8)); - - /* This bit is the same as expand_builtin_longjmp. */ - emit_stack_restore (SAVE_NONLOCAL, stack); - emit_use (hard_frame_pointer_rtx); - emit_use (stack_pointer_rtx); - - /* 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 - restoring the gp. */ - emit_move_insn (pv, lab); - - /* Prevent the insns above from being scheduled into the delay slot - of the interspace jump because the space register could change. */ - emit_insn (gen_blockage ()); - - emit_jump_insn (gen_interspace_jump (pv)); - emit_barrier (); - DONE; -}") - -;;; Operands 2 and 3 are assumed to be CONST_INTs. -(define_expand "extzvsi" - [(set (match_operand:SI 0 "register_operand" "") - (zero_extract:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "uint5_operand" "") - (match_operand:SI 3 "uint5_operand" "")))] - "" - " -{ - unsigned HOST_WIDE_INT len = UINTVAL (operands[2]); - unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]); - - /* PA extraction insns don't support zero length bitfields or fields - extending beyond the left or right-most bits. Also, the predicate - rejects lengths equal to a word as they are better handled by - the move patterns. */ - if (len == 0 || pos + len > 32) - FAIL; - - /* From mips.md: extract_bit_field doesn't verify that our source - matches the predicate, so check it again here. */ - if (!register_operand (operands[1], VOIDmode)) - FAIL; - - emit_insn (gen_extzv_32 (operands[0], operands[1], - operands[2], operands[3])); - DONE; -}") - -(define_insn "extzv_32" - [(set (match_operand:SI 0 "register_operand" "=r") - (zero_extract:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "uint5_operand" "") - (match_operand:SI 3 "uint5_operand" "")))] - "UINTVAL (operands[2]) > 0 - && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 32" - "{extru|extrw,u} %1,%3+%2-1,%2,%0" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (zero_extract:SI (match_operand:SI 1 "register_operand" "r") - (const_int 1) - (match_operand:SI 2 "register_operand" "q")))] - "" - "{vextru %1,1,%0|extrw,u %1,%%sar,1,%0}" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -(define_expand "extzvdi" - [(set (match_operand:DI 0 "register_operand" "") - (zero_extract:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "uint6_operand" "") - (match_operand:DI 3 "uint6_operand" "")))] - "TARGET_64BIT" - " -{ - unsigned HOST_WIDE_INT len = UINTVAL (operands[2]); - unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]); - - /* PA extraction insns don't support zero length bitfields or fields - extending beyond the left or right-most bits. Also, the predicate - rejects lengths equal to a doubleword as they are better handled by - the move patterns. */ - if (len == 0 || pos + len > 64) - FAIL; - - /* From mips.md: extract_bit_field doesn't verify that our source - matches the predicate, so check it again here. */ - if (!register_operand (operands[1], VOIDmode)) - FAIL; - - emit_insn (gen_extzv_64 (operands[0], operands[1], - operands[2], operands[3])); - DONE; -}") - -(define_insn "extzv_64" - [(set (match_operand:DI 0 "register_operand" "=r") - (zero_extract:DI (match_operand:DI 1 "register_operand" "r") - (match_operand:DI 2 "uint6_operand" "") - (match_operand:DI 3 "uint6_operand" "")))] - "TARGET_64BIT - && UINTVAL (operands[2]) > 0 - && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 64" - "extrd,u %1,%3+%2-1,%2,%0" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (zero_extract:DI (match_operand:DI 1 "register_operand" "r") - (const_int 1) - (match_operand:DI 2 "register_operand" "q")))] - "TARGET_64BIT" - "extrd,u %1,%%sar,1,%0" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -;;; Operands 2 and 3 are assumed to be CONST_INTs. -(define_expand "extvsi" - [(set (match_operand:SI 0 "register_operand" "") - (sign_extract:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "uint5_operand" "") - (match_operand:SI 3 "uint5_operand" "")))] - "" - " -{ - unsigned HOST_WIDE_INT len = UINTVAL (operands[2]); - unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]); - - /* PA extraction insns don't support zero length bitfields or fields - extending beyond the left or right-most bits. Also, the predicate - rejects lengths equal to a word as they are better handled by - the move patterns. */ - if (len == 0 || pos + len > 32) - FAIL; - - /* From mips.md: extract_bit_field doesn't verify that our source - matches the predicate, so check it again here. */ - if (!register_operand (operands[1], VOIDmode)) - FAIL; - - emit_insn (gen_extv_32 (operands[0], operands[1], - operands[2], operands[3])); - DONE; -}") - -(define_insn "extv_32" - [(set (match_operand:SI 0 "register_operand" "=r") - (sign_extract:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "uint5_operand" "") - (match_operand:SI 3 "uint5_operand" "")))] - "UINTVAL (operands[2]) > 0 - && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 32" - "{extrs|extrw,s} %1,%3+%2-1,%2,%0" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (sign_extract:SI (match_operand:SI 1 "register_operand" "r") - (const_int 1) - (match_operand:SI 2 "register_operand" "q")))] - "!TARGET_64BIT" - "{vextrs %1,1,%0|extrw,s %1,%%sar,1,%0}" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -(define_expand "extvdi" - [(set (match_operand:DI 0 "register_operand" "") - (sign_extract:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "uint6_operand" "") - (match_operand:DI 3 "uint6_operand" "")))] - "TARGET_64BIT" - " -{ - unsigned HOST_WIDE_INT len = UINTVAL (operands[2]); - unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]); - - /* PA extraction insns don't support zero length bitfields or fields - extending beyond the left or right-most bits. Also, the predicate - rejects lengths equal to a doubleword as they are better handled by - the move patterns. */ - if (len == 0 || pos + len > 64) - FAIL; - - /* From mips.md: extract_bit_field doesn't verify that our source - matches the predicate, so check it again here. */ - if (!register_operand (operands[1], VOIDmode)) - FAIL; - - emit_insn (gen_extv_64 (operands[0], operands[1], - operands[2], operands[3])); - DONE; -}") - -(define_insn "extv_64" - [(set (match_operand:DI 0 "register_operand" "=r") - (sign_extract:DI (match_operand:DI 1 "register_operand" "r") - (match_operand:DI 2 "uint6_operand" "") - (match_operand:DI 3 "uint6_operand" "")))] - "TARGET_64BIT - && UINTVAL (operands[2]) > 0 - && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 64" - "extrd,s %1,%3+%2-1,%2,%0" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (sign_extract:DI (match_operand:DI 1 "register_operand" "r") - (const_int 1) - (match_operand:DI 2 "register_operand" "q")))] - "TARGET_64BIT" - "extrd,s %1,%%sar,1,%0" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -;;; Operands 1 and 2 are assumed to be CONST_INTs. -(define_expand "insvsi" - [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "") - (match_operand:SI 1 "uint5_operand" "") - (match_operand:SI 2 "uint5_operand" "")) - (match_operand:SI 3 "arith5_operand" ""))] - "" - " -{ - unsigned HOST_WIDE_INT len = UINTVAL (operands[1]); - unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]); - - /* PA insertion insns don't support zero length bitfields or fields - extending beyond the left or right-most bits. Also, the predicate - rejects lengths equal to a word as they are better handled by - the move patterns. */ - if (len <= 0 || pos + len > 32) - FAIL; - - /* From mips.md: insert_bit_field doesn't verify that our destination - matches the predicate, so check it again here. */ - if (!register_operand (operands[0], VOIDmode)) - FAIL; - - emit_insn (gen_insv_32 (operands[0], operands[1], - operands[2], operands[3])); - DONE; -}") - -(define_insn "insv_32" - [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r") - (match_operand:SI 1 "uint5_operand" "") - (match_operand:SI 2 "uint5_operand" "")) - (match_operand:SI 3 "arith5_operand" "r,L"))] - "UINTVAL (operands[1]) > 0 - && UINTVAL (operands[1]) + UINTVAL (operands[2]) <= 32" - "@ - {dep|depw} %3,%2+%1-1,%1,%0 - {depi|depwi} %3,%2+%1-1,%1,%0" - [(set_attr "type" "shift,shift") - (set_attr "length" "4,4")]) - -;; Optimize insertion of const_int values of type 1...1xxxx. -(define_insn "" - [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") - (match_operand:SI 1 "uint5_operand" "") - (match_operand:SI 2 "uint5_operand" "")) - (match_operand:SI 3 "const_int_operand" ""))] - "(INTVAL (operands[3]) & 0x10) != 0 && - (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0" - "* -{ - operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10); - return \"{depi|depwi} %3,%2+%1-1,%1,%0\"; -}" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -(define_expand "insvdi" - [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "") - (match_operand:DI 1 "uint6_operand" "") - (match_operand:DI 2 "uint6_operand" "")) - (match_operand:DI 3 "arith5_operand" ""))] - "TARGET_64BIT" - " -{ - unsigned HOST_WIDE_INT len = UINTVAL (operands[1]); - unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]); - - /* PA insertion insns don't support zero length bitfields or fields - extending beyond the left or right-most bits. Also, the predicate - rejects lengths equal to a doubleword as they are better handled by - the move patterns. */ - if (len <= 0 || pos + len > 64) - FAIL; - - /* From mips.md: insert_bit_field doesn't verify that our destination - matches the predicate, so check it again here. */ - if (!register_operand (operands[0], VOIDmode)) - FAIL; - - emit_insn (gen_insv_64 (operands[0], operands[1], - operands[2], operands[3])); - DONE; -}") - -(define_insn "insv_64" - [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r,r") - (match_operand:DI 1 "uint6_operand" "") - (match_operand:DI 2 "uint6_operand" "")) - (match_operand:DI 3 "arith5_operand" "r,L"))] - "TARGET_64BIT - && UINTVAL (operands[1]) > 0 - && UINTVAL (operands[1]) + UINTVAL (operands[2]) <= 64" - "@ - depd %3,%2+%1-1,%1,%0 - depdi %3,%2+%1-1,%1,%0" - [(set_attr "type" "shift,shift") - (set_attr "length" "4,4")]) - -;; Optimize insertion of const_int values of type 1...1xxxx. -(define_insn "" - [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") - (match_operand:DI 1 "uint6_operand" "") - (match_operand:DI 2 "uint6_operand" "")) - (match_operand:DI 3 "const_int_operand" ""))] - "(INTVAL (operands[3]) & 0x10) != 0 - && TARGET_64BIT - && (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0" - "* -{ - operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10); - return \"depdi %3,%2+%1-1,%1,%0\"; -}" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) - (const_int 32)))] - "TARGET_64BIT" - "depd,z %1,31,32,%0" - [(set_attr "type" "shift") - (set_attr "length" "4")]) - -;; This insn is used for some loop tests, typically loops reversed when -;; strength reduction is used. It is actually created when the instruction -;; 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 -;; reloads, hence the `m' constraints. The `!' constraints direct reload -;; to not choose the register alternatives in the event a reload is needed. -(define_insn "decrement_and_branch_until_zero" - [(set (pc) - (if_then_else - (match_operator 2 "comparison_operator" - [(plus:SI - (match_operand:SI 0 "reg_before_reload_operand" "+!r,!*f,*m") - (match_operand:SI 1 "int5_operand" "L,L,L")) - (const_int 0)]) - (label_ref (match_operand 3 "" "")) - (pc))) - (set (match_dup 0) - (plus:SI (match_dup 0) (match_dup 1))) - (clobber (match_scratch:SI 4 "=X,r,r"))] - "" - "* return pa_output_dbra (operands, insn, which_alternative); " -;; Do not expect to understand this the first time through. -[(set_attr "type" "cbranch,multi,multi") - (set (attr "length") - (if_then_else (eq_attr "alternative" "0") -;; Loop counter in register case -;; Short branch has length of 4 -;; Long branch has length of 8, 20, 24 or 28 - (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 24) - (not (match_test "flag_pic")) - (const_int 20)] - (const_int 28)) - -;; Loop counter in FP reg case. -;; Extra goo to deal with additional reload insns. - (if_then_else (eq_attr "alternative" "1") - (if_then_else (lt (match_dup 3) (pc)) - (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 24)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 24) - (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 28) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 44) - (not (match_test "flag_pic")) - (const_int 40)] - (const_int 48)) - (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 24) - (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 28) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 44) - (not (match_test "flag_pic")) - (const_int 40)] - (const_int 48))) - -;; Loop counter in memory case. -;; Extra goo to deal with additional reload insns. - (if_then_else (lt (match_dup 3) (pc)) - (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 12) - (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 16) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 32) - (not (match_test "flag_pic")) - (const_int 28)] - (const_int 36)) - (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 12) - (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 16) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 32) - (not (match_test "flag_pic")) - (const_int 28)] - (const_int 36))))))]) - -(define_insn "" - [(set (pc) - (if_then_else - (match_operator 2 "movb_comparison_operator" - [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)]) - (label_ref (match_operand 3 "" "")) - (pc))) - (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*m,!*q") - (match_dup 1))] - "" -"* return pa_output_movb (operands, insn, which_alternative, 0); " -;; Do not expect to understand this the first time through. -[(set_attr "type" "cbranch,multi,multi,multi") - (set (attr "length") - (if_then_else (eq_attr "alternative" "0") -;; Loop counter in register case -;; Short branch has length of 4 -;; Long branch has length of 8, 20, 24 or 28 - (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 24) - (not (match_test "flag_pic")) - (const_int 20)] - (const_int 28)) - -;; Loop counter in FP reg case. -;; Extra goo to deal with additional reload insns. - (if_then_else (eq_attr "alternative" "1") - (if_then_else (lt (match_dup 3) (pc)) - (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 12) - (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 16) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 32) - (not (match_test "flag_pic")) - (const_int 28)] - (const_int 36)) - (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 12) - (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 16) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 32) - (not (match_test "flag_pic")) - (const_int 28)] - (const_int 36))) - -;; Loop counter in memory or sar case. -;; Extra goo to deal with additional reload insns. - (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 8) - (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 12) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 28) - (not (match_test "flag_pic")) - (const_int 24)] - (const_int 32)))))]) - -;; Handle negated branch. -(define_insn "" - [(set (pc) - (if_then_else - (match_operator 2 "movb_comparison_operator" - [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)]) - (pc) - (label_ref (match_operand 3 "" "")))) - (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*m,!*q") - (match_dup 1))] - "" -"* return pa_output_movb (operands, insn, which_alternative, 1); " -;; Do not expect to understand this the first time through. -[(set_attr "type" "cbranch,multi,multi,multi") - (set (attr "length") - (if_then_else (eq_attr "alternative" "0") -;; Loop counter in register case -;; Short branch has length of 4 -;; Long branch has length of 8 - (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 24) - (not (match_test "flag_pic")) - (const_int 20)] - (const_int 28)) - -;; Loop counter in FP reg case. -;; Extra goo to deal with additional reload insns. - (if_then_else (eq_attr "alternative" "1") - (if_then_else (lt (match_dup 3) (pc)) - (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 12) - (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 16) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 32) - (not (match_test "flag_pic")) - (const_int 28)] - (const_int 36)) - (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 12) - (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 16) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 32) - (not (match_test "flag_pic")) - (const_int 28)] - (const_int 36))) - -;; Loop counter in memory or SAR case. -;; Extra goo to deal with additional reload insns. - (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 8) - (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 12) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 28) - (not (match_test "flag_pic")) - (const_int 24)] - (const_int 32)))))]) - -(define_insn "" - [(set (pc) (label_ref (match_operand 3 "" "" ))) - (set (match_operand:SI 0 "ireg_operand" "=r") - (plus:SI (match_operand:SI 1 "ireg_operand" "r") - (match_operand:SI 2 "ireg_or_int5_operand" "rL")))] - "(reload_completed && operands[0] == operands[1]) || operands[0] == operands[2]" - "* -{ - return pa_output_parallel_addb (operands, insn); -}" -[(set_attr "type" "parallel_branch") - (set (attr "length") - (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 24) - (not (match_test "flag_pic")) - (const_int 20)] - (const_int 28)))]) - -(define_insn "" - [(set (pc) (label_ref (match_operand 2 "" "" ))) - (set (match_operand:SF 0 "ireg_operand" "=r") - (match_operand:SF 1 "ireg_or_int5_operand" "rL"))] - "reload_completed" - "* -{ - return pa_output_parallel_movb (operands, insn); -}" -[(set_attr "type" "parallel_branch") - (set (attr "length") - (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 24) - (not (match_test "flag_pic")) - (const_int 20)] - (const_int 28)))]) - -(define_insn "" - [(set (pc) (label_ref (match_operand 2 "" "" ))) - (set (match_operand:SI 0 "ireg_operand" "=r") - (match_operand:SI 1 "ireg_or_int5_operand" "rL"))] - "reload_completed" - "* -{ - return pa_output_parallel_movb (operands, insn); -}" -[(set_attr "type" "parallel_branch") - (set (attr "length") - (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 24) - (not (match_test "flag_pic")) - (const_int 20)] - (const_int 28)))]) - -(define_insn "" - [(set (pc) (label_ref (match_operand 2 "" "" ))) - (set (match_operand:HI 0 "ireg_operand" "=r") - (match_operand:HI 1 "ireg_or_int5_operand" "rL"))] - "reload_completed" - "* -{ - return pa_output_parallel_movb (operands, insn); -}" -[(set_attr "type" "parallel_branch") - (set (attr "length") - (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 24) - (not (match_test "flag_pic")) - (const_int 20)] - (const_int 28)))]) - -(define_insn "" - [(set (pc) (label_ref (match_operand 2 "" "" ))) - (set (match_operand:QI 0 "ireg_operand" "=r") - (match_operand:QI 1 "ireg_or_int5_operand" "rL"))] - "reload_completed" - "* -{ - return pa_output_parallel_movb (operands, insn); -}" -[(set_attr "type" "parallel_branch") - (set (attr "length") - (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_12BIT_OFFSET)) - (const_int 4) - (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8)))) - (const_int MAX_17BIT_OFFSET)) - (const_int 8) - (match_test "TARGET_PORTABLE_RUNTIME") - (const_int 24) - (not (match_test "flag_pic")) - (const_int 20)] - (const_int 28)))]) - -(define_insn "" - [(set (match_operand 0 "register_operand" "=f") - (mult (match_operand 1 "register_operand" "f") - (match_operand 2 "register_operand" "f"))) - (set (match_operand 3 "register_operand" "+f") - (plus (match_operand 4 "register_operand" "f") - (match_operand 5 "register_operand" "f")))] - "TARGET_PA_11 && ! TARGET_SOFT_FLOAT - && reload_completed && pa_fmpyaddoperands (operands)" - "* -{ - if (GET_MODE (operands[0]) == DFmode) - { - if (rtx_equal_p (operands[3], operands[5])) - return \"fmpyadd,dbl %1,%2,%0,%4,%3\"; - else - return \"fmpyadd,dbl %1,%2,%0,%5,%3\"; - } - else - { - if (rtx_equal_p (operands[3], operands[5])) - return \"fmpyadd,sgl %1,%2,%0,%4,%3\"; - else - return \"fmpyadd,sgl %1,%2,%0,%5,%3\"; - } -}" - [(set_attr "type" "fpalu") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand 3 "register_operand" "+f") - (plus (match_operand 4 "register_operand" "f") - (match_operand 5 "register_operand" "f"))) - (set (match_operand 0 "register_operand" "=f") - (mult (match_operand 1 "register_operand" "f") - (match_operand 2 "register_operand" "f")))] - "TARGET_PA_11 && ! TARGET_SOFT_FLOAT - && reload_completed && pa_fmpyaddoperands (operands)" - "* -{ - if (GET_MODE (operands[0]) == DFmode) - { - if (rtx_equal_p (operands[3], operands[5])) - return \"fmpyadd,dbl %1,%2,%0,%4,%3\"; - else - return \"fmpyadd,dbl %1,%2,%0,%5,%3\"; - } - else - { - if (rtx_equal_p (operands[3], operands[5])) - return \"fmpyadd,sgl %1,%2,%0,%4,%3\"; - else - return \"fmpyadd,sgl %1,%2,%0,%5,%3\"; - } -}" - [(set_attr "type" "fpalu") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand 0 "register_operand" "=f") - (mult (match_operand 1 "register_operand" "f") - (match_operand 2 "register_operand" "f"))) - (set (match_operand 3 "register_operand" "+f") - (minus (match_operand 4 "register_operand" "f") - (match_operand 5 "register_operand" "f")))] - "TARGET_PA_11 && ! TARGET_SOFT_FLOAT - && reload_completed && pa_fmpysuboperands (operands)" - "* -{ - if (GET_MODE (operands[0]) == DFmode) - return \"fmpysub,dbl %1,%2,%0,%5,%3\"; - else - return \"fmpysub,sgl %1,%2,%0,%5,%3\"; -}" - [(set_attr "type" "fpalu") - (set_attr "length" "4")]) - -(define_insn "" - [(set (match_operand 3 "register_operand" "+f") - (minus (match_operand 4 "register_operand" "f") - (match_operand 5 "register_operand" "f"))) - (set (match_operand 0 "register_operand" "=f") - (mult (match_operand 1 "register_operand" "f") - (match_operand 2 "register_operand" "f")))] - "TARGET_PA_11 && ! TARGET_SOFT_FLOAT - && reload_completed && pa_fmpysuboperands (operands)" - "* -{ - if (GET_MODE (operands[0]) == DFmode) - return \"fmpysub,dbl %1,%2,%0,%5,%3\"; - else - return \"fmpysub,sgl %1,%2,%0,%5,%3\"; -}" - [(set_attr "type" "fpalu") - (set_attr "length" "4")]) - -;; 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 -;; (operand0) to the end address (operand1). No lines are flushed if the -;; end address is less than the start address (unsigned). -;; -;; Because the range of memory flushed is variable and the size of a MEM -;; can only be a CONST_INT, the patterns specify that they perform an -;; unspecified volatile operation on all memory. -;; -;; The address range for an icache flush must lie within a single -;; space on targets with non-equivalent space registers. -;; -;; Operand 0 contains the start address. -;; Operand 1 contains the end address. -;; Operand 2 contains the line length to use. -(define_insn "dcacheflush<P:mode>" - [(const_int 1) - (unspec_volatile [(mem:BLK (scratch))] UNSPECV_DCACHE) - (use (match_operand 0 "pmode_register_operand" "r")) - (use (match_operand 1 "pmode_register_operand" "r")) - (use (match_operand 2 "pmode_register_operand" "r")) - (clobber (match_scratch:P 3 "=&0"))] - "" - "cmpb,<dwc><<=,n %3,%1,.\;fdc,m %2(%3)\;sync" - [(set_attr "type" "multi") - (set_attr "length" "12")]) - -(define_insn "icacheflush<P:mode>" - [(const_int 2) - (unspec_volatile [(mem:BLK (scratch))] UNSPECV_ICACHE) - (use (match_operand 0 "pmode_register_operand" "r")) - (use (match_operand 1 "pmode_register_operand" "r")) - (use (match_operand 2 "pmode_register_operand" "r")) - (clobber (match_operand 3 "pmode_register_operand" "=&r")) - (clobber (match_operand 4 "pmode_register_operand" "=&r")) - (clobber (match_scratch:P 5 "=&0"))] - "" - "mfsp %%sr0,%4\;ldsid (%5),%3\;mtsp %3,%%sr0\;cmpb,<dwc><<=,n %5,%1,.\;fic,m %2(%%sr0,%5)\;sync\;mtsp %4,%%sr0\;nop\;nop\;nop\;nop\;nop\;nop" - [(set_attr "type" "multi") - (set_attr "length" "52")]) - -;; An out-of-line prologue. -(define_insn "outline_prologue_call" - [(unspec_volatile [(const_int 0)] UNSPECV_OPC) - (clobber (reg:SI 31)) - (clobber (reg:SI 22)) - (clobber (reg:SI 21)) - (clobber (reg:SI 20)) - (clobber (reg:SI 19)) - (clobber (reg:SI 1))] - "" - "* -{ - - /* We need two different versions depending on whether or not we - need a frame pointer. Also note that we return to the instruction - immediately after the branch rather than two instructions after the - break as normally is the case. */ - if (frame_pointer_needed) - { - /* Must import the magic millicode routine(s). */ - output_asm_insn (\".IMPORT __outline_prologue_fp,MILLICODE\", NULL); - - if (TARGET_PORTABLE_RUNTIME) - { - output_asm_insn (\"ldil L'__outline_prologue_fp,%%r31\", NULL); - output_asm_insn (\"ble,n R'__outline_prologue_fp(%%sr0,%%r31)\", - NULL); - } - else - output_asm_insn (\"{bl|b,l},n __outline_prologue_fp,%%r31\", NULL); - } - else - { - /* Must import the magic millicode routine(s). */ - output_asm_insn (\".IMPORT __outline_prologue,MILLICODE\", NULL); - - if (TARGET_PORTABLE_RUNTIME) - { - output_asm_insn (\"ldil L'__outline_prologue,%%r31\", NULL); - output_asm_insn (\"ble,n R'__outline_prologue(%%sr0,%%r31)\", NULL); - } - else - output_asm_insn (\"{bl|b,l},n __outline_prologue,%%r31\", NULL); - } - return \"\"; -}" - [(set_attr "type" "multi") - (set_attr "length" "8")]) - -;; An out-of-line epilogue. -(define_insn "outline_epilogue_call" - [(unspec_volatile [(const_int 1)] UNSPECV_OEC) - (use (reg:SI 29)) - (use (reg:SI 28)) - (clobber (reg:SI 31)) - (clobber (reg:SI 22)) - (clobber (reg:SI 21)) - (clobber (reg:SI 20)) - (clobber (reg:SI 19)) - (clobber (reg:SI 2)) - (clobber (reg:SI 1))] - "" - "* -{ - - /* We need two different versions depending on whether or not we - need a frame pointer. Also note that we return to the instruction - immediately after the branch rather than two instructions after the - break as normally is the case. */ - if (frame_pointer_needed) - { - /* Must import the magic millicode routine. */ - output_asm_insn (\".IMPORT __outline_epilogue_fp,MILLICODE\", NULL); - - /* The out-of-line prologue will make sure we return to the right - instruction. */ - if (TARGET_PORTABLE_RUNTIME) - { - output_asm_insn (\"ldil L'__outline_epilogue_fp,%%r31\", NULL); - output_asm_insn (\"ble,n R'__outline_epilogue_fp(%%sr0,%%r31)\", - NULL); - } - else - output_asm_insn (\"{bl|b,l},n __outline_epilogue_fp,%%r31\", NULL); - } - else - { - /* Must import the magic millicode routine. */ - output_asm_insn (\".IMPORT __outline_epilogue,MILLICODE\", NULL); - - /* The out-of-line prologue will make sure we return to the right - instruction. */ - if (TARGET_PORTABLE_RUNTIME) - { - output_asm_insn (\"ldil L'__outline_epilogue,%%r31\", NULL); - output_asm_insn (\"ble,n R'__outline_epilogue(%%sr0,%%r31)\", NULL); - } - else - output_asm_insn (\"{bl|b,l},n __outline_epilogue,%%r31\", NULL); - } - return \"\"; -}" - [(set_attr "type" "multi") - (set_attr "length" "8")]) - -;; Given a function pointer, canonicalize it so it can be -;; reliably compared to another function pointer. */ -(define_expand "canonicalize_funcptr_for_compare" - [(set (reg:SI 26) (match_operand:SI 1 "register_operand" "")) - (parallel [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] UNSPEC_CFFC)) - (clobber (match_dup 2)) - (clobber (reg:SI 26)) - (clobber (reg:SI 22)) - (clobber (reg:SI 31))]) - (set (match_operand:SI 0 "register_operand" "") - (reg:SI 29))] - "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT" - " -{ - if (TARGET_ELF32) - { - rtx canonicalize_funcptr_for_compare_libfunc - = init_one_libfunc (CANONICALIZE_FUNCPTR_FOR_COMPARE_LIBCALL); - - emit_library_call_value (canonicalize_funcptr_for_compare_libfunc, - operands[0], LCT_NORMAL, Pmode, - 1, operands[1], Pmode); - DONE; - } - - operands[2] = gen_reg_rtx (SImode); - if (GET_CODE (operands[1]) != REG) - { - rtx tmp = gen_reg_rtx (Pmode); - emit_move_insn (tmp, operands[1]); - operands[1] = tmp; - } -}") - -(define_insn "*$$sh_func_adrs" - [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] UNSPEC_CFFC)) - (clobber (match_operand:SI 0 "register_operand" "=a")) - (clobber (reg:SI 26)) - (clobber (reg:SI 22)) - (clobber (reg:SI 31))] - "!TARGET_64BIT" - "* -{ - int length = get_attr_length (insn); - rtx xoperands[2]; - - xoperands[0] = GEN_INT (length - 8); - xoperands[1] = GEN_INT (length - 16); - - /* Must import the magic millicode routine. */ - output_asm_insn (\".IMPORT $$sh_func_adrs,MILLICODE\", NULL); - - /* This is absolutely amazing. - - First, copy our input parameter into %r29 just in case we don't - need to call $$sh_func_adrs. */ - output_asm_insn (\"copy %%r26,%%r29\", 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 - we use %r26 unchanged. */ - output_asm_insn (\"{comib|cmpib},<>,n 2,%%r31,.+%0\", xoperands); - output_asm_insn (\"ldi 4096,%%r31\", NULL); - - /* Next, compare %r26 with 4096, if %r26 is less than or equal to - 4096, then again we use %r26 unchanged. */ - output_asm_insn (\"{comb|cmpb},<<,n %%r26,%%r31,.+%1\", xoperands); - - /* Finally, call $$sh_func_adrs to extract the function's real add24. */ - return pa_output_millicode_call (insn, - gen_rtx_SYMBOL_REF (SImode, - \"$$sh_func_adrs\")); -}" - [(set_attr "type" "sh_func_adrs") - (set (attr "length") - (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 28)] - (plus (symbol_ref "pa_attr_length_millicode_call (insn)") - (const_int 20))))]) - -;; On the PA, the PIC register is call clobbered, so it must -;; be saved & restored around calls by the caller. If the call -;; doesn't return normally (nonlocal goto, or an exception is -;; thrown), then the code at the exception handler label must -;; restore the PIC register. -(define_expand "exception_receiver" - [(const_int 4)] - "flag_pic" - " -{ - /* On the 64-bit port, we need a blockage because there is - confusion regarding the dependence of the restore on the - frame pointer. As a result, the frame pointer and pic - register restores sometimes are interchanged erroneously. */ - if (TARGET_64BIT) - emit_insn (gen_blockage ()); - /* Restore the PIC register using hppa_pic_save_rtx (). The - PIC register is not saved in the frame in 64-bit ABI. */ - emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ()); - emit_insn (gen_blockage ()); - DONE; -}") - -(define_expand "builtin_setjmp_receiver" - [(label_ref (match_operand 0 "" ""))] - "flag_pic" - " -{ - if (TARGET_64BIT) - emit_insn (gen_blockage ()); - /* Restore the PIC register. Hopefully, this will always be from - a stack slot. The only registers that are valid after a - builtin_longjmp are the stack and frame pointers. */ - emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ()); - emit_insn (gen_blockage ()); - DONE; -}") - -;; 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 64-bit compiler copies words at -48, -32 and -24. -;; The 32-bit compiler copies the word at -16 (Static Link). We -;; currently don't copy these values. -;; -;; Since the copy of the frame marker can't be done atomically, I -;; suspect that using it for unwind purposes may be somewhat unreliable. -;; The HP compilers appear to raise the stack and copy the frame -;; marker in a strict instruction sequence. This suggests that the -;; unwind library may check for an alloca sequence when 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 -;; here in strict sequence. -(define_expand "allocate_stack" - [(match_operand 0 "" "") - (match_operand 1 "" "")] - "" - " -{ - rtx addr; - - /* Since the stack grows upward, we need to store virtual_stack_dynamic_rtx - in operand 0 before adjusting the stack. */ - emit_move_insn (operands[0], virtual_stack_dynamic_rtx); - anti_adjust_stack (operands[1]); - if (TARGET_HPUX_UNWIND_LIBRARY) - { - addr = gen_rtx_PLUS (word_mode, stack_pointer_rtx, - GEN_INT (TARGET_64BIT ? -8 : -4)); - emit_move_insn (gen_rtx_MEM (word_mode, addr), hard_frame_pointer_rtx); - } - if (!TARGET_64BIT && flag_pic) - { - 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); - } - DONE; -}") - -(define_expand "prefetch" - [(match_operand 0 "address_operand" "") - (match_operand 1 "const_int_operand" "") - (match_operand 2 "const_int_operand" "")] - "TARGET_PA_20" -{ - operands[0] = copy_addr_to_reg (operands[0]); - emit_insn (gen_prefetch_20 (operands[0], operands[1], operands[2])); - DONE; -}) - -(define_insn "prefetch_20" - [(prefetch (match_operand 0 "pmode_register_operand" "r") - (match_operand:SI 1 "const_int_operand" "n") - (match_operand:SI 2 "const_int_operand" "n"))] - "TARGET_PA_20" -{ - /* The SL cache-control completer indicates good spatial locality but - poor temporal locality. The ldw instruction with a target of general - register 0 prefetches a cache line for a read. The ldd instruction - prefetches a cache line for a write. */ - static const char * const instr[2][2] = { - { - "ldw,sl 0(%0),%%r0", - "ldd,sl 0(%0),%%r0" - }, - { - "ldw 0(%0),%%r0", - "ldd 0(%0),%%r0" - } - }; - int read_or_write = INTVAL (operands[1]) == 0 ? 0 : 1; - int locality = INTVAL (operands[2]) == 0 ? 0 : 1; - - return instr [locality][read_or_write]; -} - [(set_attr "type" "load") - (set_attr "length" "4")]) - -;; TLS Support -(define_insn "tgd_load" - [(set (match_operand:SI 0 "register_operand" "=r") - (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD)) - (clobber (reg:SI 1)) - (use (reg:SI 27))] - "" - "* -{ - return \"addil LR'%1-$tls_gdidx$,%%r27\;ldo RR'%1-$tls_gdidx$(%%r1),%0\"; -}" - [(set_attr "type" "multi") - (set_attr "length" "8")]) - -(define_insn "tgd_load_pic" - [(set (match_operand:SI 0 "register_operand" "=r") - (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD_PIC)) - (clobber (reg:SI 1)) - (use (reg:SI 19))] - "" - "* -{ - return \"addil LT'%1-$tls_gdidx$,%%r19\;ldo RT'%1-$tls_gdidx$(%%r1),%0\"; -}" - [(set_attr "type" "multi") - (set_attr "length" "8")]) - -(define_insn "tld_load" - [(set (match_operand:SI 0 "register_operand" "=r") - (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM)) - (clobber (reg:SI 1)) - (use (reg:SI 27))] - "" - "* -{ - return \"addil LR'%1-$tls_ldidx$,%%r27\;ldo RR'%1-$tls_ldidx$(%%r1),%0\"; -}" - [(set_attr "type" "multi") - (set_attr "length" "8")]) - -(define_insn "tld_load_pic" - [(set (match_operand:SI 0 "register_operand" "=r") - (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM_PIC)) - (clobber (reg:SI 1)) - (use (reg:SI 19))] - "" - "* -{ - return \"addil LT'%1-$tls_ldidx$,%%r19\;ldo RT'%1-$tls_ldidx$(%%r1),%0\"; -}" - [(set_attr "type" "multi") - (set_attr "length" "8")]) - -(define_insn "tld_offset_load" - [(set (match_operand:SI 0 "register_operand" "=r") - (plus:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] - UNSPEC_TLSLDO) - (match_operand:SI 2 "register_operand" "r"))) - (clobber (reg:SI 1))] - "" - "* -{ - return \"addil LR'%1-$tls_dtpoff$,%2\;ldo RR'%1-$tls_dtpoff$(%%r1),%0\"; -}" - [(set_attr "type" "multi") - (set_attr "length" "8")]) - -(define_insn "tp_load" - [(set (match_operand:SI 0 "register_operand" "=r") - (unspec:SI [(const_int 0)] UNSPEC_TP))] - "" - "mfctl %%cr27,%0" - [(set_attr "type" "multi") - (set_attr "length" "4")]) - -(define_insn "tie_load" - [(set (match_operand:SI 0 "register_operand" "=r") - (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE)) - (clobber (reg:SI 1)) - (use (reg:SI 27))] - "" - "* -{ - return \"addil LR'%1-$tls_ieoff$,%%r27\;ldw RR'%1-$tls_ieoff$(%%r1),%0\"; -}" - [(set_attr "type" "multi") - (set_attr "length" "8")]) - -(define_insn "tie_load_pic" - [(set (match_operand:SI 0 "register_operand" "=r") - (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE_PIC)) - (clobber (reg:SI 1)) - (use (reg:SI 19))] - "" - "* -{ - return \"addil LT'%1-$tls_ieoff$,%%r19\;ldw RT'%1-$tls_ieoff$(%%r1),%0\"; -}" - [(set_attr "type" "multi") - (set_attr "length" "8")]) - -(define_insn "tle_load" - [(set (match_operand:SI 0 "register_operand" "=r") - (plus:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")] - UNSPEC_TLSLE) - (match_operand:SI 2 "register_operand" "r"))) - (clobber (reg:SI 1))] - "" - "addil LR'%1-$tls_leoff$,%2\;ldo RR'%1-$tls_leoff$(%%r1),%0" - [(set_attr "type" "multi") - (set_attr "length" "8")]) |