X-Git-Url: https://oss.titaniummirror.com/gitweb?a=blobdiff_plain;f=gcc%2Fconfig%2Falpha%2Falpha.md;fp=gcc%2Fconfig%2Falpha%2Falpha.md;h=479084e77bccf2baa27be3fcf22981ef5d54db88;hb=6fed43773c9b0ce596dca5686f37ac3fc0fa11c0;hp=6dcf191411b49ae5bc55836da1aad2fb7ef34ed0;hpb=27b11d56b743098deb193d510b337ba22dc52e5c;p=msp430-gcc.git diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md index 6dcf1914..479084e7 100644 --- a/gcc/config/alpha/alpha.md +++ b/gcc/config/alpha/alpha.md @@ -1,24 +1,24 @@ ;; Machine description for DEC Alpha for GNU C compiler ;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -;; 2000, 2001, 2003 Free Software Foundation, Inc. +;; 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008 +;; Free Software Foundation, Inc. ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) ;; -;; This file is part of GNU CC. +;; This file is part of GCC. ;; -;; GNU CC is free software; you can redistribute it and/or modify +;; GCC is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) +;; the Free Software Foundation; either version 3, or (at your option) ;; any later version. ;; -;; GNU CC is distributed in the hope that it will be useful, +;; GCC is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; 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 GNU CC; see the file COPYING. If not, write to -;; the Free Software Foundation, 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;; along with GCC; see the file COPYING3. If not see +;; . ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. @@ -26,11 +26,11 @@ (define_constants [(UNSPEC_ARG_HOME 0) - (UNSPEC_CTTZ 1) + (UNSPEC_LDGP1 1) (UNSPEC_INSXH 2) (UNSPEC_MSKXH 3) (UNSPEC_CVTQL 4) - (UNSPEC_NT_LDA 5) + (UNSPEC_CVTLQ 5) (UNSPEC_UMK_LAUM 6) (UNSPEC_UMK_LALM 7) (UNSPEC_UMK_LAL 8) @@ -40,6 +40,29 @@ (UNSPEC_LITUSE 12) (UNSPEC_SIBCALL 13) (UNSPEC_SYMBOL 14) + + ;; TLS Support + (UNSPEC_TLSGD_CALL 15) + (UNSPEC_TLSLDM_CALL 16) + (UNSPEC_TLSGD 17) + (UNSPEC_TLSLDM 18) + (UNSPEC_DTPREL 19) + (UNSPEC_TPREL 20) + (UNSPEC_TP 21) + + ;; Builtins + (UNSPEC_CMPBGE 22) + (UNSPEC_ZAP 23) + (UNSPEC_AMASK 24) + (UNSPEC_IMPLVER 25) + (UNSPEC_PERR 26) + (UNSPEC_COPYSIGN 27) + + ;; Atomic operations + (UNSPEC_MB 28) + (UNSPEC_ATOMIC 31) + (UNSPEC_CMPXCHG 32) + (UNSPEC_XCHG 33) ]) ;; UNSPEC_VOLATILE: @@ -57,8 +80,23 @@ (UNSPECV_FORCE_MOV 9) (UNSPECV_LDGP1 10) (UNSPECV_PLDGP2 11) ; prologue ldgp + (UNSPECV_SET_TP 12) + (UNSPECV_RPCC 13) + (UNSPECV_SETJMPR_ER 14) ; builtin_setjmp_receiver fragment + (UNSPECV_LL 15) ; load-locked + (UNSPECV_SC 16) ; store-conditional ]) +;; On non-BWX targets, CQImode must be handled the similarly to HImode +;; when generating reloads. +(define_mode_iterator RELOAD12 [QI HI CQI]) +(define_mode_attr reloadmode [(QI "qi") (HI "hi") (CQI "hi")]) + +;; Other mode iterators +(define_mode_iterator I12MODE [QI HI]) +(define_mode_iterator I48MODE [SI DI]) +(define_mode_attr modesuffix [(SI "l") (DI "q")]) + ;; Where necessary, the suffixes _le and _be are used to distinguish between ;; little-endian and big-endian patterns. ;; @@ -68,8 +106,8 @@ ;; Processor type -- this attribute must exactly match the processor_type ;; enumeration in alpha.h. -(define_attr "cpu" "ev4,ev5,ev6" - (const (symbol_ref "alpha_cpu"))) +(define_attr "tune" "ev4,ev5,ev6" + (const (symbol_ref "alpha_tune"))) ;; Define an insn type attribute. This is used in function unit delay ;; computations, among other purposes. For the most part, we use the names @@ -77,8 +115,9 @@ ;; separately. (define_attr "type" - "ild,fld,ldsym,ist,fst,ibr,fbr,jsr,iadd,ilog,shift,icmov,fcmov,icmp,imul,\ -fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" + "ild,fld,ldsym,ist,fst,ibr,callpal,fbr,jsr,iadd,ilog,shift,icmov,fcmov, + icmp,imul,fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,mb,ld_l,st_c, + multi,none" (const_string "iadd")) ;; Describe a user's asm statement. @@ -100,7 +139,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" ;; The ROUND_SUFFIX attribute marks which instructions require a ;; rounding-mode suffix. The value NONE indicates no suffix, -;; the value NORMAL indicates a suffix controled by alpha_fprm. +;; the value NORMAL indicates a suffix controlled by alpha_fprm. (define_attr "round_suffix" "none,normal,c" (const_string "none")) @@ -113,7 +152,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" ;; V_SV_SVI accepts /v, /sv and /svi (cvttq only) ;; U_SU_SUI accepts /u, /su and /sui (most fp instructions) ;; -;; The actual suffix emitted is controled by alpha_fptm. +;; The actual suffix emitted is controlled by alpha_fptm. (define_attr "trap_suffix" "none,su,sui,v_sv,v_sv_svi,u_su_sui" (const_string "none")) @@ -122,313 +161,38 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_attr "length" "" (const_int 4)) + +;; The USEGP attribute marks instructions that have relocations that use +;; the GP. + +(define_attr "usegp" "no,yes" + (cond [(eq_attr "type" "ldsym,jsr") + (const_string "yes") + (eq_attr "type" "ild,fld,ist,fst") + (symbol_ref "alpha_find_lo_sum_using_gp(insn)") + ] + (const_string "no"))) + +;; The CANNOT_COPY attribute marks instructions with relocations that +;; cannot easily be duplicated. This includes insns with gpdisp relocs +;; since they have to stay in 1-1 correspondence with one another. This +;; also includes jsr insns, since they must stay in correspondence with +;; the immediately following gpdisp instructions. + +(define_attr "cannot_copy" "false,true" + (const_string "false")) -;; On EV4 there are two classes of resources to consider: resources needed -;; to issue, and resources needed to execute. IBUS[01] are in the first -;; category. ABOX, BBOX, EBOX, FBOX, IMUL & FDIV make up the second. -;; (There are a few other register-like resources, but ...) - -; First, describe all of the issue constraints with single cycle delays. -; All insns need a bus, but all except loads require one or the other. -(define_function_unit "ev4_ibus0" 1 0 - (and (eq_attr "cpu" "ev4") - (eq_attr "type" "fst,fbr,iadd,imul,ilog,shift,icmov,icmp")) - 1 1) - -(define_function_unit "ev4_ibus1" 1 0 - (and (eq_attr "cpu" "ev4") - (eq_attr "type" "ist,ibr,jsr,fadd,fcmov,fcpys,fmul,fdiv,misc")) - 1 1) - -; Memory delivers its result in three cycles. Actually return one and -; take care of this in adjust_cost, since we want to handle user-defined -; memory latencies. -(define_function_unit "ev4_abox" 1 0 - (and (eq_attr "cpu" "ev4") - (eq_attr "type" "ild,fld,ldsym,ist,fst")) - 1 1) - -; Branches have no delay cost, but do tie up the unit for two cycles. -(define_function_unit "ev4_bbox" 1 1 - (and (eq_attr "cpu" "ev4") - (eq_attr "type" "ibr,fbr,jsr")) - 2 2) - -; Arithmetic insns are normally have their results available after -; two cycles. There are a number of exceptions. They are encoded in -; ADJUST_COST. Some of the other insns have similar exceptions. -(define_function_unit "ev4_ebox" 1 0 - (and (eq_attr "cpu" "ev4") - (eq_attr "type" "iadd,ilog,shift,icmov,icmp,misc")) - 2 1) - -(define_function_unit "imul" 1 0 - (and (eq_attr "cpu" "ev4") - (and (eq_attr "type" "imul") - (eq_attr "opsize" "si"))) - 21 19) - -(define_function_unit "imul" 1 0 - (and (eq_attr "cpu" "ev4") - (and (eq_attr "type" "imul") - (eq_attr "opsize" "!si"))) - 23 21) - -(define_function_unit "ev4_fbox" 1 0 - (and (eq_attr "cpu" "ev4") - (eq_attr "type" "fadd,fmul,fcpys,fcmov")) - 6 1) - -(define_function_unit "fdiv" 1 0 - (and (eq_attr "cpu" "ev4") - (and (eq_attr "type" "fdiv") - (eq_attr "opsize" "si"))) - 34 30) - -(define_function_unit "fdiv" 1 0 - (and (eq_attr "cpu" "ev4") - (and (eq_attr "type" "fdiv") - (eq_attr "opsize" "di"))) - 63 59) - -;; EV5 scheduling. EV5 can issue 4 insns per clock. -;; -;; EV5 has two asymetric integer units. Model this with E0 & E1 along -;; with the combined resource EBOX. - -(define_function_unit "ev5_ebox" 2 0 - (and (eq_attr "cpu" "ev5") - (eq_attr "type" "!fbr,fcmov,fadd,fmul,fcpys,fdiv")) - 1 1) - -; Memory takes at least 2 clocks. Return one from here and fix up with -; user-defined latencies in adjust_cost. -(define_function_unit "ev5_ebox" 2 0 - (and (eq_attr "cpu" "ev5") - (eq_attr "type" "ild,fld,ldsym")) - 1 1) - -; Loads can dual issue with one another, but loads and stores do not mix. -(define_function_unit "ev5_e0" 1 0 - (and (eq_attr "cpu" "ev5") - (eq_attr "type" "ild,fld,ldsym")) - 1 1 - [(eq_attr "type" "ist,fst")]) - -; Stores, shifts, multiplies can only issue to E0 -(define_function_unit "ev5_e0" 1 0 - (and (eq_attr "cpu" "ev5") - (eq_attr "type" "ist,fst,shift,imul")) - 1 1) - -; Motion video insns also issue only to E0, and take two ticks. -(define_function_unit "ev5_e0" 1 0 - (and (eq_attr "cpu" "ev5") - (eq_attr "type" "mvi")) - 2 1) - -; Conditional moves always take 2 ticks. -(define_function_unit "ev5_ebox" 2 0 - (and (eq_attr "cpu" "ev5") - (eq_attr "type" "icmov")) - 2 1) - -; Branches can only issue to E1 -(define_function_unit "ev5_e1" 1 0 - (and (eq_attr "cpu" "ev5") - (eq_attr "type" "ibr,jsr")) - 1 1) - -; Multiplies also use the integer multiplier. -; ??? How to: "No instruction can be issued to pipe E0 exactly two -; cycles before an integer multiplication completes." -(define_function_unit "imul" 1 0 - (and (eq_attr "cpu" "ev5") - (and (eq_attr "type" "imul") - (eq_attr "opsize" "si"))) - 8 4) - -(define_function_unit "imul" 1 0 - (and (eq_attr "cpu" "ev5") - (and (eq_attr "type" "imul") - (eq_attr "opsize" "di"))) - 12 8) - -(define_function_unit "imul" 1 0 - (and (eq_attr "cpu" "ev5") - (and (eq_attr "type" "imul") - (eq_attr "opsize" "udi"))) - 14 8) - -;; Similarly for the FPU we have two asymetric units. But fcpys can issue -;; on either so we have to play the game again. - -(define_function_unit "ev5_fbox" 2 0 - (and (eq_attr "cpu" "ev5") - (eq_attr "type" "fadd,fcmov,fmul,fcpys,fbr,fdiv")) - 4 1) - -(define_function_unit "ev5_fm" 1 0 - (and (eq_attr "cpu" "ev5") - (eq_attr "type" "fmul")) - 4 1) - -; Add and cmov as you would expect; fbr never produces a result; -; fdiv issues through fa to the divider, -(define_function_unit "ev5_fa" 1 0 - (and (eq_attr "cpu" "ev5") - (eq_attr "type" "fadd,fcmov,fbr,fdiv")) - 4 1) - -; ??? How to: "No instruction can be issued to pipe FA exactly five -; cycles before a floating point divide completes." -(define_function_unit "fdiv" 1 0 - (and (eq_attr "cpu" "ev5") - (and (eq_attr "type" "fdiv") - (eq_attr "opsize" "si"))) - 15 15) ; 15 to 31 data dependent - -(define_function_unit "fdiv" 1 0 - (and (eq_attr "cpu" "ev5") - (and (eq_attr "type" "fdiv") - (eq_attr "opsize" "di"))) - 22 22) ; 22 to 60 data dependent +;; Include scheduling descriptions. + +(include "ev4.md") +(include "ev5.md") +(include "ev6.md") + -;; EV6 scheduling. EV6 can issue 4 insns per clock. -;; -;; EV6 has two symmetric pairs ("clusters") of two asymetric integer units -;; ("upper" and "lower"), yielding pipe names U0, U1, L0, L1. - -;; Conditional moves decompose into two independent primitives, each -;; taking one cycle. Since ev6 is out-of-order, we can't see anything -;; but two cycles. -(define_function_unit "ev6_ebox" 4 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "icmov")) - 2 1) - -(define_function_unit "ev6_ebox" 4 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "!fbr,fcmov,fadd,fmul,fcpys,fdiv,fsqrt")) - 1 1) - -;; Integer loads take at least 3 clocks, and only issue to lower units. -;; Return one from here and fix up with user-defined latencies in adjust_cost. -(define_function_unit "ev6_l" 2 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "ild,ldsym,ist,fst")) - 1 1) - -;; FP loads take at least 4 clocks. Return two from here... -(define_function_unit "ev6_l" 2 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "fld")) - 2 1) - -;; Motion video insns also issue only to U0, and take three ticks. -(define_function_unit "ev6_u0" 1 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "mvi")) - 3 1) - -(define_function_unit "ev6_u" 2 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "mvi")) - 3 1) - -;; Shifts issue to either upper pipe. -(define_function_unit "ev6_u" 2 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "shift")) - 1 1) - -;; Multiplies issue only to U1, and all take 7 ticks. -;; Rather than create a new function unit just for U1, reuse IMUL -(define_function_unit "imul" 1 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "imul")) - 7 1) - -(define_function_unit "ev6_u" 2 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "imul")) - 7 1) - -;; Branches issue to either upper pipe -(define_function_unit "ev6_u" 2 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "ibr")) - 3 1) - -;; Calls only issue to L0. -(define_function_unit "ev6_l0" 1 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "jsr")) - 1 1) - -(define_function_unit "ev6_l" 2 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "jsr")) - 1 1) - -;; Ftoi/itof only issue to lower pipes -(define_function_unit "ev6_l" 2 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "ftoi")) - 3 1) - -(define_function_unit "ev6_l" 2 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "itof")) - 4 1) - -;; For the FPU we are very similar to EV5, except there's no insn that -;; can issue to fm & fa, so we get to leave that out. - -(define_function_unit "ev6_fm" 1 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "fmul")) - 4 1) - -(define_function_unit "ev6_fa" 1 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "fadd,fcpys,fbr,fdiv,fsqrt")) - 4 1) - -(define_function_unit "ev6_fa" 1 0 - (and (eq_attr "cpu" "ev6") - (eq_attr "type" "fcmov")) - 8 1) - -(define_function_unit "fdiv" 1 0 - (and (eq_attr "cpu" "ev6") - (and (eq_attr "type" "fdiv") - (eq_attr "opsize" "si"))) - 12 10) - -(define_function_unit "fdiv" 1 0 - (and (eq_attr "cpu" "ev6") - (and (eq_attr "type" "fdiv") - (eq_attr "opsize" "di"))) - 15 13) - -(define_function_unit "fsqrt" 1 0 - (and (eq_attr "cpu" "ev6") - (and (eq_attr "type" "fsqrt") - (eq_attr "opsize" "si"))) - 16 14) - -(define_function_unit "fsqrt" 1 0 - (and (eq_attr "cpu" "ev6") - (and (eq_attr "type" "fsqrt") - (eq_attr "opsize" "di"))) - 32 30) - -; ??? The FPU communicates with memory and the integer register file -; via two fp store units. We need a slot in the fst immediately, and -; a slot in LOW after the operand data is ready. At which point the -; data may be moved either to the store queue or the integer register -; file and the insn retired. +;; Operand and operator predicates and constraints + +(include "predicates.md") +(include "constraints.md") ;; First define the arithmetic insns. Note that the 32-bit forms also @@ -447,41 +211,36 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" "" "") -(define_insn "*extendsidi2_nofix" - [(set (match_operand:DI 0 "register_operand" "=r,r,*f,?*f") - (sign_extend:DI - (match_operand:SI 1 "nonimmediate_operand" "r,m,*f,m")))] - "! TARGET_FIX" - "@ - addl %1,$31,%0 - ldl %0,%1 - cvtlq %1,%0 - lds %0,%1\;cvtlq %0,%0" - [(set_attr "type" "iadd,ild,fadd,fld") - (set_attr "length" "*,*,*,8")]) +(define_insn "*cvtlq" + [(set (match_operand:DI 0 "register_operand" "=f") + (unspec:DI [(match_operand:SF 1 "reg_or_0_operand" "fG")] + UNSPEC_CVTLQ))] + "" + "cvtlq %1,%0" + [(set_attr "type" "fadd")]) -(define_insn "*extendsidi2_fix" - [(set (match_operand:DI 0 "register_operand" "=r,r,r,?*f,?*f") +(define_insn "*extendsidi2_1" + [(set (match_operand:DI 0 "register_operand" "=r,r,!*f") (sign_extend:DI - (match_operand:SI 1 "nonimmediate_operand" "r,m,*f,*f,m")))] - "TARGET_FIX" + (match_operand:SI 1 "nonimmediate_operand" "r,m,m")))] + "" "@ - addl %1,$31,%0 + addl $31,%1,%0 ldl %0,%1 - ftois %1,%0 - cvtlq %1,%0 lds %0,%1\;cvtlq %0,%0" - [(set_attr "type" "iadd,ild,ftoi,fadd,fld") - (set_attr "length" "*,*,*,*,8")]) + [(set_attr "type" "iadd,ild,fld") + (set_attr "length" "*,*,8")]) -;; Due to issues with CLASS_CANNOT_CHANGE_SIZE, we cannot use a subreg here. (define_split [(set (match_operand:DI 0 "hard_fp_register_operand" "") (sign_extend:DI (match_operand:SI 1 "memory_operand" "")))] "reload_completed" [(set (match_dup 2) (match_dup 1)) - (set (match_dup 0) (sign_extend:DI (match_dup 2)))] - "operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]));") + (set (match_dup 0) (unspec:DI [(match_dup 2)] UNSPEC_CVTLQ))] +{ + operands[1] = adjust_address (operands[1], SFmode, 0); + operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0])); +}) ;; Optimize sign-extension of SImode loads. This shows up in the wake of ;; reload when converting fp->int. @@ -497,38 +256,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (sign_extend:DI (match_dup 1)))] "") -(define_peephole2 - [(set (match_operand:SI 0 "hard_int_register_operand" "") - (match_operand:SI 1 "hard_fp_register_operand" "")) - (set (match_operand:DI 2 "hard_int_register_operand" "") - (sign_extend:DI (match_dup 0)))] - "TARGET_FIX - && (true_regnum (operands[0]) == true_regnum (operands[2]) - || peep2_reg_dead_p (2, operands[0]))" - [(set (match_dup 2) - (sign_extend:DI (match_dup 1)))] - "") - -(define_peephole2 - [(set (match_operand:DI 0 "hard_fp_register_operand" "") - (sign_extend:DI (match_operand:SI 1 "hard_fp_register_operand" ""))) - (set (match_operand:DI 2 "hard_int_register_operand" "") - (match_dup 0))] - "TARGET_FIX && peep2_reg_dead_p (2, operands[0])" - [(set (match_dup 2) - (sign_extend:DI (match_dup 1)))] - "") - -;; Don't say we have addsi3 if optimizing. This generates better code. We -;; have the anonymous addsi3 pattern below in case combine wants to make it. -(define_expand "addsi3" - [(set (match_operand:SI 0 "register_operand" "") - (plus:SI (match_operand:SI 1 "reg_or_0_operand" "") - (match_operand:SI 2 "add_operand" "")))] - "! optimize" - "") - -(define_insn "*addsi_internal" +(define_insn "addsi3" [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ") (match_operand:SI 2 "add_operand" "rI,O,K,L")))] @@ -637,12 +365,55 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" "" "") +(define_insn "*adddi_er_lo16_dtp" + [(set (match_operand:DI 0 "register_operand" "=r") + (lo_sum:DI (match_operand:DI 1 "register_operand" "r") + (match_operand:DI 2 "dtp16_symbolic_operand" "")))] + "HAVE_AS_TLS" + "lda %0,%2(%1)\t\t!dtprel") + +(define_insn "*adddi_er_hi32_dtp" + [(set (match_operand:DI 0 "register_operand" "=r") + (plus:DI (match_operand:DI 1 "register_operand" "r") + (high:DI (match_operand:DI 2 "dtp32_symbolic_operand" ""))))] + "HAVE_AS_TLS" + "ldah %0,%2(%1)\t\t!dtprelhi") + +(define_insn "*adddi_er_lo32_dtp" + [(set (match_operand:DI 0 "register_operand" "=r") + (lo_sum:DI (match_operand:DI 1 "register_operand" "r") + (match_operand:DI 2 "dtp32_symbolic_operand" "")))] + "HAVE_AS_TLS" + "lda %0,%2(%1)\t\t!dtprello") + +(define_insn "*adddi_er_lo16_tp" + [(set (match_operand:DI 0 "register_operand" "=r") + (lo_sum:DI (match_operand:DI 1 "register_operand" "r") + (match_operand:DI 2 "tp16_symbolic_operand" "")))] + "HAVE_AS_TLS" + "lda %0,%2(%1)\t\t!tprel") + +(define_insn "*adddi_er_hi32_tp" + [(set (match_operand:DI 0 "register_operand" "=r") + (plus:DI (match_operand:DI 1 "register_operand" "r") + (high:DI (match_operand:DI 2 "tp32_symbolic_operand" ""))))] + "HAVE_AS_TLS" + "ldah %0,%2(%1)\t\t!tprelhi") + +(define_insn "*adddi_er_lo32_tp" + [(set (match_operand:DI 0 "register_operand" "=r") + (lo_sum:DI (match_operand:DI 1 "register_operand" "r") + (match_operand:DI 2 "tp32_symbolic_operand" "")))] + "HAVE_AS_TLS" + "lda %0,%2(%1)\t\t!tprello") + (define_insn "*adddi_er_high_l" [(set (match_operand:DI 0 "register_operand" "=r") (plus:DI (match_operand:DI 1 "register_operand" "r") (high:DI (match_operand:DI 2 "local_symbolic_operand" ""))))] - "TARGET_EXPLICIT_RELOCS" - "ldah %0,%2(%1)\t\t!gprelhigh") + "TARGET_EXPLICIT_RELOCS && reload_completed" + "ldah %0,%2(%1)\t\t!gprelhigh" + [(set_attr "usegp" "yes")]) (define_split [(set (match_operand:DI 0 "register_operand" "") @@ -684,9 +455,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" ;; and if we split before reload, we will require additional instructions. (define_insn "*adddi_fp_hack" - [(set (match_operand:DI 0 "register_operand" "=r") - (plus:DI (match_operand:DI 1 "reg_no_subreg_operand" "r") - (match_operand:DI 2 "const_int_operand" "n")))] + [(set (match_operand:DI 0 "register_operand" "=r,r,r") + (plus:DI (match_operand:DI 1 "reg_no_subreg_operand" "r,r,r") + (match_operand:DI 2 "const_int_operand" "K,L,n")))] "NONSTRICT_REG_OK_FP_BASE_P (operands[1]) && INTVAL (operands[2]) >= 0 /* This is the largest constant an lda+ldah pair can add, minus @@ -695,12 +466,15 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" && INTVAL (operands[2]) < (0x7fff8000 - FIRST_PSEUDO_REGISTER * UNITS_PER_WORD - - ALPHA_ROUND(current_function_outgoing_args_size) + - ALPHA_ROUND(crtl->outgoing_args_size) - (ALPHA_ROUND (get_frame_size () + max_reg_num () * UNITS_PER_WORD - + current_function_pretend_args_size) - - current_function_pretend_args_size))" - "#") + + crtl->args.pretend_args_size) + - crtl->args.pretend_args_size))" + "@ + lda %0,%2(%1) + ldah %0,%h2(%1) + #") ;; Don't do this if we are adjusting SP since we don't want to do it ;; in two steps. Don't split FP sources for the reason listed above. @@ -718,11 +492,12 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" HOST_WIDE_INT val = INTVAL (operands[2]); HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000); HOST_WIDE_INT rest = val - low; + rtx rest_rtx = GEN_INT (rest); operands[4] = GEN_INT (low); - if (CONST_OK_FOR_LETTER_P (rest, 'L')) - operands[3] = GEN_INT (rest); - else if (! no_new_pseudos) + if (satisfies_constraint_L (rest_rtx)) + operands[3] = rest_rtx; + else if (can_create_pseudo_p ()) { operands[3] = gen_reg_rtx (DImode); emit_move_insn (operands[3], operands[2]); @@ -835,14 +610,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" "" "subqv $31,%1,%0") -(define_expand "subsi3" - [(set (match_operand:SI 0 "register_operand" "") - (minus:SI (match_operand:SI 1 "reg_or_0_operand" "") - (match_operand:SI 2 "reg_or_8bit_operand" "")))] - "! optimize" - "") - -(define_insn "*subsi_internal" +(define_insn "subsi3" [(set (match_operand:SI 0 "register_operand" "=r") (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") (match_operand:SI 2 "reg_or_8bit_operand" "rI")))] @@ -977,17 +745,31 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" "mulqv %r1,%2,%0" [(set_attr "type" "imul")]) -(define_insn "umuldi3_highpart" +(define_expand "umuldi3_highpart" + [(set (match_operand:DI 0 "register_operand" "") + (truncate:DI + (lshiftrt:TI + (mult:TI (zero_extend:TI + (match_operand:DI 1 "register_operand" "")) + (match_operand:DI 2 "reg_or_8bit_operand" "")) + (const_int 64))))] + "" +{ + if (REG_P (operands[2])) + operands[2] = gen_rtx_ZERO_EXTEND (TImode, operands[2]); +}) + +(define_insn "*umuldi3_highpart_reg" [(set (match_operand:DI 0 "register_operand" "=r") (truncate:DI (lshiftrt:TI (mult:TI (zero_extend:TI - (match_operand:DI 1 "reg_or_0_operand" "%rJ")) + (match_operand:DI 1 "register_operand" "r")) (zero_extend:TI - (match_operand:DI 2 "reg_or_8bit_operand" "rI"))) + (match_operand:DI 2 "register_operand" "r"))) (const_int 64))))] "" - "umulh %r1,%2,%0" + "umulh %1,%2,%0" [(set_attr "type" "imul") (set_attr "opsize" "udi")]) @@ -1195,7 +977,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (clobber (reg:DI 23)) (clobber (reg:DI 28))] "TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS" - "ldq $27,__%E3($29)\t\t!literal!%#\;jsr $23,($27),__%E3\t\t!lituse_jsr!%#" + "#" "&& reload_completed" [(parallel [(set (match_dup 0) (sign_extend:DI (match_dup 3))) @@ -1220,7 +1002,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" str = "__remlu"; break; default: - abort (); + gcc_unreachable (); } operands[4] = GEN_INT (alpha_next_sequence_number++); emit_insn (gen_movdi_er_high_g (operands[0], pic_offset_table_rtx, @@ -1240,7 +1022,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (clobber (reg:DI 23)) (clobber (reg:DI 28))] "TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS" - "jsr $23,($27),__%E3%J5" + "jsr $23,($27),__%E3%j5" [(set_attr "type" "jsr") (set_attr "length" "4")]) @@ -1264,7 +1046,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (clobber (reg:DI 23)) (clobber (reg:DI 28))] "TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS" - "ldq $27,__%E3($29)\t\t!literal!%#\;jsr $23,($27),__%E3\t\t!lituse_jsr!%#" + "#" "&& reload_completed" [(parallel [(set (match_dup 0) (match_dup 3)) (use (match_dup 0)) @@ -1288,7 +1070,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" str = "__remqu"; break; default: - abort (); + gcc_unreachable (); } operands[4] = GEN_INT (alpha_next_sequence_number++); emit_insn (gen_movdi_er_high_g (operands[0], pic_offset_table_rtx, @@ -1308,7 +1090,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (clobber (reg:DI 23)) (clobber (reg:DI 28))] "TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS" - "jsr $23,($27),__%E3%J5" + "jsr $23,($27),__%E3%j5" [(set_attr "type" "jsr") (set_attr "length" "4")]) @@ -1324,7 +1106,20 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" [(set_attr "type" "jsr") (set_attr "length" "8")]) -;; Next are the basic logical operations. These only exist in DImode. +;; Next are the basic logical operations. We only expose the DImode operations +;; to the rtl expanders, but SImode versions exist for combine as well as for +;; the atomic operation splitters. + +(define_insn "*andsi_internal" + [(set (match_operand:SI 0 "register_operand" "=r,r,r") + (and:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ") + (match_operand:SI 2 "and_operand" "rI,N,MH")))] + "" + "@ + and %r1,%2,%0 + bic %r1,%N2,%0 + zapnot %r1,%m2,%0" + [(set_attr "type" "ilog,ilog,shift")]) (define_insn "anddi3" [(set (match_operand:DI 0 "register_operand" "=r,r,r") @@ -1499,6 +1294,14 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" "zapnot %1,15,%0" [(set_attr "type" "shift")]) +(define_insn "*andnotsi3" + [(set (match_operand:SI 0 "register_operand" "=r") + (and:SI (not:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")) + (match_operand:SI 2 "reg_or_0_operand" "rJ")))] + "" + "bic %r2,%1,%0" + [(set_attr "type" "ilog")]) + (define_insn "andnotdi3" [(set (match_operand:DI 0 "register_operand" "=r") (and:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")) @@ -1507,6 +1310,16 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" "bic %r2,%1,%0" [(set_attr "type" "ilog")]) +(define_insn "*iorsi_internal" + [(set (match_operand:SI 0 "register_operand" "=r,r") + (ior:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ") + (match_operand:SI 2 "or_operand" "rI,N")))] + "" + "@ + bis %r1,%2,%0 + ornot %r1,%N2,%0" + [(set_attr "type" "ilog")]) + (define_insn "iordi3" [(set (match_operand:DI 0 "register_operand" "=r,r") (ior:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ") @@ -1517,6 +1330,13 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" ornot %r1,%N2,%0" [(set_attr "type" "ilog")]) +(define_insn "*one_cmplsi_internal" + [(set (match_operand:SI 0 "register_operand" "=r") + (not:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")))] + "" + "ornot $31,%1,%0" + [(set_attr "type" "ilog")]) + (define_insn "one_cmpldi2" [(set (match_operand:DI 0 "register_operand" "=r") (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))] @@ -1524,7 +1344,15 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" "ornot $31,%1,%0" [(set_attr "type" "ilog")]) -(define_insn "*iornot" +(define_insn "*iornotsi3" + [(set (match_operand:SI 0 "register_operand" "=r") + (ior:SI (not:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")) + (match_operand:SI 2 "reg_or_0_operand" "rJ")))] + "" + "ornot %r2,%1,%0" + [(set_attr "type" "ilog")]) + +(define_insn "*iornotdi3" [(set (match_operand:DI 0 "register_operand" "=r") (ior:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")) (match_operand:DI 2 "reg_or_0_operand" "rJ")))] @@ -1532,6 +1360,16 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" "ornot %r2,%1,%0" [(set_attr "type" "ilog")]) +(define_insn "*xorsi_internal" + [(set (match_operand:SI 0 "register_operand" "=r,r") + (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ") + (match_operand:SI 2 "or_operand" "rI,N")))] + "" + "@ + xor %r1,%2,%0 + eqv %r1,%N2,%0" + [(set_attr "type" "ilog")]) + (define_insn "xordi3" [(set (match_operand:DI 0 "register_operand" "=r,r") (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ") @@ -1542,7 +1380,15 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" eqv %r1,%N2,%0" [(set_attr "type" "ilog")]) -(define_insn "*xornot" +(define_insn "*xornotsi3" + [(set (match_operand:SI 0 "register_operand" "=r") + (not:SI (xor:SI (match_operand:SI 1 "register_operand" "%rJ") + (match_operand:SI 2 "register_operand" "rI"))))] + "" + "eqv %r1,%2,%0" + [(set_attr "type" "ilog")]) + +(define_insn "*xornotdi3" [(set (match_operand:DI 0 "register_operand" "=r") (not:DI (xor:DI (match_operand:DI 1 "register_operand" "%rJ") (match_operand:DI 2 "register_operand" "rI"))))] @@ -1550,11 +1396,11 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" "eqv %r1,%2,%0" [(set_attr "type" "ilog")]) -;; Handle the FFS insn iff we support CIX. +;; Handle FFS and related insns iff we support CIX. (define_expand "ffsdi2" [(set (match_dup 2) - (unspec:DI [(match_operand:DI 1 "register_operand" "")] UNSPEC_CTTZ)) + (ctz:DI (match_operand:DI 1 "register_operand" ""))) (set (match_dup 3) (plus:DI (match_dup 2) (const_int 1))) (set (match_operand:DI 0 "register_operand" "") @@ -1566,14 +1412,80 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" operands[3] = gen_reg_rtx (DImode); }) -(define_insn "*cttz" +(define_insn "clzdi2" + [(set (match_operand:DI 0 "register_operand" "=r") + (clz:DI (match_operand:DI 1 "register_operand" "r")))] + "TARGET_CIX" + "ctlz %1,%0" + [(set_attr "type" "mvi")]) + +(define_insn "ctzdi2" [(set (match_operand:DI 0 "register_operand" "=r") - (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_CTTZ))] + (ctz:DI (match_operand:DI 1 "register_operand" "r")))] "TARGET_CIX" "cttz %1,%0" - ; EV6 calls all mvi and cttz/ctlz/popc class imisc, so just - ; reuse the existing type name. [(set_attr "type" "mvi")]) + +(define_insn "popcountdi2" + [(set (match_operand:DI 0 "register_operand" "=r") + (popcount:DI (match_operand:DI 1 "register_operand" "r")))] + "TARGET_CIX" + "ctpop %1,%0" + [(set_attr "type" "mvi")]) + +(define_expand "bswapsi2" + [(set (match_operand:SI 0 "register_operand" "") + (bswap:SI (match_operand:SI 1 "register_operand" "")))] + "!optimize_size" +{ + rtx t0, t1; + + t0 = gen_reg_rtx (DImode); + t1 = gen_reg_rtx (DImode); + + emit_insn (gen_insxh (t0, gen_lowpart (DImode, operands[1]), + GEN_INT (32), GEN_INT (WORDS_BIG_ENDIAN ? 0 : 7))); + emit_insn (gen_inswl_const (t1, gen_lowpart (HImode, operands[1]), + GEN_INT (24))); + emit_insn (gen_iordi3 (t1, t0, t1)); + emit_insn (gen_lshrdi3 (t0, t1, GEN_INT (16))); + emit_insn (gen_anddi3 (t1, t1, alpha_expand_zap_mask (0x5))); + emit_insn (gen_anddi3 (t0, t0, alpha_expand_zap_mask (0xa))); + emit_insn (gen_addsi3 (operands[0], gen_lowpart (SImode, t0), + gen_lowpart (SImode, t1))); + DONE; +}) + +(define_expand "bswapdi2" + [(set (match_operand:DI 0 "register_operand" "") + (bswap:DI (match_operand:DI 1 "register_operand" "")))] + "!optimize_size" +{ + rtx t0, t1; + + t0 = gen_reg_rtx (DImode); + t1 = gen_reg_rtx (DImode); + + /* This method of shifting and masking is not specific to Alpha, but + is only profitable on Alpha because of our handy byte zap insn. */ + + emit_insn (gen_lshrdi3 (t0, operands[1], GEN_INT (32))); + emit_insn (gen_ashldi3 (t1, operands[1], GEN_INT (32))); + emit_insn (gen_iordi3 (t1, t0, t1)); + + emit_insn (gen_lshrdi3 (t0, t1, GEN_INT (16))); + emit_insn (gen_ashldi3 (t1, t1, GEN_INT (16))); + emit_insn (gen_anddi3 (t0, t0, alpha_expand_zap_mask (0xcc))); + emit_insn (gen_anddi3 (t1, t1, alpha_expand_zap_mask (0x33))); + emit_insn (gen_iordi3 (t1, t0, t1)); + + emit_insn (gen_lshrdi3 (t0, t1, GEN_INT (8))); + emit_insn (gen_ashldi3 (t1, t1, GEN_INT (8))); + emit_insn (gen_anddi3 (t0, t0, alpha_expand_zap_mask (0xaa))); + emit_insn (gen_anddi3 (t1, t1, alpha_expand_zap_mask (0x55))); + emit_insn (gen_iordi3 (operands[0], t0, t1)); + DONE; +}) ;; Next come the shifts and the various extract and insert operations. @@ -1593,7 +1505,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" case 1: return "sll %r1,%2,%0"; default: - abort(); + gcc_unreachable (); } } [(set_attr "type" "iadd,shift")]) @@ -1746,10 +1658,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" if (unaligned_memory_operand (operands[1], QImode)) { - rtx seq - = gen_unaligned_extendqidi (operands[0], - get_unaligned_address (operands[1], 1)); - + rtx seq = gen_unaligned_extendqidi (operands[0], XEXP (operands[1], 0)); alpha_set_memflags (seq, operands[1]); emit_insn (seq); DONE; @@ -1809,9 +1718,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" if (unaligned_memory_operand (operands[1], HImode)) { - rtx seq - = gen_unaligned_extendhidi (operands[0], - get_unaligned_address (operands[1], 2)); + rtx seq = gen_unaligned_extendhidi (operands[0], XEXP (operands[1], 0)); alpha_set_memflags (seq, operands[1]); emit_insn (seq); @@ -1826,12 +1733,13 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" ;; as a pattern saves one instruction. The code is similar to that for ;; the unaligned loads (see below). ;; -;; Operand 1 is the address + 1 (+2 for HI), operand 0 is the result. +;; Operand 1 is the address, operand 0 is the result. (define_expand "unaligned_extendqidi" [(use (match_operand:QI 0 "register_operand" "")) (use (match_operand:DI 1 "address_operand" ""))] "" { + operands[0] = gen_lowpart (DImode, operands[0]); if (WORDS_BIG_ENDIAN) emit_insn (gen_unaligned_extendqidi_be (operands[0], operands[1])); else @@ -1840,48 +1748,40 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" }) (define_expand "unaligned_extendqidi_le" - [(set (match_dup 2) (match_operand:DI 1 "address_operand" "")) - (set (match_dup 3) - (mem:DI (and:DI (plus:DI (match_dup 2) (const_int -1)) - (const_int -8)))) + [(set (match_dup 3) + (mem:DI (and:DI (match_operand:DI 1 "" "") (const_int -8)))) (set (match_dup 4) (ashift:DI (match_dup 3) (minus:DI (const_int 64) (ashift:DI (and:DI (match_dup 2) (const_int 7)) (const_int 3))))) - (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0) + (set (match_operand:DI 0 "register_operand" "") (ashiftrt:DI (match_dup 4) (const_int 56)))] "! WORDS_BIG_ENDIAN" { - operands[2] = gen_reg_rtx (DImode); + operands[2] = get_unaligned_offset (operands[1], 1); operands[3] = gen_reg_rtx (DImode); operands[4] = gen_reg_rtx (DImode); }) (define_expand "unaligned_extendqidi_be" - [(set (match_dup 2) (match_operand:DI 1 "address_operand" "")) - (set (match_dup 3) (plus:DI (match_dup 2) (const_int -1))) + [(set (match_dup 3) + (mem:DI (and:DI (match_operand:DI 1 "" "") (const_int -8)))) (set (match_dup 4) - (mem:DI (and:DI (match_dup 3) - (const_int -8)))) - (set (match_dup 5) (plus:DI (match_dup 2) (const_int -2))) - (set (match_dup 6) - (ashift:DI (match_dup 4) + (ashift:DI (match_dup 3) (ashift:DI (and:DI - (plus:DI (match_dup 5) (const_int 1)) + (plus:DI (match_dup 2) (const_int 1)) (const_int 7)) (const_int 3)))) - (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0) - (ashiftrt:DI (match_dup 6) (const_int 56)))] + (set (match_operand:DI 0 "register_operand" "") + (ashiftrt:DI (match_dup 4) (const_int 56)))] "WORDS_BIG_ENDIAN" { - operands[2] = gen_reg_rtx (DImode); + operands[2] = get_unaligned_offset (operands[1], -1); operands[3] = gen_reg_rtx (DImode); operands[4] = gen_reg_rtx (DImode); - operands[5] = gen_reg_rtx (DImode); - operands[6] = gen_reg_rtx (DImode); }) (define_expand "unaligned_extendhidi" @@ -1890,17 +1790,16 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" "" { operands[0] = gen_lowpart (DImode, operands[0]); - emit_insn ((WORDS_BIG_ENDIAN - ? gen_unaligned_extendhidi_be - : gen_unaligned_extendhidi_le) (operands[0], operands[1])); + if (WORDS_BIG_ENDIAN) + emit_insn (gen_unaligned_extendhidi_be (operands[0], operands[1])); + else + emit_insn (gen_unaligned_extendhidi_le (operands[0], operands[1])); DONE; }) (define_expand "unaligned_extendhidi_le" - [(set (match_dup 2) (match_operand:DI 1 "address_operand" "")) - (set (match_dup 3) - (mem:DI (and:DI (plus:DI (match_dup 2) (const_int -2)) - (const_int -8)))) + [(set (match_dup 3) + (mem:DI (and:DI (match_operand:DI 1 "" "") (const_int -8)))) (set (match_dup 4) (ashift:DI (match_dup 3) (minus:DI (const_int 64) @@ -1911,34 +1810,28 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (ashiftrt:DI (match_dup 4) (const_int 48)))] "! WORDS_BIG_ENDIAN" { - operands[2] = gen_reg_rtx (DImode); + operands[2] = get_unaligned_offset (operands[1], 2); operands[3] = gen_reg_rtx (DImode); operands[4] = gen_reg_rtx (DImode); }) (define_expand "unaligned_extendhidi_be" - [(set (match_dup 2) (match_operand:DI 1 "address_operand" "")) - (set (match_dup 3) (plus:DI (match_dup 2) (const_int -2))) + [(set (match_dup 3) + (mem:DI (and:DI (match_operand:DI 1 "" "") (const_int -8)))) (set (match_dup 4) - (mem:DI (and:DI (match_dup 3) - (const_int -8)))) - (set (match_dup 5) (plus:DI (match_dup 2) (const_int -3))) - (set (match_dup 6) - (ashift:DI (match_dup 4) + (ashift:DI (match_dup 3) (ashift:DI (and:DI - (plus:DI (match_dup 5) (const_int 1)) + (plus:DI (match_dup 2) (const_int 1)) (const_int 7)) (const_int 3)))) (set (match_operand:DI 0 "register_operand" "") - (ashiftrt:DI (match_dup 6) (const_int 48)))] + (ashiftrt:DI (match_dup 4) (const_int 48)))] "WORDS_BIG_ENDIAN" { - operands[2] = gen_reg_rtx (DImode); + operands[2] = get_unaligned_offset (operands[1], -1); operands[3] = gen_reg_rtx (DImode); operands[4] = gen_reg_rtx (DImode); - operands[5] = gen_reg_rtx (DImode); - operands[6] = gen_reg_rtx (DImode); }) (define_insn "*extxl_const" @@ -1973,7 +1866,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" "ext%M2l %r1,%3,%0" [(set_attr "type" "shift")]) -;; Combine has some strange notion of preserving existing undefined behaviour +;; Combine has some strange notion of preserving existing undefined behavior ;; in shifts larger than a word size. So capture these patterns that it ;; should have turned into zero_extracts. @@ -2145,7 +2038,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" "insbl %1,%s2,%0" [(set_attr "type" "shift")]) -(define_insn "*inswl_const" +(define_insn "inswl_const" [(set (match_operand:DI 0 "register_operand" "=r") (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r")) (match_operand:DI 2 "mul8_operand" "I")))] @@ -2265,7 +2158,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" == (unsigned HOST_WIDE_INT) INTVAL (operands[3])) return "insll %1,%s2,%0"; #endif - abort(); + gcc_unreachable (); } [(set_attr "type" "shift")]) @@ -2346,35 +2239,35 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "abssf2" [(set (match_operand:SF 0 "register_operand" "=f") - (abs:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))] + (abs:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))] "TARGET_FP" "cpys $f31,%R1,%0" [(set_attr "type" "fcpys")]) (define_insn "*nabssf2" [(set (match_operand:SF 0 "register_operand" "=f") - (neg:SF (abs:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))] + (neg:SF (abs:SF (match_operand:SF 1 "reg_or_0_operand" "fG"))))] "TARGET_FP" "cpysn $f31,%R1,%0" [(set_attr "type" "fadd")]) (define_insn "absdf2" [(set (match_operand:DF 0 "register_operand" "=f") - (abs:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))] + (abs:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))] "TARGET_FP" "cpys $f31,%R1,%0" [(set_attr "type" "fcpys")]) (define_insn "*nabsdf2" [(set (match_operand:DF 0 "register_operand" "=f") - (neg:DF (abs:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG"))))] + (neg:DF (abs:DF (match_operand:DF 1 "reg_or_0_operand" "fG"))))] "TARGET_FP" "cpysn $f31,%R1,%0" [(set_attr "type" "fadd")]) (define_expand "abstf2" [(parallel [(set (match_operand:TF 0 "register_operand" "") - (abs:TF (match_operand:TF 1 "reg_or_fp0_operand" ""))) + (abs:TF (match_operand:TF 1 "reg_or_0_operand" ""))) (use (match_dup 2))])] "TARGET_HAS_XFLOATING_LIBS" { @@ -2387,7 +2280,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn_and_split "*abstf_internal" [(set (match_operand:TF 0 "register_operand" "=r") - (abs:TF (match_operand:TF 1 "reg_or_fp0_operand" "rG"))) + (abs:TF (match_operand:TF 1 "reg_or_0_operand" "rG"))) (use (match_operand:DI 2 "register_operand" "r"))] "TARGET_HAS_XFLOATING_LIBS" "#" @@ -2397,21 +2290,21 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "negsf2" [(set (match_operand:SF 0 "register_operand" "=f") - (neg:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))] + (neg:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))] "TARGET_FP" "cpysn %R1,%R1,%0" [(set_attr "type" "fadd")]) (define_insn "negdf2" [(set (match_operand:DF 0 "register_operand" "=f") - (neg:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))] + (neg:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))] "TARGET_FP" "cpysn %R1,%R1,%0" [(set_attr "type" "fadd")]) (define_expand "negtf2" [(parallel [(set (match_operand:TF 0 "register_operand" "") - (neg:TF (match_operand:TF 1 "reg_or_fp0_operand" ""))) + (neg:TF (match_operand:TF 1 "reg_or_0_operand" ""))) (use (match_dup 2))])] "TARGET_HAS_XFLOATING_LIBS" { @@ -2424,7 +2317,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn_and_split "*negtf_internal" [(set (match_operand:TF 0 "register_operand" "=r") - (neg:TF (match_operand:TF 1 "reg_or_fp0_operand" "rG"))) + (neg:TF (match_operand:TF 1 "reg_or_0_operand" "rG"))) (use (match_operand:DI 2 "register_operand" "r"))] "TARGET_HAS_XFLOATING_LIBS" "#" @@ -2432,10 +2325,46 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" [(const_int 0)] "alpha_split_tfmode_frobsign (operands, gen_xordi3); DONE;") +(define_insn "copysignsf3" + [(set (match_operand:SF 0 "register_operand" "=f") + (unspec:SF [(match_operand:SF 1 "reg_or_0_operand" "fG") + (match_operand:SF 2 "reg_or_0_operand" "fG")] + UNSPEC_COPYSIGN))] + "TARGET_FP" + "cpys %R2,%R1,%0" + [(set_attr "type" "fadd")]) + +(define_insn "*ncopysignsf3" + [(set (match_operand:SF 0 "register_operand" "=f") + (neg:SF (unspec:SF [(match_operand:SF 1 "reg_or_0_operand" "fG") + (match_operand:SF 2 "reg_or_0_operand" "fG")] + UNSPEC_COPYSIGN)))] + "TARGET_FP" + "cpysn %R2,%R1,%0" + [(set_attr "type" "fadd")]) + +(define_insn "copysigndf3" + [(set (match_operand:DF 0 "register_operand" "=f") + (unspec:DF [(match_operand:DF 1 "reg_or_0_operand" "fG") + (match_operand:DF 2 "reg_or_0_operand" "fG")] + UNSPEC_COPYSIGN))] + "TARGET_FP" + "cpys %R2,%R1,%0" + [(set_attr "type" "fadd")]) + +(define_insn "*ncopysigndf3" + [(set (match_operand:DF 0 "register_operand" "=f") + (neg:DF (unspec:DF [(match_operand:DF 1 "reg_or_0_operand" "fG") + (match_operand:DF 2 "reg_or_0_operand" "fG")] + UNSPEC_COPYSIGN)))] + "TARGET_FP" + "cpysn %R2,%R1,%0" + [(set_attr "type" "fadd")]) + (define_insn "*addsf_ieee" [(set (match_operand:SF 0 "register_operand" "=&f") - (plus:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG") - (match_operand:SF 2 "reg_or_fp0_operand" "fG")))] + (plus:SF (match_operand:SF 1 "reg_or_0_operand" "%fG") + (match_operand:SF 2 "reg_or_0_operand" "fG")))] "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" "add%,%/ %R1,%R2,%0" [(set_attr "type" "fadd") @@ -2445,8 +2374,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "addsf3" [(set (match_operand:SF 0 "register_operand" "=f") - (plus:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG") - (match_operand:SF 2 "reg_or_fp0_operand" "fG")))] + (plus:SF (match_operand:SF 1 "reg_or_0_operand" "%fG") + (match_operand:SF 2 "reg_or_0_operand" "fG")))] "TARGET_FP" "add%,%/ %R1,%R2,%0" [(set_attr "type" "fadd") @@ -2456,8 +2385,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "*adddf_ieee" [(set (match_operand:DF 0 "register_operand" "=&f") - (plus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG") - (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] + (plus:DF (match_operand:DF 1 "reg_or_0_operand" "%fG") + (match_operand:DF 2 "reg_or_0_operand" "fG")))] "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" "add%-%/ %R1,%R2,%0" [(set_attr "type" "fadd") @@ -2467,8 +2396,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "adddf3" [(set (match_operand:DF 0 "register_operand" "=f") - (plus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG") - (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] + (plus:DF (match_operand:DF 1 "reg_or_0_operand" "%fG") + (match_operand:DF 2 "reg_or_0_operand" "fG")))] "TARGET_FP" "add%-%/ %R1,%R2,%0" [(set_attr "type" "fadd") @@ -2479,8 +2408,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "*adddf_ext1" [(set (match_operand:DF 0 "register_operand" "=f") (plus:DF (float_extend:DF - (match_operand:SF 1 "reg_or_fp0_operand" "fG")) - (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] + (match_operand:SF 1 "reg_or_0_operand" "fG")) + (match_operand:DF 2 "reg_or_0_operand" "fG")))] "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" "add%-%/ %R1,%R2,%0" [(set_attr "type" "fadd") @@ -2491,9 +2420,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "*adddf_ext2" [(set (match_operand:DF 0 "register_operand" "=f") (plus:DF (float_extend:DF - (match_operand:SF 1 "reg_or_fp0_operand" "%fG")) + (match_operand:SF 1 "reg_or_0_operand" "%fG")) (float_extend:DF - (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))] + (match_operand:SF 2 "reg_or_0_operand" "fG"))))] "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" "add%-%/ %R1,%R2,%0" [(set_attr "type" "fadd") @@ -2518,8 +2447,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" ;; processing, it is cheaper to do the truncation in the int regs. (define_insn "*cvtql" - [(set (match_operand:SI 0 "register_operand" "=f") - (unspec:SI [(match_operand:DI 1 "reg_or_fp0_operand" "fG")] + [(set (match_operand:SF 0 "register_operand" "=f") + (unspec:SF [(match_operand:DI 1 "reg_or_0_operand" "fG")] UNSPEC_CVTQL))] "TARGET_FP" "cvtql%/ %R1,%0" @@ -2529,37 +2458,46 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn_and_split "*fix_truncdfsi_ieee" [(set (match_operand:SI 0 "memory_operand" "=m") - (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")) 0)) + (subreg:SI + (match_operator:DI 4 "fix_operator" + [(match_operand:DF 1 "reg_or_0_operand" "fG")]) 0)) (clobber (match_scratch:DI 2 "=&f")) - (clobber (match_scratch:SI 3 "=&f"))] + (clobber (match_scratch:SF 3 "=&f"))] "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" "#" "&& reload_completed" - [(set (match_dup 2) (fix:DI (match_dup 1))) - (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL)) - (set (match_dup 0) (match_dup 3))] - "" + [(set (match_dup 2) (match_op_dup 4 [(match_dup 1)])) + (set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL)) + (set (match_dup 5) (match_dup 3))] +{ + operands[5] = adjust_address (operands[0], SFmode, 0); +} [(set_attr "type" "fadd") (set_attr "trap" "yes")]) (define_insn_and_split "*fix_truncdfsi_internal" [(set (match_operand:SI 0 "memory_operand" "=m") - (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")) 0)) + (subreg:SI + (match_operator:DI 3 "fix_operator" + [(match_operand:DF 1 "reg_or_0_operand" "fG")]) 0)) (clobber (match_scratch:DI 2 "=f"))] "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" "#" "&& reload_completed" - [(set (match_dup 2) (fix:DI (match_dup 1))) - (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL)) - (set (match_dup 0) (match_dup 3))] - ;; Due to REG_CANNOT_CHANGE_SIZE issues, we cannot simply use SUBREG. - "operands[3] = gen_rtx_REG (SImode, REGNO (operands[2]));" + [(set (match_dup 2) (match_op_dup 3 [(match_dup 1)])) + (set (match_dup 4) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL)) + (set (match_dup 5) (match_dup 4))] +{ + operands[4] = gen_rtx_REG (SFmode, REGNO (operands[2])); + operands[5] = adjust_address (operands[0], SFmode, 0); +} [(set_attr "type" "fadd") (set_attr "trap" "yes")]) (define_insn "*fix_truncdfdi_ieee" [(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f") - (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))] + (match_operator:DI 2 "fix_operator" + [(match_operand:DF 1 "reg_or_0_operand" "fG")]))] "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" "cvt%-q%/ %R1,%0" [(set_attr "type" "fadd") @@ -2567,9 +2505,10 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (set_attr "round_suffix" "c") (set_attr "trap_suffix" "v_sv_svi")]) -(define_insn "fix_truncdfdi2" +(define_insn "*fix_truncdfdi2" [(set (match_operand:DI 0 "reg_no_subreg_operand" "=f") - (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))] + (match_operator:DI 2 "fix_operator" + [(match_operand:DF 1 "reg_or_0_operand" "fG")]))] "TARGET_FP" "cvt%-q%/ %R1,%0" [(set_attr "type" "fadd") @@ -2577,44 +2516,64 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (set_attr "round_suffix" "c") (set_attr "trap_suffix" "v_sv_svi")]) +(define_expand "fix_truncdfdi2" + [(set (match_operand:DI 0 "reg_no_subreg_operand" "") + (fix:DI (match_operand:DF 1 "reg_or_0_operand" "")))] + "TARGET_FP" + "") + +(define_expand "fixuns_truncdfdi2" + [(set (match_operand:DI 0 "reg_no_subreg_operand" "") + (unsigned_fix:DI (match_operand:DF 1 "reg_or_0_operand" "")))] + "TARGET_FP" + "") + ;; Likewise between SFmode and SImode. (define_insn_and_split "*fix_truncsfsi_ieee" [(set (match_operand:SI 0 "memory_operand" "=m") - (subreg:SI (fix:DI (float_extend:DF - (match_operand:SF 1 "reg_or_fp0_operand" "fG"))) 0)) + (subreg:SI + (match_operator:DI 4 "fix_operator" + [(float_extend:DF + (match_operand:SF 1 "reg_or_0_operand" "fG"))]) 0)) (clobber (match_scratch:DI 2 "=&f")) - (clobber (match_scratch:SI 3 "=&f"))] + (clobber (match_scratch:SF 3 "=&f"))] "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" "#" "&& reload_completed" - [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1)))) - (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL)) - (set (match_dup 0) (match_dup 3))] - "" + [(set (match_dup 2) (match_op_dup 4 [(float_extend:DF (match_dup 1))])) + (set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL)) + (set (match_dup 5) (match_dup 3))] +{ + operands[5] = adjust_address (operands[0], SFmode, 0); +} [(set_attr "type" "fadd") (set_attr "trap" "yes")]) (define_insn_and_split "*fix_truncsfsi_internal" [(set (match_operand:SI 0 "memory_operand" "=m") - (subreg:SI (fix:DI (float_extend:DF - (match_operand:SF 1 "reg_or_fp0_operand" "fG"))) 0)) + (subreg:SI + (match_operator:DI 3 "fix_operator" + [(float_extend:DF + (match_operand:SF 1 "reg_or_0_operand" "fG"))]) 0)) (clobber (match_scratch:DI 2 "=f"))] "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" "#" "&& reload_completed" - [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1)))) - (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL)) - (set (match_dup 0) (match_dup 3))] - ;; Due to REG_CANNOT_CHANGE_SIZE issues, we cannot simply use SUBREG. - "operands[3] = gen_rtx_REG (SImode, REGNO (operands[2]));" + [(set (match_dup 2) (match_op_dup 3 [(float_extend:DF (match_dup 1))])) + (set (match_dup 4) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL)) + (set (match_dup 5) (match_dup 4))] +{ + operands[4] = gen_rtx_REG (SFmode, REGNO (operands[2])); + operands[5] = adjust_address (operands[0], SFmode, 0); +} [(set_attr "type" "fadd") (set_attr "trap" "yes")]) (define_insn "*fix_truncsfdi_ieee" [(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f") - (fix:DI (float_extend:DF - (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))] + (match_operator:DI 2 "fix_operator" + [(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))]))] "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" "cvt%-q%/ %R1,%0" [(set_attr "type" "fadd") @@ -2622,10 +2581,10 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (set_attr "round_suffix" "c") (set_attr "trap_suffix" "v_sv_svi")]) -(define_insn "fix_truncsfdi2" +(define_insn "*fix_truncsfdi2" [(set (match_operand:DI 0 "reg_no_subreg_operand" "=f") - (fix:DI (float_extend:DF - (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))] + (match_operator:DI 2 "fix_operator" + [(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))]))] "TARGET_FP" "cvt%-q%/ %R1,%0" [(set_attr "type" "fadd") @@ -2633,12 +2592,31 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (set_attr "round_suffix" "c") (set_attr "trap_suffix" "v_sv_svi")]) +(define_expand "fix_truncsfdi2" + [(set (match_operand:DI 0 "reg_no_subreg_operand" "") + (fix:DI (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))))] + "TARGET_FP" + "") + +(define_expand "fixuns_truncsfdi2" + [(set (match_operand:DI 0 "reg_no_subreg_operand" "") + (unsigned_fix:DI + (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))))] + "TARGET_FP" + "") + (define_expand "fix_trunctfdi2" [(use (match_operand:DI 0 "register_operand" "")) (use (match_operand:TF 1 "general_operand" ""))] "TARGET_HAS_XFLOATING_LIBS" "alpha_emit_xfloating_cvt (FIX, operands); DONE;") +(define_expand "fixuns_trunctfdi2" + [(use (match_operand:DI 0 "register_operand" "")) + (use (match_operand:TF 1 "general_operand" ""))] + "TARGET_HAS_XFLOATING_LIBS" + "alpha_emit_xfloating_cvt (UNSIGNED_FIX, operands); DONE;") + (define_insn "*floatdisf_ieee" [(set (match_operand:SF 0 "register_operand" "=&f") (float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))] @@ -2659,6 +2637,35 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (set_attr "round_suffix" "normal") (set_attr "trap_suffix" "sui")]) +(define_insn_and_split "*floatsisf2_ieee" + [(set (match_operand:SF 0 "register_operand" "=&f") + (float:SF (match_operand:SI 1 "memory_operand" "m"))) + (clobber (match_scratch:DI 2 "=&f")) + (clobber (match_scratch:SF 3 "=&f"))] + "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" + "#" + "&& reload_completed" + [(set (match_dup 3) (match_dup 1)) + (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ)) + (set (match_dup 0) (float:SF (match_dup 2)))] +{ + operands[1] = adjust_address (operands[1], SFmode, 0); +}) + +(define_insn_and_split "*floatsisf2" + [(set (match_operand:SF 0 "register_operand" "=f") + (float:SF (match_operand:SI 1 "memory_operand" "m")))] + "TARGET_FP" + "#" + "&& reload_completed" + [(set (match_dup 0) (match_dup 1)) + (set (match_dup 2) (unspec:DI [(match_dup 0)] UNSPEC_CVTLQ)) + (set (match_dup 0) (float:SF (match_dup 2)))] +{ + operands[1] = adjust_address (operands[1], SFmode, 0); + operands[2] = gen_rtx_REG (DImode, REGNO (operands[0])); +}) + (define_insn "*floatdidf_ieee" [(set (match_operand:DF 0 "register_operand" "=&f") (float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))] @@ -2679,6 +2686,36 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (set_attr "round_suffix" "normal") (set_attr "trap_suffix" "sui")]) +(define_insn_and_split "*floatsidf2_ieee" + [(set (match_operand:DF 0 "register_operand" "=&f") + (float:DF (match_operand:SI 1 "memory_operand" "m"))) + (clobber (match_scratch:DI 2 "=&f")) + (clobber (match_scratch:SF 3 "=&f"))] + "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" + "#" + "&& reload_completed" + [(set (match_dup 3) (match_dup 1)) + (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ)) + (set (match_dup 0) (float:DF (match_dup 2)))] +{ + operands[1] = adjust_address (operands[1], SFmode, 0); +}) + +(define_insn_and_split "*floatsidf2" + [(set (match_operand:DF 0 "register_operand" "=f") + (float:DF (match_operand:SI 1 "memory_operand" "m")))] + "TARGET_FP" + "#" + "&& reload_completed" + [(set (match_dup 3) (match_dup 1)) + (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ)) + (set (match_dup 0) (float:DF (match_dup 2)))] +{ + operands[1] = adjust_address (operands[1], SFmode, 0); + operands[2] = gen_rtx_REG (DImode, REGNO (operands[0])); + operands[3] = gen_rtx_REG (SFmode, REGNO (operands[0])); +}) + (define_expand "floatditf2" [(use (match_operand:TF 0 "register_operand" "")) (use (match_operand:DI 1 "general_operand" ""))] @@ -2733,9 +2770,12 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" st%- %1,%0" [(set_attr "type" "fcpys,fld,fst")]) +;; Use register_operand for operand 1 to prevent compress_float_constant +;; from doing something silly. When optimizing we'll put things back +;; together anyway. (define_expand "extendsftf2" [(use (match_operand:TF 0 "register_operand" "")) - (use (match_operand:SF 1 "general_operand" ""))] + (use (match_operand:SF 1 "register_operand" ""))] "TARGET_HAS_XFLOATING_LIBS" { rtx tmp = gen_reg_rtx (DFmode); @@ -2746,13 +2786,13 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_expand "extenddftf2" [(use (match_operand:TF 0 "register_operand" "")) - (use (match_operand:DF 1 "general_operand" ""))] + (use (match_operand:DF 1 "register_operand" ""))] "TARGET_HAS_XFLOATING_LIBS" "alpha_emit_xfloating_cvt (FLOAT_EXTEND, operands); DONE;") (define_insn "*truncdfsf2_ieee" [(set (match_operand:SF 0 "register_operand" "=&f") - (float_truncate:SF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))] + (float_truncate:SF (match_operand:DF 1 "reg_or_0_operand" "fG")))] "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" "cvt%-%,%/ %R1,%0" [(set_attr "type" "fadd") @@ -2762,7 +2802,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "truncdfsf2" [(set (match_operand:SF 0 "register_operand" "=f") - (float_truncate:SF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))] + (float_truncate:SF (match_operand:DF 1 "reg_or_0_operand" "fG")))] "TARGET_FP" "cvt%-%,%/ %R1,%0" [(set_attr "type" "fadd") @@ -2804,8 +2844,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "*divsf3_ieee" [(set (match_operand:SF 0 "register_operand" "=&f") - (div:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG") - (match_operand:SF 2 "reg_or_fp0_operand" "fG")))] + (div:SF (match_operand:SF 1 "reg_or_0_operand" "fG") + (match_operand:SF 2 "reg_or_0_operand" "fG")))] "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" "div%,%/ %R1,%R2,%0" [(set_attr "type" "fdiv") @@ -2816,8 +2856,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "divsf3" [(set (match_operand:SF 0 "register_operand" "=f") - (div:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG") - (match_operand:SF 2 "reg_or_fp0_operand" "fG")))] + (div:SF (match_operand:SF 1 "reg_or_0_operand" "fG") + (match_operand:SF 2 "reg_or_0_operand" "fG")))] "TARGET_FP" "div%,%/ %R1,%R2,%0" [(set_attr "type" "fdiv") @@ -2828,8 +2868,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "*divdf3_ieee" [(set (match_operand:DF 0 "register_operand" "=&f") - (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG") - (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] + (div:DF (match_operand:DF 1 "reg_or_0_operand" "fG") + (match_operand:DF 2 "reg_or_0_operand" "fG")))] "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" "div%-%/ %R1,%R2,%0" [(set_attr "type" "fdiv") @@ -2839,8 +2879,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "divdf3" [(set (match_operand:DF 0 "register_operand" "=f") - (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG") - (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] + (div:DF (match_operand:DF 1 "reg_or_0_operand" "fG") + (match_operand:DF 2 "reg_or_0_operand" "fG")))] "TARGET_FP" "div%-%/ %R1,%R2,%0" [(set_attr "type" "fdiv") @@ -2850,8 +2890,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "*divdf_ext1" [(set (match_operand:DF 0 "register_operand" "=f") - (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG")) - (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] + (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG")) + (match_operand:DF 2 "reg_or_0_operand" "fG")))] "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" "div%-%/ %R1,%R2,%0" [(set_attr "type" "fdiv") @@ -2861,9 +2901,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "*divdf_ext2" [(set (match_operand:DF 0 "register_operand" "=f") - (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG") + (div:DF (match_operand:DF 1 "reg_or_0_operand" "fG") (float_extend:DF - (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))] + (match_operand:SF 2 "reg_or_0_operand" "fG"))))] "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" "div%-%/ %R1,%R2,%0" [(set_attr "type" "fdiv") @@ -2873,8 +2913,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "*divdf_ext3" [(set (match_operand:DF 0 "register_operand" "=f") - (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG")) - (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))] + (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG")) + (float_extend:DF (match_operand:SF 2 "reg_or_0_operand" "fG"))))] "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" "div%-%/ %R1,%R2,%0" [(set_attr "type" "fdiv") @@ -2891,8 +2931,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "*mulsf3_ieee" [(set (match_operand:SF 0 "register_operand" "=&f") - (mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG") - (match_operand:SF 2 "reg_or_fp0_operand" "fG")))] + (mult:SF (match_operand:SF 1 "reg_or_0_operand" "%fG") + (match_operand:SF 2 "reg_or_0_operand" "fG")))] "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" "mul%,%/ %R1,%R2,%0" [(set_attr "type" "fmul") @@ -2902,8 +2942,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "mulsf3" [(set (match_operand:SF 0 "register_operand" "=f") - (mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG") - (match_operand:SF 2 "reg_or_fp0_operand" "fG")))] + (mult:SF (match_operand:SF 1 "reg_or_0_operand" "%fG") + (match_operand:SF 2 "reg_or_0_operand" "fG")))] "TARGET_FP" "mul%,%/ %R1,%R2,%0" [(set_attr "type" "fmul") @@ -2913,8 +2953,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "*muldf3_ieee" [(set (match_operand:DF 0 "register_operand" "=&f") - (mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG") - (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] + (mult:DF (match_operand:DF 1 "reg_or_0_operand" "%fG") + (match_operand:DF 2 "reg_or_0_operand" "fG")))] "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" "mul%-%/ %R1,%R2,%0" [(set_attr "type" "fmul") @@ -2924,8 +2964,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "muldf3" [(set (match_operand:DF 0 "register_operand" "=f") - (mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG") - (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] + (mult:DF (match_operand:DF 1 "reg_or_0_operand" "%fG") + (match_operand:DF 2 "reg_or_0_operand" "fG")))] "TARGET_FP" "mul%-%/ %R1,%R2,%0" [(set_attr "type" "fmul") @@ -2936,8 +2976,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "*muldf_ext1" [(set (match_operand:DF 0 "register_operand" "=f") (mult:DF (float_extend:DF - (match_operand:SF 1 "reg_or_fp0_operand" "fG")) - (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] + (match_operand:SF 1 "reg_or_0_operand" "fG")) + (match_operand:DF 2 "reg_or_0_operand" "fG")))] "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" "mul%-%/ %R1,%R2,%0" [(set_attr "type" "fmul") @@ -2948,9 +2988,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "*muldf_ext2" [(set (match_operand:DF 0 "register_operand" "=f") (mult:DF (float_extend:DF - (match_operand:SF 1 "reg_or_fp0_operand" "%fG")) + (match_operand:SF 1 "reg_or_0_operand" "%fG")) (float_extend:DF - (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))] + (match_operand:SF 2 "reg_or_0_operand" "fG"))))] "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" "mul%-%/ %R1,%R2,%0" [(set_attr "type" "fmul") @@ -2967,8 +3007,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "*subsf3_ieee" [(set (match_operand:SF 0 "register_operand" "=&f") - (minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG") - (match_operand:SF 2 "reg_or_fp0_operand" "fG")))] + (minus:SF (match_operand:SF 1 "reg_or_0_operand" "fG") + (match_operand:SF 2 "reg_or_0_operand" "fG")))] "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" "sub%,%/ %R1,%R2,%0" [(set_attr "type" "fadd") @@ -2978,8 +3018,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "subsf3" [(set (match_operand:SF 0 "register_operand" "=f") - (minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG") - (match_operand:SF 2 "reg_or_fp0_operand" "fG")))] + (minus:SF (match_operand:SF 1 "reg_or_0_operand" "fG") + (match_operand:SF 2 "reg_or_0_operand" "fG")))] "TARGET_FP" "sub%,%/ %R1,%R2,%0" [(set_attr "type" "fadd") @@ -2989,8 +3029,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "*subdf3_ieee" [(set (match_operand:DF 0 "register_operand" "=&f") - (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG") - (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] + (minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG") + (match_operand:DF 2 "reg_or_0_operand" "fG")))] "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" "sub%-%/ %R1,%R2,%0" [(set_attr "type" "fadd") @@ -3000,8 +3040,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "subdf3" [(set (match_operand:DF 0 "register_operand" "=f") - (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG") - (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] + (minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG") + (match_operand:DF 2 "reg_or_0_operand" "fG")))] "TARGET_FP" "sub%-%/ %R1,%R2,%0" [(set_attr "type" "fadd") @@ -3012,8 +3052,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "*subdf_ext1" [(set (match_operand:DF 0 "register_operand" "=f") (minus:DF (float_extend:DF - (match_operand:SF 1 "reg_or_fp0_operand" "fG")) - (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] + (match_operand:SF 1 "reg_or_0_operand" "fG")) + (match_operand:DF 2 "reg_or_0_operand" "fG")))] "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" "sub%-%/ %R1,%R2,%0" [(set_attr "type" "fadd") @@ -3023,9 +3063,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "*subdf_ext2" [(set (match_operand:DF 0 "register_operand" "=f") - (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG") + (minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG") (float_extend:DF - (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))] + (match_operand:SF 2 "reg_or_0_operand" "fG"))))] "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" "sub%-%/ %R1,%R2,%0" [(set_attr "type" "fadd") @@ -3036,9 +3076,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "*subdf_ext3" [(set (match_operand:DF 0 "register_operand" "=f") (minus:DF (float_extend:DF - (match_operand:SF 1 "reg_or_fp0_operand" "fG")) + (match_operand:SF 1 "reg_or_0_operand" "fG")) (float_extend:DF - (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))] + (match_operand:SF 2 "reg_or_0_operand" "fG"))))] "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" "sub%-%/ %R1,%R2,%0" [(set_attr "type" "fadd") @@ -3055,7 +3095,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "*sqrtsf2_ieee" [(set (match_operand:SF 0 "register_operand" "=&f") - (sqrt:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))] + (sqrt:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))] "TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU" "sqrt%,%/ %R1,%0" [(set_attr "type" "fsqrt") @@ -3066,7 +3106,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "sqrtsf2" [(set (match_operand:SF 0 "register_operand" "=f") - (sqrt:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))] + (sqrt:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))] "TARGET_FP && TARGET_FIX" "sqrt%,%/ %R1,%0" [(set_attr "type" "fsqrt") @@ -3077,7 +3117,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "*sqrtdf2_ieee" [(set (match_operand:DF 0 "register_operand" "=&f") - (sqrt:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))] + (sqrt:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))] "TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU" "sqrt%-%/ %R1,%0" [(set_attr "type" "fsqrt") @@ -3087,9 +3127,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "sqrtdf2" [(set (match_operand:DF 0 "register_operand" "=f") - (sqrt:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))] + (sqrt:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))] "TARGET_FP && TARGET_FIX" - "sqrt%-%/ %1,%0" + "sqrt%-%/ %R1,%0" [(set_attr "type" "fsqrt") (set_attr "trap" "yes") (set_attr "round_suffix" "normal") @@ -3152,7 +3192,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")]) (match_operand:QI 1 "add_operand" "rI,0,rI,0") (match_operand:QI 5 "add_operand" "0,rI,0,rI")))] - "(operands[3] == const0_rtx || operands[4] == const0_rtx)" + "(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)" "@ cmov%C2 %r3,%1,%0 cmov%D2 %r3,%5,%0 @@ -3168,7 +3208,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")]) (match_operand:HI 1 "add_operand" "rI,0,rI,0") (match_operand:HI 5 "add_operand" "0,rI,0,rI")))] - "(operands[3] == const0_rtx || operands[4] == const0_rtx)" + "(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)" "@ cmov%C2 %r3,%1,%0 cmov%D2 %r3,%5,%0 @@ -3184,7 +3224,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")]) (match_operand:SI 1 "add_operand" "rI,0,rI,0") (match_operand:SI 5 "add_operand" "0,rI,0,rI")))] - "(operands[3] == const0_rtx || operands[4] == const0_rtx)" + "(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)" "@ cmov%C2 %r3,%1,%0 cmov%D2 %r3,%5,%0 @@ -3200,7 +3240,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")]) (match_operand:DI 1 "add_operand" "rI,0,rI,0") (match_operand:DI 5 "add_operand" "0,rI,0,rI")))] - "(operands[3] == const0_rtx || operands[4] == const0_rtx)" + "(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)" "@ cmov%C2 %r3,%1,%0 cmov%D2 %r3,%5,%0 @@ -3462,7 +3502,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (match_operand:HI 2 "reg_or_8bit_operand" "rI")))] "TARGET_MAX" "maxuw4 %r1,%2,%0" - [(set_attr "type" "shift")]) + [(set_attr "type" "mvi")]) (define_expand "smaxdi3" [(set (match_dup 3) @@ -3647,8 +3687,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "*cmpdf_ieee" [(set (match_operand:DF 0 "register_operand" "=&f") (match_operator:DF 1 "alpha_fp_comparison_operator" - [(match_operand:DF 2 "reg_or_fp0_operand" "fG") - (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))] + [(match_operand:DF 2 "reg_or_0_operand" "fG") + (match_operand:DF 3 "reg_or_0_operand" "fG")]))] "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" "cmp%-%C1%/ %R2,%R3,%0" [(set_attr "type" "fadd") @@ -3658,82 +3698,45 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_insn "*cmpdf_internal" [(set (match_operand:DF 0 "register_operand" "=f") (match_operator:DF 1 "alpha_fp_comparison_operator" - [(match_operand:DF 2 "reg_or_fp0_operand" "fG") - (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))] - "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" + [(match_operand:DF 2 "reg_or_0_operand" "fG") + (match_operand:DF 3 "reg_or_0_operand" "fG")]))] + "TARGET_FP" "cmp%-%C1%/ %R2,%R3,%0" [(set_attr "type" "fadd") (set_attr "trap" "yes") (set_attr "trap_suffix" "su")]) -(define_insn "*cmpdf_ieee_ext1" - [(set (match_operand:DF 0 "register_operand" "=&f") +(define_insn "*cmpdf_ext1" + [(set (match_operand:DF 0 "register_operand" "=f") (match_operator:DF 1 "alpha_fp_comparison_operator" [(float_extend:DF - (match_operand:SF 2 "reg_or_fp0_operand" "fG")) - (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))] - "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" + (match_operand:SF 2 "reg_or_0_operand" "fG")) + (match_operand:DF 3 "reg_or_0_operand" "fG")]))] + "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" "cmp%-%C1%/ %R2,%R3,%0" [(set_attr "type" "fadd") (set_attr "trap" "yes") (set_attr "trap_suffix" "su")]) -(define_insn "*cmpdf_ext1" +(define_insn "*cmpdf_ext2" [(set (match_operand:DF 0 "register_operand" "=f") (match_operator:DF 1 "alpha_fp_comparison_operator" - [(float_extend:DF - (match_operand:SF 2 "reg_or_fp0_operand" "fG")) - (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))] + [(match_operand:DF 2 "reg_or_0_operand" "fG") + (float_extend:DF + (match_operand:SF 3 "reg_or_0_operand" "fG"))]))] "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" "cmp%-%C1%/ %R2,%R3,%0" [(set_attr "type" "fadd") (set_attr "trap" "yes") (set_attr "trap_suffix" "su")]) -(define_insn "*cmpdf_ieee_ext2" - [(set (match_operand:DF 0 "register_operand" "=&f") - (match_operator:DF 1 "alpha_fp_comparison_operator" - [(match_operand:DF 2 "reg_or_fp0_operand" "fG") - (float_extend:DF - (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))] - "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" - "cmp%-%C1%/ %R2,%R3,%0" - [(set_attr "type" "fadd") - (set_attr "trap" "yes") - (set_attr "trap_suffix" "su")]) - -(define_insn "*cmpdf_ext2" - [(set (match_operand:DF 0 "register_operand" "=f") - (match_operator:DF 1 "alpha_fp_comparison_operator" - [(match_operand:DF 2 "reg_or_fp0_operand" "fG") - (float_extend:DF - (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))] - "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" - "cmp%-%C1%/ %R2,%R3,%0" - [(set_attr "type" "fadd") - (set_attr "trap" "yes") - (set_attr "trap_suffix" "su")]) - -(define_insn "*cmpdf_ieee_ext3" - [(set (match_operand:DF 0 "register_operand" "=&f") - (match_operator:DF 1 "alpha_fp_comparison_operator" - [(float_extend:DF - (match_operand:SF 2 "reg_or_fp0_operand" "fG")) - (float_extend:DF - (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))] - "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" - "cmp%-%C1%/ %R2,%R3,%0" - [(set_attr "type" "fadd") - (set_attr "trap" "yes") - (set_attr "trap_suffix" "su")]) - (define_insn "*cmpdf_ext3" [(set (match_operand:DF 0 "register_operand" "=f") (match_operator:DF 1 "alpha_fp_comparison_operator" [(float_extend:DF - (match_operand:SF 2 "reg_or_fp0_operand" "fG")) + (match_operand:SF 2 "reg_or_0_operand" "fG")) (float_extend:DF - (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))] + (match_operand:SF 3 "reg_or_0_operand" "fG"))]))] "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" "cmp%-%C1%/ %R2,%R3,%0" [(set_attr "type" "fadd") @@ -3744,10 +3747,10 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" [(set (match_operand:DF 0 "register_operand" "=f,f") (if_then_else:DF (match_operator 3 "signed_comparison_operator" - [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG") - (match_operand:DF 2 "fp0_operand" "G,G")]) - (match_operand:DF 1 "reg_or_fp0_operand" "fG,0") - (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))] + [(match_operand:DF 4 "reg_or_0_operand" "fG,fG") + (match_operand:DF 2 "const0_operand" "G,G")]) + (match_operand:DF 1 "reg_or_0_operand" "fG,0") + (match_operand:DF 5 "reg_or_0_operand" "0,fG")))] "TARGET_FP" "@ fcmov%C3 %R4,%R1,%0 @@ -3758,10 +3761,10 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" [(set (match_operand:SF 0 "register_operand" "=f,f") (if_then_else:SF (match_operator 3 "signed_comparison_operator" - [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG") - (match_operand:DF 2 "fp0_operand" "G,G")]) - (match_operand:SF 1 "reg_or_fp0_operand" "fG,0") - (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))] + [(match_operand:DF 4 "reg_or_0_operand" "fG,fG") + (match_operand:DF 2 "const0_operand" "G,G")]) + (match_operand:SF 1 "reg_or_0_operand" "fG,0") + (match_operand:SF 5 "reg_or_0_operand" "0,fG")))] "TARGET_FP" "@ fcmov%C3 %R4,%R1,%0 @@ -3772,11 +3775,11 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" [(set (match_operand:DF 0 "register_operand" "=f,f") (if_then_else:DF (match_operator 3 "signed_comparison_operator" - [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG") - (match_operand:DF 2 "fp0_operand" "G,G")]) - (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")) - (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))] - "TARGET_FP" + [(match_operand:DF 4 "reg_or_0_operand" "fG,fG") + (match_operand:DF 2 "const0_operand" "G,G")]) + (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG,0")) + (match_operand:DF 5 "reg_or_0_operand" "0,fG")))] + "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" "@ fcmov%C3 %R4,%R1,%0 fcmov%D3 %R4,%R5,%0" @@ -3787,11 +3790,11 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (if_then_else:DF (match_operator 3 "signed_comparison_operator" [(float_extend:DF - (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG")) - (match_operand:DF 2 "fp0_operand" "G,G")]) - (match_operand:DF 1 "reg_or_fp0_operand" "fG,0") - (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))] - "TARGET_FP" + (match_operand:SF 4 "reg_or_0_operand" "fG,fG")) + (match_operand:DF 2 "const0_operand" "G,G")]) + (match_operand:DF 1 "reg_or_0_operand" "fG,0") + (match_operand:DF 5 "reg_or_0_operand" "0,fG")))] + "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" "@ fcmov%C3 %R4,%R1,%0 fcmov%D3 %R4,%R5,%0" @@ -3802,11 +3805,11 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (if_then_else:SF (match_operator 3 "signed_comparison_operator" [(float_extend:DF - (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG")) - (match_operand:DF 2 "fp0_operand" "G,G")]) - (match_operand:SF 1 "reg_or_fp0_operand" "fG,0") - (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))] - "TARGET_FP" + (match_operand:SF 4 "reg_or_0_operand" "fG,fG")) + (match_operand:DF 2 "const0_operand" "G,G")]) + (match_operand:SF 1 "reg_or_0_operand" "fG,0") + (match_operand:SF 5 "reg_or_0_operand" "0,fG")))] + "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" "@ fcmov%C3 %R4,%R1,%0 fcmov%D3 %R4,%R5,%0" @@ -3817,20 +3820,20 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (if_then_else:DF (match_operator 3 "signed_comparison_operator" [(float_extend:DF - (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG")) - (match_operand:DF 2 "fp0_operand" "G,G")]) - (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")) - (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))] - "TARGET_FP" + (match_operand:SF 4 "reg_or_0_operand" "fG,fG")) + (match_operand:DF 2 "const0_operand" "G,G")]) + (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG,0")) + (match_operand:DF 5 "reg_or_0_operand" "0,fG")))] + "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" "@ fcmov%C3 %R4,%R1,%0 fcmov%D3 %R4,%R5,%0" [(set_attr "type" "fcmov")]) -(define_expand "maxdf3" +(define_expand "smaxdf3" [(set (match_dup 3) - (le:DF (match_operand:DF 1 "reg_or_fp0_operand" "") - (match_operand:DF 2 "reg_or_fp0_operand" ""))) + (le:DF (match_operand:DF 1 "reg_or_0_operand" "") + (match_operand:DF 2 "reg_or_0_operand" ""))) (set (match_operand:DF 0 "register_operand" "") (if_then_else:DF (eq (match_dup 3) (match_dup 4)) (match_dup 1) (match_dup 2)))] @@ -3840,10 +3843,10 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" operands[4] = CONST0_RTX (DFmode); }) -(define_expand "mindf3" +(define_expand "smindf3" [(set (match_dup 3) - (lt:DF (match_operand:DF 1 "reg_or_fp0_operand" "") - (match_operand:DF 2 "reg_or_fp0_operand" ""))) + (lt:DF (match_operand:DF 1 "reg_or_0_operand" "") + (match_operand:DF 2 "reg_or_0_operand" ""))) (set (match_operand:DF 0 "register_operand" "") (if_then_else:DF (ne (match_dup 3) (match_dup 4)) (match_dup 1) (match_dup 2)))] @@ -3853,27 +3856,27 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" operands[4] = CONST0_RTX (DFmode); }) -(define_expand "maxsf3" +(define_expand "smaxsf3" [(set (match_dup 3) - (le:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "")) - (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "")))) + (le:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "")) + (float_extend:DF (match_operand:SF 2 "reg_or_0_operand" "")))) (set (match_operand:SF 0 "register_operand" "") (if_then_else:SF (eq (match_dup 3) (match_dup 4)) (match_dup 1) (match_dup 2)))] - "TARGET_FP" + "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" { operands[3] = gen_reg_rtx (DFmode); operands[4] = CONST0_RTX (DFmode); }) -(define_expand "minsf3" +(define_expand "sminsf3" [(set (match_dup 3) - (lt:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "")) - (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "")))) + (lt:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "")) + (float_extend:DF (match_operand:SF 2 "reg_or_0_operand" "")))) (set (match_operand:SF 0 "register_operand" "") (if_then_else:SF (ne (match_dup 3) (match_dup 4)) (match_dup 1) (match_dup 2)))] - "TARGET_FP" + "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" { operands[3] = gen_reg_rtx (DFmode); operands[4] = CONST0_RTX (DFmode); @@ -3883,8 +3886,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" [(set (pc) (if_then_else (match_operator 1 "signed_comparison_operator" - [(match_operand:DF 2 "reg_or_fp0_operand" "fG") - (match_operand:DF 3 "fp0_operand" "G")]) + [(match_operand:DF 2 "reg_or_0_operand" "fG") + (match_operand:DF 3 "const0_operand" "G")]) (label_ref (match_operand 0 "" "")) (pc)))] "TARGET_FP" @@ -3896,8 +3899,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (if_then_else (match_operator 1 "signed_comparison_operator" [(float_extend:DF - (match_operand:SF 2 "reg_or_fp0_operand" "fG")) - (match_operand:DF 3 "fp0_operand" "G")]) + (match_operand:SF 2 "reg_or_0_operand" "fG")) + (match_operand:DF 3 "const0_operand" "G")]) (label_ref (match_operand 0 "" "")) (pc)))] "TARGET_FP" @@ -3908,8 +3911,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" ;; and compares. (define_expand "cmpdf" - [(set (cc0) (compare (match_operand:DF 0 "reg_or_fp0_operand" "") - (match_operand:DF 1 "reg_or_fp0_operand" "")))] + [(set (cc0) (compare (match_operand:DF 0 "reg_or_0_operand" "") + (match_operand:DF 1 "reg_or_0_operand" "")))] "TARGET_FP" { alpha_compare.op0 = operands[0]; @@ -3930,8 +3933,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" }) (define_expand "cmpdi" - [(set (cc0) (compare (match_operand:DI 0 "general_operand" "") - (match_operand:DI 1 "general_operand" "")))] + [(set (cc0) (compare (match_operand:DI 0 "some_operand" "") + (match_operand:DI 1 "some_operand" "")))] "" { alpha_compare.op0 = operands[0]; @@ -4263,100 +4266,6 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" operands[6], const0_rtx); }) -(define_split - [(set (pc) - (if_then_else - (match_operator 1 "comparison_operator" - [(match_operand:DI 2 "reg_or_0_operand" "") - (match_operand:DI 3 "reg_or_cint_operand" "")]) - (label_ref (match_operand 0 "" "")) - (pc))) - (clobber (match_operand:DI 4 "register_operand" ""))] - "operands[3] != const0_rtx" - [(set (match_dup 4) (match_dup 5)) - (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))] -{ - enum rtx_code code = GET_CODE (operands[1]); - int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU); - - if (code == NE || code == EQ - || (extended_count (operands[2], DImode, unsignedp) >= 1 - && extended_count (operands[3], DImode, unsignedp) >= 1)) - { - if (GET_CODE (operands[3]) == CONST_INT) - operands[5] = gen_rtx_PLUS (DImode, operands[2], - GEN_INT (- INTVAL (operands[3]))); - else - operands[5] = gen_rtx_MINUS (DImode, operands[2], operands[3]); - - operands[6] = gen_rtx_fmt_ee (code, VOIDmode, operands[4], const0_rtx); - } - - else if (code == EQ || code == LE || code == LT - || code == LEU || code == LTU) - { - operands[5] = gen_rtx_fmt_ee (code, DImode, operands[2], operands[3]); - operands[6] = gen_rtx_NE (VOIDmode, operands[4], const0_rtx); - } - else - { - operands[5] = gen_rtx_fmt_ee (reverse_condition (code), DImode, - operands[2], operands[3]); - operands[6] = gen_rtx_EQ (VOIDmode, operands[4], const0_rtx); - } -}) - -(define_split - [(set (pc) - (if_then_else - (match_operator 1 "comparison_operator" - [(match_operand:SI 2 "reg_or_0_operand" "") - (match_operand:SI 3 "const_int_operand" "")]) - (label_ref (match_operand 0 "" "")) - (pc))) - (clobber (match_operand:DI 4 "register_operand" ""))] - "operands[3] != const0_rtx - && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)" - [(set (match_dup 4) (match_dup 5)) - (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))] -{ - rtx tem; - - if (GET_CODE (operands[3]) == CONST_INT) - tem = gen_rtx_PLUS (SImode, operands[2], - GEN_INT (- INTVAL (operands[3]))); - else - tem = gen_rtx_MINUS (SImode, operands[2], operands[3]); - - operands[5] = gen_rtx_SIGN_EXTEND (DImode, tem); - operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode, - operands[4], const0_rtx); -}) - -;; We can convert such things as "a > 0xffff" to "t = a & ~ 0xffff; t != 0". -;; This eliminates one, and sometimes two, insns when the AND can be done -;; with a ZAP. -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (match_operator:DI 1 "comparison_operator" - [(match_operand:DI 2 "register_operand" "") - (match_operand:DI 3 "const_int_operand" "")])) - (clobber (match_operand:DI 4 "register_operand" ""))] - "exact_log2 (INTVAL (operands[3]) + 1) >= 0 - && (GET_CODE (operands[1]) == GTU - || GET_CODE (operands[1]) == LEU - || ((GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == LE) - && extended_count (operands[2], DImode, 1) > 0))" - [(set (match_dup 4) (and:DI (match_dup 2) (match_dup 5))) - (set (match_dup 0) (match_dup 6))] -{ - operands[5] = GEN_INT (~ INTVAL (operands[3])); - operands[6] = gen_rtx_fmt_ee (((GET_CODE (operands[1]) == GTU - || GET_CODE (operands[1]) == GT) - ? NE : EQ), - DImode, operands[4], const0_rtx); -}) - ;; Prefer to use cmp and arithmetic when possible instead of a cmove. (define_split @@ -4408,14 +4317,14 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (clobber (match_scratch:DI 5 "=r"))] "" "#" - "! no_new_pseudos || reload_completed" + "" [(set (match_dup 5) (match_op_dup:DI 1 [(match_dup 2) (const_int 0)])) (set (match_dup 0) (plus:DI (mult:DI (match_dup 5) (match_dup 3)) (match_dup 4)))] { - if (! no_new_pseudos) + if (can_create_pseudo_p ()) operands[5] = gen_reg_rtx (DImode); else if (reg_overlap_mentioned_p (operands[5], operands[4])) operands[5] = operands[0]; @@ -4433,15 +4342,15 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (clobber (match_scratch:SI 5 "=r"))] "" "#" - "! no_new_pseudos || reload_completed" + "" [(set (match_dup 5) (match_op_dup:SI 1 [(match_dup 2) (const_int 0)])) (set (match_dup 0) (plus:SI (mult:SI (match_dup 5) (match_dup 3)) (match_dup 4)))] { - if (! no_new_pseudos) - operands[5] = gen_reg_rtx (DImode); + if (can_create_pseudo_p ()) + operands[5] = gen_reg_rtx (SImode); else if (reg_overlap_mentioned_p (operands[5], operands[4])) operands[5] = operands[0]; }) @@ -4459,17 +4368,17 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (clobber (match_scratch:SI 5 "=r"))] "" "#" - "! no_new_pseudos || reload_completed" + "" [(set (match_dup 5) (match_op_dup:SI 1 [(match_dup 2) (const_int 0)])) (set (match_dup 0) (sign_extend:DI (plus:SI (mult:SI (match_dup 5) (match_dup 3)) (match_dup 4))))] { - if (! no_new_pseudos) - operands[5] = gen_reg_rtx (DImode); + if (can_create_pseudo_p ()) + operands[5] = gen_reg_rtx (SImode); else if (reg_overlap_mentioned_p (operands[5], operands[4])) - operands[5] = operands[0]; + operands[5] = gen_lowpart (SImode, operands[0]); }) (define_insn_and_split "*cmp_ssub_di" @@ -4484,14 +4393,14 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (clobber (match_scratch:DI 5 "=r"))] "" "#" - "! no_new_pseudos || reload_completed" + "" [(set (match_dup 5) (match_op_dup:DI 1 [(match_dup 2) (const_int 0)])) (set (match_dup 0) (minus:DI (mult:DI (match_dup 5) (match_dup 3)) (match_dup 4)))] { - if (! no_new_pseudos) + if (can_create_pseudo_p ()) operands[5] = gen_reg_rtx (DImode); else if (reg_overlap_mentioned_p (operands[5], operands[4])) operands[5] = operands[0]; @@ -4509,15 +4418,15 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (clobber (match_scratch:SI 5 "=r"))] "" "#" - "! no_new_pseudos || reload_completed" + "" [(set (match_dup 5) (match_op_dup:SI 1 [(match_dup 2) (const_int 0)])) (set (match_dup 0) (minus:SI (mult:SI (match_dup 5) (match_dup 3)) (match_dup 4)))] { - if (! no_new_pseudos) - operands[5] = gen_reg_rtx (DImode); + if (can_create_pseudo_p ()) + operands[5] = gen_reg_rtx (SImode); else if (reg_overlap_mentioned_p (operands[5], operands[4])) operands[5] = operands[0]; }) @@ -4535,17 +4444,17 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (clobber (match_scratch:SI 5 "=r"))] "" "#" - "! no_new_pseudos || reload_completed" + "" [(set (match_dup 5) (match_op_dup:SI 1 [(match_dup 2) (const_int 0)])) (set (match_dup 0) (sign_extend:DI (minus:SI (mult:SI (match_dup 5) (match_dup 3)) (match_dup 4))))] { - if (! no_new_pseudos) - operands[5] = gen_reg_rtx (DImode); + if (can_create_pseudo_p ()) + operands[5] = gen_reg_rtx (SImode); else if (reg_overlap_mentioned_p (operands[5], operands[4])) - operands[5] = operands[0]; + operands[5] = gen_lowpart (SImode, operands[0]); }) ;; Here are the CALL and unconditional branch insns. Calls on NT and OSF @@ -4585,8 +4494,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (unspec [(reg:DI 29)] UNSPEC_SIBCALL)])] "TARGET_ABI_OSF" { - if (GET_CODE (operands[0]) != MEM) - abort (); + gcc_assert (GET_CODE (operands[0]) == MEM); operands[0] = XEXP (operands[0], 0); }) @@ -4597,8 +4505,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (clobber (reg:DI 26))])] "" { - if (GET_CODE (operands[0]) != MEM) - abort (); + gcc_assert (GET_CODE (operands[0]) == MEM); operands[0] = XEXP (operands[0], 0); if (! call_operand (operands[0], Pmode)) @@ -4611,8 +4518,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (clobber (reg:DI 26))])] "" { - if (GET_CODE (operands[0]) != MEM) - abort (); + gcc_assert (GET_CODE (operands[0]) == MEM); operands[0] = XEXP (operands[0], 0); if (GET_CODE (operands[0]) != SYMBOL_REF && GET_CODE (operands[0]) != REG) @@ -4630,8 +4536,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (clobber (reg:DI 26))])] "" { - if (GET_CODE (operands[0]) != MEM) - abort (); + gcc_assert (GET_CODE (operands[0]) == MEM); /* Always load the address of the called function into a register; load the CIW in $25. */ @@ -4657,8 +4562,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (clobber (reg:DI 27))])] "" { - if (GET_CODE (operands[0]) != MEM) - abort (); + gcc_assert (GET_CODE (operands[0]) == MEM); operands[0] = XEXP (operands[0], 0); @@ -4669,11 +4573,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" emit_move_insn (gen_rtx_REG (DImode, 25), operands[1]); if (GET_CODE (operands[0]) == SYMBOL_REF) { - rtx linkage = alpha_need_linkage (XSTR (operands[0], 0), 0); + alpha_need_linkage (XSTR (operands[0], 0), 0); - emit_move_insn (gen_rtx_REG (Pmode, 26), gen_rtx_MEM (Pmode, linkage)); - operands[2] - = validize_mem (gen_rtx_MEM (Pmode, plus_constant (linkage, 8))); + operands[2] = const0_rtx; } else { @@ -4713,8 +4615,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (unspec [(reg:DI 29)] UNSPEC_SIBCALL)])] "TARGET_ABI_OSF" { - if (GET_CODE (operands[1]) != MEM) - abort (); + gcc_assert (GET_CODE (operands[1]) == MEM); operands[1] = XEXP (operands[1], 0); }) @@ -4726,8 +4627,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (clobber (reg:DI 26))])] "" { - if (GET_CODE (operands[1]) != MEM) - abort (); + gcc_assert (GET_CODE (operands[1]) == MEM); operands[1] = XEXP (operands[1], 0); if (! call_operand (operands[1], Pmode)) @@ -4741,8 +4641,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (clobber (reg:DI 26))])] "" { - if (GET_CODE (operands[1]) != MEM) - abort (); + gcc_assert (GET_CODE (operands[1]) == MEM); operands[1] = XEXP (operands[1], 0); if (GET_CODE (operands[1]) != SYMBOL_REF && GET_CODE (operands[1]) != REG) @@ -4759,8 +4658,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (clobber (reg:DI 27))])] "" { - if (GET_CODE (operands[1]) != MEM) - abort (); + gcc_assert (GET_CODE (operands[1]) == MEM); operands[1] = XEXP (operands[1], 0); @@ -4771,11 +4669,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]); if (GET_CODE (operands[1]) == SYMBOL_REF) { - rtx linkage = alpha_need_linkage (XSTR (operands[1], 0), 0); + alpha_need_linkage (XSTR (operands[1], 0), 0); - emit_move_insn (gen_rtx_REG (Pmode, 26), gen_rtx_MEM (Pmode, linkage)); - operands[3] - = validize_mem (gen_rtx_MEM (Pmode, plus_constant (linkage, 8))); + operands[3] = const0_rtx; } else { @@ -4793,8 +4689,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (clobber (reg:DI 26))])] "" { - if (GET_CODE (operands[1]) != MEM) - abort (); + gcc_assert (GET_CODE (operands[1]) == MEM); operands[1] = XEXP (operands[1], 0); if (GET_CODE (operands[1]) != REG) @@ -4803,6 +4698,20 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]); }) +(define_insn "*call_osf_1_er_noreturn" + [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s")) + (match_operand 1 "" "")) + (use (reg:DI 29)) + (clobber (reg:DI 26))] + "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF + && find_reg_note (insn, REG_NORETURN, NULL_RTX)" + "@ + jsr $26,($27),0 + bsr $26,%0\t\t!samegp + ldq $27,%0($29)\t\t!literal!%#\;jsr $26,($27),%0\t\t!lituse_jsr!%#" + [(set_attr "type" "jsr") + (set_attr "length" "*,*,8")]) + (define_insn "*call_osf_1_er" [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s")) (match_operand 1 "" "")) @@ -4811,7 +4720,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" "@ jsr $26,(%0),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%* - bsr $26,$%0..ng + bsr $26,%0\t\t!samegp ldq $27,%0($29)\t\t!literal!%#\;jsr $26,($27),%0\t\t!lituse_jsr!%#\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*" [(set_attr "type" "jsr") (set_attr "length" "12,*,16")]) @@ -4824,14 +4733,15 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (use (reg:DI 29)) (clobber (reg:DI 26))])] "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed - && ! current_file_function_operand (operands[0], Pmode) - && peep2_regno_dead_p (1, 29)" + && ! samegp_function_operand (operands[0], Pmode) + && (peep2_regno_dead_p (1, 29) + || find_reg_note (insn, REG_NORETURN, NULL_RTX))" [(parallel [(call (mem:DI (match_dup 2)) (match_dup 1)) - (set (reg:DI 26) (plus:DI (pc) (const_int 4))) - (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE) + (use (reg:DI 29)) (use (match_dup 0)) - (use (match_dup 3))])] + (use (match_dup 3)) + (clobber (reg:DI 26))])] { if (CONSTANT_P (operands[0])) { @@ -4854,18 +4764,18 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (use (reg:DI 29)) (clobber (reg:DI 26))])] "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed - && ! current_file_function_operand (operands[0], Pmode) - && ! peep2_regno_dead_p (1, 29)" + && ! samegp_function_operand (operands[0], Pmode) + && ! (peep2_regno_dead_p (1, 29) + || find_reg_note (insn, REG_NORETURN, NULL_RTX))" [(parallel [(call (mem:DI (match_dup 2)) (match_dup 1)) - (set (reg:DI 26) (plus:DI (pc) (const_int 4))) - (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE) + (set (match_dup 5) + (unspec:DI [(match_dup 5) (match_dup 3)] UNSPEC_LDGP1)) (use (match_dup 0)) - (use (match_dup 4))]) - (set (reg:DI 29) - (unspec_volatile:DI [(reg:DI 26) (match_dup 3)] UNSPECV_LDGP1)) - (set (reg:DI 29) - (unspec:DI [(reg:DI 29) (match_dup 3)] UNSPEC_LDGP2))] + (use (match_dup 4)) + (clobber (reg:DI 26))]) + (set (match_dup 5) + (unspec:DI [(match_dup 5) (match_dup 3)] UNSPEC_LDGP2))] { if (CONSTANT_P (operands[0])) { @@ -4881,22 +4791,35 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" operands[4] = const0_rtx; } operands[3] = GEN_INT (alpha_next_sequence_number++); + operands[5] = pic_offset_table_rtx; }) -;; We add a blockage unspec_volatile to prevent insns from moving down -;; from above the call to in between the call and the ldah gpdisp. - -(define_insn "*call_osf_2_er" +(define_insn "*call_osf_2_er_nogp" [(call (mem:DI (match_operand:DI 0 "register_operand" "c")) (match_operand 1 "" "")) - (set (reg:DI 26) (plus:DI (pc) (const_int 4))) - (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE) + (use (reg:DI 29)) (use (match_operand 2 "" "")) - (use (match_operand 3 "const_int_operand" ""))] + (use (match_operand 3 "const_int_operand" "")) + (clobber (reg:DI 26))] "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" "jsr $26,(%0),%2%J3" [(set_attr "type" "jsr")]) +(define_insn "*call_osf_2_er" + [(call (mem:DI (match_operand:DI 0 "register_operand" "c")) + (match_operand 1 "" "")) + (set (reg:DI 29) + (unspec:DI [(reg:DI 29) (match_operand 4 "const_int_operand" "")] + UNSPEC_LDGP1)) + (use (match_operand 2 "" "")) + (use (match_operand 3 "const_int_operand" "")) + (clobber (reg:DI 26))] + "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" + "jsr $26,(%0),%2%J3\;ldah $29,0($26)\t\t!gpdisp!%4" + [(set_attr "type" "jsr") + (set_attr "cannot_copy" "true") + (set_attr "length" "8")]) + (define_insn "*call_osf_1_noreturn" [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s")) (match_operand 1 "" "")) @@ -4924,19 +4847,19 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" [(set_attr "type" "jsr") (set_attr "length" "12,*,16")]) -;; Note that the DEC assembler expands "jmp foo" with $at, which -;; doesn't do what we want. (define_insn "*sibcall_osf_1_er" [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s")) (match_operand 1 "" "")) (unspec [(reg:DI 29)] UNSPEC_SIBCALL)] "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" "@ - br $31,$%0..ng + br $31,%0\t\t!samegp ldq $27,%0($29)\t\t!literal!%#\;jmp $31,($27),%0\t\t!lituse_jsr!%#" [(set_attr "type" "jsr") (set_attr "length" "*,8")]) +;; Note that the DEC assembler expands "jmp foo" with $at, which +;; doesn't do what we want. (define_insn "*sibcall_osf_1" [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s")) (match_operand 1 "" "")) @@ -4960,17 +4883,30 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" [(set_attr "type" "jsr") (set_attr "length" "*,*,12")]) +; GAS relies on the order and position of instructions output below in order +; to generate relocs for VMS link to potentially optimize the call. +; Please do not molest. (define_insn "*call_vms_1" [(call (mem:DI (match_operand:DI 0 "call_operand" "r,s")) (match_operand 1 "" "")) - (use (match_operand:DI 2 "nonimmediate_operand" "r,m")) + (use (match_operand:DI 2 "nonmemory_operand" "r,n")) (use (reg:DI 25)) (use (reg:DI 26)) (clobber (reg:DI 27))] "TARGET_ABI_OPEN_VMS" - "@ - mov %2,$27\;jsr $26,0\;ldq $27,0($29) - ldq $27,%2\;jsr $26,%0\;ldq $27,0($29)" +{ + switch (which_alternative) + { + case 0: + return "mov %2,$27\;jsr $26,0\;ldq $27,0($29)"; + case 1: + operands [2] = alpha_use_linkage (operands [0], cfun->decl, 1, 0); + operands [3] = alpha_use_linkage (operands [0], cfun->decl, 0, 0); + return "ldq $26,%3\;ldq $27,%2\;jsr $26,%0\;ldq $27,0($29)"; + default: + gcc_unreachable (); + } +} [(set_attr "type" "jsr") (set_attr "length" "12,16")]) @@ -5018,7 +4954,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] "" "" - [(set_attr "length" "0")]) + [(set_attr "length" "0") + (set_attr "type" "none")]) (define_insn "jump" [(set (pc) @@ -5087,15 +5024,11 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" ;; Cache flush. Used by INITIALIZE_TRAMPOLINE. 0x86 is PAL_imb, but we don't ;; want to have to include pal.h in our .s file. -;; -;; Technically the type for call_pal is jsr, but we use that for determining -;; if we need a GP. Use ibr instead since it has the same EV5 scheduling -;; characteristics. (define_insn "imb" [(unspec_volatile [(const_int 0)] UNSPECV_IMB)] "" "call_pal 0x86" - [(set_attr "type" "ibr")]) + [(set_attr "type" "callpal")]) ;; BUGCHK is documented common to OSF/1 and VMS PALcode. ;; NT does not document anything at 0x81 -- presumably it would generate @@ -5105,7 +5038,44 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" [(trap_if (const_int 1) (const_int 0))] "!TARGET_ABI_WINDOWS_NT" "call_pal 0x81" - [(set_attr "type" "ibr")]) + [(set_attr "type" "callpal")]) + +;; For userland, we load the thread pointer from the TCB. +;; For the kernel, we load the per-cpu private value. + +(define_insn "load_tp" + [(set (match_operand:DI 0 "register_operand" "=v") + (unspec:DI [(const_int 0)] UNSPEC_TP))] + "TARGET_ABI_OSF" +{ + if (TARGET_TLS_KERNEL) + return "call_pal 0x32"; + else + return "call_pal 0x9e"; +} + [(set_attr "type" "callpal")]) + +;; For completeness, and possibly a __builtin function, here's how to +;; set the thread pointer. Since we don't describe enough of this +;; quantity for CSE, we have to use a volatile unspec, and then there's +;; not much point in creating an R16_REG register class. + +(define_expand "set_tp" + [(set (reg:DI 16) (match_operand:DI 0 "input_operand" "")) + (unspec_volatile [(reg:DI 16)] UNSPECV_SET_TP)] + "TARGET_ABI_OSF" + "") + +(define_insn "*set_tp" + [(unspec_volatile [(reg:DI 16)] UNSPECV_SET_TP)] + "TARGET_ABI_OSF" +{ + if (TARGET_TLS_KERNEL) + return "call_pal 0x31"; + else + return "call_pal 0x9f"; +} + [(set_attr "type" "callpal")]) ;; Finally, we have the basic data motion insns. The byte and word insns ;; are done via define_expand. Start with the floating-point insns, since @@ -5116,7 +5086,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r"))] "TARGET_FPREGS && ! TARGET_FIX && (register_operand (operands[0], SFmode) - || reg_or_fp0_operand (operands[1], SFmode))" + || reg_or_0_operand (operands[1], SFmode))" "@ cpys %R1,%R1,%0 ld%, %0,%1 @@ -5131,7 +5101,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))] "TARGET_FPREGS && TARGET_FIX && (register_operand (operands[0], SFmode) - || reg_or_fp0_operand (operands[1], SFmode))" + || reg_or_0_operand (operands[1], SFmode))" "@ cpys %R1,%R1,%0 ld%, %0,%1 @@ -5148,7 +5118,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (match_operand:SF 1 "input_operand" "rG,m,r"))] "! TARGET_FPREGS && (register_operand (operands[0], SFmode) - || reg_or_fp0_operand (operands[1], SFmode))" + || reg_or_0_operand (operands[1], SFmode))" "@ bis $31,%r1,%0 ldl %0,%1 @@ -5160,7 +5130,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r"))] "TARGET_FPREGS && ! TARGET_FIX && (register_operand (operands[0], DFmode) - || reg_or_fp0_operand (operands[1], DFmode))" + || reg_or_0_operand (operands[1], DFmode))" "@ cpys %R1,%R1,%0 ld%- %0,%1 @@ -5175,7 +5145,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))] "TARGET_FPREGS && TARGET_FIX && (register_operand (operands[0], DFmode) - || reg_or_fp0_operand (operands[1], DFmode))" + || reg_or_0_operand (operands[1], DFmode))" "@ cpys %R1,%R1,%0 ld%- %0,%1 @@ -5192,7 +5162,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (match_operand:DF 1 "input_operand" "rG,m,r"))] "! TARGET_FPREGS && (register_operand (operands[0], DFmode) - || reg_or_fp0_operand (operands[1], DFmode))" + || reg_or_0_operand (operands[1], DFmode))" "@ bis $31,%r1,%0 ldq %0,%1 @@ -5206,19 +5176,13 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o") (match_operand:TF 1 "input_operand" "roG,rG"))] "register_operand (operands[0], TFmode) - || reg_or_fp0_operand (operands[1], TFmode)" + || reg_or_0_operand (operands[1], TFmode)" "#" "reload_completed" [(set (match_dup 0) (match_dup 2)) (set (match_dup 1) (match_dup 3))] { - alpha_split_tfmode_pair (operands); - if (reg_overlap_mentioned_p (operands[0], operands[3])) - { - rtx tmp; - tmp = operands[0], operands[0] = operands[1], operands[1] = tmp; - tmp = operands[2], operands[2] = operands[3], operands[3] = tmp; - } + alpha_split_tmode_pair (operands, TFmode, true); }) (define_expand "movsf" @@ -5227,7 +5191,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" "" { if (GET_CODE (operands[0]) == MEM - && ! reg_or_fp0_operand (operands[1], SFmode)) + && ! reg_or_0_operand (operands[1], SFmode)) operands[1] = force_reg (SFmode, operands[1]); }) @@ -5237,7 +5201,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" "" { if (GET_CODE (operands[0]) == MEM - && ! reg_or_fp0_operand (operands[1], DFmode)) + && ! reg_or_0_operand (operands[1], DFmode)) operands[1] = force_reg (DFmode, operands[1]); }) @@ -5247,70 +5211,29 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" "" { if (GET_CODE (operands[0]) == MEM - && ! reg_or_fp0_operand (operands[1], TFmode)) + && ! reg_or_0_operand (operands[1], TFmode)) operands[1] = force_reg (TFmode, operands[1]); }) -(define_insn "*movsi_nofix" - [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*f,*f,m") - (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f"))] - "(TARGET_ABI_OSF || TARGET_ABI_UNICOSMK) && ! TARGET_FIX - && (register_operand (operands[0], SImode) - || reg_or_0_operand (operands[1], SImode))" - "@ - bis $31,%r1,%0 - lda %0,%1($31) - ldah %0,%h1($31) - ldl %0,%1 - stl %r1,%0 - cpys %R1,%R1,%0 - ld%, %0,%1 - st%, %R1,%0" - [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst")]) - -(define_insn "*movsi_fix" - [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*f,*f,m,r,*f") - (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f,*f,r"))] - "TARGET_ABI_OSF && TARGET_FIX +(define_insn "*movsi" + [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m") + (match_operand:SI 1 "input_operand" "rJ,K,L,n,m,rJ"))] + "(TARGET_ABI_OSF || TARGET_ABI_UNICOSMK) && (register_operand (operands[0], SImode) || reg_or_0_operand (operands[1], SImode))" "@ bis $31,%r1,%0 lda %0,%1($31) ldah %0,%h1($31) + # ldl %0,%1 - stl %r1,%0 - cpys %R1,%R1,%0 - ld%, %0,%1 - st%, %R1,%0 - ftois %1,%0 - itofs %1,%0" - [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst,ftoi,itof")]) - -(define_insn "*movsi_nt_vms_nofix" - [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,m") - (match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,m,*f"))] - "(TARGET_ABI_WINDOWS_NT || TARGET_ABI_OPEN_VMS) - && !TARGET_FIX - && (register_operand (operands[0], SImode) - || reg_or_0_operand (operands[1], SImode))" - "@ - bis $31,%1,%0 - lda %0,%1 - ldah %0,%h1 - lda %0,%1 - ldl %0,%1 - stl %r1,%0 - cpys %R1,%R1,%0 - ld%, %0,%1 - st%, %R1,%0" - [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")]) + stl %r1,%0" + [(set_attr "type" "ilog,iadd,iadd,multi,ild,ist")]) -(define_insn "*movsi_nt_vms_fix" - [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,m,r,*f") - (match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,m,*f,*f,r"))] +(define_insn "*movsi_nt_vms" + [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m") + (match_operand:SI 1 "input_operand" "rJ,K,L,s,n,m,rJ"))] "(TARGET_ABI_WINDOWS_NT || TARGET_ABI_OPEN_VMS) - && TARGET_FIX && (register_operand (operands[0], SImode) || reg_or_0_operand (operands[1], SImode))" "@ @@ -5318,14 +5241,10 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" lda %0,%1 ldah %0,%h1 lda %0,%1 + # ldl %0,%1 - stl %r1,%0 - cpys %R1,%R1,%0 - ld%, %0,%1 - st%, %R1,%0 - ftois %1,%0 - itofs %1,%0" - [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")]) + stl %r1,%0" + [(set_attr "type" "ilog,iadd,iadd,ldsym,multi,ild,ist")]) (define_insn "*movhi_nobwx" [(set (match_operand:HI 0 "register_operand" "=r,r") @@ -5392,15 +5311,11 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_split [(set (match_operand:SI 0 "register_operand" "") - (match_operand:SI 1 "const_int_operand" ""))] - "! add_operand (operands[1], SImode)" - [(set (match_dup 0) (match_dup 2)) - (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))] + (match_operand:SI 1 "non_add_const_operand" ""))] + "" + [(const_int 0)] { - rtx tem - = alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 2); - - if (tem == operands[0]) + if (alpha_split_const_mov (SImode, operands)) DONE; else FAIL; @@ -5408,9 +5323,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" ;; Split the load of an address into a four-insn sequence on Unicos/Mk. ;; Always generate a REG_EQUAL note for the last instruction to facilitate -;; optimisations. If the symbolic operand is a label_ref, generate REG_LABEL -;; notes and update LABEL_NUSES because this is not done automatically. -;; Labels may be incorrectly deleted if we don't do this. +;; optimizations. If the symbolic operand is a label_ref, generate +;; REG_LABEL_OPERAND notes and update LABEL_NUSES because this is not done +;; automatically. Labels may be incorrectly deleted if we don't do this. ;; ;; Describing what the individual instructions do correctly is too complicated ;; so use UNSPECs for each of the three parts of an address. @@ -5427,18 +5342,18 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32))); insn2 = emit_insn (gen_umk_lalm (operands[0], operands[0], operands[1])); insn3 = emit_insn (gen_umk_lal (operands[0], operands[0], operands[1])); - REG_NOTES (insn3) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1], - REG_NOTES (insn3)); + set_unique_reg_note (insn3, REG_EQUAL, operands[1]); + if (GET_CODE (operands[1]) == LABEL_REF) { rtx label; label = XEXP (operands[1], 0); - REG_NOTES (insn1) = gen_rtx_EXPR_LIST (REG_LABEL, label, + REG_NOTES (insn1) = gen_rtx_EXPR_LIST (REG_LABEL_OPERAND, label, REG_NOTES (insn1)); - REG_NOTES (insn2) = gen_rtx_EXPR_LIST (REG_LABEL, label, + REG_NOTES (insn2) = gen_rtx_EXPR_LIST (REG_LABEL_OPERAND, label, REG_NOTES (insn2)); - REG_NOTES (insn3) = gen_rtx_EXPR_LIST (REG_LABEL, label, + REG_NOTES (insn3) = gen_rtx_EXPR_LIST (REG_LABEL_OPERAND, label, REG_NOTES (insn3)); LABEL_NUSES (label) += 3; } @@ -5497,7 +5412,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" return "lda %0,%2(%1)\t\t!gprel"; else return "lda %0,%2(%1)\t\t!gprellow"; -}) +} + [(set_attr "usegp" "yes")]) (define_split [(set (match_operand:DI 0 "register_operand" "") @@ -5519,7 +5435,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_split [(match_operand 0 "some_small_symbolic_operand" "")] - "TARGET_EXPLICIT_RELOCS && reload_completed" + "" [(match_dup 0)] "operands[0] = split_small_symbolic_operand (operands[0]);") @@ -5550,44 +5466,80 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (const_int 0)] UNSPEC_LITERAL))] "operands[2] = pic_offset_table_rtx;") -;; With RTL inlining, at -O3, rtl is generated, stored, then actually -;; compiled at the end of compilation. In the meantime, someone can -;; re-encode-section-info on some symbol changing it e.g. from global -;; to local-not-small. If this happens, we'd have emitted a plain -;; load rather than a high+losum load and not recognize the insn. -;; -;; So if rtl inlining is in effect, we delay the global/not-global -;; decision until rest_of_compilation by wrapping it in an UNSPEC_SYMBOL. +(define_insn "movdi_er_tlsgd" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(match_operand:DI 1 "register_operand" "r") + (match_operand:DI 2 "symbolic_operand" "") + (match_operand 3 "const_int_operand" "")] + UNSPEC_TLSGD))] + "HAVE_AS_TLS" +{ + if (INTVAL (operands[3]) == 0) + return "lda %0,%2(%1)\t\t!tlsgd"; + else + return "lda %0,%2(%1)\t\t!tlsgd!%3"; +}) -(define_insn_and_split "movdi_er_maybe_g" +(define_insn "movdi_er_tlsldm" [(set (match_operand:DI 0 "register_operand" "=r") - (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] - UNSPEC_SYMBOL))] - "TARGET_EXPLICIT_RELOCS && flag_inline_functions" - "#" - "" - [(set (match_dup 0) (match_dup 1))] + (unspec:DI [(match_operand:DI 1 "register_operand" "r") + (match_operand 2 "const_int_operand" "")] + UNSPEC_TLSLDM))] + "HAVE_AS_TLS" { - if (local_symbolic_operand (operands[1], Pmode) - && !small_symbolic_operand (operands[1], Pmode)) - { - rtx subtarget = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode); - rtx tmp; + if (INTVAL (operands[2]) == 0) + return "lda %0,%&(%1)\t\t!tlsldm"; + else + return "lda %0,%&(%1)\t\t!tlsldm!%2"; +}) - tmp = gen_rtx_HIGH (Pmode, operands[1]); - if (reload_completed) - tmp = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, tmp); - emit_insn (gen_rtx_SET (VOIDmode, subtarget, tmp)); +(define_insn "*movdi_er_gotdtp" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(match_operand:DI 1 "register_operand" "r") + (match_operand:DI 2 "symbolic_operand" "")] + UNSPEC_DTPREL))] + "HAVE_AS_TLS" + "ldq %0,%2(%1)\t\t!gotdtprel" + [(set_attr "type" "ild") + (set_attr "usegp" "yes")]) - tmp = gen_rtx_LO_SUM (Pmode, subtarget, operands[1]); - emit_insn (gen_rtx_SET (VOIDmode, operands[0], tmp)); - DONE; - } +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "gotdtp_symbolic_operand" ""))] + "HAVE_AS_TLS && reload_completed" + [(set (match_dup 0) + (unspec:DI [(match_dup 2) + (match_dup 1)] UNSPEC_DTPREL))] +{ + operands[1] = XVECEXP (XEXP (operands[1], 0), 0, 0); + operands[2] = pic_offset_table_rtx; +}) + +(define_insn "*movdi_er_gottp" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(match_operand:DI 1 "register_operand" "r") + (match_operand:DI 2 "symbolic_operand" "")] + UNSPEC_TPREL))] + "HAVE_AS_TLS" + "ldq %0,%2(%1)\t\t!gottprel" + [(set_attr "type" "ild") + (set_attr "usegp" "yes")]) + +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "gottp_symbolic_operand" ""))] + "HAVE_AS_TLS && reload_completed" + [(set (match_dup 0) + (unspec:DI [(match_dup 2) + (match_dup 1)] UNSPEC_TPREL))] +{ + operands[1] = XVECEXP (XEXP (operands[1], 0), 0, 0); + operands[2] = pic_offset_table_rtx; }) (define_insn "*movdi_er_nofix" - [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,*f,*f,Q") - (match_operand:DI 1 "input_operand" "rJ,K,L,T,s,m,rJ,*fJ,Q,*f"))] + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,r,m,*f,*f,Q") + (match_operand:DI 1 "input_operand" "rJ,K,L,T,s,n,m,rJ,*fJ,Q,*f"))] "TARGET_EXPLICIT_RELOCS && ! TARGET_FIX && (register_operand (operands[0], DImode) || reg_or_0_operand (operands[1], DImode))" @@ -5597,20 +5549,22 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" ldah %0,%h1($31) # # + # ldq%A1 %0,%1 stq%A0 %r1,%0 fmov %R1,%0 ldt %0,%1 stt %R1,%0" - [(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")]) + [(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,multi,ild,ist,fcpys,fld,fst") + (set_attr "usegp" "*,*,*,yes,*,*,*,*,*,*,*")]) ;; The 'U' constraint matches symbolic operands on Unicos/Mk. Those should ;; have been split up by the rules above but we shouldn't reject the ;; possibility of them getting through. (define_insn "*movdi_nofix" - [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,*f,*f,Q") - (match_operand:DI 1 "input_operand" "rJ,K,L,U,s,m,rJ,*fJ,Q,*f"))] + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,r,m,*f,*f,Q") + (match_operand:DI 1 "input_operand" "rJ,K,L,U,s,n,m,rJ,*fJ,Q,*f"))] "! TARGET_FIX && (register_operand (operands[0], DImode) || reg_or_0_operand (operands[1], DImode))" @@ -5620,19 +5574,20 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" ldah %0,%h1($31) laum %0,%t1($31)\;sll %0,32,%0\;lalm %0,%t1(%0)\;lal %0,%t1(%0) lda %0,%1 + # ldq%A1 %0,%1 stq%A0 %r1,%0 cpys %R1,%R1,%0 ldt %0,%1 stt %R1,%0" - [(set_attr "type" "ilog,iadd,iadd,ldsym,ldsym,ild,ist,fcpys,fld,fst") - (set_attr "length" "*,*,*,16,*,*,*,*,*,*")]) + [(set_attr "type" "ilog,iadd,iadd,ldsym,ldsym,multi,ild,ist,fcpys,fld,fst") + (set_attr "length" "*,*,*,16,*,*,*,*,*,*,*")]) (define_insn "*movdi_er_fix" [(set (match_operand:DI 0 "nonimmediate_operand" - "=r,r,r,r,r,r, m, *f,*f, Q, r,*f") + "=r,r,r,r,r,r,r, m, *f,*f, Q, r,*f") (match_operand:DI 1 "input_operand" - "rJ,K,L,T,s,m,rJ,*fJ, Q,*f,*f, r"))] + "rJ,K,L,T,s,n,m,rJ,*fJ, Q,*f,*f, r"))] "TARGET_EXPLICIT_RELOCS && TARGET_FIX && (register_operand (operands[0], DImode) || reg_or_0_operand (operands[1], DImode))" @@ -5642,6 +5597,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" ldah %0,%h1($31) # # + # ldq%A1 %0,%1 stq%A0 %r1,%0 fmov %R1,%0 @@ -5649,11 +5605,12 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" stt %R1,%0 ftoit %1,%0 itoft %1,%0" - [(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")]) + [(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,multi,ild,ist,fcpys,fld,fst,ftoi,itof") + (set_attr "usegp" "*,*,*,yes,*,*,*,*,*,*,*,*,*")]) (define_insn "*movdi_fix" - [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,Q,r,*f") - (match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,Q,*f,*f,r"))] + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,*f,*f,Q,r,*f") + (match_operand:DI 1 "input_operand" "rJ,K,L,s,n,m,rJ,*fJ,Q,*f,*f,r"))] "! TARGET_EXPLICIT_RELOCS && TARGET_FIX && (register_operand (operands[0], DImode) || reg_or_0_operand (operands[1], DImode))" @@ -5662,6 +5619,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" lda %0,%1($31) ldah %0,%h1($31) lda %0,%1 + # ldq%A1 %0,%1 stq%A0 %r1,%0 cpys %R1,%R1,%0 @@ -5669,11 +5627,11 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" stt %R1,%0 ftoit %1,%0 itoft %1,%0" - [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")]) + [(set_attr "type" "ilog,iadd,iadd,ldsym,multi,ild,ist,fcpys,fld,fst,ftoi,itof")]) ;; VMS needs to set up "vms_base_regno" for unwinding. This move ;; often appears dead to the life analysis code, at which point we -;; abort for emitting dead prologue instructions. Force this live. +;; die for emitting dead prologue instructions. Force this live. (define_insn "force_movdi" [(set (match_operand:DI 0 "register_operand" "=r") @@ -5700,20 +5658,90 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_split [(set (match_operand:DI 0 "register_operand" "") - (match_operand:DI 1 "const_int_operand" ""))] - "! add_operand (operands[1], DImode)" - [(set (match_dup 0) (match_dup 2)) - (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))] + (match_operand:DI 1 "non_add_const_operand" ""))] + "" + [(const_int 0)] { - rtx tem - = alpha_emit_set_const (operands[0], DImode, INTVAL (operands[1]), 2); - - if (tem == operands[0]) + if (alpha_split_const_mov (DImode, operands)) DONE; else FAIL; }) +;; We need to prevent reload from splitting TImode moves, because it +;; might decide to overwrite a pointer with the value it points to. +;; In that case we have to do the loads in the appropriate order so +;; that the pointer is not destroyed too early. + +(define_insn_and_split "*movti_internal" + [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o") + (match_operand:TI 1 "input_operand" "roJ,rJ"))] + "(register_operand (operands[0], TImode) + /* Prevent rematerialization of constants. */ + && ! CONSTANT_P (operands[1])) + || reg_or_0_operand (operands[1], TImode)" + "#" + "reload_completed" + [(set (match_dup 0) (match_dup 2)) + (set (match_dup 1) (match_dup 3))] +{ + alpha_split_tmode_pair (operands, TImode, true); +}) + +(define_expand "movti" + [(set (match_operand:TI 0 "nonimmediate_operand" "") + (match_operand:TI 1 "general_operand" ""))] + "" +{ + if (GET_CODE (operands[0]) == MEM + && ! reg_or_0_operand (operands[1], TImode)) + operands[1] = force_reg (TImode, operands[1]); + + if (operands[1] == const0_rtx) + ; + /* We must put 64-bit constants in memory. We could keep the + 32-bit constants in TImode and rely on the splitter, but + this doesn't seem to be worth the pain. */ + else if (GET_CODE (operands[1]) == CONST_INT + || GET_CODE (operands[1]) == CONST_DOUBLE) + { + rtx in[2], out[2], target; + + gcc_assert (can_create_pseudo_p ()); + + split_double (operands[1], &in[0], &in[1]); + + if (in[0] == const0_rtx) + out[0] = const0_rtx; + else + { + out[0] = gen_reg_rtx (DImode); + emit_insn (gen_movdi (out[0], in[0])); + } + + if (in[1] == const0_rtx) + out[1] = const0_rtx; + else + { + out[1] = gen_reg_rtx (DImode); + emit_insn (gen_movdi (out[1], in[1])); + } + + if (GET_CODE (operands[0]) != REG) + target = gen_reg_rtx (TImode); + else + target = operands[0]; + + emit_insn (gen_movdi (operand_subword (target, 0, 0, TImode), out[0])); + emit_insn (gen_movdi (operand_subword (target, 1, 0, TImode), out[1])); + + if (target != operands[0]) + emit_insn (gen_rtx_SET (VOIDmode, operands[0], target)); + + DONE; + } +}) + ;; These are the partial-word cases. ;; ;; First we have the code to load an aligned word. Operand 0 is the register @@ -5726,7 +5754,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_expand "aligned_loadqi" [(set (match_operand:SI 3 "register_operand" "") (match_operand:SI 1 "memory_operand" "")) - (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0) + (set (match_operand:DI 0 "register_operand" "") (zero_extract:DI (subreg:DI (match_dup 3) 0) (const_int 8) (match_operand:DI 2 "const_int_operand" "")))] @@ -5737,7 +5765,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (define_expand "aligned_loadhi" [(set (match_operand:SI 3 "register_operand" "") (match_operand:SI 1 "memory_operand" "")) - (set (subreg:DI (match_operand:HI 0 "register_operand" "") 0) + (set (match_operand:DI 0 "register_operand" "") (zero_extract:DI (subreg:DI (match_dup 3) 0) (const_int 16) (match_operand:DI 2 "const_int_operand" "")))] @@ -5753,7 +5781,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" ;; operand 3 can overlap the input and output registers. (define_expand "unaligned_loadqi" - [(use (match_operand:QI 0 "register_operand" "")) + [(use (match_operand:DI 0 "register_operand" "")) (use (match_operand:DI 1 "address_operand" "")) (use (match_operand:DI 2 "register_operand" "")) (use (match_operand:DI 3 "register_operand" ""))] @@ -5774,7 +5802,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (const_int -8)))) (set (match_operand:DI 3 "register_operand" "") (match_dup 1)) - (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0) + (set (match_operand:DI 0 "register_operand" "") (zero_extract:DI (match_dup 2) (const_int 8) (ashift:DI (match_dup 3) (const_int 3))))] @@ -5787,7 +5815,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (const_int -8)))) (set (match_operand:DI 3 "register_operand" "") (match_dup 1)) - (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0) + (set (match_operand:DI 0 "register_operand" "") (zero_extract:DI (match_dup 2) (const_int 8) (minus:DI @@ -5797,7 +5825,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" "") (define_expand "unaligned_loadhi" - [(use (match_operand:QI 0 "register_operand" "")) + [(use (match_operand:DI 0 "register_operand" "")) (use (match_operand:DI 1 "address_operand" "")) (use (match_operand:DI 2 "register_operand" "")) (use (match_operand:DI 3 "register_operand" ""))] @@ -5818,7 +5846,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (const_int -8)))) (set (match_operand:DI 3 "register_operand" "") (match_dup 1)) - (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0) + (set (match_operand:DI 0 "register_operand" "") (zero_extract:DI (match_dup 2) (const_int 16) (ashift:DI (match_dup 3) (const_int 3))))] @@ -5831,7 +5859,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (const_int -8)))) (set (match_operand:DI 3 "register_operand" "") (plus:DI (match_dup 1) (const_int 1))) - (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0) + (set (match_operand:DI 0 "register_operand" "") (zero_extract:DI (match_dup 2) (const_int 16) (minus:DI @@ -5971,7 +5999,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (mem:DI (and:DI (match_operand:DI 0 "address_operand" "") (const_int -8)))) (set (match_operand:DI 2 "register_operand" "") - (plus:DI (match_dup 0) (const_int 1))) + (plus:DI (match_dup 5) (const_int 1))) (set (match_dup 3) (and:DI (not:DI (ashift:DI (const_int 65535) @@ -5986,7 +6014,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (set (mem:DI (and:DI (match_dup 0) (const_int -8))) (match_dup 4))] "WORDS_BIG_ENDIAN" - "") + "operands[5] = force_reg (DImode, operands[0]);") ;; Here are the define_expand's for QI and HI moves that use the above ;; patterns. We have the normal sets, plus the ones that need scratch @@ -6014,148 +6042,120 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" DONE; }) -;; Here are the versions for reload. Note that in the unaligned cases -;; we know that the operand must not be a pseudo-register because stack -;; slots are always aligned references. - -(define_expand "reload_inqi" - [(parallel [(match_operand:QI 0 "register_operand" "=r") - (match_operand:QI 1 "any_memory_operand" "m") - (match_operand:TI 2 "register_operand" "=&r")])] - "! TARGET_BWX" +;; We need to hook into the extra support that we have for HImode +;; reloads when BWX insns are not available. +(define_expand "movcqi" + [(set (match_operand:CQI 0 "nonimmediate_operand" "") + (match_operand:CQI 1 "general_operand" ""))] + "!TARGET_BWX" { - rtx scratch, seq; - - if (GET_CODE (operands[1]) != MEM) - abort (); - - if (aligned_memory_operand (operands[1], QImode)) + if (GET_CODE (operands[0]) == CONCAT || GET_CODE (operands[1]) == CONCAT) + ; + else if (!any_memory_operand (operands[0], CQImode)) { - seq = gen_reload_inqi_help (operands[0], operands[1], - gen_rtx_REG (SImode, REGNO (operands[2]))); + if (!any_memory_operand (operands[1], CQImode)) + { + emit_move_insn (gen_lowpart (HImode, operands[0]), + gen_lowpart (HImode, operands[1])); + DONE; + } + if (aligned_memory_operand (operands[1], CQImode)) + { + bool done; + do_aligned1: + operands[1] = gen_lowpart (HImode, operands[1]); + do_aligned2: + operands[0] = gen_lowpart (HImode, operands[0]); + done = alpha_expand_mov_nobwx (HImode, operands); + gcc_assert (done); + DONE; + } } - else + else if (aligned_memory_operand (operands[0], CQImode)) { - rtx addr; - - /* It is possible that one of the registers we got for operands[2] - might coincide with that of operands[0] (which is why we made - it TImode). Pick the other one to use as our scratch. */ - if (REGNO (operands[0]) == REGNO (operands[2])) - scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1); - else - scratch = gen_rtx_REG (DImode, REGNO (operands[2])); - - addr = get_unaligned_address (operands[1], 0); - seq = gen_unaligned_loadqi (operands[0], addr, scratch, - gen_rtx_REG (DImode, REGNO (operands[0]))); - alpha_set_memflags (seq, operands[1]); + if (MEM_P (operands[1])) + { + rtx x = gen_reg_rtx (HImode); + emit_move_insn (gen_lowpart (CQImode, x), operands[1]); + operands[1] = x; + goto do_aligned2; + } + goto do_aligned1; } - emit_insn (seq); + + gcc_assert (!reload_in_progress); + emit_move_complex_parts (operands[0], operands[1]); DONE; }) -(define_expand "reload_inhi" - [(parallel [(match_operand:HI 0 "register_operand" "=r") - (match_operand:HI 1 "any_memory_operand" "m") +;; Here are the versions for reload. +;; +;; The aligned input case is recognized early in alpha_secondary_reload +;; in order to avoid allocating an unnecessary scratch register. +;; +;; Note that in the unaligned cases we know that the operand must not be +;; a pseudo-register because stack slots are always aligned references. + +(define_expand "reload_in" + [(parallel [(match_operand:RELOAD12 0 "register_operand" "=r") + (match_operand:RELOAD12 1 "any_memory_operand" "m") (match_operand:TI 2 "register_operand" "=&r")])] - "! TARGET_BWX" + "!TARGET_BWX" { - rtx scratch, seq; - - if (GET_CODE (operands[1]) != MEM) - abort (); + rtx scratch, seq, addr; + unsigned regno = REGNO (operands[2]); - if (aligned_memory_operand (operands[1], HImode)) - { - seq = gen_reload_inhi_help (operands[0], operands[1], - gen_rtx_REG (SImode, REGNO (operands[2]))); - } - else - { - rtx addr; + /* It is possible that one of the registers we got for operands[2] + might coincide with that of operands[0] (which is why we made + it TImode). Pick the other one to use as our scratch. */ + if (regno == REGNO (operands[0])) + regno++; + scratch = gen_rtx_REG (DImode, regno); - /* It is possible that one of the registers we got for operands[2] - might coincide with that of operands[0] (which is why we made - it TImode). Pick the other one to use as our scratch. */ - if (REGNO (operands[0]) == REGNO (operands[2])) - scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1); - else - scratch = gen_rtx_REG (DImode, REGNO (operands[2])); + addr = get_unaligned_address (operands[1]); + operands[0] = gen_rtx_REG (DImode, REGNO (operands[0])); + seq = gen_unaligned_load (operands[0], addr, + scratch, operands[0]); + alpha_set_memflags (seq, operands[1]); - addr = get_unaligned_address (operands[1], 0); - seq = gen_unaligned_loadhi (operands[0], addr, scratch, - gen_rtx_REG (DImode, REGNO (operands[0]))); - alpha_set_memflags (seq, operands[1]); - } emit_insn (seq); DONE; }) -(define_expand "reload_outqi" - [(parallel [(match_operand:QI 0 "any_memory_operand" "=m") - (match_operand:QI 1 "register_operand" "r") +(define_expand "reload_out" + [(parallel [(match_operand:RELOAD12 0 "any_memory_operand" "=m") + (match_operand:RELOAD12 1 "register_operand" "r") (match_operand:TI 2 "register_operand" "=&r")])] "! TARGET_BWX" { - if (GET_CODE (operands[0]) != MEM) - abort (); + unsigned regno = REGNO (operands[2]); - if (aligned_memory_operand (operands[0], QImode)) - { - emit_insn (gen_reload_outqi_help - (operands[0], operands[1], - gen_rtx_REG (SImode, REGNO (operands[2])), - gen_rtx_REG (SImode, REGNO (operands[2]) + 1))); - } - else + if (mode == CQImode) { - rtx addr = get_unaligned_address (operands[0], 0); - rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2])); - rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1); - rtx scratch3 = scratch1; - rtx seq; - - if (GET_CODE (addr) == REG) - scratch1 = addr; - - seq = gen_unaligned_storeqi (addr, operands[1], scratch1, - scratch2, scratch3); - alpha_set_memflags (seq, operands[0]); - emit_insn (seq); + operands[0] = gen_lowpart (HImode, operands[0]); + operands[1] = gen_lowpart (HImode, operands[1]); } - DONE; -}) - -(define_expand "reload_outhi" - [(parallel [(match_operand:HI 0 "any_memory_operand" "=m") - (match_operand:HI 1 "register_operand" "r") - (match_operand:TI 2 "register_operand" "=&r")])] - "! TARGET_BWX" -{ - if (GET_CODE (operands[0]) != MEM) - abort (); - if (aligned_memory_operand (operands[0], HImode)) + if (aligned_memory_operand (operands[0], mode)) { - emit_insn (gen_reload_outhi_help + emit_insn (gen_reload_out_aligned (operands[0], operands[1], - gen_rtx_REG (SImode, REGNO (operands[2])), - gen_rtx_REG (SImode, REGNO (operands[2]) + 1))); + gen_rtx_REG (SImode, regno), + gen_rtx_REG (SImode, regno + 1))); } else { - rtx addr = get_unaligned_address (operands[0], 0); - rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2])); - rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1); + rtx addr = get_unaligned_address (operands[0]); + rtx scratch1 = gen_rtx_REG (DImode, regno); + rtx scratch2 = gen_rtx_REG (DImode, regno + 1); rtx scratch3 = scratch1; rtx seq; if (GET_CODE (addr) == REG) scratch1 = addr; - seq = gen_unaligned_storehi (addr, operands[1], scratch1, - scratch2, scratch3); + seq = gen_unaligned_store (addr, operands[1], scratch1, + scratch2, scratch3); alpha_set_memflags (seq, operands[0]); emit_insn (seq); } @@ -6166,72 +6166,30 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" ;; always get a proper address for a stack slot during reload_foo ;; expansion, so we must delay our address manipulations until after. -(define_insn "reload_inqi_help" - [(set (match_operand:QI 0 "register_operand" "=r") - (match_operand:QI 1 "memory_operand" "m")) - (clobber (match_operand:SI 2 "register_operand" "=r"))] - "! TARGET_BWX && (reload_in_progress || reload_completed)" - "#") - -(define_insn "reload_inhi_help" - [(set (match_operand:HI 0 "register_operand" "=r") - (match_operand:HI 1 "memory_operand" "m")) - (clobber (match_operand:SI 2 "register_operand" "=r"))] - "! TARGET_BWX && (reload_in_progress || reload_completed)" - "#") - -(define_insn "reload_outqi_help" - [(set (match_operand:QI 0 "memory_operand" "=m") - (match_operand:QI 1 "register_operand" "r")) - (clobber (match_operand:SI 2 "register_operand" "=r")) - (clobber (match_operand:SI 3 "register_operand" "=r"))] - "! TARGET_BWX && (reload_in_progress || reload_completed)" - "#") - -(define_insn "reload_outhi_help" - [(set (match_operand:HI 0 "memory_operand" "=m") - (match_operand:HI 1 "register_operand" "r")) - (clobber (match_operand:SI 2 "register_operand" "=r")) - (clobber (match_operand:SI 3 "register_operand" "=r"))] - "! TARGET_BWX && (reload_in_progress || reload_completed)" - "#") - -(define_split - [(set (match_operand:QI 0 "register_operand" "") - (match_operand:QI 1 "memory_operand" "")) - (clobber (match_operand:SI 2 "register_operand" ""))] - "! TARGET_BWX && reload_completed" - [(const_int 0)] -{ - rtx aligned_mem, bitnum; - get_aligned_mem (operands[1], &aligned_mem, &bitnum); - - emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum, - operands[2])); - DONE; -}) - -(define_split - [(set (match_operand:HI 0 "register_operand" "") - (match_operand:HI 1 "memory_operand" "")) - (clobber (match_operand:SI 2 "register_operand" ""))] - "! TARGET_BWX && reload_completed" +(define_insn_and_split "reload_in_aligned" + [(set (match_operand:I12MODE 0 "register_operand" "=r") + (match_operand:I12MODE 1 "memory_operand" "m"))] + "!TARGET_BWX && (reload_in_progress || reload_completed)" + "#" + "!TARGET_BWX && reload_completed" [(const_int 0)] { rtx aligned_mem, bitnum; get_aligned_mem (operands[1], &aligned_mem, &bitnum); - - emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum, - operands[2])); + emit_insn (gen_aligned_load + (gen_lowpart (DImode, operands[0]), aligned_mem, bitnum, + gen_rtx_REG (SImode, REGNO (operands[0])))); DONE; }) -(define_split - [(set (match_operand:QI 0 "memory_operand" "") - (match_operand:QI 1 "register_operand" "")) - (clobber (match_operand:SI 2 "register_operand" "")) - (clobber (match_operand:SI 3 "register_operand" ""))] - "! TARGET_BWX && reload_completed" +(define_insn_and_split "reload_out_aligned" + [(set (match_operand:I12MODE 0 "memory_operand" "=m") + (match_operand:I12MODE 1 "register_operand" "r")) + (clobber (match_operand:SI 2 "register_operand" "=r")) + (clobber (match_operand:SI 3 "register_operand" "=r"))] + "!TARGET_BWX && (reload_in_progress || reload_completed)" + "#" + "!TARGET_BWX && reload_completed" [(const_int 0)] { rtx aligned_mem, bitnum; @@ -6240,21 +6198,214 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" operands[2], operands[3])); DONE; }) + +;; Vector operations + +(define_mode_iterator VEC [V8QI V4HI V2SI]) + +(define_expand "mov" + [(set (match_operand:VEC 0 "nonimmediate_operand" "") + (match_operand:VEC 1 "general_operand" ""))] + "" +{ + if (alpha_expand_mov (mode, operands)) + DONE; +}) (define_split - [(set (match_operand:HI 0 "memory_operand" "") - (match_operand:HI 1 "register_operand" "")) - (clobber (match_operand:SI 2 "register_operand" "")) - (clobber (match_operand:SI 3 "register_operand" ""))] - "! TARGET_BWX && reload_completed" + [(set (match_operand:VEC 0 "register_operand" "") + (match_operand:VEC 1 "non_zero_const_operand" ""))] + "" [(const_int 0)] { - rtx aligned_mem, bitnum; - get_aligned_mem (operands[0], &aligned_mem, &bitnum); - emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum, - operands[2], operands[3])); + if (alpha_split_const_mov (mode, operands)) + DONE; + else + FAIL; +}) + + +(define_expand "movmisalign" + [(set (match_operand:VEC 0 "nonimmediate_operand" "") + (match_operand:VEC 1 "general_operand" ""))] + "" +{ + alpha_expand_movmisalign (mode, operands); DONE; }) + +(define_insn "*mov_fix" + [(set (match_operand:VEC 0 "nonimmediate_operand" "=r,r,r,m,*f,*f,m,r,*f") + (match_operand:VEC 1 "input_operand" "rW,i,m,rW,*fW,m,*f,*f,r"))] + "TARGET_FIX + && (register_operand (operands[0], mode) + || reg_or_0_operand (operands[1], mode))" + "@ + bis $31,%r1,%0 + # + ldq %0,%1 + stq %r1,%0 + cpys %R1,%R1,%0 + ldt %0,%1 + stt %R1,%0 + ftoit %1,%0 + itoft %1,%0" + [(set_attr "type" "ilog,multi,ild,ist,fcpys,fld,fst,ftoi,itof")]) + +(define_insn "*mov_nofix" + [(set (match_operand:VEC 0 "nonimmediate_operand" "=r,r,r,m,*f,*f,m") + (match_operand:VEC 1 "input_operand" "rW,i,m,rW,*fW,m,*f"))] + "! TARGET_FIX + && (register_operand (operands[0], mode) + || reg_or_0_operand (operands[1], mode))" + "@ + bis $31,%r1,%0 + # + ldq %0,%1 + stq %r1,%0 + cpys %R1,%R1,%0 + ldt %0,%1 + stt %R1,%0" + [(set_attr "type" "ilog,multi,ild,ist,fcpys,fld,fst")]) + +(define_insn "uminv8qi3" + [(set (match_operand:V8QI 0 "register_operand" "=r") + (umin:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW") + (match_operand:V8QI 2 "reg_or_0_operand" "rW")))] + "TARGET_MAX" + "minub8 %r1,%r2,%0" + [(set_attr "type" "mvi")]) + +(define_insn "sminv8qi3" + [(set (match_operand:V8QI 0 "register_operand" "=r") + (smin:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW") + (match_operand:V8QI 2 "reg_or_0_operand" "rW")))] + "TARGET_MAX" + "minsb8 %r1,%r2,%0" + [(set_attr "type" "mvi")]) + +(define_insn "uminv4hi3" + [(set (match_operand:V4HI 0 "register_operand" "=r") + (umin:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW") + (match_operand:V4HI 2 "reg_or_0_operand" "rW")))] + "TARGET_MAX" + "minuw4 %r1,%r2,%0" + [(set_attr "type" "mvi")]) + +(define_insn "sminv4hi3" + [(set (match_operand:V4HI 0 "register_operand" "=r") + (smin:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW") + (match_operand:V4HI 2 "reg_or_0_operand" "rW")))] + "TARGET_MAX" + "minsw4 %r1,%r2,%0" + [(set_attr "type" "mvi")]) + +(define_insn "umaxv8qi3" + [(set (match_operand:V8QI 0 "register_operand" "=r") + (umax:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW") + (match_operand:V8QI 2 "reg_or_0_operand" "rW")))] + "TARGET_MAX" + "maxub8 %r1,%r2,%0" + [(set_attr "type" "mvi")]) + +(define_insn "smaxv8qi3" + [(set (match_operand:V8QI 0 "register_operand" "=r") + (smax:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW") + (match_operand:V8QI 2 "reg_or_0_operand" "rW")))] + "TARGET_MAX" + "maxsb8 %r1,%r2,%0" + [(set_attr "type" "mvi")]) + +(define_insn "umaxv4hi3" + [(set (match_operand:V4HI 0 "register_operand" "=r") + (umax:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW") + (match_operand:V4HI 2 "reg_or_0_operand" "rW")))] + "TARGET_MAX" + "maxuw4 %r1,%r2,%0" + [(set_attr "type" "mvi")]) + +(define_insn "smaxv4hi3" + [(set (match_operand:V4HI 0 "register_operand" "=r") + (smax:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW") + (match_operand:V4HI 2 "reg_or_0_operand" "rW")))] + "TARGET_MAX" + "maxsw4 %r1,%r2,%0" + [(set_attr "type" "mvi")]) + +(define_insn "one_cmpl2" + [(set (match_operand:VEC 0 "register_operand" "=r") + (not:VEC (match_operand:VEC 1 "register_operand" "r")))] + "" + "ornot $31,%1,%0" + [(set_attr "type" "ilog")]) + +(define_insn "and3" + [(set (match_operand:VEC 0 "register_operand" "=r") + (and:VEC (match_operand:VEC 1 "register_operand" "r") + (match_operand:VEC 2 "register_operand" "r")))] + "" + "and %1,%2,%0" + [(set_attr "type" "ilog")]) + +(define_insn "*andnot3" + [(set (match_operand:VEC 0 "register_operand" "=r") + (and:VEC (not:VEC (match_operand:VEC 1 "register_operand" "r")) + (match_operand:VEC 2 "register_operand" "r")))] + "" + "bic %2,%1,%0" + [(set_attr "type" "ilog")]) + +(define_insn "ior3" + [(set (match_operand:VEC 0 "register_operand" "=r") + (ior:VEC (match_operand:VEC 1 "register_operand" "r") + (match_operand:VEC 2 "register_operand" "r")))] + "" + "bis %1,%2,%0" + [(set_attr "type" "ilog")]) + +(define_insn "*iornot3" + [(set (match_operand:VEC 0 "register_operand" "=r") + (ior:VEC (not:DI (match_operand:VEC 1 "register_operand" "r")) + (match_operand:VEC 2 "register_operand" "r")))] + "" + "ornot %2,%1,%0" + [(set_attr "type" "ilog")]) + +(define_insn "xor3" + [(set (match_operand:VEC 0 "register_operand" "=r") + (xor:VEC (match_operand:VEC 1 "register_operand" "r") + (match_operand:VEC 2 "register_operand" "r")))] + "" + "xor %1,%2,%0" + [(set_attr "type" "ilog")]) + +(define_insn "*xornot3" + [(set (match_operand:VEC 0 "register_operand" "=r") + (not:VEC (xor:VEC (match_operand:VEC 1 "register_operand" "r") + (match_operand:VEC 2 "register_operand" "r"))))] + "" + "eqv %1,%2,%0" + [(set_attr "type" "ilog")]) + +(define_expand "vec_shl_" + [(set (match_operand:VEC 0 "register_operand" "") + (ashift:DI (match_operand:VEC 1 "register_operand" "") + (match_operand:DI 2 "reg_or_6bit_operand" "")))] + "" +{ + operands[0] = gen_lowpart (DImode, operands[0]); + operands[1] = gen_lowpart (DImode, operands[1]); +}) + +(define_expand "vec_shr_" + [(set (match_operand:VEC 0 "register_operand" "") + (lshiftrt:DI (match_operand:VEC 1 "register_operand" "") + (match_operand:DI 2 "reg_or_6bit_operand" "")))] + "" +{ + operands[0] = gen_lowpart (DImode, operands[0]); + operands[1] = gen_lowpart (DImode, operands[1]); +}) ;; Bit field extract patterns which use ext[wlq][lh] @@ -6316,7 +6467,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" { int ofs; - /* Fail 8 bit fields, falling back on a simple byte load. */ + /* Fail 8-bit fields, falling back on a simple byte load. */ if (INTVAL (operands[2]) == 8) FAIL; @@ -6383,7 +6534,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" ;; Argument 2 is the length ;; Argument 3 is the alignment -(define_expand "movstrqi" +(define_expand "movmemqi" [(parallel [(set (match_operand:BLK 0 "memory_operand" "") (match_operand:BLK 1 "memory_operand" "")) (use (match_operand:DI 2 "immediate_operand" "")) @@ -6396,29 +6547,132 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" FAIL; }) -(define_expand "clrstrqi" +(define_expand "movmemdi" [(parallel [(set (match_operand:BLK 0 "memory_operand" "") - (const_int 0)) - (use (match_operand:DI 1 "immediate_operand" "")) - (use (match_operand:DI 2 "immediate_operand" ""))])] - "" -{ - if (alpha_expand_block_clear (operands)) - DONE; - else - FAIL; -}) - -;; Subroutine of stack space allocation. Perform a stack probe. -(define_expand "probe_stack" - [(set (match_dup 1) (match_operand:DI 0 "const_int_operand" ""))] - "" + (match_operand:BLK 1 "memory_operand" "")) + (use (match_operand:DI 2 "immediate_operand" "")) + (use (match_operand:DI 3 "immediate_operand" "")) + (use (match_dup 4)) + (clobber (reg:DI 25)) + (clobber (reg:DI 16)) + (clobber (reg:DI 17)) + (clobber (reg:DI 18)) + (clobber (reg:DI 19)) + (clobber (reg:DI 20)) + (clobber (reg:DI 26)) + (clobber (reg:DI 27))])] + "TARGET_ABI_OPEN_VMS" { - operands[1] = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, - INTVAL (operands[0]))); - MEM_VOLATILE_P (operands[1]) = 1; - - operands[0] = const0_rtx; + operands[4] = gen_rtx_SYMBOL_REF (Pmode, "OTS$MOVE"); + alpha_need_linkage (XSTR (operands[4], 0), 0); +}) + +(define_insn "*movmemdi_1" + [(set (match_operand:BLK 0 "memory_operand" "=m,=m") + (match_operand:BLK 1 "memory_operand" "m,m")) + (use (match_operand:DI 2 "nonmemory_operand" "r,i")) + (use (match_operand:DI 3 "immediate_operand" "")) + (use (match_operand:DI 4 "call_operand" "i,i")) + (clobber (reg:DI 25)) + (clobber (reg:DI 16)) + (clobber (reg:DI 17)) + (clobber (reg:DI 18)) + (clobber (reg:DI 19)) + (clobber (reg:DI 20)) + (clobber (reg:DI 26)) + (clobber (reg:DI 27))] + "TARGET_ABI_OPEN_VMS" +{ + operands [5] = alpha_use_linkage (operands [4], cfun->decl, 0, 1); + switch (which_alternative) + { + case 0: + return "lda $16,%0\;bis $31,%2,$17\;lda $18,%1\;ldq $26,%5\;lda $25,3($31)\;jsr $26,%4\;ldq $27,0($29)"; + case 1: + return "lda $16,%0\;lda $17,%2($31)\;lda $18,%1\;ldq $26,%5\;lda $25,3($31)\;jsr $26,%4\;ldq $27,0($29)"; + default: + gcc_unreachable (); + } +} + [(set_attr "type" "multi") + (set_attr "length" "28")]) + +(define_expand "setmemqi" + [(parallel [(set (match_operand:BLK 0 "memory_operand" "") + (match_operand 2 "const_int_operand" "")) + (use (match_operand:DI 1 "immediate_operand" "")) + (use (match_operand:DI 3 "immediate_operand" ""))])] + "" +{ + /* If value to set is not zero, use the library routine. */ + if (operands[2] != const0_rtx) + FAIL; + + if (alpha_expand_block_clear (operands)) + DONE; + else + FAIL; +}) + +(define_expand "setmemdi" + [(parallel [(set (match_operand:BLK 0 "memory_operand" "") + (match_operand 2 "const_int_operand" "")) + (use (match_operand:DI 1 "immediate_operand" "")) + (use (match_operand:DI 3 "immediate_operand" "")) + (use (match_dup 4)) + (clobber (reg:DI 25)) + (clobber (reg:DI 16)) + (clobber (reg:DI 17)) + (clobber (reg:DI 26)) + (clobber (reg:DI 27))])] + "TARGET_ABI_OPEN_VMS" +{ + /* If value to set is not zero, use the library routine. */ + if (operands[2] != const0_rtx) + FAIL; + + operands[4] = gen_rtx_SYMBOL_REF (Pmode, "OTS$ZERO"); + alpha_need_linkage (XSTR (operands[4], 0), 0); +}) + +(define_insn "*clrmemdi_1" + [(set (match_operand:BLK 0 "memory_operand" "=m,=m") + (const_int 0)) + (use (match_operand:DI 1 "nonmemory_operand" "r,i")) + (use (match_operand:DI 2 "immediate_operand" "")) + (use (match_operand:DI 3 "call_operand" "i,i")) + (clobber (reg:DI 25)) + (clobber (reg:DI 16)) + (clobber (reg:DI 17)) + (clobber (reg:DI 26)) + (clobber (reg:DI 27))] + "TARGET_ABI_OPEN_VMS" +{ + operands [4] = alpha_use_linkage (operands [3], cfun->decl, 0, 1); + switch (which_alternative) + { + case 0: + return "lda $16,%0\;bis $31,%1,$17\;ldq $26,%4\;lda $25,2($31)\;jsr $26,%3\;ldq $27,0($29)"; + case 1: + return "lda $16,%0\;lda $17,%1($31)\;ldq $26,%4\;lda $25,2($31)\;jsr $26,%3\;ldq $27,0($29)"; + default: + gcc_unreachable (); + } +} + [(set_attr "type" "multi") + (set_attr "length" "24")]) + + +;; Subroutine of stack space allocation. Perform a stack probe. +(define_expand "probe_stack" + [(set (match_dup 1) (match_operand:DI 0 "const_int_operand" ""))] + "" +{ + operands[1] = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, + INTVAL (operands[0]))); + MEM_VOLATILE_P (operands[1]) = 1; + + operands[0] = const0_rtx; }) ;; This is how we allocate stack space. If we are allocating a @@ -6507,7 +6761,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" "" { operands[2] = gen_label_rtx (); - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", + (*targetm.asm_out.internal_label) (asm_out_file, "L", CODE_LABEL_NUMBER (operands[2])); return "stq $31,-8192(%1)\;subq %0,1,%0\;lda %1,-8192(%1)\;bne %0,%l2"; @@ -6550,7 +6804,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (match_operand 2 "const_int_operand" "")] UNSPECV_LDGP1))] "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" - "ldah %0,0(%1)\t\t!gpdisp!%2") + "ldah %0,0(%1)\t\t!gpdisp!%2" + [(set_attr "cannot_copy" "true")]) (define_insn "*ldgp_er_2" [(set (match_operand:DI 0 "register_operand" "=r") @@ -6558,7 +6813,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (match_operand 2 "const_int_operand" "")] UNSPEC_LDGP2))] "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" - "lda %0,0(%1)\t\t!gpdisp!%2") + "lda %0,0(%1)\t\t!gpdisp!%2" + [(set_attr "cannot_copy" "true")]) (define_insn "*prologue_ldgp_er_2" [(set (match_operand:DI 0 "register_operand" "=r") @@ -6566,7 +6822,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (match_operand 2 "const_int_operand" "")] UNSPECV_PLDGP2))] "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" - "lda %0,0(%1)\t\t!gpdisp!%2\n$%~..ng:") + "lda %0,0(%1)\t\t!gpdisp!%2\n$%~..ng:" + [(set_attr "cannot_copy" "true")]) (define_insn "*prologue_ldgp_1" [(set (match_operand:DI 0 "register_operand" "=r") @@ -6574,7 +6831,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (match_operand 2 "const_int_operand" "")] UNSPECV_LDGP1))] "" - "ldgp %0,0(%1)\n$%~..ng:") + "ldgp %0,0(%1)\n$%~..ng:" + [(set_attr "cannot_copy" "true")]) (define_insn "*prologue_ldgp_2" [(set (match_operand:DI 0 "register_operand" "=r") @@ -6624,17 +6882,6 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" DONE; }) -;; In creating a large stack frame, NT _must_ use ldah+lda to load -;; the frame size into a register. We use this pattern to ensure -;; we get lda instead of addq. -(define_insn "nt_lda" - [(set (match_operand:DI 0 "register_operand" "=r") - (unspec:DI [(match_dup 0) - (match_operand:DI 1 "const_int_operand" "n")] - UNSPEC_NT_LDA))] - "" - "lda %0,%1(%0)") - (define_expand "builtin_longjmp" [(use (match_operand:DI 0 "register_operand" "r"))] "TARGET_ABI_OSF" @@ -6649,8 +6896,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" emit_move_insn (hard_frame_pointer_rtx, fp); emit_move_insn (pv, lab); emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX); - emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx)); - emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx)); + emit_use (hard_frame_pointer_rtx); + emit_use (stack_pointer_rtx); /* Load the label we are jumping through into $27 so that we know where to look for it when we get back to setjmp's function for @@ -6670,66 +6917,46 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" "jmp $31,(%0),0" [(set_attr "type" "ibr")]) -(define_insn "*builtin_setjmp_receiver_er_sl_1" - [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)] - "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && TARGET_AS_CAN_SUBTRACT_LABELS" - "lda $27,$LSJ%=-%l0($27)\n$LSJ%=:") - -(define_insn "*builtin_setjmp_receiver_er_1" - [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)] - "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" - "br $27,$LSJ%=\n$LSJ%=:" - [(set_attr "type" "ibr")]) - -(define_split - [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)] - "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF - && prev_nonnote_insn (insn) == operands[0]" - [(const_int 0)] - "DONE;") - -(define_insn "*builtin_setjmp_receiver_1" +(define_expand "builtin_setjmp_receiver" [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)] "TARGET_ABI_OSF" - "br $27,$LSJ%=\n$LSJ%=:\;ldgp $29,0($27)" - [(set_attr "length" "12") - (set_attr "type" "multi")]) + "") -(define_expand "builtin_setjmp_receiver_er" - [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR) - (set (match_dup 1) +(define_insn_and_split "*builtin_setjmp_receiver_1" + [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR)] + "TARGET_ABI_OSF" +{ + if (TARGET_EXPLICIT_RELOCS) + return "#"; + else + return "br $27,$LSJ%=\n$LSJ%=:\;ldgp $29,0($27)"; +} + "&& TARGET_EXPLICIT_RELOCS && reload_completed" + [(set (match_dup 1) (unspec_volatile:DI [(match_dup 2) (match_dup 3)] UNSPECV_LDGP1)) (set (match_dup 1) (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_LDGP2))] - "" { + if (prev_nonnote_insn (curr_insn) != XEXP (operands[0], 0)) + emit_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, operands[0]), + UNSPECV_SETJMPR_ER)); operands[1] = pic_offset_table_rtx; operands[2] = gen_rtx_REG (Pmode, 27); operands[3] = GEN_INT (alpha_next_sequence_number++); -}) - -(define_expand "builtin_setjmp_receiver" - [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)] - "TARGET_ABI_OSF" -{ - if (TARGET_EXPLICIT_RELOCS) - { - emit_insn (gen_builtin_setjmp_receiver_er (operands[0])); - DONE; - } -}) +} + [(set_attr "length" "12") + (set_attr "type" "multi")]) -(define_expand "exception_receiver_er" - [(set (match_dup 0) - (unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1)) - (set (match_dup 0) - (unspec:DI [(match_dup 0) (match_dup 2)] UNSPEC_LDGP2))] - "" -{ - operands[0] = pic_offset_table_rtx; - operands[1] = gen_rtx_REG (Pmode, 26); - operands[2] = GEN_INT (alpha_next_sequence_number++); -}) +(define_insn "*builtin_setjmp_receiver_er_sl_1" + [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR_ER)] + "TARGET_ABI_OSF && TARGET_EXPLICIT_RELOCS && TARGET_AS_CAN_SUBTRACT_LABELS" + "lda $27,$LSJ%=-%l0($27)\n$LSJ%=:") + +(define_insn "*builtin_setjmp_receiver_er_1" + [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR_ER)] + "TARGET_ABI_OSF && TARGET_EXPLICIT_RELOCS" + "br $27,$LSJ%=\n$LSJ%=:" + [(set_attr "type" "ibr")]) (define_expand "exception_receiver" [(unspec_volatile [(match_dup 0)] UNSPECV_EHR)] @@ -6737,28 +6964,38 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" { if (TARGET_LD_BUGGY_LDGP) operands[0] = alpha_gp_save_rtx (); - else if (TARGET_EXPLICIT_RELOCS) - { - emit_insn (gen_exception_receiver_er ()); - DONE; - } else operands[0] = const0_rtx; }) -(define_insn "*exception_receiver_1" - [(unspec_volatile [(const_int 0)] UNSPECV_EHR)] - "! TARGET_LD_BUGGY_LDGP" - "ldgp $29,0($26)" - [(set_attr "length" "8") - (set_attr "type" "multi")]) - (define_insn "*exception_receiver_2" [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_EHR)] - "TARGET_LD_BUGGY_LDGP" + "TARGET_ABI_OSF && TARGET_LD_BUGGY_LDGP" "ldq $29,%0" [(set_attr "type" "ild")]) +(define_insn_and_split "*exception_receiver_1" + [(unspec_volatile [(const_int 0)] UNSPECV_EHR)] + "TARGET_ABI_OSF" +{ + if (TARGET_EXPLICIT_RELOCS) + return "ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*"; + else + return "ldgp $29,0($26)"; +} + "&& TARGET_EXPLICIT_RELOCS && reload_completed" + [(set (match_dup 0) + (unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1)) + (set (match_dup 0) + (unspec:DI [(match_dup 0) (match_dup 2)] UNSPEC_LDGP2))] +{ + operands[0] = pic_offset_table_rtx; + operands[1] = gen_rtx_REG (Pmode, 26); + operands[2] = GEN_INT (alpha_next_sequence_number++); +} + [(set_attr "length" "8") + (set_attr "type" "multi")]) + (define_expand "nonlocal_goto_receiver" [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) (set (reg:DI 27) (mem:DI (reg:DI 29))) @@ -6859,19 +7096,19 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" [(prefetch (match_operand:DI 0 "address_operand" "p") (match_operand:DI 1 "const_int_operand" "n") (match_operand:DI 2 "const_int_operand" "n"))] - "TARGET_FIXUP_EV5_PREFETCH || TARGET_CPU_EV6" + "TARGET_FIXUP_EV5_PREFETCH || alpha_cpu == PROCESSOR_EV6" { /* Interpret "no temporal locality" as this data should be evicted once it is used. The "evict next" alternatives load the data into the cache and leave the LRU eviction counter pointing to that block. */ static const char * const alt[2][2] = { { - "lds $f31,%a0", /* read, evict next */ + "ldq $31,%a0", /* read, evict next */ "ldl $31,%a0", /* read, evict last */ }, { "ldt $f31,%a0", /* write, evict next */ - "ldq $31,%a0", /* write, evict last */ + "lds $f31,%a0", /* write, evict last */ } }; @@ -6924,125 +7161,876 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" else return ".align %0 #realign"; }) + +;; Instructions to be emitted from __builtins. -;; The call patterns are at the end of the file because their -;; wildcard operand0 interferes with nice recognition. +(define_insn "builtin_cmpbge" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rJ") + (match_operand:DI 2 "reg_or_8bit_operand" "rI")] + UNSPEC_CMPBGE))] + "" + "cmpbge %r1,%2,%0" + ;; The EV6 data sheets list this as ILOG. OTOH, EV6 doesn't + ;; actually differentiate between ILOG and ICMP in the schedule. + [(set_attr "type" "icmp")]) -(define_insn "*call_value_osf_1_er" - [(set (match_operand 0 "" "") - (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s")) - (match_operand 2 "" ""))) - (use (reg:DI 29)) - (clobber (reg:DI 26))] - "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" - "@ - jsr $26,(%1),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%* - bsr $26,$%1..ng - ldq $27,%1($29)\t\t!literal!%#\;jsr $26,($27),0\t\t!lituse_jsr!%#\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*" - [(set_attr "type" "jsr") - (set_attr "length" "12,*,16")]) +(define_expand "builtin_extbl" + [(match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "reg_or_0_operand" "") + (match_operand:DI 2 "reg_or_8bit_operand" "")] + "" +{ + rtx (*gen) (rtx, rtx, rtx, rtx); + if (WORDS_BIG_ENDIAN) + gen = gen_extxl_be; + else + gen = gen_extxl_le; + emit_insn ((*gen) (operands[0], operands[1], GEN_INT (8), operands[2])); + DONE; +}) -;; We must use peep2 instead of a split because we need accurate life -;; information for $gp. Consider the case of { bar(); while (1); }. -(define_peephole2 - [(parallel [(set (match_operand 0 "" "") - (call (mem:DI (match_operand:DI 1 "call_operand" "")) - (match_operand 2 "" ""))) - (use (reg:DI 29)) - (clobber (reg:DI 26))])] - "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed - && ! current_file_function_operand (operands[1], Pmode) - && peep2_regno_dead_p (1, 29)" - [(parallel [(set (match_dup 0) - (call (mem:DI (match_dup 3)) - (match_dup 2))) - (set (reg:DI 26) (plus:DI (pc) (const_int 4))) - (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE) - (use (match_dup 1)) - (use (match_dup 4))])] +(define_expand "builtin_extwl" + [(match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "reg_or_0_operand" "") + (match_operand:DI 2 "reg_or_8bit_operand" "")] + "" { - if (CONSTANT_P (operands[1])) - { - operands[3] = gen_rtx_REG (Pmode, 27); - operands[4] = GEN_INT (alpha_next_sequence_number++); - emit_insn (gen_movdi_er_high_g (operands[3], pic_offset_table_rtx, - operands[1], operands[4])); - } + rtx (*gen) (rtx, rtx, rtx, rtx); + if (WORDS_BIG_ENDIAN) + gen = gen_extxl_be; else - { - operands[3] = operands[1]; - operands[1] = const0_rtx; - operands[4] = const0_rtx; - } + gen = gen_extxl_le; + emit_insn ((*gen) (operands[0], operands[1], GEN_INT (16), operands[2])); + DONE; }) -(define_peephole2 - [(parallel [(set (match_operand 0 "" "") - (call (mem:DI (match_operand:DI 1 "call_operand" "")) - (match_operand 2 "" ""))) - (use (reg:DI 29)) - (clobber (reg:DI 26))])] - "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed - && ! current_file_function_operand (operands[1], Pmode) - && ! peep2_regno_dead_p (1, 29)" - [(parallel [(set (match_dup 0) - (call (mem:DI (match_dup 3)) - (match_dup 2))) - (set (reg:DI 26) (plus:DI (pc) (const_int 4))) - (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE) - (use (match_dup 1)) - (use (match_dup 5))]) - (set (reg:DI 29) - (unspec_volatile:DI [(reg:DI 26) (match_dup 4)] UNSPECV_LDGP1)) - (set (reg:DI 29) - (unspec:DI [(reg:DI 29) (match_dup 4)] UNSPEC_LDGP2))] +(define_expand "builtin_extll" + [(match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "reg_or_0_operand" "") + (match_operand:DI 2 "reg_or_8bit_operand" "")] + "" { - if (CONSTANT_P (operands[1])) - { - operands[3] = gen_rtx_REG (Pmode, 27); - operands[5] = GEN_INT (alpha_next_sequence_number++); - emit_insn (gen_movdi_er_high_g (operands[3], pic_offset_table_rtx, - operands[1], operands[5])); - } + rtx (*gen) (rtx, rtx, rtx, rtx); + if (WORDS_BIG_ENDIAN) + gen = gen_extxl_be; else - { - operands[3] = operands[1]; - operands[1] = const0_rtx; - operands[5] = const0_rtx; - } - operands[4] = GEN_INT (alpha_next_sequence_number++); + gen = gen_extxl_le; + emit_insn ((*gen) (operands[0], operands[1], GEN_INT (32), operands[2])); + DONE; }) -;; We add a blockage unspec_volatile to prevent insns from moving down -;; from above the call to in between the call and the ldah gpdisp. -(define_insn "*call_value_osf_2_er" - [(set (match_operand 0 "" "") - (call (mem:DI (match_operand:DI 1 "register_operand" "c")) - (match_operand 2 "" ""))) - (set (reg:DI 26) - (plus:DI (pc) (const_int 4))) - (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE) - (use (match_operand 3 "" "")) - (use (match_operand 4 "const_int_operand" ""))] - "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" - "jsr $26,(%1),%3%J4" - [(set_attr "type" "jsr")]) +(define_expand "builtin_extql" + [(match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "reg_or_0_operand" "") + (match_operand:DI 2 "reg_or_8bit_operand" "")] + "" +{ + rtx (*gen) (rtx, rtx, rtx, rtx); + if (WORDS_BIG_ENDIAN) + gen = gen_extxl_be; + else + gen = gen_extxl_le; + emit_insn ((*gen) (operands[0], operands[1], GEN_INT (64), operands[2])); + DONE; +}) -(define_insn "*call_value_osf_1_noreturn" - [(set (match_operand 0 "" "") - (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s")) - (match_operand 2 "" ""))) - (use (reg:DI 29)) - (clobber (reg:DI 26))] - "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF - && find_reg_note (insn, REG_NORETURN, NULL_RTX)" - "@ - jsr $26,($27),0 - bsr $26,$%1..ng - jsr $26,%1" - [(set_attr "type" "jsr") +(define_expand "builtin_extwh" + [(match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "reg_or_0_operand" "") + (match_operand:DI 2 "reg_or_8bit_operand" "")] + "" +{ + rtx (*gen) (rtx, rtx, rtx); + if (WORDS_BIG_ENDIAN) + gen = gen_extwh_be; + else + gen = gen_extwh_le; + emit_insn ((*gen) (operands[0], operands[1], operands[2])); + DONE; +}) + +(define_expand "builtin_extlh" + [(match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "reg_or_0_operand" "") + (match_operand:DI 2 "reg_or_8bit_operand" "")] + "" +{ + rtx (*gen) (rtx, rtx, rtx); + if (WORDS_BIG_ENDIAN) + gen = gen_extlh_be; + else + gen = gen_extlh_le; + emit_insn ((*gen) (operands[0], operands[1], operands[2])); + DONE; +}) + +(define_expand "builtin_extqh" + [(match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "reg_or_0_operand" "") + (match_operand:DI 2 "reg_or_8bit_operand" "")] + "" +{ + rtx (*gen) (rtx, rtx, rtx); + if (WORDS_BIG_ENDIAN) + gen = gen_extqh_be; + else + gen = gen_extqh_le; + emit_insn ((*gen) (operands[0], operands[1], operands[2])); + DONE; +}) + +(define_expand "builtin_insbl" + [(match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "register_operand" "") + (match_operand:DI 2 "reg_or_8bit_operand" "")] + "" +{ + rtx (*gen) (rtx, rtx, rtx); + if (WORDS_BIG_ENDIAN) + gen = gen_insbl_be; + else + gen = gen_insbl_le; + operands[1] = gen_lowpart (QImode, operands[1]); + emit_insn ((*gen) (operands[0], operands[1], operands[2])); + DONE; +}) + +(define_expand "builtin_inswl" + [(match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "register_operand" "") + (match_operand:DI 2 "reg_or_8bit_operand" "")] + "" +{ + rtx (*gen) (rtx, rtx, rtx); + if (WORDS_BIG_ENDIAN) + gen = gen_inswl_be; + else + gen = gen_inswl_le; + operands[1] = gen_lowpart (HImode, operands[1]); + emit_insn ((*gen) (operands[0], operands[1], operands[2])); + DONE; +}) + +(define_expand "builtin_insll" + [(match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "register_operand" "") + (match_operand:DI 2 "reg_or_8bit_operand" "")] + "" +{ + rtx (*gen) (rtx, rtx, rtx); + if (WORDS_BIG_ENDIAN) + gen = gen_insll_be; + else + gen = gen_insll_le; + operands[1] = gen_lowpart (SImode, operands[1]); + emit_insn ((*gen) (operands[0], operands[1], operands[2])); + emit_insn ((*gen) (operands[0], operands[1], operands[2])); + DONE; +}) + +(define_expand "builtin_insql" + [(match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "reg_or_0_operand" "") + (match_operand:DI 2 "reg_or_8bit_operand" "")] + "" +{ + rtx (*gen) (rtx, rtx, rtx); + if (WORDS_BIG_ENDIAN) + gen = gen_insql_be; + else + gen = gen_insql_le; + emit_insn ((*gen) (operands[0], operands[1], operands[2])); + DONE; +}) + +(define_expand "builtin_inswh" + [(match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "register_operand" "") + (match_operand:DI 2 "reg_or_8bit_operand" "")] + "" +{ + emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (16), operands[2])); + DONE; +}) + +(define_expand "builtin_inslh" + [(match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "register_operand" "") + (match_operand:DI 2 "reg_or_8bit_operand" "")] + "" +{ + emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (32), operands[2])); + DONE; +}) + +(define_expand "builtin_insqh" + [(match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "register_operand" "") + (match_operand:DI 2 "reg_or_8bit_operand" "")] + "" +{ + emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (64), operands[2])); + DONE; +}) + +(define_expand "builtin_mskbl" + [(match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "reg_or_0_operand" "") + (match_operand:DI 2 "reg_or_8bit_operand" "")] + "" +{ + rtx (*gen) (rtx, rtx, rtx, rtx); + rtx mask; + if (WORDS_BIG_ENDIAN) + gen = gen_mskxl_be; + else + gen = gen_mskxl_le; + mask = GEN_INT (0xff); + emit_insn ((*gen) (operands[0], operands[1], mask, operands[2])); + DONE; +}) + +(define_expand "builtin_mskwl" + [(match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "reg_or_0_operand" "") + (match_operand:DI 2 "reg_or_8bit_operand" "")] + "" +{ + rtx (*gen) (rtx, rtx, rtx, rtx); + rtx mask; + if (WORDS_BIG_ENDIAN) + gen = gen_mskxl_be; + else + gen = gen_mskxl_le; + mask = GEN_INT (0xffff); + emit_insn ((*gen) (operands[0], operands[1], mask, operands[2])); + DONE; +}) + +(define_expand "builtin_mskll" + [(match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "reg_or_0_operand" "") + (match_operand:DI 2 "reg_or_8bit_operand" "")] + "" +{ + rtx (*gen) (rtx, rtx, rtx, rtx); + rtx mask; + if (WORDS_BIG_ENDIAN) + gen = gen_mskxl_be; + else + gen = gen_mskxl_le; + mask = immed_double_const (0xffffffff, 0, DImode); + emit_insn ((*gen) (operands[0], operands[1], mask, operands[2])); + DONE; +}) + +(define_expand "builtin_mskql" + [(match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "reg_or_0_operand" "") + (match_operand:DI 2 "reg_or_8bit_operand" "")] + "" +{ + rtx (*gen) (rtx, rtx, rtx, rtx); + rtx mask; + if (WORDS_BIG_ENDIAN) + gen = gen_mskxl_be; + else + gen = gen_mskxl_le; + mask = constm1_rtx; + emit_insn ((*gen) (operands[0], operands[1], mask, operands[2])); + DONE; +}) + +(define_expand "builtin_mskwh" + [(match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "register_operand" "") + (match_operand:DI 2 "reg_or_8bit_operand" "")] + "" +{ + emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (16), operands[2])); + DONE; +}) + +(define_expand "builtin_msklh" + [(match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "register_operand" "") + (match_operand:DI 2 "reg_or_8bit_operand" "")] + "" +{ + emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (32), operands[2])); + DONE; +}) + +(define_expand "builtin_mskqh" + [(match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "register_operand" "") + (match_operand:DI 2 "reg_or_8bit_operand" "")] + "" +{ + emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (64), operands[2])); + DONE; +}) + +(define_expand "builtin_zap" + [(set (match_operand:DI 0 "register_operand" "") + (and:DI (unspec:DI + [(match_operand:DI 2 "reg_or_cint_operand" "")] + UNSPEC_ZAP) + (match_operand:DI 1 "reg_or_cint_operand" "")))] + "" +{ + if (GET_CODE (operands[2]) == CONST_INT) + { + rtx mask = alpha_expand_zap_mask (INTVAL (operands[2])); + + if (mask == const0_rtx) + { + emit_move_insn (operands[0], const0_rtx); + DONE; + } + if (mask == constm1_rtx) + { + emit_move_insn (operands[0], operands[1]); + DONE; + } + + operands[1] = force_reg (DImode, operands[1]); + emit_insn (gen_anddi3 (operands[0], operands[1], mask)); + DONE; + } + + operands[1] = force_reg (DImode, operands[1]); + operands[2] = gen_lowpart (QImode, operands[2]); +}) + +(define_insn "*builtin_zap_1" + [(set (match_operand:DI 0 "register_operand" "=r,r,r,r") + (and:DI (unspec:DI + [(match_operand:QI 2 "reg_or_cint_operand" "n,n,r,r")] + UNSPEC_ZAP) + (match_operand:DI 1 "reg_or_cint_operand" "n,r,J,r")))] + "" + "@ + # + # + bis $31,$31,%0 + zap %r1,%2,%0" + [(set_attr "type" "shift,shift,ilog,shift")]) + +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (and:DI (unspec:DI + [(match_operand:QI 2 "const_int_operand" "")] + UNSPEC_ZAP) + (match_operand:DI 1 "const_int_operand" "")))] + "" + [(const_int 0)] +{ + rtx mask = alpha_expand_zap_mask (INTVAL (operands[2])); + if (HOST_BITS_PER_WIDE_INT >= 64 || GET_CODE (mask) == CONST_INT) + operands[1] = gen_int_mode (INTVAL (operands[1]) & INTVAL (mask), DImode); + else + { + HOST_WIDE_INT c_lo = INTVAL (operands[1]); + HOST_WIDE_INT c_hi = (c_lo < 0 ? -1 : 0); + operands[1] = immed_double_const (c_lo & CONST_DOUBLE_LOW (mask), + c_hi & CONST_DOUBLE_HIGH (mask), + DImode); + } + emit_move_insn (operands[0], operands[1]); + DONE; +}) + +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (and:DI (unspec:DI + [(match_operand:QI 2 "const_int_operand" "")] + UNSPEC_ZAP) + (match_operand:DI 1 "register_operand" "")))] + "" + [(set (match_dup 0) + (and:DI (match_dup 1) (match_dup 2)))] +{ + operands[2] = alpha_expand_zap_mask (INTVAL (operands[2])); + if (operands[2] == const0_rtx) + { + emit_move_insn (operands[0], const0_rtx); + DONE; + } + if (operands[2] == constm1_rtx) + { + emit_move_insn (operands[0], operands[1]); + DONE; + } +}) + +(define_expand "builtin_zapnot" + [(set (match_operand:DI 0 "register_operand" "") + (and:DI (unspec:DI + [(not:QI (match_operand:DI 2 "reg_or_cint_operand" ""))] + UNSPEC_ZAP) + (match_operand:DI 1 "reg_or_cint_operand" "")))] + "" +{ + if (GET_CODE (operands[2]) == CONST_INT) + { + rtx mask = alpha_expand_zap_mask (~ INTVAL (operands[2])); + + if (mask == const0_rtx) + { + emit_move_insn (operands[0], const0_rtx); + DONE; + } + if (mask == constm1_rtx) + { + emit_move_insn (operands[0], operands[1]); + DONE; + } + + operands[1] = force_reg (DImode, operands[1]); + emit_insn (gen_anddi3 (operands[0], operands[1], mask)); + DONE; + } + + operands[1] = force_reg (DImode, operands[1]); + operands[2] = gen_lowpart (QImode, operands[2]); +}) + +(define_insn "*builtin_zapnot_1" + [(set (match_operand:DI 0 "register_operand" "=r") + (and:DI (unspec:DI + [(not:QI (match_operand:QI 2 "register_operand" "r"))] + UNSPEC_ZAP) + (match_operand:DI 1 "reg_or_0_operand" "rJ")))] + "" + "zapnot %r1,%2,%0" + [(set_attr "type" "shift")]) + +(define_insn "builtin_amask" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(match_operand:DI 1 "reg_or_8bit_operand" "rI")] + UNSPEC_AMASK))] + "" + "amask %1,%0" + [(set_attr "type" "ilog")]) + +(define_insn "builtin_implver" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(const_int 0)] UNSPEC_IMPLVER))] + "" + "implver %0" + [(set_attr "type" "ilog")]) + +(define_insn "builtin_rpcc" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec_volatile:DI [(const_int 0)] UNSPECV_RPCC))] + "" + "rpcc %0" + [(set_attr "type" "ilog")]) + +(define_expand "builtin_minub8" + [(match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "reg_or_0_operand" "") + (match_operand:DI 2 "reg_or_0_operand" "")] + "TARGET_MAX" +{ + alpha_expand_builtin_vector_binop (gen_uminv8qi3, V8QImode, operands[0], + operands[1], operands[2]); + DONE; +}) + +(define_expand "builtin_minsb8" + [(match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "reg_or_0_operand" "") + (match_operand:DI 2 "reg_or_0_operand" "")] + "TARGET_MAX" +{ + alpha_expand_builtin_vector_binop (gen_sminv8qi3, V8QImode, operands[0], + operands[1], operands[2]); + DONE; +}) + +(define_expand "builtin_minuw4" + [(match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "reg_or_0_operand" "") + (match_operand:DI 2 "reg_or_0_operand" "")] + "TARGET_MAX" +{ + alpha_expand_builtin_vector_binop (gen_uminv4hi3, V4HImode, operands[0], + operands[1], operands[2]); + DONE; +}) + +(define_expand "builtin_minsw4" + [(match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "reg_or_0_operand" "") + (match_operand:DI 2 "reg_or_0_operand" "")] + "TARGET_MAX" +{ + alpha_expand_builtin_vector_binop (gen_sminv4hi3, V4HImode, operands[0], + operands[1], operands[2]); + DONE; +}) + +(define_expand "builtin_maxub8" + [(match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "reg_or_0_operand" "") + (match_operand:DI 2 "reg_or_0_operand" "")] + "TARGET_MAX" +{ + alpha_expand_builtin_vector_binop (gen_umaxv8qi3, V8QImode, operands[0], + operands[1], operands[2]); + DONE; +}) + +(define_expand "builtin_maxsb8" + [(match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "reg_or_0_operand" "") + (match_operand:DI 2 "reg_or_0_operand" "")] + "TARGET_MAX" +{ + alpha_expand_builtin_vector_binop (gen_smaxv8qi3, V8QImode, operands[0], + operands[1], operands[2]); + DONE; +}) + +(define_expand "builtin_maxuw4" + [(match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "reg_or_0_operand" "") + (match_operand:DI 2 "reg_or_0_operand" "")] + "TARGET_MAX" +{ + alpha_expand_builtin_vector_binop (gen_umaxv4hi3, V4HImode, operands[0], + operands[1], operands[2]); + DONE; +}) + +(define_expand "builtin_maxsw4" + [(match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "reg_or_0_operand" "") + (match_operand:DI 2 "reg_or_0_operand" "")] + "TARGET_MAX" +{ + alpha_expand_builtin_vector_binop (gen_smaxv4hi3, V4HImode, operands[0], + operands[1], operands[2]); + DONE; +}) + +(define_insn "builtin_perr" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "%rJ") + (match_operand:DI 2 "reg_or_8bit_operand" "rJ")] + UNSPEC_PERR))] + "TARGET_MAX" + "perr %r1,%r2,%0" + [(set_attr "type" "mvi")]) + +(define_expand "builtin_pklb" + [(set (match_operand:DI 0 "register_operand" "") + (vec_concat:V8QI + (vec_concat:V4QI + (truncate:V2QI (match_operand:DI 1 "register_operand" "")) + (match_dup 2)) + (match_dup 3)))] + "TARGET_MAX" +{ + operands[0] = gen_lowpart (V8QImode, operands[0]); + operands[1] = gen_lowpart (V2SImode, operands[1]); + operands[2] = CONST0_RTX (V2QImode); + operands[3] = CONST0_RTX (V4QImode); +}) + +(define_insn "*pklb" + [(set (match_operand:V8QI 0 "register_operand" "=r") + (vec_concat:V8QI + (vec_concat:V4QI + (truncate:V2QI (match_operand:V2SI 1 "register_operand" "r")) + (match_operand:V2QI 2 "const0_operand" "")) + (match_operand:V4QI 3 "const0_operand" "")))] + "TARGET_MAX" + "pklb %r1,%0" + [(set_attr "type" "mvi")]) + +(define_expand "builtin_pkwb" + [(set (match_operand:DI 0 "register_operand" "") + (vec_concat:V8QI + (truncate:V4QI (match_operand:DI 1 "register_operand" "")) + (match_dup 2)))] + "TARGET_MAX" +{ + operands[0] = gen_lowpart (V8QImode, operands[0]); + operands[1] = gen_lowpart (V4HImode, operands[1]); + operands[2] = CONST0_RTX (V4QImode); +}) + +(define_insn "*pkwb" + [(set (match_operand:V8QI 0 "register_operand" "=r") + (vec_concat:V8QI + (truncate:V4QI (match_operand:V4HI 1 "register_operand" "r")) + (match_operand:V4QI 2 "const0_operand" "")))] + "TARGET_MAX" + "pkwb %r1,%0" + [(set_attr "type" "mvi")]) + +(define_expand "builtin_unpkbl" + [(set (match_operand:DI 0 "register_operand" "") + (zero_extend:V2SI + (vec_select:V2QI (match_operand:DI 1 "register_operand" "") + (parallel [(const_int 0) (const_int 1)]))))] + "TARGET_MAX" +{ + operands[0] = gen_lowpart (V2SImode, operands[0]); + operands[1] = gen_lowpart (V8QImode, operands[1]); +}) + +(define_insn "*unpkbl" + [(set (match_operand:V2SI 0 "register_operand" "=r") + (zero_extend:V2SI + (vec_select:V2QI (match_operand:V8QI 1 "reg_or_0_operand" "rW") + (parallel [(const_int 0) (const_int 1)]))))] + "TARGET_MAX" + "unpkbl %r1,%0" + [(set_attr "type" "mvi")]) + +(define_expand "builtin_unpkbw" + [(set (match_operand:DI 0 "register_operand" "") + (zero_extend:V4HI + (vec_select:V4QI (match_operand:DI 1 "register_operand" "") + (parallel [(const_int 0) + (const_int 1) + (const_int 2) + (const_int 3)]))))] + "TARGET_MAX" +{ + operands[0] = gen_lowpart (V4HImode, operands[0]); + operands[1] = gen_lowpart (V8QImode, operands[1]); +}) + +(define_insn "*unpkbw" + [(set (match_operand:V4HI 0 "register_operand" "=r") + (zero_extend:V4HI + (vec_select:V4QI (match_operand:V8QI 1 "reg_or_0_operand" "rW") + (parallel [(const_int 0) + (const_int 1) + (const_int 2) + (const_int 3)]))))] + "TARGET_MAX" + "unpkbw %r1,%0" + [(set_attr "type" "mvi")]) + +(include "sync.md") + +;; The call patterns are at the end of the file because their +;; wildcard operand0 interferes with nice recognition. + +(define_insn "*call_value_osf_1_er_noreturn" + [(set (match_operand 0 "" "") + (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s")) + (match_operand 2 "" ""))) + (use (reg:DI 29)) + (clobber (reg:DI 26))] + "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF + && find_reg_note (insn, REG_NORETURN, NULL_RTX)" + "@ + jsr $26,($27),0 + bsr $26,%1\t\t!samegp + ldq $27,%1($29)\t\t!literal!%#\;jsr $26,($27),%1\t\t!lituse_jsr!%#" + [(set_attr "type" "jsr") (set_attr "length" "*,*,8")]) +(define_insn "*call_value_osf_1_er" + [(set (match_operand 0 "" "") + (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s")) + (match_operand 2 "" ""))) + (use (reg:DI 29)) + (clobber (reg:DI 26))] + "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" + "@ + jsr $26,(%1),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%* + bsr $26,%1\t\t!samegp + ldq $27,%1($29)\t\t!literal!%#\;jsr $26,($27),0\t\t!lituse_jsr!%#\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*" + [(set_attr "type" "jsr") + (set_attr "length" "12,*,16")]) + +;; We must use peep2 instead of a split because we need accurate life +;; information for $gp. Consider the case of { bar(); while (1); }. +(define_peephole2 + [(parallel [(set (match_operand 0 "" "") + (call (mem:DI (match_operand:DI 1 "call_operand" "")) + (match_operand 2 "" ""))) + (use (reg:DI 29)) + (clobber (reg:DI 26))])] + "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed + && ! samegp_function_operand (operands[1], Pmode) + && (peep2_regno_dead_p (1, 29) + || find_reg_note (insn, REG_NORETURN, NULL_RTX))" + [(parallel [(set (match_dup 0) + (call (mem:DI (match_dup 3)) + (match_dup 2))) + (use (reg:DI 29)) + (use (match_dup 1)) + (use (match_dup 4)) + (clobber (reg:DI 26))])] +{ + if (CONSTANT_P (operands[1])) + { + operands[3] = gen_rtx_REG (Pmode, 27); + operands[4] = GEN_INT (alpha_next_sequence_number++); + emit_insn (gen_movdi_er_high_g (operands[3], pic_offset_table_rtx, + operands[1], operands[4])); + } + else + { + operands[3] = operands[1]; + operands[1] = const0_rtx; + operands[4] = const0_rtx; + } +}) + +(define_peephole2 + [(parallel [(set (match_operand 0 "" "") + (call (mem:DI (match_operand:DI 1 "call_operand" "")) + (match_operand 2 "" ""))) + (use (reg:DI 29)) + (clobber (reg:DI 26))])] + "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed + && ! samegp_function_operand (operands[1], Pmode) + && ! (peep2_regno_dead_p (1, 29) + || find_reg_note (insn, REG_NORETURN, NULL_RTX))" + [(parallel [(set (match_dup 0) + (call (mem:DI (match_dup 3)) + (match_dup 2))) + (set (match_dup 6) + (unspec:DI [(match_dup 6) (match_dup 4)] UNSPEC_LDGP1)) + (use (match_dup 1)) + (use (match_dup 5)) + (clobber (reg:DI 26))]) + (set (match_dup 6) + (unspec:DI [(match_dup 6) (match_dup 4)] UNSPEC_LDGP2))] +{ + if (CONSTANT_P (operands[1])) + { + operands[3] = gen_rtx_REG (Pmode, 27); + operands[5] = GEN_INT (alpha_next_sequence_number++); + emit_insn (gen_movdi_er_high_g (operands[3], pic_offset_table_rtx, + operands[1], operands[5])); + } + else + { + operands[3] = operands[1]; + operands[1] = const0_rtx; + operands[5] = const0_rtx; + } + operands[4] = GEN_INT (alpha_next_sequence_number++); + operands[6] = pic_offset_table_rtx; +}) + +(define_insn "*call_value_osf_2_er_nogp" + [(set (match_operand 0 "" "") + (call (mem:DI (match_operand:DI 1 "register_operand" "c")) + (match_operand 2 "" ""))) + (use (reg:DI 29)) + (use (match_operand 3 "" "")) + (use (match_operand 4 "" "")) + (clobber (reg:DI 26))] + "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" + "jsr $26,(%1),%3%J4" + [(set_attr "type" "jsr")]) + +(define_insn "*call_value_osf_2_er" + [(set (match_operand 0 "" "") + (call (mem:DI (match_operand:DI 1 "register_operand" "c")) + (match_operand 2 "" ""))) + (set (reg:DI 29) + (unspec:DI [(reg:DI 29) (match_operand 5 "const_int_operand" "")] + UNSPEC_LDGP1)) + (use (match_operand 3 "" "")) + (use (match_operand 4 "" "")) + (clobber (reg:DI 26))] + "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" + "jsr $26,(%1),%3%J4\;ldah $29,0($26)\t\t!gpdisp!%5" + [(set_attr "type" "jsr") + (set_attr "cannot_copy" "true") + (set_attr "length" "8")]) + +(define_insn "*call_value_osf_1_noreturn" + [(set (match_operand 0 "" "") + (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s")) + (match_operand 2 "" ""))) + (use (reg:DI 29)) + (clobber (reg:DI 26))] + "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF + && find_reg_note (insn, REG_NORETURN, NULL_RTX)" + "@ + jsr $26,($27),0 + bsr $26,$%1..ng + jsr $26,%1" + [(set_attr "type" "jsr") + (set_attr "length" "*,*,8")]) + +(define_insn_and_split "call_value_osf_tlsgd" + [(set (match_operand 0 "" "") + (call (mem:DI (match_operand:DI 1 "symbolic_operand" "")) + (const_int 0))) + (unspec [(match_operand:DI 2 "const_int_operand" "")] UNSPEC_TLSGD_CALL) + (use (reg:DI 29)) + (clobber (reg:DI 26))] + "HAVE_AS_TLS" + "#" + "&& reload_completed" + [(set (match_dup 3) + (unspec:DI [(match_dup 5) + (match_dup 1) + (match_dup 2)] UNSPEC_LITERAL)) + (parallel [(set (match_dup 0) + (call (mem:DI (match_dup 3)) + (const_int 0))) + (set (match_dup 5) + (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP1)) + (use (match_dup 1)) + (use (unspec [(match_dup 2)] UNSPEC_TLSGD_CALL)) + (clobber (reg:DI 26))]) + (set (match_dup 5) + (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP2))] +{ + operands[3] = gen_rtx_REG (Pmode, 27); + operands[4] = GEN_INT (alpha_next_sequence_number++); + operands[5] = pic_offset_table_rtx; +} + [(set_attr "type" "multi")]) + +(define_insn_and_split "call_value_osf_tlsldm" + [(set (match_operand 0 "" "") + (call (mem:DI (match_operand:DI 1 "symbolic_operand" "")) + (const_int 0))) + (unspec [(match_operand:DI 2 "const_int_operand" "")] UNSPEC_TLSLDM_CALL) + (use (reg:DI 29)) + (clobber (reg:DI 26))] + "HAVE_AS_TLS" + "#" + "&& reload_completed" + [(set (match_dup 3) + (unspec:DI [(match_dup 5) + (match_dup 1) + (match_dup 2)] UNSPEC_LITERAL)) + (parallel [(set (match_dup 0) + (call (mem:DI (match_dup 3)) + (const_int 0))) + (set (match_dup 5) + (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP1)) + (use (match_dup 1)) + (use (unspec [(match_dup 2)] UNSPEC_TLSLDM_CALL)) + (clobber (reg:DI 26))]) + (set (match_dup 5) + (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP2))] +{ + operands[3] = gen_rtx_REG (Pmode, 27); + operands[4] = GEN_INT (alpha_next_sequence_number++); + operands[5] = pic_offset_table_rtx; +} + [(set_attr "type" "multi")]) + (define_insn "*call_value_osf_1" [(set (match_operand 0 "" "") (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s")) @@ -7064,7 +8052,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (unspec [(reg:DI 29)] UNSPEC_SIBCALL)] "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" "@ - br $31,$%1..ng + br $31,%1\t\t!samegp ldq $27,%1($29)\t\t!literal!%#\;jmp $31,($27),%1\t\t!lituse_jsr!%#" [(set_attr "type" "jsr") (set_attr "length" "*,8")]) @@ -7094,18 +8082,31 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" [(set_attr "type" "jsr") (set_attr "length" "*,*,12")]) +; GAS relies on the order and position of instructions output below in order +; to generate relocs for VMS link to potentially optimize the call. +; Please do not molest. (define_insn "*call_value_vms_1" [(set (match_operand 0 "" "") (call (mem:DI (match_operand:DI 1 "call_operand" "r,s")) (match_operand 2 "" ""))) - (use (match_operand:DI 3 "nonimmediate_operand" "r,m")) + (use (match_operand:DI 3 "nonmemory_operand" "r,n")) (use (reg:DI 25)) (use (reg:DI 26)) (clobber (reg:DI 27))] "TARGET_ABI_OPEN_VMS" - "@ - mov %3,$27\;jsr $26,0\;ldq $27,0($29) - ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)" +{ + switch (which_alternative) + { + case 0: + return "mov %3,$27\;jsr $26,0\;ldq $27,0($29)"; + case 1: + operands [3] = alpha_use_linkage (operands [1], cfun->decl, 1, 0); + operands [4] = alpha_use_linkage (operands [1], cfun->decl, 0, 0); + return "ldq $26,%4\;ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)"; + default: + gcc_unreachable (); + } +} [(set_attr "type" "jsr") (set_attr "length" "12,16")]) @@ -7118,4 +8119,3 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" "TARGET_ABI_UNICOSMK" "jsr $26,(%1)" [(set_attr "type" "jsr")]) -