;; Machine description for DEC Alpha for GNU C compiler
|
;; Machine description for DEC Alpha for GNU C compiler
|
;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
;; 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
|
;; 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
|
;; Free Software Foundation, Inc.
|
;; Free Software Foundation, Inc.
|
;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
|
;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
|
;;
|
;;
|
;; This file is part of GCC.
|
;; This file is part of GCC.
|
;;
|
;;
|
;; GCC is free software; you can redistribute it and/or modify
|
;; GCC is free software; you can redistribute it and/or modify
|
;; it under the terms of the GNU General Public License as published by
|
;; it under the terms of the GNU General Public License as published by
|
;; the Free Software Foundation; either version 3, or (at your option)
|
;; the Free Software Foundation; either version 3, or (at your option)
|
;; any later version.
|
;; any later version.
|
;;
|
;;
|
;; GCC is distributed in the hope that it will be useful,
|
;; GCC is distributed in the hope that it will be useful,
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
;; GNU General Public License for more details.
|
;; GNU General Public License for more details.
|
;;
|
;;
|
;; You should have received a copy of the GNU General Public License
|
;; You should have received a copy of the GNU General Public License
|
;; along with GCC; see the file COPYING3. If not see
|
;; along with GCC; see the file COPYING3. If not see
|
;; .
|
;; .
|
|
|
;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
|
;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
|
|
|
;; Uses of UNSPEC in this file:
|
;; Uses of UNSPEC in this file:
|
|
|
(define_constants
|
(define_constants
|
[(UNSPEC_ARG_HOME 0)
|
[(UNSPEC_ARG_HOME 0)
|
(UNSPEC_LDGP1 1)
|
(UNSPEC_LDGP1 1)
|
(UNSPEC_INSXH 2)
|
(UNSPEC_INSXH 2)
|
(UNSPEC_MSKXH 3)
|
(UNSPEC_MSKXH 3)
|
(UNSPEC_CVTQL 4)
|
(UNSPEC_CVTQL 4)
|
(UNSPEC_CVTLQ 5)
|
(UNSPEC_CVTLQ 5)
|
(UNSPEC_UMK_LAUM 6)
|
(UNSPEC_UMK_LAUM 6)
|
(UNSPEC_UMK_LALM 7)
|
(UNSPEC_UMK_LALM 7)
|
(UNSPEC_UMK_LAL 8)
|
(UNSPEC_UMK_LAL 8)
|
(UNSPEC_UMK_LOAD_CIW 9)
|
(UNSPEC_UMK_LOAD_CIW 9)
|
(UNSPEC_LDGP2 10)
|
(UNSPEC_LDGP2 10)
|
(UNSPEC_LITERAL 11)
|
(UNSPEC_LITERAL 11)
|
(UNSPEC_LITUSE 12)
|
(UNSPEC_LITUSE 12)
|
(UNSPEC_SIBCALL 13)
|
(UNSPEC_SIBCALL 13)
|
(UNSPEC_SYMBOL 14)
|
(UNSPEC_SYMBOL 14)
|
|
|
;; TLS Support
|
;; TLS Support
|
(UNSPEC_TLSGD_CALL 15)
|
(UNSPEC_TLSGD_CALL 15)
|
(UNSPEC_TLSLDM_CALL 16)
|
(UNSPEC_TLSLDM_CALL 16)
|
(UNSPEC_TLSGD 17)
|
(UNSPEC_TLSGD 17)
|
(UNSPEC_TLSLDM 18)
|
(UNSPEC_TLSLDM 18)
|
(UNSPEC_DTPREL 19)
|
(UNSPEC_DTPREL 19)
|
(UNSPEC_TPREL 20)
|
(UNSPEC_TPREL 20)
|
(UNSPEC_TP 21)
|
(UNSPEC_TP 21)
|
|
|
;; Builtins
|
;; Builtins
|
(UNSPEC_CMPBGE 22)
|
(UNSPEC_CMPBGE 22)
|
(UNSPEC_ZAP 23)
|
(UNSPEC_ZAP 23)
|
(UNSPEC_AMASK 24)
|
(UNSPEC_AMASK 24)
|
(UNSPEC_IMPLVER 25)
|
(UNSPEC_IMPLVER 25)
|
(UNSPEC_PERR 26)
|
(UNSPEC_PERR 26)
|
(UNSPEC_COPYSIGN 27)
|
(UNSPEC_COPYSIGN 27)
|
|
|
;; Atomic operations
|
;; Atomic operations
|
(UNSPEC_MB 28)
|
(UNSPEC_MB 28)
|
(UNSPEC_ATOMIC 31)
|
(UNSPEC_ATOMIC 31)
|
(UNSPEC_CMPXCHG 32)
|
(UNSPEC_CMPXCHG 32)
|
(UNSPEC_XCHG 33)
|
(UNSPEC_XCHG 33)
|
])
|
])
|
|
|
;; UNSPEC_VOLATILE:
|
;; UNSPEC_VOLATILE:
|
|
|
(define_constants
|
(define_constants
|
[(UNSPECV_IMB 0)
|
[(UNSPECV_IMB 0)
|
(UNSPECV_BLOCKAGE 1)
|
(UNSPECV_BLOCKAGE 1)
|
(UNSPECV_SETJMPR 2) ; builtin_setjmp_receiver
|
(UNSPECV_SETJMPR 2) ; builtin_setjmp_receiver
|
(UNSPECV_LONGJMP 3) ; builtin_longjmp
|
(UNSPECV_LONGJMP 3) ; builtin_longjmp
|
(UNSPECV_TRAPB 4)
|
(UNSPECV_TRAPB 4)
|
(UNSPECV_PSPL 5) ; prologue_stack_probe_loop
|
(UNSPECV_PSPL 5) ; prologue_stack_probe_loop
|
(UNSPECV_REALIGN 6)
|
(UNSPECV_REALIGN 6)
|
(UNSPECV_EHR 7) ; exception_receiver
|
(UNSPECV_EHR 7) ; exception_receiver
|
(UNSPECV_MCOUNT 8)
|
(UNSPECV_MCOUNT 8)
|
(UNSPECV_FORCE_MOV 9)
|
(UNSPECV_FORCE_MOV 9)
|
(UNSPECV_LDGP1 10)
|
(UNSPECV_LDGP1 10)
|
(UNSPECV_PLDGP2 11) ; prologue ldgp
|
(UNSPECV_PLDGP2 11) ; prologue ldgp
|
(UNSPECV_SET_TP 12)
|
(UNSPECV_SET_TP 12)
|
(UNSPECV_RPCC 13)
|
(UNSPECV_RPCC 13)
|
(UNSPECV_SETJMPR_ER 14) ; builtin_setjmp_receiver fragment
|
(UNSPECV_SETJMPR_ER 14) ; builtin_setjmp_receiver fragment
|
(UNSPECV_LL 15) ; load-locked
|
(UNSPECV_LL 15) ; load-locked
|
(UNSPECV_SC 16) ; store-conditional
|
(UNSPECV_SC 16) ; store-conditional
|
])
|
])
|
|
|
;; On non-BWX targets, CQImode must be handled the similarly to HImode
|
;; On non-BWX targets, CQImode must be handled the similarly to HImode
|
;; when generating reloads.
|
;; when generating reloads.
|
(define_mode_iterator RELOAD12 [QI HI CQI])
|
(define_mode_iterator RELOAD12 [QI HI CQI])
|
(define_mode_attr reloadmode [(QI "qi") (HI "hi") (CQI "hi")])
|
(define_mode_attr reloadmode [(QI "qi") (HI "hi") (CQI "hi")])
|
|
|
;; Other mode iterators
|
;; Other mode iterators
|
(define_mode_iterator I12MODE [QI HI])
|
(define_mode_iterator I12MODE [QI HI])
|
(define_mode_iterator I48MODE [SI DI])
|
(define_mode_iterator I48MODE [SI DI])
|
(define_mode_attr modesuffix [(SI "l") (DI "q")])
|
(define_mode_attr modesuffix [(SI "l") (DI "q")])
|
|
|
;; Where necessary, the suffixes _le and _be are used to distinguish between
|
;; Where necessary, the suffixes _le and _be are used to distinguish between
|
;; little-endian and big-endian patterns.
|
;; little-endian and big-endian patterns.
|
;;
|
;;
|
;; Note that the Unicos/Mk assembler does not support the following
|
;; Note that the Unicos/Mk assembler does not support the following
|
;; opcodes: mov, fmov, nop, fnop, unop.
|
;; opcodes: mov, fmov, nop, fnop, unop.
|
|
|
;; Processor type -- this attribute must exactly match the processor_type
|
;; Processor type -- this attribute must exactly match the processor_type
|
;; enumeration in alpha.h.
|
;; enumeration in alpha.h.
|
|
|
(define_attr "tune" "ev4,ev5,ev6"
|
(define_attr "tune" "ev4,ev5,ev6"
|
(const (symbol_ref "((enum attr_tune) alpha_tune)")))
|
(const (symbol_ref "((enum attr_tune) alpha_tune)")))
|
|
|
;; Define an insn type attribute. This is used in function unit delay
|
;; Define an insn type attribute. This is used in function unit delay
|
;; computations, among other purposes. For the most part, we use the names
|
;; computations, among other purposes. For the most part, we use the names
|
;; defined in the EV4 documentation, but add a few that we have to know about
|
;; defined in the EV4 documentation, but add a few that we have to know about
|
;; separately.
|
;; separately.
|
|
|
(define_attr "type"
|
(define_attr "type"
|
"ild,fld,ldsym,ist,fst,ibr,callpal,fbr,jsr,iadd,ilog,shift,icmov,fcmov,
|
"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,
|
icmp,imul,fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,mb,ld_l,st_c,
|
multi,none"
|
multi,none"
|
(const_string "iadd"))
|
(const_string "iadd"))
|
|
|
;; Describe a user's asm statement.
|
;; Describe a user's asm statement.
|
(define_asm_attributes
|
(define_asm_attributes
|
[(set_attr "type" "multi")])
|
[(set_attr "type" "multi")])
|
|
|
;; Define the operand size an insn operates on. Used primarily by mul
|
;; Define the operand size an insn operates on. Used primarily by mul
|
;; and div operations that have size dependent timings.
|
;; and div operations that have size dependent timings.
|
|
|
(define_attr "opsize" "si,di,udi"
|
(define_attr "opsize" "si,di,udi"
|
(const_string "di"))
|
(const_string "di"))
|
|
|
;; The TRAP attribute marks instructions that may generate traps
|
;; The TRAP attribute marks instructions that may generate traps
|
;; (which are imprecise and may need a trapb if software completion
|
;; (which are imprecise and may need a trapb if software completion
|
;; is desired).
|
;; is desired).
|
|
|
(define_attr "trap" "no,yes"
|
(define_attr "trap" "no,yes"
|
(const_string "no"))
|
(const_string "no"))
|
|
|
;; The ROUND_SUFFIX attribute marks which instructions require a
|
;; The ROUND_SUFFIX attribute marks which instructions require a
|
;; rounding-mode suffix. The value NONE indicates no suffix,
|
;; rounding-mode suffix. The value NONE indicates no suffix,
|
;; the value NORMAL indicates a suffix controlled by alpha_fprm.
|
;; the value NORMAL indicates a suffix controlled by alpha_fprm.
|
|
|
(define_attr "round_suffix" "none,normal,c"
|
(define_attr "round_suffix" "none,normal,c"
|
(const_string "none"))
|
(const_string "none"))
|
|
|
;; The TRAP_SUFFIX attribute marks instructions requiring a trap-mode suffix:
|
;; The TRAP_SUFFIX attribute marks instructions requiring a trap-mode suffix:
|
;; NONE no suffix
|
;; NONE no suffix
|
;; SU accepts only /su (cmpt et al)
|
;; SU accepts only /su (cmpt et al)
|
;; SUI accepts only /sui (cvtqt and cvtqs)
|
;; SUI accepts only /sui (cvtqt and cvtqs)
|
;; V_SV accepts /v and /sv (cvtql only)
|
;; V_SV accepts /v and /sv (cvtql only)
|
;; V_SV_SVI accepts /v, /sv and /svi (cvttq only)
|
;; V_SV_SVI accepts /v, /sv and /svi (cvttq only)
|
;; U_SU_SUI accepts /u, /su and /sui (most fp instructions)
|
;; U_SU_SUI accepts /u, /su and /sui (most fp instructions)
|
;;
|
;;
|
;; The actual suffix emitted is controlled 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"
|
(define_attr "trap_suffix" "none,su,sui,v_sv,v_sv_svi,u_su_sui"
|
(const_string "none"))
|
(const_string "none"))
|
|
|
;; The length of an instruction sequence in bytes.
|
;; The length of an instruction sequence in bytes.
|
|
|
(define_attr "length" ""
|
(define_attr "length" ""
|
(const_int 4))
|
(const_int 4))
|
|
|
;; The USEGP attribute marks instructions that have relocations that use
|
;; The USEGP attribute marks instructions that have relocations that use
|
;; the GP.
|
;; the GP.
|
|
|
(define_attr "usegp" "no,yes"
|
(define_attr "usegp" "no,yes"
|
(cond [(eq_attr "type" "ldsym,jsr")
|
(cond [(eq_attr "type" "ldsym,jsr")
|
(const_string "yes")
|
(const_string "yes")
|
(eq_attr "type" "ild,fld,ist,fst")
|
(eq_attr "type" "ild,fld,ist,fst")
|
(symbol_ref "((enum attr_usegp) alpha_find_lo_sum_using_gp (insn))")
|
(symbol_ref "((enum attr_usegp) alpha_find_lo_sum_using_gp (insn))")
|
]
|
]
|
(const_string "no")))
|
(const_string "no")))
|
|
|
;; The CANNOT_COPY attribute marks instructions with relocations that
|
;; The CANNOT_COPY attribute marks instructions with relocations that
|
;; cannot easily be duplicated. This includes insns with gpdisp relocs
|
;; cannot easily be duplicated. This includes insns with gpdisp relocs
|
;; since they have to stay in 1-1 correspondence with one another. This
|
;; since they have to stay in 1-1 correspondence with one another. This
|
;; also includes jsr insns, since they must stay in correspondence with
|
;; also includes jsr insns, since they must stay in correspondence with
|
;; the immediately following gpdisp instructions.
|
;; the immediately following gpdisp instructions.
|
|
|
(define_attr "cannot_copy" "false,true"
|
(define_attr "cannot_copy" "false,true"
|
(const_string "false"))
|
(const_string "false"))
|
|
|
;; Include scheduling descriptions.
|
;; Include scheduling descriptions.
|
|
|
(include "ev4.md")
|
(include "ev4.md")
|
(include "ev5.md")
|
(include "ev5.md")
|
(include "ev6.md")
|
(include "ev6.md")
|
|
|
|
|
;; Operand and operator predicates and constraints
|
;; Operand and operator predicates and constraints
|
|
|
(include "predicates.md")
|
(include "predicates.md")
|
(include "constraints.md")
|
(include "constraints.md")
|
|
|
|
|
;; First define the arithmetic insns. Note that the 32-bit forms also
|
;; First define the arithmetic insns. Note that the 32-bit forms also
|
;; sign-extend.
|
;; sign-extend.
|
|
|
;; Handle 32-64 bit extension from memory to a floating point register
|
;; Handle 32-64 bit extension from memory to a floating point register
|
;; specially, since this occurs frequently in int->double conversions.
|
;; specially, since this occurs frequently in int->double conversions.
|
;;
|
;;
|
;; Note that while we must retain the =f case in the insn for reload's
|
;; Note that while we must retain the =f case in the insn for reload's
|
;; benefit, it should be eliminated after reload, so we should never emit
|
;; benefit, it should be eliminated after reload, so we should never emit
|
;; code for that case. But we don't reject the possibility.
|
;; code for that case. But we don't reject the possibility.
|
|
|
(define_expand "extendsidi2"
|
(define_expand "extendsidi2"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
|
(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
|
""
|
""
|
"")
|
"")
|
|
|
(define_insn "*cvtlq"
|
(define_insn "*cvtlq"
|
[(set (match_operand:DI 0 "register_operand" "=f")
|
[(set (match_operand:DI 0 "register_operand" "=f")
|
(unspec:DI [(match_operand:SF 1 "reg_or_0_operand" "fG")]
|
(unspec:DI [(match_operand:SF 1 "reg_or_0_operand" "fG")]
|
UNSPEC_CVTLQ))]
|
UNSPEC_CVTLQ))]
|
""
|
""
|
"cvtlq %1,%0"
|
"cvtlq %1,%0"
|
[(set_attr "type" "fadd")])
|
[(set_attr "type" "fadd")])
|
|
|
(define_insn "*extendsidi2_1"
|
(define_insn "*extendsidi2_1"
|
[(set (match_operand:DI 0 "register_operand" "=r,r,!*f")
|
[(set (match_operand:DI 0 "register_operand" "=r,r,!*f")
|
(sign_extend:DI
|
(sign_extend:DI
|
(match_operand:SI 1 "nonimmediate_operand" "r,m,m")))]
|
(match_operand:SI 1 "nonimmediate_operand" "r,m,m")))]
|
""
|
""
|
"@
|
"@
|
addl $31,%1,%0
|
addl $31,%1,%0
|
ldl %0,%1
|
ldl %0,%1
|
lds %0,%1\;cvtlq %0,%0"
|
lds %0,%1\;cvtlq %0,%0"
|
[(set_attr "type" "iadd,ild,fld")
|
[(set_attr "type" "iadd,ild,fld")
|
(set_attr "length" "*,*,8")])
|
(set_attr "length" "*,*,8")])
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:DI 0 "hard_fp_register_operand" "")
|
[(set (match_operand:DI 0 "hard_fp_register_operand" "")
|
(sign_extend:DI (match_operand:SI 1 "memory_operand" "")))]
|
(sign_extend:DI (match_operand:SI 1 "memory_operand" "")))]
|
"reload_completed"
|
"reload_completed"
|
[(set (match_dup 2) (match_dup 1))
|
[(set (match_dup 2) (match_dup 1))
|
(set (match_dup 0) (unspec:DI [(match_dup 2)] UNSPEC_CVTLQ))]
|
(set (match_dup 0) (unspec:DI [(match_dup 2)] UNSPEC_CVTLQ))]
|
{
|
{
|
operands[1] = adjust_address (operands[1], SFmode, 0);
|
operands[1] = adjust_address (operands[1], SFmode, 0);
|
operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));
|
operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));
|
})
|
})
|
|
|
;; Optimize sign-extension of SImode loads. This shows up in the wake of
|
;; Optimize sign-extension of SImode loads. This shows up in the wake of
|
;; reload when converting fp->int.
|
;; reload when converting fp->int.
|
|
|
(define_peephole2
|
(define_peephole2
|
[(set (match_operand:SI 0 "hard_int_register_operand" "")
|
[(set (match_operand:SI 0 "hard_int_register_operand" "")
|
(match_operand:SI 1 "memory_operand" ""))
|
(match_operand:SI 1 "memory_operand" ""))
|
(set (match_operand:DI 2 "hard_int_register_operand" "")
|
(set (match_operand:DI 2 "hard_int_register_operand" "")
|
(sign_extend:DI (match_dup 0)))]
|
(sign_extend:DI (match_dup 0)))]
|
"true_regnum (operands[0]) == true_regnum (operands[2])
|
"true_regnum (operands[0]) == true_regnum (operands[2])
|
|| peep2_reg_dead_p (2, operands[0])"
|
|| peep2_reg_dead_p (2, operands[0])"
|
[(set (match_dup 2)
|
[(set (match_dup 2)
|
(sign_extend:DI (match_dup 1)))]
|
(sign_extend:DI (match_dup 1)))]
|
"")
|
"")
|
|
|
(define_insn "addsi3"
|
(define_insn "addsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
|
[(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")
|
(plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ")
|
(match_operand:SI 2 "add_operand" "rI,O,K,L")))]
|
(match_operand:SI 2 "add_operand" "rI,O,K,L")))]
|
""
|
""
|
"@
|
"@
|
addl %r1,%2,%0
|
addl %r1,%2,%0
|
subl %r1,%n2,%0
|
subl %r1,%n2,%0
|
lda %0,%2(%r1)
|
lda %0,%2(%r1)
|
ldah %0,%h2(%r1)")
|
ldah %0,%h2(%r1)")
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:SI 0 "register_operand" "")
|
[(set (match_operand:SI 0 "register_operand" "")
|
(plus:SI (match_operand:SI 1 "register_operand" "")
|
(plus:SI (match_operand:SI 1 "register_operand" "")
|
(match_operand:SI 2 "const_int_operand" "")))]
|
(match_operand:SI 2 "const_int_operand" "")))]
|
"! add_operand (operands[2], SImode)"
|
"! add_operand (operands[2], SImode)"
|
[(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))
|
[(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))
|
(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
|
(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
|
{
|
{
|
HOST_WIDE_INT val = INTVAL (operands[2]);
|
HOST_WIDE_INT val = INTVAL (operands[2]);
|
HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
|
HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
|
HOST_WIDE_INT rest = val - low;
|
HOST_WIDE_INT rest = val - low;
|
|
|
operands[3] = GEN_INT (rest);
|
operands[3] = GEN_INT (rest);
|
operands[4] = GEN_INT (low);
|
operands[4] = GEN_INT (low);
|
})
|
})
|
|
|
(define_insn "*addsi_se"
|
(define_insn "*addsi_se"
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
(sign_extend:DI
|
(sign_extend:DI
|
(plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
|
(plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
|
(match_operand:SI 2 "sext_add_operand" "rI,O"))))]
|
(match_operand:SI 2 "sext_add_operand" "rI,O"))))]
|
""
|
""
|
"@
|
"@
|
addl %r1,%2,%0
|
addl %r1,%2,%0
|
subl %r1,%n2,%0")
|
subl %r1,%n2,%0")
|
|
|
(define_insn "*addsi_se2"
|
(define_insn "*addsi_se2"
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
(sign_extend:DI
|
(sign_extend:DI
|
(subreg:SI (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
|
(subreg:SI (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
|
(match_operand:DI 2 "sext_add_operand" "rI,O"))
|
(match_operand:DI 2 "sext_add_operand" "rI,O"))
|
0)))]
|
0)))]
|
""
|
""
|
"@
|
"@
|
addl %r1,%2,%0
|
addl %r1,%2,%0
|
subl %r1,%n2,%0")
|
subl %r1,%n2,%0")
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(sign_extend:DI
|
(sign_extend:DI
|
(plus:SI (match_operand:SI 1 "reg_not_elim_operand" "")
|
(plus:SI (match_operand:SI 1 "reg_not_elim_operand" "")
|
(match_operand:SI 2 "const_int_operand" ""))))
|
(match_operand:SI 2 "const_int_operand" ""))))
|
(clobber (match_operand:SI 3 "reg_not_elim_operand" ""))]
|
(clobber (match_operand:SI 3 "reg_not_elim_operand" ""))]
|
"! sext_add_operand (operands[2], SImode) && INTVAL (operands[2]) > 0
|
"! sext_add_operand (operands[2], SImode) && INTVAL (operands[2]) > 0
|
&& INTVAL (operands[2]) % 4 == 0"
|
&& INTVAL (operands[2]) % 4 == 0"
|
[(set (match_dup 3) (match_dup 4))
|
[(set (match_dup 3) (match_dup 4))
|
(set (match_dup 0) (sign_extend:DI (plus:SI (mult:SI (match_dup 3)
|
(set (match_dup 0) (sign_extend:DI (plus:SI (mult:SI (match_dup 3)
|
(match_dup 5))
|
(match_dup 5))
|
(match_dup 1))))]
|
(match_dup 1))))]
|
{
|
{
|
HOST_WIDE_INT val = INTVAL (operands[2]) / 4;
|
HOST_WIDE_INT val = INTVAL (operands[2]) / 4;
|
int mult = 4;
|
int mult = 4;
|
|
|
if (val % 2 == 0)
|
if (val % 2 == 0)
|
val /= 2, mult = 8;
|
val /= 2, mult = 8;
|
|
|
operands[4] = GEN_INT (val);
|
operands[4] = GEN_INT (val);
|
operands[5] = GEN_INT (mult);
|
operands[5] = GEN_INT (mult);
|
})
|
})
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(sign_extend:DI
|
(sign_extend:DI
|
(plus:SI (match_operator:SI 1 "comparison_operator"
|
(plus:SI (match_operator:SI 1 "comparison_operator"
|
[(match_operand 2 "" "")
|
[(match_operand 2 "" "")
|
(match_operand 3 "" "")])
|
(match_operand 3 "" "")])
|
(match_operand:SI 4 "add_operand" ""))))
|
(match_operand:SI 4 "add_operand" ""))))
|
(clobber (match_operand:DI 5 "register_operand" ""))]
|
(clobber (match_operand:DI 5 "register_operand" ""))]
|
""
|
""
|
[(set (match_dup 5) (match_dup 6))
|
[(set (match_dup 5) (match_dup 6))
|
(set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 7) (match_dup 4))))]
|
(set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 7) (match_dup 4))))]
|
{
|
{
|
operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[1]), DImode,
|
operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[1]), DImode,
|
operands[2], operands[3]);
|
operands[2], operands[3]);
|
operands[7] = gen_lowpart (SImode, operands[5]);
|
operands[7] = gen_lowpart (SImode, operands[5]);
|
})
|
})
|
|
|
(define_insn "addvsi3"
|
(define_insn "addvsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
(plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
|
(plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
|
(match_operand:SI 2 "sext_add_operand" "rI,O")))
|
(match_operand:SI 2 "sext_add_operand" "rI,O")))
|
(trap_if (ne (plus:DI (sign_extend:DI (match_dup 1))
|
(trap_if (ne (plus:DI (sign_extend:DI (match_dup 1))
|
(sign_extend:DI (match_dup 2)))
|
(sign_extend:DI (match_dup 2)))
|
(sign_extend:DI (plus:SI (match_dup 1)
|
(sign_extend:DI (plus:SI (match_dup 1)
|
(match_dup 2))))
|
(match_dup 2))))
|
(const_int 0))]
|
(const_int 0))]
|
""
|
""
|
"@
|
"@
|
addlv %r1,%2,%0
|
addlv %r1,%2,%0
|
sublv %r1,%n2,%0")
|
sublv %r1,%n2,%0")
|
|
|
(define_expand "adddi3"
|
(define_expand "adddi3"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(plus:DI (match_operand:DI 1 "register_operand" "")
|
(plus:DI (match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 2 "add_operand" "")))]
|
(match_operand:DI 2 "add_operand" "")))]
|
""
|
""
|
"")
|
"")
|
|
|
(define_insn "*adddi_er_lo16_dtp"
|
(define_insn "*adddi_er_lo16_dtp"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
|
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
|
(match_operand:DI 2 "dtp16_symbolic_operand" "")))]
|
(match_operand:DI 2 "dtp16_symbolic_operand" "")))]
|
"HAVE_AS_TLS"
|
"HAVE_AS_TLS"
|
"lda %0,%2(%1)\t\t!dtprel")
|
"lda %0,%2(%1)\t\t!dtprel")
|
|
|
(define_insn "*adddi_er_hi32_dtp"
|
(define_insn "*adddi_er_hi32_dtp"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(plus:DI (match_operand:DI 1 "register_operand" "r")
|
(plus:DI (match_operand:DI 1 "register_operand" "r")
|
(high:DI (match_operand:DI 2 "dtp32_symbolic_operand" ""))))]
|
(high:DI (match_operand:DI 2 "dtp32_symbolic_operand" ""))))]
|
"HAVE_AS_TLS"
|
"HAVE_AS_TLS"
|
"ldah %0,%2(%1)\t\t!dtprelhi")
|
"ldah %0,%2(%1)\t\t!dtprelhi")
|
|
|
(define_insn "*adddi_er_lo32_dtp"
|
(define_insn "*adddi_er_lo32_dtp"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
|
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
|
(match_operand:DI 2 "dtp32_symbolic_operand" "")))]
|
(match_operand:DI 2 "dtp32_symbolic_operand" "")))]
|
"HAVE_AS_TLS"
|
"HAVE_AS_TLS"
|
"lda %0,%2(%1)\t\t!dtprello")
|
"lda %0,%2(%1)\t\t!dtprello")
|
|
|
(define_insn "*adddi_er_lo16_tp"
|
(define_insn "*adddi_er_lo16_tp"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
|
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
|
(match_operand:DI 2 "tp16_symbolic_operand" "")))]
|
(match_operand:DI 2 "tp16_symbolic_operand" "")))]
|
"HAVE_AS_TLS"
|
"HAVE_AS_TLS"
|
"lda %0,%2(%1)\t\t!tprel")
|
"lda %0,%2(%1)\t\t!tprel")
|
|
|
(define_insn "*adddi_er_hi32_tp"
|
(define_insn "*adddi_er_hi32_tp"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(plus:DI (match_operand:DI 1 "register_operand" "r")
|
(plus:DI (match_operand:DI 1 "register_operand" "r")
|
(high:DI (match_operand:DI 2 "tp32_symbolic_operand" ""))))]
|
(high:DI (match_operand:DI 2 "tp32_symbolic_operand" ""))))]
|
"HAVE_AS_TLS"
|
"HAVE_AS_TLS"
|
"ldah %0,%2(%1)\t\t!tprelhi")
|
"ldah %0,%2(%1)\t\t!tprelhi")
|
|
|
(define_insn "*adddi_er_lo32_tp"
|
(define_insn "*adddi_er_lo32_tp"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
|
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
|
(match_operand:DI 2 "tp32_symbolic_operand" "")))]
|
(match_operand:DI 2 "tp32_symbolic_operand" "")))]
|
"HAVE_AS_TLS"
|
"HAVE_AS_TLS"
|
"lda %0,%2(%1)\t\t!tprello")
|
"lda %0,%2(%1)\t\t!tprello")
|
|
|
(define_insn "*adddi_er_high_l"
|
(define_insn "*adddi_er_high_l"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(plus:DI (match_operand:DI 1 "register_operand" "r")
|
(plus:DI (match_operand:DI 1 "register_operand" "r")
|
(high:DI (match_operand:DI 2 "local_symbolic_operand" ""))))]
|
(high:DI (match_operand:DI 2 "local_symbolic_operand" ""))))]
|
"TARGET_EXPLICIT_RELOCS && reload_completed"
|
"TARGET_EXPLICIT_RELOCS && reload_completed"
|
"ldah %0,%2(%1)\t\t!gprelhigh"
|
"ldah %0,%2(%1)\t\t!gprelhigh"
|
[(set_attr "usegp" "yes")])
|
[(set_attr "usegp" "yes")])
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(high:DI (match_operand:DI 1 "local_symbolic_operand" "")))]
|
(high:DI (match_operand:DI 1 "local_symbolic_operand" "")))]
|
"TARGET_EXPLICIT_RELOCS && reload_completed"
|
"TARGET_EXPLICIT_RELOCS && reload_completed"
|
[(set (match_dup 0)
|
[(set (match_dup 0)
|
(plus:DI (match_dup 2) (high:DI (match_dup 1))))]
|
(plus:DI (match_dup 2) (high:DI (match_dup 1))))]
|
"operands[2] = pic_offset_table_rtx;")
|
"operands[2] = pic_offset_table_rtx;")
|
|
|
;; We used to expend quite a lot of effort choosing addq/subq/lda.
|
;; We used to expend quite a lot of effort choosing addq/subq/lda.
|
;; With complications like
|
;; With complications like
|
;;
|
;;
|
;; The NT stack unwind code can't handle a subq to adjust the stack
|
;; The NT stack unwind code can't handle a subq to adjust the stack
|
;; (that's a bug, but not one we can do anything about). As of NT4.0 SP3,
|
;; (that's a bug, but not one we can do anything about). As of NT4.0 SP3,
|
;; the exception handling code will loop if a subq is used and an
|
;; the exception handling code will loop if a subq is used and an
|
;; exception occurs.
|
;; exception occurs.
|
;;
|
;;
|
;; The 19980616 change to emit prologues as RTL also confused some
|
;; The 19980616 change to emit prologues as RTL also confused some
|
;; versions of GDB, which also interprets prologues. This has been
|
;; versions of GDB, which also interprets prologues. This has been
|
;; fixed as of GDB 4.18, but it does not harm to unconditionally
|
;; fixed as of GDB 4.18, but it does not harm to unconditionally
|
;; use lda here.
|
;; use lda here.
|
;;
|
;;
|
;; and the fact that the three insns schedule exactly the same, it's
|
;; and the fact that the three insns schedule exactly the same, it's
|
;; just not worth the effort.
|
;; just not worth the effort.
|
|
|
(define_insn "*adddi_internal"
|
(define_insn "*adddi_internal"
|
[(set (match_operand:DI 0 "register_operand" "=r,r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r,r")
|
(plus:DI (match_operand:DI 1 "register_operand" "%r,r,r")
|
(plus:DI (match_operand:DI 1 "register_operand" "%r,r,r")
|
(match_operand:DI 2 "add_operand" "r,K,L")))]
|
(match_operand:DI 2 "add_operand" "r,K,L")))]
|
""
|
""
|
"@
|
"@
|
addq %1,%2,%0
|
addq %1,%2,%0
|
lda %0,%2(%1)
|
lda %0,%2(%1)
|
ldah %0,%h2(%1)")
|
ldah %0,%h2(%1)")
|
|
|
;; ??? Allow large constants when basing off the frame pointer or some
|
;; ??? Allow large constants when basing off the frame pointer or some
|
;; virtual register that may eliminate to the frame pointer. This is
|
;; virtual register that may eliminate to the frame pointer. This is
|
;; done because register elimination offsets will change the hi/lo split,
|
;; done because register elimination offsets will change the hi/lo split,
|
;; and if we split before reload, we will require additional instructions.
|
;; and if we split before reload, we will require additional instructions.
|
|
|
(define_insn "*adddi_fp_hack"
|
(define_insn "*adddi_fp_hack"
|
[(set (match_operand:DI 0 "register_operand" "=r,r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r,r")
|
(plus:DI (match_operand:DI 1 "reg_no_subreg_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")))]
|
(match_operand:DI 2 "const_int_operand" "K,L,n")))]
|
"NONSTRICT_REG_OK_FP_BASE_P (operands[1])
|
"NONSTRICT_REG_OK_FP_BASE_P (operands[1])
|
&& INTVAL (operands[2]) >= 0
|
&& INTVAL (operands[2]) >= 0
|
/* This is the largest constant an lda+ldah pair can add, minus
|
/* This is the largest constant an lda+ldah pair can add, minus
|
an upper bound on the displacement between SP and AP during
|
an upper bound on the displacement between SP and AP during
|
register elimination. See INITIAL_ELIMINATION_OFFSET. */
|
register elimination. See INITIAL_ELIMINATION_OFFSET. */
|
&& INTVAL (operands[2])
|
&& INTVAL (operands[2])
|
< (0x7fff8000
|
< (0x7fff8000
|
- FIRST_PSEUDO_REGISTER * UNITS_PER_WORD
|
- FIRST_PSEUDO_REGISTER * UNITS_PER_WORD
|
- ALPHA_ROUND(crtl->outgoing_args_size)
|
- ALPHA_ROUND(crtl->outgoing_args_size)
|
- (ALPHA_ROUND (get_frame_size ()
|
- (ALPHA_ROUND (get_frame_size ()
|
+ max_reg_num () * UNITS_PER_WORD
|
+ max_reg_num () * UNITS_PER_WORD
|
+ crtl->args.pretend_args_size)
|
+ crtl->args.pretend_args_size)
|
- crtl->args.pretend_args_size))"
|
- crtl->args.pretend_args_size))"
|
"@
|
"@
|
lda %0,%2(%1)
|
lda %0,%2(%1)
|
ldah %0,%h2(%1)
|
ldah %0,%h2(%1)
|
#")
|
#")
|
|
|
;; Don't do this if we are adjusting SP since we don't want to do it
|
;; 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.
|
;; in two steps. Don't split FP sources for the reason listed above.
|
(define_split
|
(define_split
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(plus:DI (match_operand:DI 1 "register_operand" "")
|
(plus:DI (match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 2 "const_int_operand" "")))]
|
(match_operand:DI 2 "const_int_operand" "")))]
|
"! add_operand (operands[2], DImode)
|
"! add_operand (operands[2], DImode)
|
&& operands[0] != stack_pointer_rtx
|
&& operands[0] != stack_pointer_rtx
|
&& operands[1] != frame_pointer_rtx
|
&& operands[1] != frame_pointer_rtx
|
&& operands[1] != arg_pointer_rtx"
|
&& operands[1] != arg_pointer_rtx"
|
[(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3)))
|
[(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3)))
|
(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
|
(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
|
{
|
{
|
HOST_WIDE_INT val = INTVAL (operands[2]);
|
HOST_WIDE_INT val = INTVAL (operands[2]);
|
HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
|
HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
|
HOST_WIDE_INT rest = val - low;
|
HOST_WIDE_INT rest = val - low;
|
rtx rest_rtx = GEN_INT (rest);
|
rtx rest_rtx = GEN_INT (rest);
|
|
|
operands[4] = GEN_INT (low);
|
operands[4] = GEN_INT (low);
|
if (satisfies_constraint_L (rest_rtx))
|
if (satisfies_constraint_L (rest_rtx))
|
operands[3] = rest_rtx;
|
operands[3] = rest_rtx;
|
else if (can_create_pseudo_p ())
|
else if (can_create_pseudo_p ())
|
{
|
{
|
operands[3] = gen_reg_rtx (DImode);
|
operands[3] = gen_reg_rtx (DImode);
|
emit_move_insn (operands[3], operands[2]);
|
emit_move_insn (operands[3], operands[2]);
|
emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
|
emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
|
DONE;
|
DONE;
|
}
|
}
|
else
|
else
|
FAIL;
|
FAIL;
|
})
|
})
|
|
|
(define_insn "*saddl"
|
(define_insn "*saddl"
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
(plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r")
|
(plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r")
|
(match_operand:SI 2 "const48_operand" "I,I"))
|
(match_operand:SI 2 "const48_operand" "I,I"))
|
(match_operand:SI 3 "sext_add_operand" "rI,O")))]
|
(match_operand:SI 3 "sext_add_operand" "rI,O")))]
|
""
|
""
|
"@
|
"@
|
s%2addl %1,%3,%0
|
s%2addl %1,%3,%0
|
s%2subl %1,%n3,%0")
|
s%2subl %1,%n3,%0")
|
|
|
(define_insn "*saddl_se"
|
(define_insn "*saddl_se"
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
(sign_extend:DI
|
(sign_extend:DI
|
(plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r")
|
(plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r")
|
(match_operand:SI 2 "const48_operand" "I,I"))
|
(match_operand:SI 2 "const48_operand" "I,I"))
|
(match_operand:SI 3 "sext_add_operand" "rI,O"))))]
|
(match_operand:SI 3 "sext_add_operand" "rI,O"))))]
|
""
|
""
|
"@
|
"@
|
s%2addl %1,%3,%0
|
s%2addl %1,%3,%0
|
s%2subl %1,%n3,%0")
|
s%2subl %1,%n3,%0")
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(sign_extend:DI
|
(sign_extend:DI
|
(plus:SI (mult:SI (match_operator:SI 1 "comparison_operator"
|
(plus:SI (mult:SI (match_operator:SI 1 "comparison_operator"
|
[(match_operand 2 "" "")
|
[(match_operand 2 "" "")
|
(match_operand 3 "" "")])
|
(match_operand 3 "" "")])
|
(match_operand:SI 4 "const48_operand" ""))
|
(match_operand:SI 4 "const48_operand" ""))
|
(match_operand:SI 5 "sext_add_operand" ""))))
|
(match_operand:SI 5 "sext_add_operand" ""))))
|
(clobber (match_operand:DI 6 "reg_not_elim_operand" ""))]
|
(clobber (match_operand:DI 6 "reg_not_elim_operand" ""))]
|
""
|
""
|
[(set (match_dup 6) (match_dup 7))
|
[(set (match_dup 6) (match_dup 7))
|
(set (match_dup 0)
|
(set (match_dup 0)
|
(sign_extend:DI (plus:SI (mult:SI (match_dup 8) (match_dup 4))
|
(sign_extend:DI (plus:SI (mult:SI (match_dup 8) (match_dup 4))
|
(match_dup 5))))]
|
(match_dup 5))))]
|
{
|
{
|
operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[1]), DImode,
|
operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[1]), DImode,
|
operands[2], operands[3]);
|
operands[2], operands[3]);
|
operands[8] = gen_lowpart (SImode, operands[6]);
|
operands[8] = gen_lowpart (SImode, operands[6]);
|
})
|
})
|
|
|
(define_insn "*saddq"
|
(define_insn "*saddq"
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
(plus:DI (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r,r")
|
(plus:DI (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r,r")
|
(match_operand:DI 2 "const48_operand" "I,I"))
|
(match_operand:DI 2 "const48_operand" "I,I"))
|
(match_operand:DI 3 "sext_add_operand" "rI,O")))]
|
(match_operand:DI 3 "sext_add_operand" "rI,O")))]
|
""
|
""
|
"@
|
"@
|
s%2addq %1,%3,%0
|
s%2addq %1,%3,%0
|
s%2subq %1,%n3,%0")
|
s%2subq %1,%n3,%0")
|
|
|
(define_insn "addvdi3"
|
(define_insn "addvdi3"
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
(plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
|
(plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
|
(match_operand:DI 2 "sext_add_operand" "rI,O")))
|
(match_operand:DI 2 "sext_add_operand" "rI,O")))
|
(trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
|
(trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
|
(sign_extend:TI (match_dup 2)))
|
(sign_extend:TI (match_dup 2)))
|
(sign_extend:TI (plus:DI (match_dup 1)
|
(sign_extend:TI (plus:DI (match_dup 1)
|
(match_dup 2))))
|
(match_dup 2))))
|
(const_int 0))]
|
(const_int 0))]
|
""
|
""
|
"@
|
"@
|
addqv %r1,%2,%0
|
addqv %r1,%2,%0
|
subqv %r1,%n2,%0")
|
subqv %r1,%n2,%0")
|
|
|
(define_insn "negsi2"
|
(define_insn "negsi2"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(neg:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")))]
|
(neg:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")))]
|
""
|
""
|
"subl $31,%1,%0")
|
"subl $31,%1,%0")
|
|
|
(define_insn "*negsi_se"
|
(define_insn "*negsi_se"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(sign_extend:DI (neg:SI
|
(sign_extend:DI (neg:SI
|
(match_operand:SI 1 "reg_or_8bit_operand" "rI"))))]
|
(match_operand:SI 1 "reg_or_8bit_operand" "rI"))))]
|
""
|
""
|
"subl $31,%1,%0")
|
"subl $31,%1,%0")
|
|
|
(define_insn "negvsi2"
|
(define_insn "negvsi2"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(neg:SI (match_operand:SI 1 "register_operand" "r")))
|
(neg:SI (match_operand:SI 1 "register_operand" "r")))
|
(trap_if (ne (neg:DI (sign_extend:DI (match_dup 1)))
|
(trap_if (ne (neg:DI (sign_extend:DI (match_dup 1)))
|
(sign_extend:DI (neg:SI (match_dup 1))))
|
(sign_extend:DI (neg:SI (match_dup 1))))
|
(const_int 0))]
|
(const_int 0))]
|
""
|
""
|
"sublv $31,%1,%0")
|
"sublv $31,%1,%0")
|
|
|
(define_insn "negdi2"
|
(define_insn "negdi2"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(neg:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
|
(neg:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
|
""
|
""
|
"subq $31,%1,%0")
|
"subq $31,%1,%0")
|
|
|
(define_insn "negvdi2"
|
(define_insn "negvdi2"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(neg:DI (match_operand:DI 1 "register_operand" "r")))
|
(neg:DI (match_operand:DI 1 "register_operand" "r")))
|
(trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
|
(trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
|
(sign_extend:TI (neg:DI (match_dup 1))))
|
(sign_extend:TI (neg:DI (match_dup 1))))
|
(const_int 0))]
|
(const_int 0))]
|
""
|
""
|
"subqv $31,%1,%0")
|
"subqv $31,%1,%0")
|
|
|
(define_insn "subsi3"
|
(define_insn "subsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
|
(minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
|
(match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
|
(match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
|
""
|
""
|
"subl %r1,%2,%0")
|
"subl %r1,%2,%0")
|
|
|
(define_insn "*subsi_se"
|
(define_insn "*subsi_se"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
|
(sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
|
(match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
|
(match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
|
""
|
""
|
"subl %r1,%2,%0")
|
"subl %r1,%2,%0")
|
|
|
(define_insn "*subsi_se2"
|
(define_insn "*subsi_se2"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(sign_extend:DI
|
(sign_extend:DI
|
(subreg:SI (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(subreg:SI (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(match_operand:DI 2 "reg_or_8bit_operand" "rI"))
|
(match_operand:DI 2 "reg_or_8bit_operand" "rI"))
|
0)))]
|
0)))]
|
""
|
""
|
"subl %r1,%2,%0")
|
"subl %r1,%2,%0")
|
|
|
(define_insn "subvsi3"
|
(define_insn "subvsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
|
(minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
|
(match_operand:SI 2 "reg_or_8bit_operand" "rI")))
|
(match_operand:SI 2 "reg_or_8bit_operand" "rI")))
|
(trap_if (ne (minus:DI (sign_extend:DI (match_dup 1))
|
(trap_if (ne (minus:DI (sign_extend:DI (match_dup 1))
|
(sign_extend:DI (match_dup 2)))
|
(sign_extend:DI (match_dup 2)))
|
(sign_extend:DI (minus:SI (match_dup 1)
|
(sign_extend:DI (minus:SI (match_dup 1)
|
(match_dup 2))))
|
(match_dup 2))))
|
(const_int 0))]
|
(const_int 0))]
|
""
|
""
|
"sublv %r1,%2,%0")
|
"sublv %r1,%2,%0")
|
|
|
(define_insn "subdi3"
|
(define_insn "subdi3"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(match_operand:DI 2 "reg_or_8bit_operand" "rI")))]
|
(match_operand:DI 2 "reg_or_8bit_operand" "rI")))]
|
""
|
""
|
"subq %r1,%2,%0")
|
"subq %r1,%2,%0")
|
|
|
(define_insn "*ssubl"
|
(define_insn "*ssubl"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r")
|
(minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r")
|
(match_operand:SI 2 "const48_operand" "I"))
|
(match_operand:SI 2 "const48_operand" "I"))
|
(match_operand:SI 3 "reg_or_8bit_operand" "rI")))]
|
(match_operand:SI 3 "reg_or_8bit_operand" "rI")))]
|
""
|
""
|
"s%2subl %1,%3,%0")
|
"s%2subl %1,%3,%0")
|
|
|
(define_insn "*ssubl_se"
|
(define_insn "*ssubl_se"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(sign_extend:DI
|
(sign_extend:DI
|
(minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r")
|
(minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r")
|
(match_operand:SI 2 "const48_operand" "I"))
|
(match_operand:SI 2 "const48_operand" "I"))
|
(match_operand:SI 3 "reg_or_8bit_operand" "rI"))))]
|
(match_operand:SI 3 "reg_or_8bit_operand" "rI"))))]
|
""
|
""
|
"s%2subl %1,%3,%0")
|
"s%2subl %1,%3,%0")
|
|
|
(define_insn "*ssubq"
|
(define_insn "*ssubq"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(minus:DI (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r")
|
(minus:DI (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r")
|
(match_operand:DI 2 "const48_operand" "I"))
|
(match_operand:DI 2 "const48_operand" "I"))
|
(match_operand:DI 3 "reg_or_8bit_operand" "rI")))]
|
(match_operand:DI 3 "reg_or_8bit_operand" "rI")))]
|
""
|
""
|
"s%2subq %1,%3,%0")
|
"s%2subq %1,%3,%0")
|
|
|
(define_insn "subvdi3"
|
(define_insn "subvdi3"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(match_operand:DI 2 "reg_or_8bit_operand" "rI")))
|
(match_operand:DI 2 "reg_or_8bit_operand" "rI")))
|
(trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
|
(trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
|
(sign_extend:TI (match_dup 2)))
|
(sign_extend:TI (match_dup 2)))
|
(sign_extend:TI (minus:DI (match_dup 1)
|
(sign_extend:TI (minus:DI (match_dup 1)
|
(match_dup 2))))
|
(match_dup 2))))
|
(const_int 0))]
|
(const_int 0))]
|
""
|
""
|
"subqv %r1,%2,%0")
|
"subqv %r1,%2,%0")
|
|
|
;; The Unicos/Mk assembler doesn't support mull.
|
;; The Unicos/Mk assembler doesn't support mull.
|
|
|
(define_insn "mulsi3"
|
(define_insn "mulsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
|
(mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
|
(match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
|
(match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
|
"!TARGET_ABI_UNICOSMK"
|
"!TARGET_ABI_UNICOSMK"
|
"mull %r1,%2,%0"
|
"mull %r1,%2,%0"
|
[(set_attr "type" "imul")
|
[(set_attr "type" "imul")
|
(set_attr "opsize" "si")])
|
(set_attr "opsize" "si")])
|
|
|
(define_insn "*mulsi_se"
|
(define_insn "*mulsi_se"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(sign_extend:DI
|
(sign_extend:DI
|
(mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
|
(mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
|
(match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
|
(match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
|
"!TARGET_ABI_UNICOSMK"
|
"!TARGET_ABI_UNICOSMK"
|
"mull %r1,%2,%0"
|
"mull %r1,%2,%0"
|
[(set_attr "type" "imul")
|
[(set_attr "type" "imul")
|
(set_attr "opsize" "si")])
|
(set_attr "opsize" "si")])
|
|
|
(define_insn "mulvsi3"
|
(define_insn "mulvsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
|
(mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
|
(match_operand:SI 2 "reg_or_8bit_operand" "rI")))
|
(match_operand:SI 2 "reg_or_8bit_operand" "rI")))
|
(trap_if (ne (mult:DI (sign_extend:DI (match_dup 1))
|
(trap_if (ne (mult:DI (sign_extend:DI (match_dup 1))
|
(sign_extend:DI (match_dup 2)))
|
(sign_extend:DI (match_dup 2)))
|
(sign_extend:DI (mult:SI (match_dup 1)
|
(sign_extend:DI (mult:SI (match_dup 1)
|
(match_dup 2))))
|
(match_dup 2))))
|
(const_int 0))]
|
(const_int 0))]
|
"!TARGET_ABI_UNICOSMK"
|
"!TARGET_ABI_UNICOSMK"
|
"mullv %r1,%2,%0"
|
"mullv %r1,%2,%0"
|
[(set_attr "type" "imul")
|
[(set_attr "type" "imul")
|
(set_attr "opsize" "si")])
|
(set_attr "opsize" "si")])
|
|
|
(define_insn "muldi3"
|
(define_insn "muldi3"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(mult:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
|
(mult:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
|
(match_operand:DI 2 "reg_or_8bit_operand" "rI")))]
|
(match_operand:DI 2 "reg_or_8bit_operand" "rI")))]
|
""
|
""
|
"mulq %r1,%2,%0"
|
"mulq %r1,%2,%0"
|
[(set_attr "type" "imul")])
|
[(set_attr "type" "imul")])
|
|
|
(define_insn "mulvdi3"
|
(define_insn "mulvdi3"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(mult:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
|
(mult:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
|
(match_operand:DI 2 "reg_or_8bit_operand" "rI")))
|
(match_operand:DI 2 "reg_or_8bit_operand" "rI")))
|
(trap_if (ne (mult:TI (sign_extend:TI (match_dup 1))
|
(trap_if (ne (mult:TI (sign_extend:TI (match_dup 1))
|
(sign_extend:TI (match_dup 2)))
|
(sign_extend:TI (match_dup 2)))
|
(sign_extend:TI (mult:DI (match_dup 1)
|
(sign_extend:TI (mult:DI (match_dup 1)
|
(match_dup 2))))
|
(match_dup 2))))
|
(const_int 0))]
|
(const_int 0))]
|
""
|
""
|
"mulqv %r1,%2,%0"
|
"mulqv %r1,%2,%0"
|
[(set_attr "type" "imul")])
|
[(set_attr "type" "imul")])
|
|
|
(define_expand "umuldi3_highpart"
|
(define_expand "umuldi3_highpart"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(truncate:DI
|
(truncate:DI
|
(lshiftrt:TI
|
(lshiftrt:TI
|
(mult:TI (zero_extend:TI
|
(mult:TI (zero_extend:TI
|
(match_operand:DI 1 "register_operand" ""))
|
(match_operand:DI 1 "register_operand" ""))
|
(match_operand:DI 2 "reg_or_8bit_operand" ""))
|
(match_operand:DI 2 "reg_or_8bit_operand" ""))
|
(const_int 64))))]
|
(const_int 64))))]
|
""
|
""
|
{
|
{
|
if (REG_P (operands[2]))
|
if (REG_P (operands[2]))
|
operands[2] = gen_rtx_ZERO_EXTEND (TImode, operands[2]);
|
operands[2] = gen_rtx_ZERO_EXTEND (TImode, operands[2]);
|
})
|
})
|
|
|
(define_insn "*umuldi3_highpart_reg"
|
(define_insn "*umuldi3_highpart_reg"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(truncate:DI
|
(truncate:DI
|
(lshiftrt:TI
|
(lshiftrt:TI
|
(mult:TI (zero_extend:TI
|
(mult:TI (zero_extend:TI
|
(match_operand:DI 1 "register_operand" "r"))
|
(match_operand:DI 1 "register_operand" "r"))
|
(zero_extend:TI
|
(zero_extend:TI
|
(match_operand:DI 2 "register_operand" "r")))
|
(match_operand:DI 2 "register_operand" "r")))
|
(const_int 64))))]
|
(const_int 64))))]
|
""
|
""
|
"umulh %1,%2,%0"
|
"umulh %1,%2,%0"
|
[(set_attr "type" "imul")
|
[(set_attr "type" "imul")
|
(set_attr "opsize" "udi")])
|
(set_attr "opsize" "udi")])
|
|
|
(define_insn "*umuldi3_highpart_const"
|
(define_insn "*umuldi3_highpart_const"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(truncate:DI
|
(truncate:DI
|
(lshiftrt:TI
|
(lshiftrt:TI
|
(mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
|
(mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
|
(match_operand:TI 2 "cint8_operand" "I"))
|
(match_operand:TI 2 "cint8_operand" "I"))
|
(const_int 64))))]
|
(const_int 64))))]
|
""
|
""
|
"umulh %1,%2,%0"
|
"umulh %1,%2,%0"
|
[(set_attr "type" "imul")
|
[(set_attr "type" "imul")
|
(set_attr "opsize" "udi")])
|
(set_attr "opsize" "udi")])
|
|
|
;; The divide and remainder operations take their inputs from r24 and
|
;; The divide and remainder operations take their inputs from r24 and
|
;; r25, put their output in r27, and clobber r23 and r28 on all
|
;; r25, put their output in r27, and clobber r23 and r28 on all
|
;; systems except Unicos/Mk. On Unicos, the standard library provides
|
;; systems except Unicos/Mk. On Unicos, the standard library provides
|
;; subroutines which use the standard calling convention and work on
|
;; subroutines which use the standard calling convention and work on
|
;; DImode operands.
|
;; DImode operands.
|
|
|
;; ??? Force sign-extension here because some versions of OSF/1 and
|
;; ??? Force sign-extension here because some versions of OSF/1 and
|
;; Interix/NT don't do the right thing if the inputs are not properly
|
;; Interix/NT don't do the right thing if the inputs are not properly
|
;; sign-extended. But Linux, for instance, does not have this
|
;; sign-extended. But Linux, for instance, does not have this
|
;; problem. Is it worth the complication here to eliminate the sign
|
;; problem. Is it worth the complication here to eliminate the sign
|
;; extension?
|
;; extension?
|
|
|
(define_expand "divsi3"
|
(define_expand "divsi3"
|
[(set (match_dup 3)
|
[(set (match_dup 3)
|
(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
|
(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
|
(set (match_dup 4)
|
(set (match_dup 4)
|
(sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
|
(sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
|
(parallel [(set (match_dup 5)
|
(parallel [(set (match_dup 5)
|
(sign_extend:DI (div:SI (match_dup 3) (match_dup 4))))
|
(sign_extend:DI (div:SI (match_dup 3) (match_dup 4))))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 28))])
|
(clobber (reg:DI 28))])
|
(set (match_operand:SI 0 "nonimmediate_operand" "")
|
(set (match_operand:SI 0 "nonimmediate_operand" "")
|
(subreg:SI (match_dup 5) 0))]
|
(subreg:SI (match_dup 5) 0))]
|
"! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
|
"! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
|
{
|
{
|
operands[3] = gen_reg_rtx (DImode);
|
operands[3] = gen_reg_rtx (DImode);
|
operands[4] = gen_reg_rtx (DImode);
|
operands[4] = gen_reg_rtx (DImode);
|
operands[5] = gen_reg_rtx (DImode);
|
operands[5] = gen_reg_rtx (DImode);
|
})
|
})
|
|
|
(define_expand "udivsi3"
|
(define_expand "udivsi3"
|
[(set (match_dup 3)
|
[(set (match_dup 3)
|
(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
|
(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
|
(set (match_dup 4)
|
(set (match_dup 4)
|
(sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
|
(sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
|
(parallel [(set (match_dup 5)
|
(parallel [(set (match_dup 5)
|
(sign_extend:DI (udiv:SI (match_dup 3) (match_dup 4))))
|
(sign_extend:DI (udiv:SI (match_dup 3) (match_dup 4))))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 28))])
|
(clobber (reg:DI 28))])
|
(set (match_operand:SI 0 "nonimmediate_operand" "")
|
(set (match_operand:SI 0 "nonimmediate_operand" "")
|
(subreg:SI (match_dup 5) 0))]
|
(subreg:SI (match_dup 5) 0))]
|
"! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
|
"! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
|
{
|
{
|
operands[3] = gen_reg_rtx (DImode);
|
operands[3] = gen_reg_rtx (DImode);
|
operands[4] = gen_reg_rtx (DImode);
|
operands[4] = gen_reg_rtx (DImode);
|
operands[5] = gen_reg_rtx (DImode);
|
operands[5] = gen_reg_rtx (DImode);
|
})
|
})
|
|
|
(define_expand "modsi3"
|
(define_expand "modsi3"
|
[(set (match_dup 3)
|
[(set (match_dup 3)
|
(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
|
(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
|
(set (match_dup 4)
|
(set (match_dup 4)
|
(sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
|
(sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
|
(parallel [(set (match_dup 5)
|
(parallel [(set (match_dup 5)
|
(sign_extend:DI (mod:SI (match_dup 3) (match_dup 4))))
|
(sign_extend:DI (mod:SI (match_dup 3) (match_dup 4))))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 28))])
|
(clobber (reg:DI 28))])
|
(set (match_operand:SI 0 "nonimmediate_operand" "")
|
(set (match_operand:SI 0 "nonimmediate_operand" "")
|
(subreg:SI (match_dup 5) 0))]
|
(subreg:SI (match_dup 5) 0))]
|
"! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
|
"! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
|
{
|
{
|
operands[3] = gen_reg_rtx (DImode);
|
operands[3] = gen_reg_rtx (DImode);
|
operands[4] = gen_reg_rtx (DImode);
|
operands[4] = gen_reg_rtx (DImode);
|
operands[5] = gen_reg_rtx (DImode);
|
operands[5] = gen_reg_rtx (DImode);
|
})
|
})
|
|
|
(define_expand "umodsi3"
|
(define_expand "umodsi3"
|
[(set (match_dup 3)
|
[(set (match_dup 3)
|
(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
|
(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
|
(set (match_dup 4)
|
(set (match_dup 4)
|
(sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
|
(sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
|
(parallel [(set (match_dup 5)
|
(parallel [(set (match_dup 5)
|
(sign_extend:DI (umod:SI (match_dup 3) (match_dup 4))))
|
(sign_extend:DI (umod:SI (match_dup 3) (match_dup 4))))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 28))])
|
(clobber (reg:DI 28))])
|
(set (match_operand:SI 0 "nonimmediate_operand" "")
|
(set (match_operand:SI 0 "nonimmediate_operand" "")
|
(subreg:SI (match_dup 5) 0))]
|
(subreg:SI (match_dup 5) 0))]
|
"! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
|
"! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
|
{
|
{
|
operands[3] = gen_reg_rtx (DImode);
|
operands[3] = gen_reg_rtx (DImode);
|
operands[4] = gen_reg_rtx (DImode);
|
operands[4] = gen_reg_rtx (DImode);
|
operands[5] = gen_reg_rtx (DImode);
|
operands[5] = gen_reg_rtx (DImode);
|
})
|
})
|
|
|
(define_expand "divdi3"
|
(define_expand "divdi3"
|
[(parallel [(set (match_operand:DI 0 "register_operand" "")
|
[(parallel [(set (match_operand:DI 0 "register_operand" "")
|
(div:DI (match_operand:DI 1 "register_operand" "")
|
(div:DI (match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 2 "register_operand" "")))
|
(match_operand:DI 2 "register_operand" "")))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 28))])]
|
(clobber (reg:DI 28))])]
|
"! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
|
"! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
|
"")
|
"")
|
|
|
(define_expand "udivdi3"
|
(define_expand "udivdi3"
|
[(parallel [(set (match_operand:DI 0 "register_operand" "")
|
[(parallel [(set (match_operand:DI 0 "register_operand" "")
|
(udiv:DI (match_operand:DI 1 "register_operand" "")
|
(udiv:DI (match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 2 "register_operand" "")))
|
(match_operand:DI 2 "register_operand" "")))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 28))])]
|
(clobber (reg:DI 28))])]
|
"! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
|
"! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
|
"")
|
"")
|
|
|
(define_expand "moddi3"
|
(define_expand "moddi3"
|
[(use (match_operand:DI 0 "register_operand" ""))
|
[(use (match_operand:DI 0 "register_operand" ""))
|
(use (match_operand:DI 1 "register_operand" ""))
|
(use (match_operand:DI 1 "register_operand" ""))
|
(use (match_operand:DI 2 "register_operand" ""))]
|
(use (match_operand:DI 2 "register_operand" ""))]
|
"!TARGET_ABI_OPEN_VMS"
|
"!TARGET_ABI_OPEN_VMS"
|
{
|
{
|
if (TARGET_ABI_UNICOSMK)
|
if (TARGET_ABI_UNICOSMK)
|
emit_insn (gen_moddi3_umk (operands[0], operands[1], operands[2]));
|
emit_insn (gen_moddi3_umk (operands[0], operands[1], operands[2]));
|
else
|
else
|
emit_insn (gen_moddi3_dft (operands[0], operands[1], operands[2]));
|
emit_insn (gen_moddi3_dft (operands[0], operands[1], operands[2]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "moddi3_dft"
|
(define_expand "moddi3_dft"
|
[(parallel [(set (match_operand:DI 0 "register_operand" "")
|
[(parallel [(set (match_operand:DI 0 "register_operand" "")
|
(mod:DI (match_operand:DI 1 "register_operand" "")
|
(mod:DI (match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 2 "register_operand" "")))
|
(match_operand:DI 2 "register_operand" "")))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 28))])]
|
(clobber (reg:DI 28))])]
|
"! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
|
"! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
|
"")
|
"")
|
|
|
;; On Unicos/Mk, we do as the system's C compiler does:
|
;; On Unicos/Mk, we do as the system's C compiler does:
|
;; compute the quotient, multiply and subtract.
|
;; compute the quotient, multiply and subtract.
|
|
|
(define_expand "moddi3_umk"
|
(define_expand "moddi3_umk"
|
[(use (match_operand:DI 0 "register_operand" ""))
|
[(use (match_operand:DI 0 "register_operand" ""))
|
(use (match_operand:DI 1 "register_operand" ""))
|
(use (match_operand:DI 1 "register_operand" ""))
|
(use (match_operand:DI 2 "register_operand" ""))]
|
(use (match_operand:DI 2 "register_operand" ""))]
|
"TARGET_ABI_UNICOSMK"
|
"TARGET_ABI_UNICOSMK"
|
{
|
{
|
rtx div, mul = gen_reg_rtx (DImode);
|
rtx div, mul = gen_reg_rtx (DImode);
|
|
|
div = expand_binop (DImode, sdiv_optab, operands[1], operands[2],
|
div = expand_binop (DImode, sdiv_optab, operands[1], operands[2],
|
NULL_RTX, 0, OPTAB_LIB);
|
NULL_RTX, 0, OPTAB_LIB);
|
div = force_reg (DImode, div);
|
div = force_reg (DImode, div);
|
emit_insn (gen_muldi3 (mul, operands[2], div));
|
emit_insn (gen_muldi3 (mul, operands[2], div));
|
emit_insn (gen_subdi3 (operands[0], operands[1], mul));
|
emit_insn (gen_subdi3 (operands[0], operands[1], mul));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "umoddi3"
|
(define_expand "umoddi3"
|
[(use (match_operand:DI 0 "register_operand" ""))
|
[(use (match_operand:DI 0 "register_operand" ""))
|
(use (match_operand:DI 1 "register_operand" ""))
|
(use (match_operand:DI 1 "register_operand" ""))
|
(use (match_operand:DI 2 "register_operand" ""))]
|
(use (match_operand:DI 2 "register_operand" ""))]
|
"! TARGET_ABI_OPEN_VMS"
|
"! TARGET_ABI_OPEN_VMS"
|
{
|
{
|
if (TARGET_ABI_UNICOSMK)
|
if (TARGET_ABI_UNICOSMK)
|
emit_insn (gen_umoddi3_umk (operands[0], operands[1], operands[2]));
|
emit_insn (gen_umoddi3_umk (operands[0], operands[1], operands[2]));
|
else
|
else
|
emit_insn (gen_umoddi3_dft (operands[0], operands[1], operands[2]));
|
emit_insn (gen_umoddi3_dft (operands[0], operands[1], operands[2]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "umoddi3_dft"
|
(define_expand "umoddi3_dft"
|
[(parallel [(set (match_operand:DI 0 "register_operand" "")
|
[(parallel [(set (match_operand:DI 0 "register_operand" "")
|
(umod:DI (match_operand:DI 1 "register_operand" "")
|
(umod:DI (match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 2 "register_operand" "")))
|
(match_operand:DI 2 "register_operand" "")))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 28))])]
|
(clobber (reg:DI 28))])]
|
"! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
|
"! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
|
"")
|
"")
|
|
|
(define_expand "umoddi3_umk"
|
(define_expand "umoddi3_umk"
|
[(use (match_operand:DI 0 "register_operand" ""))
|
[(use (match_operand:DI 0 "register_operand" ""))
|
(use (match_operand:DI 1 "register_operand" ""))
|
(use (match_operand:DI 1 "register_operand" ""))
|
(use (match_operand:DI 2 "register_operand" ""))]
|
(use (match_operand:DI 2 "register_operand" ""))]
|
"TARGET_ABI_UNICOSMK"
|
"TARGET_ABI_UNICOSMK"
|
{
|
{
|
rtx div, mul = gen_reg_rtx (DImode);
|
rtx div, mul = gen_reg_rtx (DImode);
|
|
|
div = expand_binop (DImode, udiv_optab, operands[1], operands[2],
|
div = expand_binop (DImode, udiv_optab, operands[1], operands[2],
|
NULL_RTX, 1, OPTAB_LIB);
|
NULL_RTX, 1, OPTAB_LIB);
|
div = force_reg (DImode, div);
|
div = force_reg (DImode, div);
|
emit_insn (gen_muldi3 (mul, operands[2], div));
|
emit_insn (gen_muldi3 (mul, operands[2], div));
|
emit_insn (gen_subdi3 (operands[0], operands[1], mul));
|
emit_insn (gen_subdi3 (operands[0], operands[1], mul));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
;; Lengths of 8 for ldq $t12,__divq($gp); jsr $t9,($t12),__divq as
|
;; Lengths of 8 for ldq $t12,__divq($gp); jsr $t9,($t12),__divq as
|
;; expanded by the assembler.
|
;; expanded by the assembler.
|
|
|
(define_insn_and_split "*divmodsi_internal_er"
|
(define_insn_and_split "*divmodsi_internal_er"
|
[(set (match_operand:DI 0 "register_operand" "=c")
|
[(set (match_operand:DI 0 "register_operand" "=c")
|
(sign_extend:DI (match_operator:SI 3 "divmod_operator"
|
(sign_extend:DI (match_operator:SI 3 "divmod_operator"
|
[(match_operand:DI 1 "register_operand" "a")
|
[(match_operand:DI 1 "register_operand" "a")
|
(match_operand:DI 2 "register_operand" "b")])))
|
(match_operand:DI 2 "register_operand" "b")])))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 28))]
|
(clobber (reg:DI 28))]
|
"TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
|
"TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
|
"#"
|
"#"
|
"&& reload_completed"
|
"&& reload_completed"
|
[(parallel [(set (match_dup 0)
|
[(parallel [(set (match_dup 0)
|
(sign_extend:DI (match_dup 3)))
|
(sign_extend:DI (match_dup 3)))
|
(use (match_dup 0))
|
(use (match_dup 0))
|
(use (match_dup 4))
|
(use (match_dup 4))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 28))])]
|
(clobber (reg:DI 28))])]
|
{
|
{
|
const char *str;
|
const char *str;
|
switch (GET_CODE (operands[3]))
|
switch (GET_CODE (operands[3]))
|
{
|
{
|
case DIV:
|
case DIV:
|
str = "__divl";
|
str = "__divl";
|
break;
|
break;
|
case UDIV:
|
case UDIV:
|
str = "__divlu";
|
str = "__divlu";
|
break;
|
break;
|
case MOD:
|
case MOD:
|
str = "__reml";
|
str = "__reml";
|
break;
|
break;
|
case UMOD:
|
case UMOD:
|
str = "__remlu";
|
str = "__remlu";
|
break;
|
break;
|
default:
|
default:
|
gcc_unreachable ();
|
gcc_unreachable ();
|
}
|
}
|
operands[4] = GEN_INT (alpha_next_sequence_number++);
|
operands[4] = GEN_INT (alpha_next_sequence_number++);
|
emit_insn (gen_movdi_er_high_g (operands[0], pic_offset_table_rtx,
|
emit_insn (gen_movdi_er_high_g (operands[0], pic_offset_table_rtx,
|
gen_rtx_SYMBOL_REF (DImode, str),
|
gen_rtx_SYMBOL_REF (DImode, str),
|
operands[4]));
|
operands[4]));
|
}
|
}
|
[(set_attr "type" "jsr")
|
[(set_attr "type" "jsr")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn "*divmodsi_internal_er_1"
|
(define_insn "*divmodsi_internal_er_1"
|
[(set (match_operand:DI 0 "register_operand" "=c")
|
[(set (match_operand:DI 0 "register_operand" "=c")
|
(sign_extend:DI (match_operator:SI 3 "divmod_operator"
|
(sign_extend:DI (match_operator:SI 3 "divmod_operator"
|
[(match_operand:DI 1 "register_operand" "a")
|
[(match_operand:DI 1 "register_operand" "a")
|
(match_operand:DI 2 "register_operand" "b")])))
|
(match_operand:DI 2 "register_operand" "b")])))
|
(use (match_operand:DI 4 "register_operand" "c"))
|
(use (match_operand:DI 4 "register_operand" "c"))
|
(use (match_operand 5 "const_int_operand" ""))
|
(use (match_operand 5 "const_int_operand" ""))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 28))]
|
(clobber (reg:DI 28))]
|
"TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
|
"TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
|
"jsr $23,($27),__%E3%j5"
|
"jsr $23,($27),__%E3%j5"
|
[(set_attr "type" "jsr")
|
[(set_attr "type" "jsr")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "*divmodsi_internal"
|
(define_insn "*divmodsi_internal"
|
[(set (match_operand:DI 0 "register_operand" "=c")
|
[(set (match_operand:DI 0 "register_operand" "=c")
|
(sign_extend:DI (match_operator:SI 3 "divmod_operator"
|
(sign_extend:DI (match_operator:SI 3 "divmod_operator"
|
[(match_operand:DI 1 "register_operand" "a")
|
[(match_operand:DI 1 "register_operand" "a")
|
(match_operand:DI 2 "register_operand" "b")])))
|
(match_operand:DI 2 "register_operand" "b")])))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 28))]
|
(clobber (reg:DI 28))]
|
"! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
|
"! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
|
"%E3 %1,%2,%0"
|
"%E3 %1,%2,%0"
|
[(set_attr "type" "jsr")
|
[(set_attr "type" "jsr")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn_and_split "*divmoddi_internal_er"
|
(define_insn_and_split "*divmoddi_internal_er"
|
[(set (match_operand:DI 0 "register_operand" "=c")
|
[(set (match_operand:DI 0 "register_operand" "=c")
|
(match_operator:DI 3 "divmod_operator"
|
(match_operator:DI 3 "divmod_operator"
|
[(match_operand:DI 1 "register_operand" "a")
|
[(match_operand:DI 1 "register_operand" "a")
|
(match_operand:DI 2 "register_operand" "b")]))
|
(match_operand:DI 2 "register_operand" "b")]))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 28))]
|
(clobber (reg:DI 28))]
|
"TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
|
"TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
|
"#"
|
"#"
|
"&& reload_completed"
|
"&& reload_completed"
|
[(parallel [(set (match_dup 0) (match_dup 3))
|
[(parallel [(set (match_dup 0) (match_dup 3))
|
(use (match_dup 0))
|
(use (match_dup 0))
|
(use (match_dup 4))
|
(use (match_dup 4))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 28))])]
|
(clobber (reg:DI 28))])]
|
{
|
{
|
const char *str;
|
const char *str;
|
switch (GET_CODE (operands[3]))
|
switch (GET_CODE (operands[3]))
|
{
|
{
|
case DIV:
|
case DIV:
|
str = "__divq";
|
str = "__divq";
|
break;
|
break;
|
case UDIV:
|
case UDIV:
|
str = "__divqu";
|
str = "__divqu";
|
break;
|
break;
|
case MOD:
|
case MOD:
|
str = "__remq";
|
str = "__remq";
|
break;
|
break;
|
case UMOD:
|
case UMOD:
|
str = "__remqu";
|
str = "__remqu";
|
break;
|
break;
|
default:
|
default:
|
gcc_unreachable ();
|
gcc_unreachable ();
|
}
|
}
|
operands[4] = GEN_INT (alpha_next_sequence_number++);
|
operands[4] = GEN_INT (alpha_next_sequence_number++);
|
emit_insn (gen_movdi_er_high_g (operands[0], pic_offset_table_rtx,
|
emit_insn (gen_movdi_er_high_g (operands[0], pic_offset_table_rtx,
|
gen_rtx_SYMBOL_REF (DImode, str),
|
gen_rtx_SYMBOL_REF (DImode, str),
|
operands[4]));
|
operands[4]));
|
}
|
}
|
[(set_attr "type" "jsr")
|
[(set_attr "type" "jsr")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn "*divmoddi_internal_er_1"
|
(define_insn "*divmoddi_internal_er_1"
|
[(set (match_operand:DI 0 "register_operand" "=c")
|
[(set (match_operand:DI 0 "register_operand" "=c")
|
(match_operator:DI 3 "divmod_operator"
|
(match_operator:DI 3 "divmod_operator"
|
[(match_operand:DI 1 "register_operand" "a")
|
[(match_operand:DI 1 "register_operand" "a")
|
(match_operand:DI 2 "register_operand" "b")]))
|
(match_operand:DI 2 "register_operand" "b")]))
|
(use (match_operand:DI 4 "register_operand" "c"))
|
(use (match_operand:DI 4 "register_operand" "c"))
|
(use (match_operand 5 "const_int_operand" ""))
|
(use (match_operand 5 "const_int_operand" ""))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 28))]
|
(clobber (reg:DI 28))]
|
"TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
|
"TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
|
"jsr $23,($27),__%E3%j5"
|
"jsr $23,($27),__%E3%j5"
|
[(set_attr "type" "jsr")
|
[(set_attr "type" "jsr")
|
(set_attr "length" "4")])
|
(set_attr "length" "4")])
|
|
|
(define_insn "*divmoddi_internal"
|
(define_insn "*divmoddi_internal"
|
[(set (match_operand:DI 0 "register_operand" "=c")
|
[(set (match_operand:DI 0 "register_operand" "=c")
|
(match_operator:DI 3 "divmod_operator"
|
(match_operator:DI 3 "divmod_operator"
|
[(match_operand:DI 1 "register_operand" "a")
|
[(match_operand:DI 1 "register_operand" "a")
|
(match_operand:DI 2 "register_operand" "b")]))
|
(match_operand:DI 2 "register_operand" "b")]))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 28))]
|
(clobber (reg:DI 28))]
|
"! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
|
"! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
|
"%E3 %1,%2,%0"
|
"%E3 %1,%2,%0"
|
[(set_attr "type" "jsr")
|
[(set_attr "type" "jsr")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
;; Next are the basic logical operations. We only expose the DImode operations
|
;; 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
|
;; to the rtl expanders, but SImode versions exist for combine as well as for
|
;; the atomic operation splitters.
|
;; the atomic operation splitters.
|
|
|
(define_insn "*andsi_internal"
|
(define_insn "*andsi_internal"
|
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
|
(and:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ")
|
(and:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ")
|
(match_operand:SI 2 "and_operand" "rI,N,MH")))]
|
(match_operand:SI 2 "and_operand" "rI,N,MH")))]
|
""
|
""
|
"@
|
"@
|
and %r1,%2,%0
|
and %r1,%2,%0
|
bic %r1,%N2,%0
|
bic %r1,%N2,%0
|
zapnot %r1,%m2,%0"
|
zapnot %r1,%m2,%0"
|
[(set_attr "type" "ilog,ilog,shift")])
|
[(set_attr "type" "ilog,ilog,shift")])
|
|
|
(define_insn "anddi3"
|
(define_insn "anddi3"
|
[(set (match_operand:DI 0 "register_operand" "=r,r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r,r")
|
(and:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ")
|
(and:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ")
|
(match_operand:DI 2 "and_operand" "rI,N,MH")))]
|
(match_operand:DI 2 "and_operand" "rI,N,MH")))]
|
""
|
""
|
"@
|
"@
|
and %r1,%2,%0
|
and %r1,%2,%0
|
bic %r1,%N2,%0
|
bic %r1,%N2,%0
|
zapnot %r1,%m2,%0"
|
zapnot %r1,%m2,%0"
|
[(set_attr "type" "ilog,ilog,shift")])
|
[(set_attr "type" "ilog,ilog,shift")])
|
|
|
;; There are times when we can split an AND into two AND insns. This occurs
|
;; There are times when we can split an AND into two AND insns. This occurs
|
;; when we can first clear any bytes and then clear anything else. For
|
;; when we can first clear any bytes and then clear anything else. For
|
;; example "I & 0xffff07" is "(I & 0xffffff) & 0xffffffffffffff07".
|
;; example "I & 0xffff07" is "(I & 0xffffff) & 0xffffffffffffff07".
|
;; Only do this when running on 64-bit host since the computations are
|
;; Only do this when running on 64-bit host since the computations are
|
;; too messy otherwise.
|
;; too messy otherwise.
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(and:DI (match_operand:DI 1 "register_operand" "")
|
(and:DI (match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 2 "const_int_operand" "")))]
|
(match_operand:DI 2 "const_int_operand" "")))]
|
"HOST_BITS_PER_WIDE_INT == 64 && ! and_operand (operands[2], DImode)"
|
"HOST_BITS_PER_WIDE_INT == 64 && ! and_operand (operands[2], DImode)"
|
[(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3)))
|
[(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3)))
|
(set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))]
|
(set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))]
|
{
|
{
|
unsigned HOST_WIDE_INT mask1 = INTVAL (operands[2]);
|
unsigned HOST_WIDE_INT mask1 = INTVAL (operands[2]);
|
unsigned HOST_WIDE_INT mask2 = mask1;
|
unsigned HOST_WIDE_INT mask2 = mask1;
|
int i;
|
int i;
|
|
|
/* For each byte that isn't all zeros, make it all ones. */
|
/* For each byte that isn't all zeros, make it all ones. */
|
for (i = 0; i < 64; i += 8)
|
for (i = 0; i < 64; i += 8)
|
if ((mask1 & ((HOST_WIDE_INT) 0xff << i)) != 0)
|
if ((mask1 & ((HOST_WIDE_INT) 0xff << i)) != 0)
|
mask1 |= (HOST_WIDE_INT) 0xff << i;
|
mask1 |= (HOST_WIDE_INT) 0xff << i;
|
|
|
/* Now turn on any bits we've just turned off. */
|
/* Now turn on any bits we've just turned off. */
|
mask2 |= ~ mask1;
|
mask2 |= ~ mask1;
|
|
|
operands[3] = GEN_INT (mask1);
|
operands[3] = GEN_INT (mask1);
|
operands[4] = GEN_INT (mask2);
|
operands[4] = GEN_INT (mask2);
|
})
|
})
|
|
|
(define_expand "zero_extendqihi2"
|
(define_expand "zero_extendqihi2"
|
[(set (match_operand:HI 0 "register_operand" "")
|
[(set (match_operand:HI 0 "register_operand" "")
|
(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
|
(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
|
""
|
""
|
{
|
{
|
if (! TARGET_BWX)
|
if (! TARGET_BWX)
|
operands[1] = force_reg (QImode, operands[1]);
|
operands[1] = force_reg (QImode, operands[1]);
|
})
|
})
|
|
|
(define_insn "*zero_extendqihi2_bwx"
|
(define_insn "*zero_extendqihi2_bwx"
|
[(set (match_operand:HI 0 "register_operand" "=r,r")
|
[(set (match_operand:HI 0 "register_operand" "=r,r")
|
(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
|
(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
|
"TARGET_BWX"
|
"TARGET_BWX"
|
"@
|
"@
|
and %1,0xff,%0
|
and %1,0xff,%0
|
ldbu %0,%1"
|
ldbu %0,%1"
|
[(set_attr "type" "ilog,ild")])
|
[(set_attr "type" "ilog,ild")])
|
|
|
(define_insn "*zero_extendqihi2_nobwx"
|
(define_insn "*zero_extendqihi2_nobwx"
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
(zero_extend:HI (match_operand:QI 1 "register_operand" "r")))]
|
(zero_extend:HI (match_operand:QI 1 "register_operand" "r")))]
|
"! TARGET_BWX"
|
"! TARGET_BWX"
|
"and %1,0xff,%0"
|
"and %1,0xff,%0"
|
[(set_attr "type" "ilog")])
|
[(set_attr "type" "ilog")])
|
|
|
(define_expand "zero_extendqisi2"
|
(define_expand "zero_extendqisi2"
|
[(set (match_operand:SI 0 "register_operand" "")
|
[(set (match_operand:SI 0 "register_operand" "")
|
(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
|
(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
|
""
|
""
|
{
|
{
|
if (! TARGET_BWX)
|
if (! TARGET_BWX)
|
operands[1] = force_reg (QImode, operands[1]);
|
operands[1] = force_reg (QImode, operands[1]);
|
})
|
})
|
|
|
(define_insn "*zero_extendqisi2_bwx"
|
(define_insn "*zero_extendqisi2_bwx"
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
|
(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
|
"TARGET_BWX"
|
"TARGET_BWX"
|
"@
|
"@
|
and %1,0xff,%0
|
and %1,0xff,%0
|
ldbu %0,%1"
|
ldbu %0,%1"
|
[(set_attr "type" "ilog,ild")])
|
[(set_attr "type" "ilog,ild")])
|
|
|
(define_insn "*zero_extendqisi2_nobwx"
|
(define_insn "*zero_extendqisi2_nobwx"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(zero_extend:SI (match_operand:QI 1 "register_operand" "r")))]
|
(zero_extend:SI (match_operand:QI 1 "register_operand" "r")))]
|
"! TARGET_BWX"
|
"! TARGET_BWX"
|
"and %1,0xff,%0"
|
"and %1,0xff,%0"
|
[(set_attr "type" "ilog")])
|
[(set_attr "type" "ilog")])
|
|
|
(define_expand "zero_extendqidi2"
|
(define_expand "zero_extendqidi2"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
|
(zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
|
""
|
""
|
{
|
{
|
if (! TARGET_BWX)
|
if (! TARGET_BWX)
|
operands[1] = force_reg (QImode, operands[1]);
|
operands[1] = force_reg (QImode, operands[1]);
|
})
|
})
|
|
|
(define_insn "*zero_extendqidi2_bwx"
|
(define_insn "*zero_extendqidi2_bwx"
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
(zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
|
(zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
|
"TARGET_BWX"
|
"TARGET_BWX"
|
"@
|
"@
|
and %1,0xff,%0
|
and %1,0xff,%0
|
ldbu %0,%1"
|
ldbu %0,%1"
|
[(set_attr "type" "ilog,ild")])
|
[(set_attr "type" "ilog,ild")])
|
|
|
(define_insn "*zero_extendqidi2_nobwx"
|
(define_insn "*zero_extendqidi2_nobwx"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
|
(zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
|
"! TARGET_BWX"
|
"! TARGET_BWX"
|
"and %1,0xff,%0"
|
"and %1,0xff,%0"
|
[(set_attr "type" "ilog")])
|
[(set_attr "type" "ilog")])
|
|
|
(define_expand "zero_extendhisi2"
|
(define_expand "zero_extendhisi2"
|
[(set (match_operand:SI 0 "register_operand" "")
|
[(set (match_operand:SI 0 "register_operand" "")
|
(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
|
(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
|
""
|
""
|
{
|
{
|
if (! TARGET_BWX)
|
if (! TARGET_BWX)
|
operands[1] = force_reg (HImode, operands[1]);
|
operands[1] = force_reg (HImode, operands[1]);
|
})
|
})
|
|
|
(define_insn "*zero_extendhisi2_bwx"
|
(define_insn "*zero_extendhisi2_bwx"
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
|
(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
|
"TARGET_BWX"
|
"TARGET_BWX"
|
"@
|
"@
|
zapnot %1,3,%0
|
zapnot %1,3,%0
|
ldwu %0,%1"
|
ldwu %0,%1"
|
[(set_attr "type" "shift,ild")])
|
[(set_attr "type" "shift,ild")])
|
|
|
(define_insn "*zero_extendhisi2_nobwx"
|
(define_insn "*zero_extendhisi2_nobwx"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(zero_extend:SI (match_operand:HI 1 "register_operand" "r")))]
|
(zero_extend:SI (match_operand:HI 1 "register_operand" "r")))]
|
"! TARGET_BWX"
|
"! TARGET_BWX"
|
"zapnot %1,3,%0"
|
"zapnot %1,3,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_expand "zero_extendhidi2"
|
(define_expand "zero_extendhidi2"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
|
(zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
|
""
|
""
|
{
|
{
|
if (! TARGET_BWX)
|
if (! TARGET_BWX)
|
operands[1] = force_reg (HImode, operands[1]);
|
operands[1] = force_reg (HImode, operands[1]);
|
})
|
})
|
|
|
(define_insn "*zero_extendhidi2_bwx"
|
(define_insn "*zero_extendhidi2_bwx"
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
(zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
|
(zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
|
"TARGET_BWX"
|
"TARGET_BWX"
|
"@
|
"@
|
zapnot %1,3,%0
|
zapnot %1,3,%0
|
ldwu %0,%1"
|
ldwu %0,%1"
|
[(set_attr "type" "shift,ild")])
|
[(set_attr "type" "shift,ild")])
|
|
|
(define_insn "*zero_extendhidi2_nobwx"
|
(define_insn "*zero_extendhidi2_nobwx"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
|
(zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
|
""
|
""
|
"zapnot %1,3,%0"
|
"zapnot %1,3,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "zero_extendsidi2"
|
(define_insn "zero_extendsidi2"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
|
(zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
|
""
|
""
|
"zapnot %1,15,%0"
|
"zapnot %1,15,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "*andnotsi3"
|
(define_insn "*andnotsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(and:SI (not:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI"))
|
(and:SI (not:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI"))
|
(match_operand:SI 2 "reg_or_0_operand" "rJ")))]
|
(match_operand:SI 2 "reg_or_0_operand" "rJ")))]
|
""
|
""
|
"bic %r2,%1,%0"
|
"bic %r2,%1,%0"
|
[(set_attr "type" "ilog")])
|
[(set_attr "type" "ilog")])
|
|
|
(define_insn "andnotdi3"
|
(define_insn "andnotdi3"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(and:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
|
(and:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
|
(match_operand:DI 2 "reg_or_0_operand" "rJ")))]
|
(match_operand:DI 2 "reg_or_0_operand" "rJ")))]
|
""
|
""
|
"bic %r2,%1,%0"
|
"bic %r2,%1,%0"
|
[(set_attr "type" "ilog")])
|
[(set_attr "type" "ilog")])
|
|
|
(define_insn "*iorsi_internal"
|
(define_insn "*iorsi_internal"
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
(ior:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
|
(ior:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
|
(match_operand:SI 2 "or_operand" "rI,N")))]
|
(match_operand:SI 2 "or_operand" "rI,N")))]
|
""
|
""
|
"@
|
"@
|
bis %r1,%2,%0
|
bis %r1,%2,%0
|
ornot %r1,%N2,%0"
|
ornot %r1,%N2,%0"
|
[(set_attr "type" "ilog")])
|
[(set_attr "type" "ilog")])
|
|
|
(define_insn "iordi3"
|
(define_insn "iordi3"
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
(ior:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
|
(ior:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
|
(match_operand:DI 2 "or_operand" "rI,N")))]
|
(match_operand:DI 2 "or_operand" "rI,N")))]
|
""
|
""
|
"@
|
"@
|
bis %r1,%2,%0
|
bis %r1,%2,%0
|
ornot %r1,%N2,%0"
|
ornot %r1,%N2,%0"
|
[(set_attr "type" "ilog")])
|
[(set_attr "type" "ilog")])
|
|
|
(define_insn "*one_cmplsi_internal"
|
(define_insn "*one_cmplsi_internal"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(not:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")))]
|
(not:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")))]
|
""
|
""
|
"ornot $31,%1,%0"
|
"ornot $31,%1,%0"
|
[(set_attr "type" "ilog")])
|
[(set_attr "type" "ilog")])
|
|
|
(define_insn "one_cmpldi2"
|
(define_insn "one_cmpldi2"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
|
(not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
|
""
|
""
|
"ornot $31,%1,%0"
|
"ornot $31,%1,%0"
|
[(set_attr "type" "ilog")])
|
[(set_attr "type" "ilog")])
|
|
|
(define_insn "*iornotsi3"
|
(define_insn "*iornotsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(ior:SI (not:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI"))
|
(ior:SI (not:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI"))
|
(match_operand:SI 2 "reg_or_0_operand" "rJ")))]
|
(match_operand:SI 2 "reg_or_0_operand" "rJ")))]
|
""
|
""
|
"ornot %r2,%1,%0"
|
"ornot %r2,%1,%0"
|
[(set_attr "type" "ilog")])
|
[(set_attr "type" "ilog")])
|
|
|
(define_insn "*iornotdi3"
|
(define_insn "*iornotdi3"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(ior:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
|
(ior:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
|
(match_operand:DI 2 "reg_or_0_operand" "rJ")))]
|
(match_operand:DI 2 "reg_or_0_operand" "rJ")))]
|
""
|
""
|
"ornot %r2,%1,%0"
|
"ornot %r2,%1,%0"
|
[(set_attr "type" "ilog")])
|
[(set_attr "type" "ilog")])
|
|
|
(define_insn "*xorsi_internal"
|
(define_insn "*xorsi_internal"
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
(xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
|
(xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
|
(match_operand:SI 2 "or_operand" "rI,N")))]
|
(match_operand:SI 2 "or_operand" "rI,N")))]
|
""
|
""
|
"@
|
"@
|
xor %r1,%2,%0
|
xor %r1,%2,%0
|
eqv %r1,%N2,%0"
|
eqv %r1,%N2,%0"
|
[(set_attr "type" "ilog")])
|
[(set_attr "type" "ilog")])
|
|
|
(define_insn "xordi3"
|
(define_insn "xordi3"
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
(xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
|
(xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
|
(match_operand:DI 2 "or_operand" "rI,N")))]
|
(match_operand:DI 2 "or_operand" "rI,N")))]
|
""
|
""
|
"@
|
"@
|
xor %r1,%2,%0
|
xor %r1,%2,%0
|
eqv %r1,%N2,%0"
|
eqv %r1,%N2,%0"
|
[(set_attr "type" "ilog")])
|
[(set_attr "type" "ilog")])
|
|
|
(define_insn "*xornotsi3"
|
(define_insn "*xornotsi3"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(not:SI (xor:SI (match_operand:SI 1 "register_operand" "%rJ")
|
(not:SI (xor:SI (match_operand:SI 1 "register_operand" "%rJ")
|
(match_operand:SI 2 "register_operand" "rI"))))]
|
(match_operand:SI 2 "register_operand" "rI"))))]
|
""
|
""
|
"eqv %r1,%2,%0"
|
"eqv %r1,%2,%0"
|
[(set_attr "type" "ilog")])
|
[(set_attr "type" "ilog")])
|
|
|
(define_insn "*xornotdi3"
|
(define_insn "*xornotdi3"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(not:DI (xor:DI (match_operand:DI 1 "register_operand" "%rJ")
|
(not:DI (xor:DI (match_operand:DI 1 "register_operand" "%rJ")
|
(match_operand:DI 2 "register_operand" "rI"))))]
|
(match_operand:DI 2 "register_operand" "rI"))))]
|
""
|
""
|
"eqv %r1,%2,%0"
|
"eqv %r1,%2,%0"
|
[(set_attr "type" "ilog")])
|
[(set_attr "type" "ilog")])
|
|
|
;; Handle FFS and related insns iff we support CIX.
|
;; Handle FFS and related insns iff we support CIX.
|
|
|
(define_expand "ffsdi2"
|
(define_expand "ffsdi2"
|
[(set (match_dup 2)
|
[(set (match_dup 2)
|
(ctz:DI (match_operand:DI 1 "register_operand" "")))
|
(ctz:DI (match_operand:DI 1 "register_operand" "")))
|
(set (match_dup 3)
|
(set (match_dup 3)
|
(plus:DI (match_dup 2) (const_int 1)))
|
(plus:DI (match_dup 2) (const_int 1)))
|
(set (match_operand:DI 0 "register_operand" "")
|
(set (match_operand:DI 0 "register_operand" "")
|
(if_then_else:DI (eq (match_dup 1) (const_int 0))
|
(if_then_else:DI (eq (match_dup 1) (const_int 0))
|
(const_int 0) (match_dup 3)))]
|
(const_int 0) (match_dup 3)))]
|
"TARGET_CIX"
|
"TARGET_CIX"
|
{
|
{
|
operands[2] = gen_reg_rtx (DImode);
|
operands[2] = gen_reg_rtx (DImode);
|
operands[3] = gen_reg_rtx (DImode);
|
operands[3] = gen_reg_rtx (DImode);
|
})
|
})
|
|
|
(define_insn "clzdi2"
|
(define_insn "clzdi2"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(clz:DI (match_operand:DI 1 "register_operand" "r")))]
|
(clz:DI (match_operand:DI 1 "register_operand" "r")))]
|
"TARGET_CIX"
|
"TARGET_CIX"
|
"ctlz %1,%0"
|
"ctlz %1,%0"
|
[(set_attr "type" "mvi")])
|
[(set_attr "type" "mvi")])
|
|
|
(define_insn "ctzdi2"
|
(define_insn "ctzdi2"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(ctz:DI (match_operand:DI 1 "register_operand" "r")))]
|
(ctz:DI (match_operand:DI 1 "register_operand" "r")))]
|
"TARGET_CIX"
|
"TARGET_CIX"
|
"cttz %1,%0"
|
"cttz %1,%0"
|
[(set_attr "type" "mvi")])
|
[(set_attr "type" "mvi")])
|
|
|
(define_insn "popcountdi2"
|
(define_insn "popcountdi2"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(popcount:DI (match_operand:DI 1 "register_operand" "r")))]
|
(popcount:DI (match_operand:DI 1 "register_operand" "r")))]
|
"TARGET_CIX"
|
"TARGET_CIX"
|
"ctpop %1,%0"
|
"ctpop %1,%0"
|
[(set_attr "type" "mvi")])
|
[(set_attr "type" "mvi")])
|
|
|
(define_expand "bswapsi2"
|
(define_expand "bswapsi2"
|
[(set (match_operand:SI 0 "register_operand" "")
|
[(set (match_operand:SI 0 "register_operand" "")
|
(bswap:SI (match_operand:SI 1 "register_operand" "")))]
|
(bswap:SI (match_operand:SI 1 "register_operand" "")))]
|
"!optimize_size"
|
"!optimize_size"
|
{
|
{
|
rtx t0, t1;
|
rtx t0, t1;
|
|
|
t0 = gen_reg_rtx (DImode);
|
t0 = gen_reg_rtx (DImode);
|
t1 = gen_reg_rtx (DImode);
|
t1 = gen_reg_rtx (DImode);
|
|
|
emit_insn (gen_insxh (t0, gen_lowpart (DImode, operands[1]),
|
emit_insn (gen_insxh (t0, gen_lowpart (DImode, operands[1]),
|
GEN_INT (32), GEN_INT (WORDS_BIG_ENDIAN ? 0 : 7)));
|
GEN_INT (32), GEN_INT (WORDS_BIG_ENDIAN ? 0 : 7)));
|
emit_insn (gen_inswl_const (t1, gen_lowpart (HImode, operands[1]),
|
emit_insn (gen_inswl_const (t1, gen_lowpart (HImode, operands[1]),
|
GEN_INT (24)));
|
GEN_INT (24)));
|
emit_insn (gen_iordi3 (t1, t0, t1));
|
emit_insn (gen_iordi3 (t1, t0, t1));
|
emit_insn (gen_lshrdi3 (t0, t1, GEN_INT (16)));
|
emit_insn (gen_lshrdi3 (t0, t1, GEN_INT (16)));
|
emit_insn (gen_anddi3 (t1, t1, alpha_expand_zap_mask (0x5)));
|
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_anddi3 (t0, t0, alpha_expand_zap_mask (0xa)));
|
emit_insn (gen_addsi3 (operands[0], gen_lowpart (SImode, t0),
|
emit_insn (gen_addsi3 (operands[0], gen_lowpart (SImode, t0),
|
gen_lowpart (SImode, t1)));
|
gen_lowpart (SImode, t1)));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "bswapdi2"
|
(define_expand "bswapdi2"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(bswap:DI (match_operand:DI 1 "register_operand" "")))]
|
(bswap:DI (match_operand:DI 1 "register_operand" "")))]
|
"!optimize_size"
|
"!optimize_size"
|
{
|
{
|
rtx t0, t1;
|
rtx t0, t1;
|
|
|
t0 = gen_reg_rtx (DImode);
|
t0 = gen_reg_rtx (DImode);
|
t1 = gen_reg_rtx (DImode);
|
t1 = gen_reg_rtx (DImode);
|
|
|
/* This method of shifting and masking is not specific to Alpha, but
|
/* This method of shifting and masking is not specific to Alpha, but
|
is only profitable on Alpha because of our handy byte zap insn. */
|
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_lshrdi3 (t0, operands[1], GEN_INT (32)));
|
emit_insn (gen_ashldi3 (t1, 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_iordi3 (t1, t0, t1));
|
|
|
emit_insn (gen_lshrdi3 (t0, t1, GEN_INT (16)));
|
emit_insn (gen_lshrdi3 (t0, t1, GEN_INT (16)));
|
emit_insn (gen_ashldi3 (t1, 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 (t0, t0, alpha_expand_zap_mask (0xcc)));
|
emit_insn (gen_anddi3 (t1, t1, alpha_expand_zap_mask (0x33)));
|
emit_insn (gen_anddi3 (t1, t1, alpha_expand_zap_mask (0x33)));
|
emit_insn (gen_iordi3 (t1, t0, t1));
|
emit_insn (gen_iordi3 (t1, t0, t1));
|
|
|
emit_insn (gen_lshrdi3 (t0, t1, GEN_INT (8)));
|
emit_insn (gen_lshrdi3 (t0, t1, GEN_INT (8)));
|
emit_insn (gen_ashldi3 (t1, 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 (t0, t0, alpha_expand_zap_mask (0xaa)));
|
emit_insn (gen_anddi3 (t1, t1, alpha_expand_zap_mask (0x55)));
|
emit_insn (gen_anddi3 (t1, t1, alpha_expand_zap_mask (0x55)));
|
emit_insn (gen_iordi3 (operands[0], t0, t1));
|
emit_insn (gen_iordi3 (operands[0], t0, t1));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
;; Next come the shifts and the various extract and insert operations.
|
;; Next come the shifts and the various extract and insert operations.
|
|
|
(define_insn "ashldi3"
|
(define_insn "ashldi3"
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
(ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ")
|
(ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ")
|
(match_operand:DI 2 "reg_or_6bit_operand" "P,rS")))]
|
(match_operand:DI 2 "reg_or_6bit_operand" "P,rS")))]
|
""
|
""
|
{
|
{
|
switch (which_alternative)
|
switch (which_alternative)
|
{
|
{
|
case 0:
|
case 0:
|
if (operands[2] == const1_rtx)
|
if (operands[2] == const1_rtx)
|
return "addq %r1,%r1,%0";
|
return "addq %r1,%r1,%0";
|
else
|
else
|
return "s%P2addq %r1,0,%0";
|
return "s%P2addq %r1,0,%0";
|
case 1:
|
case 1:
|
return "sll %r1,%2,%0";
|
return "sll %r1,%2,%0";
|
default:
|
default:
|
gcc_unreachable ();
|
gcc_unreachable ();
|
}
|
}
|
}
|
}
|
[(set_attr "type" "iadd,shift")])
|
[(set_attr "type" "iadd,shift")])
|
|
|
(define_insn "*ashldi_se"
|
(define_insn "*ashldi_se"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(sign_extend:DI
|
(sign_extend:DI
|
(subreg:SI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(subreg:SI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(match_operand:DI 2 "const_int_operand" "P"))
|
(match_operand:DI 2 "const_int_operand" "P"))
|
0)))]
|
0)))]
|
"INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3"
|
"INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3"
|
{
|
{
|
if (operands[2] == const1_rtx)
|
if (operands[2] == const1_rtx)
|
return "addl %r1,%r1,%0";
|
return "addl %r1,%r1,%0";
|
else
|
else
|
return "s%P2addl %r1,0,%0";
|
return "s%P2addl %r1,0,%0";
|
}
|
}
|
[(set_attr "type" "iadd")])
|
[(set_attr "type" "iadd")])
|
|
|
(define_insn "lshrdi3"
|
(define_insn "lshrdi3"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(match_operand:DI 2 "reg_or_6bit_operand" "rS")))]
|
(match_operand:DI 2 "reg_or_6bit_operand" "rS")))]
|
""
|
""
|
"srl %r1,%2,%0"
|
"srl %r1,%2,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "ashrdi3"
|
(define_insn "ashrdi3"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(ashiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(ashiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(match_operand:DI 2 "reg_or_6bit_operand" "rS")))]
|
(match_operand:DI 2 "reg_or_6bit_operand" "rS")))]
|
""
|
""
|
"sra %r1,%2,%0"
|
"sra %r1,%2,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_expand "extendqihi2"
|
(define_expand "extendqihi2"
|
[(set (match_dup 2)
|
[(set (match_dup 2)
|
(ashift:DI (match_operand:QI 1 "some_operand" "")
|
(ashift:DI (match_operand:QI 1 "some_operand" "")
|
(const_int 56)))
|
(const_int 56)))
|
(set (match_operand:HI 0 "register_operand" "")
|
(set (match_operand:HI 0 "register_operand" "")
|
(ashiftrt:DI (match_dup 2)
|
(ashiftrt:DI (match_dup 2)
|
(const_int 56)))]
|
(const_int 56)))]
|
""
|
""
|
{
|
{
|
if (TARGET_BWX)
|
if (TARGET_BWX)
|
{
|
{
|
emit_insn (gen_extendqihi2x (operands[0],
|
emit_insn (gen_extendqihi2x (operands[0],
|
force_reg (QImode, operands[1])));
|
force_reg (QImode, operands[1])));
|
DONE;
|
DONE;
|
}
|
}
|
|
|
/* If we have an unaligned MEM, extend to DImode (which we do
|
/* If we have an unaligned MEM, extend to DImode (which we do
|
specially) and then copy to the result. */
|
specially) and then copy to the result. */
|
if (unaligned_memory_operand (operands[1], HImode))
|
if (unaligned_memory_operand (operands[1], HImode))
|
{
|
{
|
rtx temp = gen_reg_rtx (DImode);
|
rtx temp = gen_reg_rtx (DImode);
|
|
|
emit_insn (gen_extendqidi2 (temp, operands[1]));
|
emit_insn (gen_extendqidi2 (temp, operands[1]));
|
emit_move_insn (operands[0], gen_lowpart (HImode, temp));
|
emit_move_insn (operands[0], gen_lowpart (HImode, temp));
|
DONE;
|
DONE;
|
}
|
}
|
|
|
operands[0] = gen_lowpart (DImode, operands[0]);
|
operands[0] = gen_lowpart (DImode, operands[0]);
|
operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
|
operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
|
operands[2] = gen_reg_rtx (DImode);
|
operands[2] = gen_reg_rtx (DImode);
|
})
|
})
|
|
|
(define_insn "extendqidi2x"
|
(define_insn "extendqidi2x"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
|
(sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
|
"TARGET_BWX"
|
"TARGET_BWX"
|
"sextb %1,%0"
|
"sextb %1,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "extendhidi2x"
|
(define_insn "extendhidi2x"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
|
(sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
|
"TARGET_BWX"
|
"TARGET_BWX"
|
"sextw %1,%0"
|
"sextw %1,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "extendqisi2x"
|
(define_insn "extendqisi2x"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
|
(sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
|
"TARGET_BWX"
|
"TARGET_BWX"
|
"sextb %1,%0"
|
"sextb %1,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "extendhisi2x"
|
(define_insn "extendhisi2x"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
|
(sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
|
"TARGET_BWX"
|
"TARGET_BWX"
|
"sextw %1,%0"
|
"sextw %1,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "extendqihi2x"
|
(define_insn "extendqihi2x"
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
(sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
|
(sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
|
"TARGET_BWX"
|
"TARGET_BWX"
|
"sextb %1,%0"
|
"sextb %1,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_expand "extendqisi2"
|
(define_expand "extendqisi2"
|
[(set (match_dup 2)
|
[(set (match_dup 2)
|
(ashift:DI (match_operand:QI 1 "some_operand" "")
|
(ashift:DI (match_operand:QI 1 "some_operand" "")
|
(const_int 56)))
|
(const_int 56)))
|
(set (match_operand:SI 0 "register_operand" "")
|
(set (match_operand:SI 0 "register_operand" "")
|
(ashiftrt:DI (match_dup 2)
|
(ashiftrt:DI (match_dup 2)
|
(const_int 56)))]
|
(const_int 56)))]
|
""
|
""
|
{
|
{
|
if (TARGET_BWX)
|
if (TARGET_BWX)
|
{
|
{
|
emit_insn (gen_extendqisi2x (operands[0],
|
emit_insn (gen_extendqisi2x (operands[0],
|
force_reg (QImode, operands[1])));
|
force_reg (QImode, operands[1])));
|
DONE;
|
DONE;
|
}
|
}
|
|
|
/* If we have an unaligned MEM, extend to a DImode form of
|
/* If we have an unaligned MEM, extend to a DImode form of
|
the result (which we do specially). */
|
the result (which we do specially). */
|
if (unaligned_memory_operand (operands[1], QImode))
|
if (unaligned_memory_operand (operands[1], QImode))
|
{
|
{
|
rtx temp = gen_reg_rtx (DImode);
|
rtx temp = gen_reg_rtx (DImode);
|
|
|
emit_insn (gen_extendqidi2 (temp, operands[1]));
|
emit_insn (gen_extendqidi2 (temp, operands[1]));
|
emit_move_insn (operands[0], gen_lowpart (SImode, temp));
|
emit_move_insn (operands[0], gen_lowpart (SImode, temp));
|
DONE;
|
DONE;
|
}
|
}
|
|
|
operands[0] = gen_lowpart (DImode, operands[0]);
|
operands[0] = gen_lowpart (DImode, operands[0]);
|
operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
|
operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
|
operands[2] = gen_reg_rtx (DImode);
|
operands[2] = gen_reg_rtx (DImode);
|
})
|
})
|
|
|
(define_expand "extendqidi2"
|
(define_expand "extendqidi2"
|
[(set (match_dup 2)
|
[(set (match_dup 2)
|
(ashift:DI (match_operand:QI 1 "some_operand" "")
|
(ashift:DI (match_operand:QI 1 "some_operand" "")
|
(const_int 56)))
|
(const_int 56)))
|
(set (match_operand:DI 0 "register_operand" "")
|
(set (match_operand:DI 0 "register_operand" "")
|
(ashiftrt:DI (match_dup 2)
|
(ashiftrt:DI (match_dup 2)
|
(const_int 56)))]
|
(const_int 56)))]
|
""
|
""
|
{
|
{
|
if (TARGET_BWX)
|
if (TARGET_BWX)
|
{
|
{
|
emit_insn (gen_extendqidi2x (operands[0],
|
emit_insn (gen_extendqidi2x (operands[0],
|
force_reg (QImode, operands[1])));
|
force_reg (QImode, operands[1])));
|
DONE;
|
DONE;
|
}
|
}
|
|
|
if (unaligned_memory_operand (operands[1], QImode))
|
if (unaligned_memory_operand (operands[1], QImode))
|
{
|
{
|
rtx seq = gen_unaligned_extendqidi (operands[0], XEXP (operands[1], 0));
|
rtx seq = gen_unaligned_extendqidi (operands[0], XEXP (operands[1], 0));
|
alpha_set_memflags (seq, operands[1]);
|
alpha_set_memflags (seq, operands[1]);
|
emit_insn (seq);
|
emit_insn (seq);
|
DONE;
|
DONE;
|
}
|
}
|
|
|
operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
|
operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
|
operands[2] = gen_reg_rtx (DImode);
|
operands[2] = gen_reg_rtx (DImode);
|
})
|
})
|
|
|
(define_expand "extendhisi2"
|
(define_expand "extendhisi2"
|
[(set (match_dup 2)
|
[(set (match_dup 2)
|
(ashift:DI (match_operand:HI 1 "some_operand" "")
|
(ashift:DI (match_operand:HI 1 "some_operand" "")
|
(const_int 48)))
|
(const_int 48)))
|
(set (match_operand:SI 0 "register_operand" "")
|
(set (match_operand:SI 0 "register_operand" "")
|
(ashiftrt:DI (match_dup 2)
|
(ashiftrt:DI (match_dup 2)
|
(const_int 48)))]
|
(const_int 48)))]
|
""
|
""
|
{
|
{
|
if (TARGET_BWX)
|
if (TARGET_BWX)
|
{
|
{
|
emit_insn (gen_extendhisi2x (operands[0],
|
emit_insn (gen_extendhisi2x (operands[0],
|
force_reg (HImode, operands[1])));
|
force_reg (HImode, operands[1])));
|
DONE;
|
DONE;
|
}
|
}
|
|
|
/* If we have an unaligned MEM, extend to a DImode form of
|
/* If we have an unaligned MEM, extend to a DImode form of
|
the result (which we do specially). */
|
the result (which we do specially). */
|
if (unaligned_memory_operand (operands[1], HImode))
|
if (unaligned_memory_operand (operands[1], HImode))
|
{
|
{
|
rtx temp = gen_reg_rtx (DImode);
|
rtx temp = gen_reg_rtx (DImode);
|
|
|
emit_insn (gen_extendhidi2 (temp, operands[1]));
|
emit_insn (gen_extendhidi2 (temp, operands[1]));
|
emit_move_insn (operands[0], gen_lowpart (SImode, temp));
|
emit_move_insn (operands[0], gen_lowpart (SImode, temp));
|
DONE;
|
DONE;
|
}
|
}
|
|
|
operands[0] = gen_lowpart (DImode, operands[0]);
|
operands[0] = gen_lowpart (DImode, operands[0]);
|
operands[1] = gen_lowpart (DImode, force_reg (HImode, operands[1]));
|
operands[1] = gen_lowpart (DImode, force_reg (HImode, operands[1]));
|
operands[2] = gen_reg_rtx (DImode);
|
operands[2] = gen_reg_rtx (DImode);
|
})
|
})
|
|
|
(define_expand "extendhidi2"
|
(define_expand "extendhidi2"
|
[(set (match_dup 2)
|
[(set (match_dup 2)
|
(ashift:DI (match_operand:HI 1 "some_operand" "")
|
(ashift:DI (match_operand:HI 1 "some_operand" "")
|
(const_int 48)))
|
(const_int 48)))
|
(set (match_operand:DI 0 "register_operand" "")
|
(set (match_operand:DI 0 "register_operand" "")
|
(ashiftrt:DI (match_dup 2)
|
(ashiftrt:DI (match_dup 2)
|
(const_int 48)))]
|
(const_int 48)))]
|
""
|
""
|
{
|
{
|
if (TARGET_BWX)
|
if (TARGET_BWX)
|
{
|
{
|
emit_insn (gen_extendhidi2x (operands[0],
|
emit_insn (gen_extendhidi2x (operands[0],
|
force_reg (HImode, operands[1])));
|
force_reg (HImode, operands[1])));
|
DONE;
|
DONE;
|
}
|
}
|
|
|
if (unaligned_memory_operand (operands[1], HImode))
|
if (unaligned_memory_operand (operands[1], HImode))
|
{
|
{
|
rtx seq = gen_unaligned_extendhidi (operands[0], XEXP (operands[1], 0));
|
rtx seq = gen_unaligned_extendhidi (operands[0], XEXP (operands[1], 0));
|
|
|
alpha_set_memflags (seq, operands[1]);
|
alpha_set_memflags (seq, operands[1]);
|
emit_insn (seq);
|
emit_insn (seq);
|
DONE;
|
DONE;
|
}
|
}
|
|
|
operands[1] = gen_lowpart (DImode, force_reg (HImode, operands[1]));
|
operands[1] = gen_lowpart (DImode, force_reg (HImode, operands[1]));
|
operands[2] = gen_reg_rtx (DImode);
|
operands[2] = gen_reg_rtx (DImode);
|
})
|
})
|
|
|
;; Here's how we sign extend an unaligned byte and halfword. Doing this
|
;; Here's how we sign extend an unaligned byte and halfword. Doing this
|
;; as a pattern saves one instruction. The code is similar to that for
|
;; as a pattern saves one instruction. The code is similar to that for
|
;; the unaligned loads (see below).
|
;; the unaligned loads (see below).
|
;;
|
;;
|
;; Operand 1 is the address, operand 0 is the result.
|
;; Operand 1 is the address, operand 0 is the result.
|
(define_expand "unaligned_extendqidi"
|
(define_expand "unaligned_extendqidi"
|
[(use (match_operand:QI 0 "register_operand" ""))
|
[(use (match_operand:QI 0 "register_operand" ""))
|
(use (match_operand:DI 1 "address_operand" ""))]
|
(use (match_operand:DI 1 "address_operand" ""))]
|
""
|
""
|
{
|
{
|
operands[0] = gen_lowpart (DImode, operands[0]);
|
operands[0] = gen_lowpart (DImode, operands[0]);
|
if (WORDS_BIG_ENDIAN)
|
if (WORDS_BIG_ENDIAN)
|
emit_insn (gen_unaligned_extendqidi_be (operands[0], operands[1]));
|
emit_insn (gen_unaligned_extendqidi_be (operands[0], operands[1]));
|
else
|
else
|
emit_insn (gen_unaligned_extendqidi_le (operands[0], operands[1]));
|
emit_insn (gen_unaligned_extendqidi_le (operands[0], operands[1]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "unaligned_extendqidi_le"
|
(define_expand "unaligned_extendqidi_le"
|
[(set (match_dup 3)
|
[(set (match_dup 3)
|
(mem:DI (and:DI (match_operand:DI 1 "" "") (const_int -8))))
|
(mem:DI (and:DI (match_operand:DI 1 "" "") (const_int -8))))
|
(set (match_dup 4)
|
(set (match_dup 4)
|
(ashift:DI (match_dup 3)
|
(ashift:DI (match_dup 3)
|
(minus:DI (const_int 64)
|
(minus:DI (const_int 64)
|
(ashift:DI
|
(ashift:DI
|
(and:DI (match_dup 2) (const_int 7))
|
(and:DI (match_dup 2) (const_int 7))
|
(const_int 3)))))
|
(const_int 3)))))
|
(set (match_operand:DI 0 "register_operand" "")
|
(set (match_operand:DI 0 "register_operand" "")
|
(ashiftrt:DI (match_dup 4) (const_int 56)))]
|
(ashiftrt:DI (match_dup 4) (const_int 56)))]
|
"! WORDS_BIG_ENDIAN"
|
"! WORDS_BIG_ENDIAN"
|
{
|
{
|
operands[2] = get_unaligned_offset (operands[1], 1);
|
operands[2] = get_unaligned_offset (operands[1], 1);
|
operands[3] = gen_reg_rtx (DImode);
|
operands[3] = gen_reg_rtx (DImode);
|
operands[4] = gen_reg_rtx (DImode);
|
operands[4] = gen_reg_rtx (DImode);
|
})
|
})
|
|
|
(define_expand "unaligned_extendqidi_be"
|
(define_expand "unaligned_extendqidi_be"
|
[(set (match_dup 3)
|
[(set (match_dup 3)
|
(mem:DI (and:DI (match_operand:DI 1 "" "") (const_int -8))))
|
(mem:DI (and:DI (match_operand:DI 1 "" "") (const_int -8))))
|
(set (match_dup 4)
|
(set (match_dup 4)
|
(ashift:DI (match_dup 3)
|
(ashift:DI (match_dup 3)
|
(ashift:DI
|
(ashift:DI
|
(and:DI
|
(and:DI
|
(plus:DI (match_dup 2) (const_int 1))
|
(plus:DI (match_dup 2) (const_int 1))
|
(const_int 7))
|
(const_int 7))
|
(const_int 3))))
|
(const_int 3))))
|
(set (match_operand:DI 0 "register_operand" "")
|
(set (match_operand:DI 0 "register_operand" "")
|
(ashiftrt:DI (match_dup 4) (const_int 56)))]
|
(ashiftrt:DI (match_dup 4) (const_int 56)))]
|
"WORDS_BIG_ENDIAN"
|
"WORDS_BIG_ENDIAN"
|
{
|
{
|
operands[2] = get_unaligned_offset (operands[1], -1);
|
operands[2] = get_unaligned_offset (operands[1], -1);
|
operands[3] = gen_reg_rtx (DImode);
|
operands[3] = gen_reg_rtx (DImode);
|
operands[4] = gen_reg_rtx (DImode);
|
operands[4] = gen_reg_rtx (DImode);
|
})
|
})
|
|
|
(define_expand "unaligned_extendhidi"
|
(define_expand "unaligned_extendhidi"
|
[(use (match_operand:QI 0 "register_operand" ""))
|
[(use (match_operand:QI 0 "register_operand" ""))
|
(use (match_operand:DI 1 "address_operand" ""))]
|
(use (match_operand:DI 1 "address_operand" ""))]
|
""
|
""
|
{
|
{
|
operands[0] = gen_lowpart (DImode, operands[0]);
|
operands[0] = gen_lowpart (DImode, operands[0]);
|
if (WORDS_BIG_ENDIAN)
|
if (WORDS_BIG_ENDIAN)
|
emit_insn (gen_unaligned_extendhidi_be (operands[0], operands[1]));
|
emit_insn (gen_unaligned_extendhidi_be (operands[0], operands[1]));
|
else
|
else
|
emit_insn (gen_unaligned_extendhidi_le (operands[0], operands[1]));
|
emit_insn (gen_unaligned_extendhidi_le (operands[0], operands[1]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "unaligned_extendhidi_le"
|
(define_expand "unaligned_extendhidi_le"
|
[(set (match_dup 3)
|
[(set (match_dup 3)
|
(mem:DI (and:DI (match_operand:DI 1 "" "") (const_int -8))))
|
(mem:DI (and:DI (match_operand:DI 1 "" "") (const_int -8))))
|
(set (match_dup 4)
|
(set (match_dup 4)
|
(ashift:DI (match_dup 3)
|
(ashift:DI (match_dup 3)
|
(minus:DI (const_int 64)
|
(minus:DI (const_int 64)
|
(ashift:DI
|
(ashift:DI
|
(and:DI (match_dup 2) (const_int 7))
|
(and:DI (match_dup 2) (const_int 7))
|
(const_int 3)))))
|
(const_int 3)))))
|
(set (match_operand:DI 0 "register_operand" "")
|
(set (match_operand:DI 0 "register_operand" "")
|
(ashiftrt:DI (match_dup 4) (const_int 48)))]
|
(ashiftrt:DI (match_dup 4) (const_int 48)))]
|
"! WORDS_BIG_ENDIAN"
|
"! WORDS_BIG_ENDIAN"
|
{
|
{
|
operands[2] = get_unaligned_offset (operands[1], 2);
|
operands[2] = get_unaligned_offset (operands[1], 2);
|
operands[3] = gen_reg_rtx (DImode);
|
operands[3] = gen_reg_rtx (DImode);
|
operands[4] = gen_reg_rtx (DImode);
|
operands[4] = gen_reg_rtx (DImode);
|
})
|
})
|
|
|
(define_expand "unaligned_extendhidi_be"
|
(define_expand "unaligned_extendhidi_be"
|
[(set (match_dup 3)
|
[(set (match_dup 3)
|
(mem:DI (and:DI (match_operand:DI 1 "" "") (const_int -8))))
|
(mem:DI (and:DI (match_operand:DI 1 "" "") (const_int -8))))
|
(set (match_dup 4)
|
(set (match_dup 4)
|
(ashift:DI (match_dup 3)
|
(ashift:DI (match_dup 3)
|
(ashift:DI
|
(ashift:DI
|
(and:DI
|
(and:DI
|
(plus:DI (match_dup 2) (const_int 1))
|
(plus:DI (match_dup 2) (const_int 1))
|
(const_int 7))
|
(const_int 7))
|
(const_int 3))))
|
(const_int 3))))
|
(set (match_operand:DI 0 "register_operand" "")
|
(set (match_operand:DI 0 "register_operand" "")
|
(ashiftrt:DI (match_dup 4) (const_int 48)))]
|
(ashiftrt:DI (match_dup 4) (const_int 48)))]
|
"WORDS_BIG_ENDIAN"
|
"WORDS_BIG_ENDIAN"
|
{
|
{
|
operands[2] = get_unaligned_offset (operands[1], -1);
|
operands[2] = get_unaligned_offset (operands[1], -1);
|
operands[3] = gen_reg_rtx (DImode);
|
operands[3] = gen_reg_rtx (DImode);
|
operands[4] = gen_reg_rtx (DImode);
|
operands[4] = gen_reg_rtx (DImode);
|
})
|
})
|
|
|
(define_insn "*extxl_const"
|
(define_insn "*extxl_const"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(match_operand:DI 2 "mode_width_operand" "n")
|
(match_operand:DI 2 "mode_width_operand" "n")
|
(match_operand:DI 3 "mul8_operand" "I")))]
|
(match_operand:DI 3 "mul8_operand" "I")))]
|
""
|
""
|
"ext%M2l %r1,%s3,%0"
|
"ext%M2l %r1,%s3,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "extxl_le"
|
(define_insn "extxl_le"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(match_operand:DI 2 "mode_width_operand" "n")
|
(match_operand:DI 2 "mode_width_operand" "n")
|
(ashift:DI (match_operand:DI 3 "reg_or_8bit_operand" "rI")
|
(ashift:DI (match_operand:DI 3 "reg_or_8bit_operand" "rI")
|
(const_int 3))))]
|
(const_int 3))))]
|
"! WORDS_BIG_ENDIAN"
|
"! WORDS_BIG_ENDIAN"
|
"ext%M2l %r1,%3,%0"
|
"ext%M2l %r1,%3,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "extxl_be"
|
(define_insn "extxl_be"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(match_operand:DI 2 "mode_width_operand" "n")
|
(match_operand:DI 2 "mode_width_operand" "n")
|
(minus:DI
|
(minus:DI
|
(const_int 56)
|
(const_int 56)
|
(ashift:DI
|
(ashift:DI
|
(match_operand:DI 3 "reg_or_8bit_operand" "rI")
|
(match_operand:DI 3 "reg_or_8bit_operand" "rI")
|
(const_int 3)))))]
|
(const_int 3)))))]
|
"WORDS_BIG_ENDIAN"
|
"WORDS_BIG_ENDIAN"
|
"ext%M2l %r1,%3,%0"
|
"ext%M2l %r1,%3,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
;; Combine has some strange notion of preserving existing undefined behavior
|
;; Combine has some strange notion of preserving existing undefined behavior
|
;; in shifts larger than a word size. So capture these patterns that it
|
;; in shifts larger than a word size. So capture these patterns that it
|
;; should have turned into zero_extracts.
|
;; should have turned into zero_extracts.
|
|
|
(define_insn "*extxl_1_le"
|
(define_insn "*extxl_1_le"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(and:DI (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(and:DI (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(const_int 3)))
|
(const_int 3)))
|
(match_operand:DI 3 "mode_mask_operand" "n")))]
|
(match_operand:DI 3 "mode_mask_operand" "n")))]
|
"! WORDS_BIG_ENDIAN"
|
"! WORDS_BIG_ENDIAN"
|
"ext%U3l %1,%2,%0"
|
"ext%U3l %1,%2,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "*extxl_1_be"
|
(define_insn "*extxl_1_be"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(and:DI (lshiftrt:DI
|
(and:DI (lshiftrt:DI
|
(match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(minus:DI (const_int 56)
|
(minus:DI (const_int 56)
|
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(const_int 3))))
|
(const_int 3))))
|
(match_operand:DI 3 "mode_mask_operand" "n")))]
|
(match_operand:DI 3 "mode_mask_operand" "n")))]
|
"WORDS_BIG_ENDIAN"
|
"WORDS_BIG_ENDIAN"
|
"ext%U3l %1,%2,%0"
|
"ext%U3l %1,%2,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "*extql_2_le"
|
(define_insn "*extql_2_le"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(const_int 3))))]
|
(const_int 3))))]
|
"! WORDS_BIG_ENDIAN"
|
"! WORDS_BIG_ENDIAN"
|
"extql %1,%2,%0"
|
"extql %1,%2,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "*extql_2_be"
|
(define_insn "*extql_2_be"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(lshiftrt:DI
|
(lshiftrt:DI
|
(match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(minus:DI (const_int 56)
|
(minus:DI (const_int 56)
|
(ashift:DI
|
(ashift:DI
|
(match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(const_int 3)))))]
|
(const_int 3)))))]
|
"WORDS_BIG_ENDIAN"
|
"WORDS_BIG_ENDIAN"
|
"extql %1,%2,%0"
|
"extql %1,%2,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "extqh_le"
|
(define_insn "extqh_le"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(ashift:DI
|
(ashift:DI
|
(match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(minus:DI (const_int 64)
|
(minus:DI (const_int 64)
|
(ashift:DI
|
(ashift:DI
|
(and:DI
|
(and:DI
|
(match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(const_int 7))
|
(const_int 7))
|
(const_int 3)))))]
|
(const_int 3)))))]
|
"! WORDS_BIG_ENDIAN"
|
"! WORDS_BIG_ENDIAN"
|
"extqh %r1,%2,%0"
|
"extqh %r1,%2,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "extqh_be"
|
(define_insn "extqh_be"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(ashift:DI
|
(ashift:DI
|
(match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(ashift:DI
|
(ashift:DI
|
(and:DI
|
(and:DI
|
(plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(const_int 1))
|
(const_int 1))
|
(const_int 7))
|
(const_int 7))
|
(const_int 3))))]
|
(const_int 3))))]
|
"WORDS_BIG_ENDIAN"
|
"WORDS_BIG_ENDIAN"
|
"extqh %r1,%2,%0"
|
"extqh %r1,%2,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "extlh_le"
|
(define_insn "extlh_le"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(ashift:DI
|
(ashift:DI
|
(and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(const_int 2147483647))
|
(const_int 2147483647))
|
(minus:DI (const_int 64)
|
(minus:DI (const_int 64)
|
(ashift:DI
|
(ashift:DI
|
(and:DI
|
(and:DI
|
(match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(const_int 7))
|
(const_int 7))
|
(const_int 3)))))]
|
(const_int 3)))))]
|
"! WORDS_BIG_ENDIAN"
|
"! WORDS_BIG_ENDIAN"
|
"extlh %r1,%2,%0"
|
"extlh %r1,%2,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "extlh_be"
|
(define_insn "extlh_be"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(and:DI
|
(and:DI
|
(ashift:DI
|
(ashift:DI
|
(match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(ashift:DI
|
(ashift:DI
|
(and:DI
|
(and:DI
|
(plus:DI
|
(plus:DI
|
(match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(const_int 1))
|
(const_int 1))
|
(const_int 7))
|
(const_int 7))
|
(const_int 3)))
|
(const_int 3)))
|
(const_int 2147483647)))]
|
(const_int 2147483647)))]
|
"WORDS_BIG_ENDIAN"
|
"WORDS_BIG_ENDIAN"
|
"extlh %r1,%2,%0"
|
"extlh %r1,%2,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "extwh_le"
|
(define_insn "extwh_le"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(ashift:DI
|
(ashift:DI
|
(and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(const_int 65535))
|
(const_int 65535))
|
(minus:DI (const_int 64)
|
(minus:DI (const_int 64)
|
(ashift:DI
|
(ashift:DI
|
(and:DI
|
(and:DI
|
(match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(const_int 7))
|
(const_int 7))
|
(const_int 3)))))]
|
(const_int 3)))))]
|
"! WORDS_BIG_ENDIAN"
|
"! WORDS_BIG_ENDIAN"
|
"extwh %r1,%2,%0"
|
"extwh %r1,%2,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "extwh_be"
|
(define_insn "extwh_be"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(and:DI
|
(and:DI
|
(ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(ashift:DI
|
(ashift:DI
|
(and:DI
|
(and:DI
|
(plus:DI
|
(plus:DI
|
(match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(const_int 1))
|
(const_int 1))
|
(const_int 7))
|
(const_int 7))
|
(const_int 3)))
|
(const_int 3)))
|
(const_int 65535)))]
|
(const_int 65535)))]
|
"WORDS_BIG_ENDIAN"
|
"WORDS_BIG_ENDIAN"
|
"extwh %r1,%2,%0"
|
"extwh %r1,%2,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
;; This converts an extXl into an extXh with an appropriate adjustment
|
;; This converts an extXl into an extXh with an appropriate adjustment
|
;; to the address calculation.
|
;; to the address calculation.
|
|
|
;;(define_split
|
;;(define_split
|
;; [(set (match_operand:DI 0 "register_operand" "")
|
;; [(set (match_operand:DI 0 "register_operand" "")
|
;; (ashift:DI (zero_extract:DI (match_operand:DI 1 "register_operand" "")
|
;; (ashift:DI (zero_extract:DI (match_operand:DI 1 "register_operand" "")
|
;; (match_operand:DI 2 "mode_width_operand" "")
|
;; (match_operand:DI 2 "mode_width_operand" "")
|
;; (ashift:DI (match_operand:DI 3 "" "")
|
;; (ashift:DI (match_operand:DI 3 "" "")
|
;; (const_int 3)))
|
;; (const_int 3)))
|
;; (match_operand:DI 4 "const_int_operand" "")))
|
;; (match_operand:DI 4 "const_int_operand" "")))
|
;; (clobber (match_operand:DI 5 "register_operand" ""))]
|
;; (clobber (match_operand:DI 5 "register_operand" ""))]
|
;; "INTVAL (operands[4]) == 64 - INTVAL (operands[2])"
|
;; "INTVAL (operands[4]) == 64 - INTVAL (operands[2])"
|
;; [(set (match_dup 5) (match_dup 6))
|
;; [(set (match_dup 5) (match_dup 6))
|
;; (set (match_dup 0)
|
;; (set (match_dup 0)
|
;; (ashift:DI (zero_extract:DI (match_dup 1) (match_dup 2)
|
;; (ashift:DI (zero_extract:DI (match_dup 1) (match_dup 2)
|
;; (ashift:DI (plus:DI (match_dup 5)
|
;; (ashift:DI (plus:DI (match_dup 5)
|
;; (match_dup 7))
|
;; (match_dup 7))
|
;; (const_int 3)))
|
;; (const_int 3)))
|
;; (match_dup 4)))]
|
;; (match_dup 4)))]
|
;; "
|
;; "
|
;;{
|
;;{
|
;; operands[6] = plus_constant (operands[3],
|
;; operands[6] = plus_constant (operands[3],
|
;; INTVAL (operands[2]) / BITS_PER_UNIT);
|
;; INTVAL (operands[2]) / BITS_PER_UNIT);
|
;; operands[7] = GEN_INT (- INTVAL (operands[2]) / BITS_PER_UNIT);
|
;; operands[7] = GEN_INT (- INTVAL (operands[2]) / BITS_PER_UNIT);
|
;;}")
|
;;}")
|
|
|
(define_insn "*insbl_const"
|
(define_insn "*insbl_const"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
|
(ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
|
(match_operand:DI 2 "mul8_operand" "I")))]
|
(match_operand:DI 2 "mul8_operand" "I")))]
|
""
|
""
|
"insbl %1,%s2,%0"
|
"insbl %1,%s2,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "inswl_const"
|
(define_insn "inswl_const"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
|
(ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
|
(match_operand:DI 2 "mul8_operand" "I")))]
|
(match_operand:DI 2 "mul8_operand" "I")))]
|
""
|
""
|
"inswl %1,%s2,%0"
|
"inswl %1,%s2,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "*insll_const"
|
(define_insn "*insll_const"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
|
(ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
|
(match_operand:DI 2 "mul8_operand" "I")))]
|
(match_operand:DI 2 "mul8_operand" "I")))]
|
""
|
""
|
"insll %1,%s2,%0"
|
"insll %1,%s2,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "insbl_le"
|
(define_insn "insbl_le"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
|
(ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
|
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(const_int 3))))]
|
(const_int 3))))]
|
"! WORDS_BIG_ENDIAN"
|
"! WORDS_BIG_ENDIAN"
|
"insbl %1,%2,%0"
|
"insbl %1,%2,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "insbl_be"
|
(define_insn "insbl_be"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
|
(ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
|
(minus:DI (const_int 56)
|
(minus:DI (const_int 56)
|
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(const_int 3)))))]
|
(const_int 3)))))]
|
"WORDS_BIG_ENDIAN"
|
"WORDS_BIG_ENDIAN"
|
"insbl %1,%2,%0"
|
"insbl %1,%2,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "inswl_le"
|
(define_insn "inswl_le"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
|
(ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
|
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(const_int 3))))]
|
(const_int 3))))]
|
"! WORDS_BIG_ENDIAN"
|
"! WORDS_BIG_ENDIAN"
|
"inswl %1,%2,%0"
|
"inswl %1,%2,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "inswl_be"
|
(define_insn "inswl_be"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
|
(ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
|
(minus:DI (const_int 56)
|
(minus:DI (const_int 56)
|
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(const_int 3)))))]
|
(const_int 3)))))]
|
"WORDS_BIG_ENDIAN"
|
"WORDS_BIG_ENDIAN"
|
"inswl %1,%2,%0"
|
"inswl %1,%2,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "insll_le"
|
(define_insn "insll_le"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
|
(ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
|
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(const_int 3))))]
|
(const_int 3))))]
|
"! WORDS_BIG_ENDIAN"
|
"! WORDS_BIG_ENDIAN"
|
"insll %1,%2,%0"
|
"insll %1,%2,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "insll_be"
|
(define_insn "insll_be"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
|
(ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
|
(minus:DI (const_int 56)
|
(minus:DI (const_int 56)
|
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(const_int 3)))))]
|
(const_int 3)))))]
|
"WORDS_BIG_ENDIAN"
|
"WORDS_BIG_ENDIAN"
|
"insll %1,%2,%0"
|
"insll %1,%2,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "insql_le"
|
(define_insn "insql_le"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(ashift:DI (match_operand:DI 1 "register_operand" "r")
|
(ashift:DI (match_operand:DI 1 "register_operand" "r")
|
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(const_int 3))))]
|
(const_int 3))))]
|
"! WORDS_BIG_ENDIAN"
|
"! WORDS_BIG_ENDIAN"
|
"insql %1,%2,%0"
|
"insql %1,%2,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "insql_be"
|
(define_insn "insql_be"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(ashift:DI (match_operand:DI 1 "register_operand" "r")
|
(ashift:DI (match_operand:DI 1 "register_operand" "r")
|
(minus:DI (const_int 56)
|
(minus:DI (const_int 56)
|
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
(const_int 3)))))]
|
(const_int 3)))))]
|
"WORDS_BIG_ENDIAN"
|
"WORDS_BIG_ENDIAN"
|
"insql %1,%2,%0"
|
"insql %1,%2,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
;; Combine has this sometimes habit of moving the and outside of the
|
;; Combine has this sometimes habit of moving the and outside of the
|
;; shift, making life more interesting.
|
;; shift, making life more interesting.
|
|
|
(define_insn "*insxl"
|
(define_insn "*insxl"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r")
|
(and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r")
|
(match_operand:DI 2 "mul8_operand" "I"))
|
(match_operand:DI 2 "mul8_operand" "I"))
|
(match_operand:DI 3 "immediate_operand" "i")))]
|
(match_operand:DI 3 "immediate_operand" "i")))]
|
"HOST_BITS_PER_WIDE_INT == 64
|
"HOST_BITS_PER_WIDE_INT == 64
|
&& CONST_INT_P (operands[3])
|
&& CONST_INT_P (operands[3])
|
&& (((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2])
|
&& (((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2])
|
== (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
|
== (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
|
|| ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2])
|
|| ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2])
|
== (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
|
== (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
|
|| ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2])
|
|| ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2])
|
== (unsigned HOST_WIDE_INT) INTVAL (operands[3])))"
|
== (unsigned HOST_WIDE_INT) INTVAL (operands[3])))"
|
{
|
{
|
#if HOST_BITS_PER_WIDE_INT == 64
|
#if HOST_BITS_PER_WIDE_INT == 64
|
if ((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2])
|
if ((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2])
|
== (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
|
== (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
|
return "insbl %1,%s2,%0";
|
return "insbl %1,%s2,%0";
|
if ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2])
|
if ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2])
|
== (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
|
== (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
|
return "inswl %1,%s2,%0";
|
return "inswl %1,%s2,%0";
|
if ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2])
|
if ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2])
|
== (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
|
== (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
|
return "insll %1,%s2,%0";
|
return "insll %1,%s2,%0";
|
#endif
|
#endif
|
gcc_unreachable ();
|
gcc_unreachable ();
|
}
|
}
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
;; We do not include the insXh insns because they are complex to express
|
;; We do not include the insXh insns because they are complex to express
|
;; and it does not appear that we would ever want to generate them.
|
;; and it does not appear that we would ever want to generate them.
|
;;
|
;;
|
;; Since we need them for block moves, though, cop out and use unspec.
|
;; Since we need them for block moves, though, cop out and use unspec.
|
|
|
(define_insn "insxh"
|
(define_insn "insxh"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
|
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
|
(match_operand:DI 2 "mode_width_operand" "n")
|
(match_operand:DI 2 "mode_width_operand" "n")
|
(match_operand:DI 3 "reg_or_8bit_operand" "rI")]
|
(match_operand:DI 3 "reg_or_8bit_operand" "rI")]
|
UNSPEC_INSXH))]
|
UNSPEC_INSXH))]
|
""
|
""
|
"ins%M2h %1,%3,%0"
|
"ins%M2h %1,%3,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "mskxl_le"
|
(define_insn "mskxl_le"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(and:DI (not:DI (ashift:DI
|
(and:DI (not:DI (ashift:DI
|
(match_operand:DI 2 "mode_mask_operand" "n")
|
(match_operand:DI 2 "mode_mask_operand" "n")
|
(ashift:DI
|
(ashift:DI
|
(match_operand:DI 3 "reg_or_8bit_operand" "rI")
|
(match_operand:DI 3 "reg_or_8bit_operand" "rI")
|
(const_int 3))))
|
(const_int 3))))
|
(match_operand:DI 1 "reg_or_0_operand" "rJ")))]
|
(match_operand:DI 1 "reg_or_0_operand" "rJ")))]
|
"! WORDS_BIG_ENDIAN"
|
"! WORDS_BIG_ENDIAN"
|
"msk%U2l %r1,%3,%0"
|
"msk%U2l %r1,%3,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "mskxl_be"
|
(define_insn "mskxl_be"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(and:DI (not:DI (ashift:DI
|
(and:DI (not:DI (ashift:DI
|
(match_operand:DI 2 "mode_mask_operand" "n")
|
(match_operand:DI 2 "mode_mask_operand" "n")
|
(minus:DI (const_int 56)
|
(minus:DI (const_int 56)
|
(ashift:DI
|
(ashift:DI
|
(match_operand:DI 3 "reg_or_8bit_operand" "rI")
|
(match_operand:DI 3 "reg_or_8bit_operand" "rI")
|
(const_int 3)))))
|
(const_int 3)))))
|
(match_operand:DI 1 "reg_or_0_operand" "rJ")))]
|
(match_operand:DI 1 "reg_or_0_operand" "rJ")))]
|
"WORDS_BIG_ENDIAN"
|
"WORDS_BIG_ENDIAN"
|
"msk%U2l %r1,%3,%0"
|
"msk%U2l %r1,%3,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
;; We do not include the mskXh insns because it does not appear we would
|
;; We do not include the mskXh insns because it does not appear we would
|
;; ever generate one.
|
;; ever generate one.
|
;;
|
;;
|
;; Again, we do for block moves and we use unspec again.
|
;; Again, we do for block moves and we use unspec again.
|
|
|
(define_insn "mskxh"
|
(define_insn "mskxh"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
|
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
|
(match_operand:DI 2 "mode_width_operand" "n")
|
(match_operand:DI 2 "mode_width_operand" "n")
|
(match_operand:DI 3 "reg_or_8bit_operand" "rI")]
|
(match_operand:DI 3 "reg_or_8bit_operand" "rI")]
|
UNSPEC_MSKXH))]
|
UNSPEC_MSKXH))]
|
""
|
""
|
"msk%M2h %1,%3,%0"
|
"msk%M2h %1,%3,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
;; Prefer AND + NE over LSHIFTRT + AND.
|
;; Prefer AND + NE over LSHIFTRT + AND.
|
|
|
(define_insn_and_split "*ze_and_ne"
|
(define_insn_and_split "*ze_and_ne"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(const_int 1)
|
(const_int 1)
|
(match_operand 2 "const_int_operand" "I")))]
|
(match_operand 2 "const_int_operand" "I")))]
|
"(unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 8"
|
"(unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 8"
|
"#"
|
"#"
|
"(unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 8"
|
"(unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 8"
|
[(set (match_dup 0)
|
[(set (match_dup 0)
|
(and:DI (match_dup 1) (match_dup 3)))
|
(and:DI (match_dup 1) (match_dup 3)))
|
(set (match_dup 0)
|
(set (match_dup 0)
|
(ne:DI (match_dup 0) (const_int 0)))]
|
(ne:DI (match_dup 0) (const_int 0)))]
|
"operands[3] = GEN_INT (1 << INTVAL (operands[2]));")
|
"operands[3] = GEN_INT (1 << INTVAL (operands[2]));")
|
|
|
;; Floating-point operations. All the double-precision insns can extend
|
;; Floating-point operations. All the double-precision insns can extend
|
;; from single, so indicate that. The exception are the ones that simply
|
;; from single, so indicate that. The exception are the ones that simply
|
;; play with the sign bits; it's not clear what to do there.
|
;; play with the sign bits; it's not clear what to do there.
|
|
|
(define_insn "abssf2"
|
(define_insn "abssf2"
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(abs:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))]
|
(abs:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"cpys $f31,%R1,%0"
|
"cpys $f31,%R1,%0"
|
[(set_attr "type" "fcpys")])
|
[(set_attr "type" "fcpys")])
|
|
|
(define_insn "*nabssf2"
|
(define_insn "*nabssf2"
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(neg:SF (abs:SF (match_operand:SF 1 "reg_or_0_operand" "fG"))))]
|
(neg:SF (abs:SF (match_operand:SF 1 "reg_or_0_operand" "fG"))))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"cpysn $f31,%R1,%0"
|
"cpysn $f31,%R1,%0"
|
[(set_attr "type" "fadd")])
|
[(set_attr "type" "fadd")])
|
|
|
(define_insn "absdf2"
|
(define_insn "absdf2"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(abs:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
|
(abs:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"cpys $f31,%R1,%0"
|
"cpys $f31,%R1,%0"
|
[(set_attr "type" "fcpys")])
|
[(set_attr "type" "fcpys")])
|
|
|
(define_insn "*nabsdf2"
|
(define_insn "*nabsdf2"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(neg:DF (abs:DF (match_operand:DF 1 "reg_or_0_operand" "fG"))))]
|
(neg:DF (abs:DF (match_operand:DF 1 "reg_or_0_operand" "fG"))))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"cpysn $f31,%R1,%0"
|
"cpysn $f31,%R1,%0"
|
[(set_attr "type" "fadd")])
|
[(set_attr "type" "fadd")])
|
|
|
(define_expand "abstf2"
|
(define_expand "abstf2"
|
[(parallel [(set (match_operand:TF 0 "register_operand" "")
|
[(parallel [(set (match_operand:TF 0 "register_operand" "")
|
(abs:TF (match_operand:TF 1 "reg_or_0_operand" "")))
|
(abs:TF (match_operand:TF 1 "reg_or_0_operand" "")))
|
(use (match_dup 2))])]
|
(use (match_dup 2))])]
|
"TARGET_HAS_XFLOATING_LIBS"
|
"TARGET_HAS_XFLOATING_LIBS"
|
{
|
{
|
#if HOST_BITS_PER_WIDE_INT >= 64
|
#if HOST_BITS_PER_WIDE_INT >= 64
|
operands[2] = force_reg (DImode, GEN_INT ((HOST_WIDE_INT) 1 << 63));
|
operands[2] = force_reg (DImode, GEN_INT ((HOST_WIDE_INT) 1 << 63));
|
#else
|
#else
|
operands[2] = force_reg (DImode, immed_double_const (0, 0x80000000, DImode));
|
operands[2] = force_reg (DImode, immed_double_const (0, 0x80000000, DImode));
|
#endif
|
#endif
|
})
|
})
|
|
|
(define_insn_and_split "*abstf_internal"
|
(define_insn_and_split "*abstf_internal"
|
[(set (match_operand:TF 0 "register_operand" "=r")
|
[(set (match_operand:TF 0 "register_operand" "=r")
|
(abs:TF (match_operand:TF 1 "reg_or_0_operand" "rG")))
|
(abs:TF (match_operand:TF 1 "reg_or_0_operand" "rG")))
|
(use (match_operand:DI 2 "register_operand" "r"))]
|
(use (match_operand:DI 2 "register_operand" "r"))]
|
"TARGET_HAS_XFLOATING_LIBS"
|
"TARGET_HAS_XFLOATING_LIBS"
|
"#"
|
"#"
|
"&& reload_completed"
|
"&& reload_completed"
|
[(const_int 0)]
|
[(const_int 0)]
|
"alpha_split_tfmode_frobsign (operands, gen_andnotdi3); DONE;")
|
"alpha_split_tfmode_frobsign (operands, gen_andnotdi3); DONE;")
|
|
|
(define_insn "negsf2"
|
(define_insn "negsf2"
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(neg:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))]
|
(neg:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"cpysn %R1,%R1,%0"
|
"cpysn %R1,%R1,%0"
|
[(set_attr "type" "fadd")])
|
[(set_attr "type" "fadd")])
|
|
|
(define_insn "negdf2"
|
(define_insn "negdf2"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(neg:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
|
(neg:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"cpysn %R1,%R1,%0"
|
"cpysn %R1,%R1,%0"
|
[(set_attr "type" "fadd")])
|
[(set_attr "type" "fadd")])
|
|
|
(define_expand "negtf2"
|
(define_expand "negtf2"
|
[(parallel [(set (match_operand:TF 0 "register_operand" "")
|
[(parallel [(set (match_operand:TF 0 "register_operand" "")
|
(neg:TF (match_operand:TF 1 "reg_or_0_operand" "")))
|
(neg:TF (match_operand:TF 1 "reg_or_0_operand" "")))
|
(use (match_dup 2))])]
|
(use (match_dup 2))])]
|
"TARGET_HAS_XFLOATING_LIBS"
|
"TARGET_HAS_XFLOATING_LIBS"
|
{
|
{
|
#if HOST_BITS_PER_WIDE_INT >= 64
|
#if HOST_BITS_PER_WIDE_INT >= 64
|
operands[2] = force_reg (DImode, GEN_INT ((HOST_WIDE_INT) 1 << 63));
|
operands[2] = force_reg (DImode, GEN_INT ((HOST_WIDE_INT) 1 << 63));
|
#else
|
#else
|
operands[2] = force_reg (DImode, immed_double_const (0, 0x80000000, DImode));
|
operands[2] = force_reg (DImode, immed_double_const (0, 0x80000000, DImode));
|
#endif
|
#endif
|
})
|
})
|
|
|
(define_insn_and_split "*negtf_internal"
|
(define_insn_and_split "*negtf_internal"
|
[(set (match_operand:TF 0 "register_operand" "=r")
|
[(set (match_operand:TF 0 "register_operand" "=r")
|
(neg:TF (match_operand:TF 1 "reg_or_0_operand" "rG")))
|
(neg:TF (match_operand:TF 1 "reg_or_0_operand" "rG")))
|
(use (match_operand:DI 2 "register_operand" "r"))]
|
(use (match_operand:DI 2 "register_operand" "r"))]
|
"TARGET_HAS_XFLOATING_LIBS"
|
"TARGET_HAS_XFLOATING_LIBS"
|
"#"
|
"#"
|
"&& reload_completed"
|
"&& reload_completed"
|
[(const_int 0)]
|
[(const_int 0)]
|
"alpha_split_tfmode_frobsign (operands, gen_xordi3); DONE;")
|
"alpha_split_tfmode_frobsign (operands, gen_xordi3); DONE;")
|
|
|
(define_insn "copysignsf3"
|
(define_insn "copysignsf3"
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(unspec:SF [(match_operand:SF 1 "reg_or_0_operand" "fG")
|
(unspec:SF [(match_operand:SF 1 "reg_or_0_operand" "fG")
|
(match_operand:SF 2 "reg_or_0_operand" "fG")]
|
(match_operand:SF 2 "reg_or_0_operand" "fG")]
|
UNSPEC_COPYSIGN))]
|
UNSPEC_COPYSIGN))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"cpys %R2,%R1,%0"
|
"cpys %R2,%R1,%0"
|
[(set_attr "type" "fadd")])
|
[(set_attr "type" "fadd")])
|
|
|
(define_insn "*ncopysignsf3"
|
(define_insn "*ncopysignsf3"
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(neg:SF (unspec:SF [(match_operand:SF 1 "reg_or_0_operand" "fG")
|
(neg:SF (unspec:SF [(match_operand:SF 1 "reg_or_0_operand" "fG")
|
(match_operand:SF 2 "reg_or_0_operand" "fG")]
|
(match_operand:SF 2 "reg_or_0_operand" "fG")]
|
UNSPEC_COPYSIGN)))]
|
UNSPEC_COPYSIGN)))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"cpysn %R2,%R1,%0"
|
"cpysn %R2,%R1,%0"
|
[(set_attr "type" "fadd")])
|
[(set_attr "type" "fadd")])
|
|
|
(define_insn "copysigndf3"
|
(define_insn "copysigndf3"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(unspec:DF [(match_operand:DF 1 "reg_or_0_operand" "fG")
|
(unspec:DF [(match_operand:DF 1 "reg_or_0_operand" "fG")
|
(match_operand:DF 2 "reg_or_0_operand" "fG")]
|
(match_operand:DF 2 "reg_or_0_operand" "fG")]
|
UNSPEC_COPYSIGN))]
|
UNSPEC_COPYSIGN))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"cpys %R2,%R1,%0"
|
"cpys %R2,%R1,%0"
|
[(set_attr "type" "fadd")])
|
[(set_attr "type" "fadd")])
|
|
|
(define_insn "*ncopysigndf3"
|
(define_insn "*ncopysigndf3"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(neg:DF (unspec:DF [(match_operand:DF 1 "reg_or_0_operand" "fG")
|
(neg:DF (unspec:DF [(match_operand:DF 1 "reg_or_0_operand" "fG")
|
(match_operand:DF 2 "reg_or_0_operand" "fG")]
|
(match_operand:DF 2 "reg_or_0_operand" "fG")]
|
UNSPEC_COPYSIGN)))]
|
UNSPEC_COPYSIGN)))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"cpysn %R2,%R1,%0"
|
"cpysn %R2,%R1,%0"
|
[(set_attr "type" "fadd")])
|
[(set_attr "type" "fadd")])
|
|
|
(define_insn "*addsf_ieee"
|
(define_insn "*addsf_ieee"
|
[(set (match_operand:SF 0 "register_operand" "=&f")
|
[(set (match_operand:SF 0 "register_operand" "=&f")
|
(plus:SF (match_operand:SF 1 "reg_or_0_operand" "%fG")
|
(plus:SF (match_operand:SF 1 "reg_or_0_operand" "%fG")
|
(match_operand:SF 2 "reg_or_0_operand" "fG")))]
|
(match_operand:SF 2 "reg_or_0_operand" "fG")))]
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"add%,%/ %R1,%R2,%0"
|
"add%,%/ %R1,%R2,%0"
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_insn "addsf3"
|
(define_insn "addsf3"
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(plus:SF (match_operand:SF 1 "reg_or_0_operand" "%fG")
|
(plus:SF (match_operand:SF 1 "reg_or_0_operand" "%fG")
|
(match_operand:SF 2 "reg_or_0_operand" "fG")))]
|
(match_operand:SF 2 "reg_or_0_operand" "fG")))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"add%,%/ %R1,%R2,%0"
|
"add%,%/ %R1,%R2,%0"
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_insn "*adddf_ieee"
|
(define_insn "*adddf_ieee"
|
[(set (match_operand:DF 0 "register_operand" "=&f")
|
[(set (match_operand:DF 0 "register_operand" "=&f")
|
(plus:DF (match_operand:DF 1 "reg_or_0_operand" "%fG")
|
(plus:DF (match_operand:DF 1 "reg_or_0_operand" "%fG")
|
(match_operand:DF 2 "reg_or_0_operand" "fG")))]
|
(match_operand:DF 2 "reg_or_0_operand" "fG")))]
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"add%-%/ %R1,%R2,%0"
|
"add%-%/ %R1,%R2,%0"
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_insn "adddf3"
|
(define_insn "adddf3"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(plus:DF (match_operand:DF 1 "reg_or_0_operand" "%fG")
|
(plus:DF (match_operand:DF 1 "reg_or_0_operand" "%fG")
|
(match_operand:DF 2 "reg_or_0_operand" "fG")))]
|
(match_operand:DF 2 "reg_or_0_operand" "fG")))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"add%-%/ %R1,%R2,%0"
|
"add%-%/ %R1,%R2,%0"
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_insn "*adddf_ext1"
|
(define_insn "*adddf_ext1"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(plus:DF (float_extend:DF
|
(plus:DF (float_extend:DF
|
(match_operand:SF 1 "reg_or_0_operand" "fG"))
|
(match_operand:SF 1 "reg_or_0_operand" "fG"))
|
(match_operand:DF 2 "reg_or_0_operand" "fG")))]
|
(match_operand:DF 2 "reg_or_0_operand" "fG")))]
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"add%-%/ %R1,%R2,%0"
|
"add%-%/ %R1,%R2,%0"
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_insn "*adddf_ext2"
|
(define_insn "*adddf_ext2"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(plus:DF (float_extend:DF
|
(plus:DF (float_extend:DF
|
(match_operand:SF 1 "reg_or_0_operand" "%fG"))
|
(match_operand:SF 1 "reg_or_0_operand" "%fG"))
|
(float_extend:DF
|
(float_extend:DF
|
(match_operand:SF 2 "reg_or_0_operand" "fG"))))]
|
(match_operand:SF 2 "reg_or_0_operand" "fG"))))]
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"add%-%/ %R1,%R2,%0"
|
"add%-%/ %R1,%R2,%0"
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_expand "addtf3"
|
(define_expand "addtf3"
|
[(use (match_operand 0 "register_operand" ""))
|
[(use (match_operand 0 "register_operand" ""))
|
(use (match_operand 1 "general_operand" ""))
|
(use (match_operand 1 "general_operand" ""))
|
(use (match_operand 2 "general_operand" ""))]
|
(use (match_operand 2 "general_operand" ""))]
|
"TARGET_HAS_XFLOATING_LIBS"
|
"TARGET_HAS_XFLOATING_LIBS"
|
"alpha_emit_xfloating_arith (PLUS, operands); DONE;")
|
"alpha_emit_xfloating_arith (PLUS, operands); DONE;")
|
|
|
;; Define conversion operators between DFmode and SImode, using the cvtql
|
;; Define conversion operators between DFmode and SImode, using the cvtql
|
;; instruction. To allow combine et al to do useful things, we keep the
|
;; instruction. To allow combine et al to do useful things, we keep the
|
;; operation as a unit until after reload, at which point we split the
|
;; operation as a unit until after reload, at which point we split the
|
;; instructions.
|
;; instructions.
|
;;
|
;;
|
;; Note that we (attempt to) only consider this optimization when the
|
;; Note that we (attempt to) only consider this optimization when the
|
;; ultimate destination is memory. If we will be doing further integer
|
;; ultimate destination is memory. If we will be doing further integer
|
;; processing, it is cheaper to do the truncation in the int regs.
|
;; processing, it is cheaper to do the truncation in the int regs.
|
|
|
(define_insn "*cvtql"
|
(define_insn "*cvtql"
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(unspec:SF [(match_operand:DI 1 "reg_or_0_operand" "fG")]
|
(unspec:SF [(match_operand:DI 1 "reg_or_0_operand" "fG")]
|
UNSPEC_CVTQL))]
|
UNSPEC_CVTQL))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"cvtql%/ %R1,%0"
|
"cvtql%/ %R1,%0"
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "trap_suffix" "v_sv")])
|
(set_attr "trap_suffix" "v_sv")])
|
|
|
(define_insn_and_split "*fix_truncdfsi_ieee"
|
(define_insn_and_split "*fix_truncdfsi_ieee"
|
[(set (match_operand:SI 0 "memory_operand" "=m")
|
[(set (match_operand:SI 0 "memory_operand" "=m")
|
(subreg:SI
|
(subreg:SI
|
(match_operator:DI 4 "fix_operator"
|
(match_operator:DI 4 "fix_operator"
|
[(match_operand:DF 1 "reg_or_0_operand" "fG")]) 0))
|
[(match_operand:DF 1 "reg_or_0_operand" "fG")]) 0))
|
(clobber (match_scratch:DI 2 "=&f"))
|
(clobber (match_scratch:DI 2 "=&f"))
|
(clobber (match_scratch:SF 3 "=&f"))]
|
(clobber (match_scratch:SF 3 "=&f"))]
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"#"
|
"#"
|
"&& reload_completed"
|
"&& reload_completed"
|
[(set (match_dup 2) (match_op_dup 4 [(match_dup 1)]))
|
[(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 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
|
(set (match_dup 5) (match_dup 3))]
|
(set (match_dup 5) (match_dup 3))]
|
{
|
{
|
operands[5] = adjust_address (operands[0], SFmode, 0);
|
operands[5] = adjust_address (operands[0], SFmode, 0);
|
}
|
}
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")])
|
(set_attr "trap" "yes")])
|
|
|
(define_insn_and_split "*fix_truncdfsi_internal"
|
(define_insn_and_split "*fix_truncdfsi_internal"
|
[(set (match_operand:SI 0 "memory_operand" "=m")
|
[(set (match_operand:SI 0 "memory_operand" "=m")
|
(subreg:SI
|
(subreg:SI
|
(match_operator:DI 3 "fix_operator"
|
(match_operator:DI 3 "fix_operator"
|
[(match_operand:DF 1 "reg_or_0_operand" "fG")]) 0))
|
[(match_operand:DF 1 "reg_or_0_operand" "fG")]) 0))
|
(clobber (match_scratch:DI 2 "=f"))]
|
(clobber (match_scratch:DI 2 "=f"))]
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"#"
|
"#"
|
"&& reload_completed"
|
"&& reload_completed"
|
[(set (match_dup 2) (match_op_dup 3 [(match_dup 1)]))
|
[(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 4) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
|
(set (match_dup 5) (match_dup 4))]
|
(set (match_dup 5) (match_dup 4))]
|
{
|
{
|
operands[4] = gen_rtx_REG (SFmode, REGNO (operands[2]));
|
operands[4] = gen_rtx_REG (SFmode, REGNO (operands[2]));
|
operands[5] = adjust_address (operands[0], SFmode, 0);
|
operands[5] = adjust_address (operands[0], SFmode, 0);
|
}
|
}
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")])
|
(set_attr "trap" "yes")])
|
|
|
(define_insn "*fix_truncdfdi_ieee"
|
(define_insn "*fix_truncdfdi_ieee"
|
[(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
|
[(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
|
(match_operator:DI 2 "fix_operator"
|
(match_operator:DI 2 "fix_operator"
|
[(match_operand:DF 1 "reg_or_0_operand" "fG")]))]
|
[(match_operand:DF 1 "reg_or_0_operand" "fG")]))]
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"cvt%-q%/ %R1,%0"
|
"cvt%-q%/ %R1,%0"
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "c")
|
(set_attr "round_suffix" "c")
|
(set_attr "trap_suffix" "v_sv_svi")])
|
(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")
|
[(set (match_operand:DI 0 "reg_no_subreg_operand" "=f")
|
(match_operator:DI 2 "fix_operator"
|
(match_operator:DI 2 "fix_operator"
|
[(match_operand:DF 1 "reg_or_0_operand" "fG")]))]
|
[(match_operand:DF 1 "reg_or_0_operand" "fG")]))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"cvt%-q%/ %R1,%0"
|
"cvt%-q%/ %R1,%0"
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "c")
|
(set_attr "round_suffix" "c")
|
(set_attr "trap_suffix" "v_sv_svi")])
|
(set_attr "trap_suffix" "v_sv_svi")])
|
|
|
(define_expand "fix_truncdfdi2"
|
(define_expand "fix_truncdfdi2"
|
[(set (match_operand:DI 0 "reg_no_subreg_operand" "")
|
[(set (match_operand:DI 0 "reg_no_subreg_operand" "")
|
(fix:DI (match_operand:DF 1 "reg_or_0_operand" "")))]
|
(fix:DI (match_operand:DF 1 "reg_or_0_operand" "")))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"")
|
"")
|
|
|
(define_expand "fixuns_truncdfdi2"
|
(define_expand "fixuns_truncdfdi2"
|
[(set (match_operand:DI 0 "reg_no_subreg_operand" "")
|
[(set (match_operand:DI 0 "reg_no_subreg_operand" "")
|
(unsigned_fix:DI (match_operand:DF 1 "reg_or_0_operand" "")))]
|
(unsigned_fix:DI (match_operand:DF 1 "reg_or_0_operand" "")))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"")
|
"")
|
|
|
;; Likewise between SFmode and SImode.
|
;; Likewise between SFmode and SImode.
|
|
|
(define_insn_and_split "*fix_truncsfsi_ieee"
|
(define_insn_and_split "*fix_truncsfsi_ieee"
|
[(set (match_operand:SI 0 "memory_operand" "=m")
|
[(set (match_operand:SI 0 "memory_operand" "=m")
|
(subreg:SI
|
(subreg:SI
|
(match_operator:DI 4 "fix_operator"
|
(match_operator:DI 4 "fix_operator"
|
[(float_extend:DF
|
[(float_extend:DF
|
(match_operand:SF 1 "reg_or_0_operand" "fG"))]) 0))
|
(match_operand:SF 1 "reg_or_0_operand" "fG"))]) 0))
|
(clobber (match_scratch:DI 2 "=&f"))
|
(clobber (match_scratch:DI 2 "=&f"))
|
(clobber (match_scratch:SF 3 "=&f"))]
|
(clobber (match_scratch:SF 3 "=&f"))]
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"#"
|
"#"
|
"&& reload_completed"
|
"&& reload_completed"
|
[(set (match_dup 2) (match_op_dup 4 [(float_extend:DF (match_dup 1))]))
|
[(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 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
|
(set (match_dup 5) (match_dup 3))]
|
(set (match_dup 5) (match_dup 3))]
|
{
|
{
|
operands[5] = adjust_address (operands[0], SFmode, 0);
|
operands[5] = adjust_address (operands[0], SFmode, 0);
|
}
|
}
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")])
|
(set_attr "trap" "yes")])
|
|
|
(define_insn_and_split "*fix_truncsfsi_internal"
|
(define_insn_and_split "*fix_truncsfsi_internal"
|
[(set (match_operand:SI 0 "memory_operand" "=m")
|
[(set (match_operand:SI 0 "memory_operand" "=m")
|
(subreg:SI
|
(subreg:SI
|
(match_operator:DI 3 "fix_operator"
|
(match_operator:DI 3 "fix_operator"
|
[(float_extend:DF
|
[(float_extend:DF
|
(match_operand:SF 1 "reg_or_0_operand" "fG"))]) 0))
|
(match_operand:SF 1 "reg_or_0_operand" "fG"))]) 0))
|
(clobber (match_scratch:DI 2 "=f"))]
|
(clobber (match_scratch:DI 2 "=f"))]
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"#"
|
"#"
|
"&& reload_completed"
|
"&& reload_completed"
|
[(set (match_dup 2) (match_op_dup 3 [(float_extend:DF (match_dup 1))]))
|
[(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 4) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
|
(set (match_dup 5) (match_dup 4))]
|
(set (match_dup 5) (match_dup 4))]
|
{
|
{
|
operands[4] = gen_rtx_REG (SFmode, REGNO (operands[2]));
|
operands[4] = gen_rtx_REG (SFmode, REGNO (operands[2]));
|
operands[5] = adjust_address (operands[0], SFmode, 0);
|
operands[5] = adjust_address (operands[0], SFmode, 0);
|
}
|
}
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")])
|
(set_attr "trap" "yes")])
|
|
|
(define_insn "*fix_truncsfdi_ieee"
|
(define_insn "*fix_truncsfdi_ieee"
|
[(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
|
[(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
|
(match_operator:DI 2 "fix_operator"
|
(match_operator:DI 2 "fix_operator"
|
[(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))]))]
|
[(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))]))]
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"cvt%-q%/ %R1,%0"
|
"cvt%-q%/ %R1,%0"
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "c")
|
(set_attr "round_suffix" "c")
|
(set_attr "trap_suffix" "v_sv_svi")])
|
(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")
|
[(set (match_operand:DI 0 "reg_no_subreg_operand" "=f")
|
(match_operator:DI 2 "fix_operator"
|
(match_operator:DI 2 "fix_operator"
|
[(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))]))]
|
[(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))]))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"cvt%-q%/ %R1,%0"
|
"cvt%-q%/ %R1,%0"
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "c")
|
(set_attr "round_suffix" "c")
|
(set_attr "trap_suffix" "v_sv_svi")])
|
(set_attr "trap_suffix" "v_sv_svi")])
|
|
|
(define_expand "fix_truncsfdi2"
|
(define_expand "fix_truncsfdi2"
|
[(set (match_operand:DI 0 "reg_no_subreg_operand" "")
|
[(set (match_operand:DI 0 "reg_no_subreg_operand" "")
|
(fix:DI (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))))]
|
(fix:DI (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"")
|
"")
|
|
|
(define_expand "fixuns_truncsfdi2"
|
(define_expand "fixuns_truncsfdi2"
|
[(set (match_operand:DI 0 "reg_no_subreg_operand" "")
|
[(set (match_operand:DI 0 "reg_no_subreg_operand" "")
|
(unsigned_fix:DI
|
(unsigned_fix:DI
|
(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))))]
|
(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"")
|
"")
|
|
|
(define_expand "fix_trunctfdi2"
|
(define_expand "fix_trunctfdi2"
|
[(use (match_operand:DI 0 "register_operand" ""))
|
[(use (match_operand:DI 0 "register_operand" ""))
|
(use (match_operand:TF 1 "general_operand" ""))]
|
(use (match_operand:TF 1 "general_operand" ""))]
|
"TARGET_HAS_XFLOATING_LIBS"
|
"TARGET_HAS_XFLOATING_LIBS"
|
"alpha_emit_xfloating_cvt (FIX, operands); DONE;")
|
"alpha_emit_xfloating_cvt (FIX, operands); DONE;")
|
|
|
(define_expand "fixuns_trunctfdi2"
|
(define_expand "fixuns_trunctfdi2"
|
[(use (match_operand:DI 0 "register_operand" ""))
|
[(use (match_operand:DI 0 "register_operand" ""))
|
(use (match_operand:TF 1 "general_operand" ""))]
|
(use (match_operand:TF 1 "general_operand" ""))]
|
"TARGET_HAS_XFLOATING_LIBS"
|
"TARGET_HAS_XFLOATING_LIBS"
|
"alpha_emit_xfloating_cvt (UNSIGNED_FIX, operands); DONE;")
|
"alpha_emit_xfloating_cvt (UNSIGNED_FIX, operands); DONE;")
|
|
|
(define_insn "*floatdisf_ieee"
|
(define_insn "*floatdisf_ieee"
|
[(set (match_operand:SF 0 "register_operand" "=&f")
|
[(set (match_operand:SF 0 "register_operand" "=&f")
|
(float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
|
(float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"cvtq%,%/ %1,%0"
|
"cvtq%,%/ %1,%0"
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "sui")])
|
(set_attr "trap_suffix" "sui")])
|
|
|
(define_insn "floatdisf2"
|
(define_insn "floatdisf2"
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
|
(float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"cvtq%,%/ %1,%0"
|
"cvtq%,%/ %1,%0"
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "sui")])
|
(set_attr "trap_suffix" "sui")])
|
|
|
(define_insn_and_split "*floatsisf2_ieee"
|
(define_insn_and_split "*floatsisf2_ieee"
|
[(set (match_operand:SF 0 "register_operand" "=&f")
|
[(set (match_operand:SF 0 "register_operand" "=&f")
|
(float:SF (match_operand:SI 1 "memory_operand" "m")))
|
(float:SF (match_operand:SI 1 "memory_operand" "m")))
|
(clobber (match_scratch:DI 2 "=&f"))
|
(clobber (match_scratch:DI 2 "=&f"))
|
(clobber (match_scratch:SF 3 "=&f"))]
|
(clobber (match_scratch:SF 3 "=&f"))]
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"#"
|
"#"
|
"&& reload_completed"
|
"&& reload_completed"
|
[(set (match_dup 3) (match_dup 1))
|
[(set (match_dup 3) (match_dup 1))
|
(set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
|
(set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
|
(set (match_dup 0) (float:SF (match_dup 2)))]
|
(set (match_dup 0) (float:SF (match_dup 2)))]
|
{
|
{
|
operands[1] = adjust_address (operands[1], SFmode, 0);
|
operands[1] = adjust_address (operands[1], SFmode, 0);
|
})
|
})
|
|
|
(define_insn_and_split "*floatsisf2"
|
(define_insn_and_split "*floatsisf2"
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(float:SF (match_operand:SI 1 "memory_operand" "m")))]
|
(float:SF (match_operand:SI 1 "memory_operand" "m")))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"#"
|
"#"
|
"&& reload_completed"
|
"&& reload_completed"
|
[(set (match_dup 0) (match_dup 1))
|
[(set (match_dup 0) (match_dup 1))
|
(set (match_dup 2) (unspec:DI [(match_dup 0)] UNSPEC_CVTLQ))
|
(set (match_dup 2) (unspec:DI [(match_dup 0)] UNSPEC_CVTLQ))
|
(set (match_dup 0) (float:SF (match_dup 2)))]
|
(set (match_dup 0) (float:SF (match_dup 2)))]
|
{
|
{
|
operands[1] = adjust_address (operands[1], SFmode, 0);
|
operands[1] = adjust_address (operands[1], SFmode, 0);
|
operands[2] = gen_rtx_REG (DImode, REGNO (operands[0]));
|
operands[2] = gen_rtx_REG (DImode, REGNO (operands[0]));
|
})
|
})
|
|
|
(define_insn "*floatdidf_ieee"
|
(define_insn "*floatdidf_ieee"
|
[(set (match_operand:DF 0 "register_operand" "=&f")
|
[(set (match_operand:DF 0 "register_operand" "=&f")
|
(float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
|
(float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"cvtq%-%/ %1,%0"
|
"cvtq%-%/ %1,%0"
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "sui")])
|
(set_attr "trap_suffix" "sui")])
|
|
|
(define_insn "floatdidf2"
|
(define_insn "floatdidf2"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
|
(float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"cvtq%-%/ %1,%0"
|
"cvtq%-%/ %1,%0"
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "sui")])
|
(set_attr "trap_suffix" "sui")])
|
|
|
(define_insn_and_split "*floatsidf2_ieee"
|
(define_insn_and_split "*floatsidf2_ieee"
|
[(set (match_operand:DF 0 "register_operand" "=&f")
|
[(set (match_operand:DF 0 "register_operand" "=&f")
|
(float:DF (match_operand:SI 1 "memory_operand" "m")))
|
(float:DF (match_operand:SI 1 "memory_operand" "m")))
|
(clobber (match_scratch:DI 2 "=&f"))
|
(clobber (match_scratch:DI 2 "=&f"))
|
(clobber (match_scratch:SF 3 "=&f"))]
|
(clobber (match_scratch:SF 3 "=&f"))]
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"#"
|
"#"
|
"&& reload_completed"
|
"&& reload_completed"
|
[(set (match_dup 3) (match_dup 1))
|
[(set (match_dup 3) (match_dup 1))
|
(set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
|
(set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
|
(set (match_dup 0) (float:DF (match_dup 2)))]
|
(set (match_dup 0) (float:DF (match_dup 2)))]
|
{
|
{
|
operands[1] = adjust_address (operands[1], SFmode, 0);
|
operands[1] = adjust_address (operands[1], SFmode, 0);
|
})
|
})
|
|
|
(define_insn_and_split "*floatsidf2"
|
(define_insn_and_split "*floatsidf2"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(float:DF (match_operand:SI 1 "memory_operand" "m")))]
|
(float:DF (match_operand:SI 1 "memory_operand" "m")))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"#"
|
"#"
|
"&& reload_completed"
|
"&& reload_completed"
|
[(set (match_dup 3) (match_dup 1))
|
[(set (match_dup 3) (match_dup 1))
|
(set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
|
(set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
|
(set (match_dup 0) (float:DF (match_dup 2)))]
|
(set (match_dup 0) (float:DF (match_dup 2)))]
|
{
|
{
|
operands[1] = adjust_address (operands[1], SFmode, 0);
|
operands[1] = adjust_address (operands[1], SFmode, 0);
|
operands[2] = gen_rtx_REG (DImode, REGNO (operands[0]));
|
operands[2] = gen_rtx_REG (DImode, REGNO (operands[0]));
|
operands[3] = gen_rtx_REG (SFmode, REGNO (operands[0]));
|
operands[3] = gen_rtx_REG (SFmode, REGNO (operands[0]));
|
})
|
})
|
|
|
(define_expand "floatditf2"
|
(define_expand "floatditf2"
|
[(use (match_operand:TF 0 "register_operand" ""))
|
[(use (match_operand:TF 0 "register_operand" ""))
|
(use (match_operand:DI 1 "general_operand" ""))]
|
(use (match_operand:DI 1 "general_operand" ""))]
|
"TARGET_HAS_XFLOATING_LIBS"
|
"TARGET_HAS_XFLOATING_LIBS"
|
"alpha_emit_xfloating_cvt (FLOAT, operands); DONE;")
|
"alpha_emit_xfloating_cvt (FLOAT, operands); DONE;")
|
|
|
(define_expand "floatunsdisf2"
|
(define_expand "floatunsdisf2"
|
[(use (match_operand:SF 0 "register_operand" ""))
|
[(use (match_operand:SF 0 "register_operand" ""))
|
(use (match_operand:DI 1 "register_operand" ""))]
|
(use (match_operand:DI 1 "register_operand" ""))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"alpha_emit_floatuns (operands); DONE;")
|
"alpha_emit_floatuns (operands); DONE;")
|
|
|
(define_expand "floatunsdidf2"
|
(define_expand "floatunsdidf2"
|
[(use (match_operand:DF 0 "register_operand" ""))
|
[(use (match_operand:DF 0 "register_operand" ""))
|
(use (match_operand:DI 1 "register_operand" ""))]
|
(use (match_operand:DI 1 "register_operand" ""))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"alpha_emit_floatuns (operands); DONE;")
|
"alpha_emit_floatuns (operands); DONE;")
|
|
|
(define_expand "floatunsditf2"
|
(define_expand "floatunsditf2"
|
[(use (match_operand:TF 0 "register_operand" ""))
|
[(use (match_operand:TF 0 "register_operand" ""))
|
(use (match_operand:DI 1 "general_operand" ""))]
|
(use (match_operand:DI 1 "general_operand" ""))]
|
"TARGET_HAS_XFLOATING_LIBS"
|
"TARGET_HAS_XFLOATING_LIBS"
|
"alpha_emit_xfloating_cvt (UNSIGNED_FLOAT, operands); DONE;")
|
"alpha_emit_xfloating_cvt (UNSIGNED_FLOAT, operands); DONE;")
|
|
|
(define_expand "extendsfdf2"
|
(define_expand "extendsfdf2"
|
[(set (match_operand:DF 0 "register_operand" "")
|
[(set (match_operand:DF 0 "register_operand" "")
|
(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
|
(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
|
"TARGET_FP"
|
"TARGET_FP"
|
{
|
{
|
if (alpha_fptm >= ALPHA_FPTM_SU)
|
if (alpha_fptm >= ALPHA_FPTM_SU)
|
operands[1] = force_reg (SFmode, operands[1]);
|
operands[1] = force_reg (SFmode, operands[1]);
|
})
|
})
|
|
|
;; The Unicos/Mk assembler doesn't support cvtst, but we've already
|
;; The Unicos/Mk assembler doesn't support cvtst, but we've already
|
;; asserted that alpha_fptm == ALPHA_FPTM_N.
|
;; asserted that alpha_fptm == ALPHA_FPTM_N.
|
|
|
(define_insn "*extendsfdf2_ieee"
|
(define_insn "*extendsfdf2_ieee"
|
[(set (match_operand:DF 0 "register_operand" "=&f")
|
[(set (match_operand:DF 0 "register_operand" "=&f")
|
(float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
|
(float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"cvtsts %1,%0"
|
"cvtsts %1,%0"
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")])
|
(set_attr "trap" "yes")])
|
|
|
(define_insn "*extendsfdf2_internal"
|
(define_insn "*extendsfdf2_internal"
|
[(set (match_operand:DF 0 "register_operand" "=f,f,m")
|
[(set (match_operand:DF 0 "register_operand" "=f,f,m")
|
(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m,f")))]
|
(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m,f")))]
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"@
|
"@
|
cpys %1,%1,%0
|
cpys %1,%1,%0
|
ld%, %0,%1
|
ld%, %0,%1
|
st%- %1,%0"
|
st%- %1,%0"
|
[(set_attr "type" "fcpys,fld,fst")])
|
[(set_attr "type" "fcpys,fld,fst")])
|
|
|
;; Use register_operand for operand 1 to prevent compress_float_constant
|
;; Use register_operand for operand 1 to prevent compress_float_constant
|
;; from doing something silly. When optimizing we'll put things back
|
;; from doing something silly. When optimizing we'll put things back
|
;; together anyway.
|
;; together anyway.
|
(define_expand "extendsftf2"
|
(define_expand "extendsftf2"
|
[(use (match_operand:TF 0 "register_operand" ""))
|
[(use (match_operand:TF 0 "register_operand" ""))
|
(use (match_operand:SF 1 "register_operand" ""))]
|
(use (match_operand:SF 1 "register_operand" ""))]
|
"TARGET_HAS_XFLOATING_LIBS"
|
"TARGET_HAS_XFLOATING_LIBS"
|
{
|
{
|
rtx tmp = gen_reg_rtx (DFmode);
|
rtx tmp = gen_reg_rtx (DFmode);
|
emit_insn (gen_extendsfdf2 (tmp, operands[1]));
|
emit_insn (gen_extendsfdf2 (tmp, operands[1]));
|
emit_insn (gen_extenddftf2 (operands[0], tmp));
|
emit_insn (gen_extenddftf2 (operands[0], tmp));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "extenddftf2"
|
(define_expand "extenddftf2"
|
[(use (match_operand:TF 0 "register_operand" ""))
|
[(use (match_operand:TF 0 "register_operand" ""))
|
(use (match_operand:DF 1 "register_operand" ""))]
|
(use (match_operand:DF 1 "register_operand" ""))]
|
"TARGET_HAS_XFLOATING_LIBS"
|
"TARGET_HAS_XFLOATING_LIBS"
|
"alpha_emit_xfloating_cvt (FLOAT_EXTEND, operands); DONE;")
|
"alpha_emit_xfloating_cvt (FLOAT_EXTEND, operands); DONE;")
|
|
|
(define_insn "*truncdfsf2_ieee"
|
(define_insn "*truncdfsf2_ieee"
|
[(set (match_operand:SF 0 "register_operand" "=&f")
|
[(set (match_operand:SF 0 "register_operand" "=&f")
|
(float_truncate:SF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
|
(float_truncate:SF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"cvt%-%,%/ %R1,%0"
|
"cvt%-%,%/ %R1,%0"
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_insn "truncdfsf2"
|
(define_insn "truncdfsf2"
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(float_truncate:SF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
|
(float_truncate:SF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"cvt%-%,%/ %R1,%0"
|
"cvt%-%,%/ %R1,%0"
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_expand "trunctfdf2"
|
(define_expand "trunctfdf2"
|
[(use (match_operand:DF 0 "register_operand" ""))
|
[(use (match_operand:DF 0 "register_operand" ""))
|
(use (match_operand:TF 1 "general_operand" ""))]
|
(use (match_operand:TF 1 "general_operand" ""))]
|
"TARGET_HAS_XFLOATING_LIBS"
|
"TARGET_HAS_XFLOATING_LIBS"
|
"alpha_emit_xfloating_cvt (FLOAT_TRUNCATE, operands); DONE;")
|
"alpha_emit_xfloating_cvt (FLOAT_TRUNCATE, operands); DONE;")
|
|
|
(define_expand "trunctfsf2"
|
(define_expand "trunctfsf2"
|
[(use (match_operand:SF 0 "register_operand" ""))
|
[(use (match_operand:SF 0 "register_operand" ""))
|
(use (match_operand:TF 1 "general_operand" ""))]
|
(use (match_operand:TF 1 "general_operand" ""))]
|
"TARGET_FP && TARGET_HAS_XFLOATING_LIBS"
|
"TARGET_FP && TARGET_HAS_XFLOATING_LIBS"
|
{
|
{
|
rtx tmpf, sticky, arg, lo, hi;
|
rtx tmpf, sticky, arg, lo, hi;
|
|
|
tmpf = gen_reg_rtx (DFmode);
|
tmpf = gen_reg_rtx (DFmode);
|
sticky = gen_reg_rtx (DImode);
|
sticky = gen_reg_rtx (DImode);
|
arg = copy_to_mode_reg (TFmode, operands[1]);
|
arg = copy_to_mode_reg (TFmode, operands[1]);
|
lo = gen_lowpart (DImode, arg);
|
lo = gen_lowpart (DImode, arg);
|
hi = gen_highpart (DImode, arg);
|
hi = gen_highpart (DImode, arg);
|
|
|
/* Convert the low word of the TFmode value into a sticky rounding bit,
|
/* Convert the low word of the TFmode value into a sticky rounding bit,
|
then or it into the low bit of the high word. This leaves the sticky
|
then or it into the low bit of the high word. This leaves the sticky
|
bit at bit 48 of the fraction, which is representable in DFmode,
|
bit at bit 48 of the fraction, which is representable in DFmode,
|
which prevents rounding error in the final conversion to SFmode. */
|
which prevents rounding error in the final conversion to SFmode. */
|
|
|
emit_insn (gen_rtx_SET (VOIDmode, sticky,
|
emit_insn (gen_rtx_SET (VOIDmode, sticky,
|
gen_rtx_NE (DImode, lo, const0_rtx)));
|
gen_rtx_NE (DImode, lo, const0_rtx)));
|
emit_insn (gen_iordi3 (hi, hi, sticky));
|
emit_insn (gen_iordi3 (hi, hi, sticky));
|
emit_insn (gen_trunctfdf2 (tmpf, arg));
|
emit_insn (gen_trunctfdf2 (tmpf, arg));
|
emit_insn (gen_truncdfsf2 (operands[0], tmpf));
|
emit_insn (gen_truncdfsf2 (operands[0], tmpf));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_insn "*divsf3_ieee"
|
(define_insn "*divsf3_ieee"
|
[(set (match_operand:SF 0 "register_operand" "=&f")
|
[(set (match_operand:SF 0 "register_operand" "=&f")
|
(div:SF (match_operand:SF 1 "reg_or_0_operand" "fG")
|
(div:SF (match_operand:SF 1 "reg_or_0_operand" "fG")
|
(match_operand:SF 2 "reg_or_0_operand" "fG")))]
|
(match_operand:SF 2 "reg_or_0_operand" "fG")))]
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"div%,%/ %R1,%R2,%0"
|
"div%,%/ %R1,%R2,%0"
|
[(set_attr "type" "fdiv")
|
[(set_attr "type" "fdiv")
|
(set_attr "opsize" "si")
|
(set_attr "opsize" "si")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_insn "divsf3"
|
(define_insn "divsf3"
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(div:SF (match_operand:SF 1 "reg_or_0_operand" "fG")
|
(div:SF (match_operand:SF 1 "reg_or_0_operand" "fG")
|
(match_operand:SF 2 "reg_or_0_operand" "fG")))]
|
(match_operand:SF 2 "reg_or_0_operand" "fG")))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"div%,%/ %R1,%R2,%0"
|
"div%,%/ %R1,%R2,%0"
|
[(set_attr "type" "fdiv")
|
[(set_attr "type" "fdiv")
|
(set_attr "opsize" "si")
|
(set_attr "opsize" "si")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_insn "*divdf3_ieee"
|
(define_insn "*divdf3_ieee"
|
[(set (match_operand:DF 0 "register_operand" "=&f")
|
[(set (match_operand:DF 0 "register_operand" "=&f")
|
(div:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
|
(div:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
|
(match_operand:DF 2 "reg_or_0_operand" "fG")))]
|
(match_operand:DF 2 "reg_or_0_operand" "fG")))]
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"div%-%/ %R1,%R2,%0"
|
"div%-%/ %R1,%R2,%0"
|
[(set_attr "type" "fdiv")
|
[(set_attr "type" "fdiv")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_insn "divdf3"
|
(define_insn "divdf3"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(div:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
|
(div:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
|
(match_operand:DF 2 "reg_or_0_operand" "fG")))]
|
(match_operand:DF 2 "reg_or_0_operand" "fG")))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"div%-%/ %R1,%R2,%0"
|
"div%-%/ %R1,%R2,%0"
|
[(set_attr "type" "fdiv")
|
[(set_attr "type" "fdiv")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_insn "*divdf_ext1"
|
(define_insn "*divdf_ext1"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(div:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_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")))]
|
(match_operand:DF 2 "reg_or_0_operand" "fG")))]
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"div%-%/ %R1,%R2,%0"
|
"div%-%/ %R1,%R2,%0"
|
[(set_attr "type" "fdiv")
|
[(set_attr "type" "fdiv")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_insn "*divdf_ext2"
|
(define_insn "*divdf_ext2"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(div:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
|
(div:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
|
(float_extend:DF
|
(float_extend:DF
|
(match_operand:SF 2 "reg_or_0_operand" "fG"))))]
|
(match_operand:SF 2 "reg_or_0_operand" "fG"))))]
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"div%-%/ %R1,%R2,%0"
|
"div%-%/ %R1,%R2,%0"
|
[(set_attr "type" "fdiv")
|
[(set_attr "type" "fdiv")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_insn "*divdf_ext3"
|
(define_insn "*divdf_ext3"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(div:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_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"))))]
|
(float_extend:DF (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"div%-%/ %R1,%R2,%0"
|
"div%-%/ %R1,%R2,%0"
|
[(set_attr "type" "fdiv")
|
[(set_attr "type" "fdiv")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_expand "divtf3"
|
(define_expand "divtf3"
|
[(use (match_operand 0 "register_operand" ""))
|
[(use (match_operand 0 "register_operand" ""))
|
(use (match_operand 1 "general_operand" ""))
|
(use (match_operand 1 "general_operand" ""))
|
(use (match_operand 2 "general_operand" ""))]
|
(use (match_operand 2 "general_operand" ""))]
|
"TARGET_HAS_XFLOATING_LIBS"
|
"TARGET_HAS_XFLOATING_LIBS"
|
"alpha_emit_xfloating_arith (DIV, operands); DONE;")
|
"alpha_emit_xfloating_arith (DIV, operands); DONE;")
|
|
|
(define_insn "*mulsf3_ieee"
|
(define_insn "*mulsf3_ieee"
|
[(set (match_operand:SF 0 "register_operand" "=&f")
|
[(set (match_operand:SF 0 "register_operand" "=&f")
|
(mult:SF (match_operand:SF 1 "reg_or_0_operand" "%fG")
|
(mult:SF (match_operand:SF 1 "reg_or_0_operand" "%fG")
|
(match_operand:SF 2 "reg_or_0_operand" "fG")))]
|
(match_operand:SF 2 "reg_or_0_operand" "fG")))]
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"mul%,%/ %R1,%R2,%0"
|
"mul%,%/ %R1,%R2,%0"
|
[(set_attr "type" "fmul")
|
[(set_attr "type" "fmul")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_insn "mulsf3"
|
(define_insn "mulsf3"
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(mult:SF (match_operand:SF 1 "reg_or_0_operand" "%fG")
|
(mult:SF (match_operand:SF 1 "reg_or_0_operand" "%fG")
|
(match_operand:SF 2 "reg_or_0_operand" "fG")))]
|
(match_operand:SF 2 "reg_or_0_operand" "fG")))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"mul%,%/ %R1,%R2,%0"
|
"mul%,%/ %R1,%R2,%0"
|
[(set_attr "type" "fmul")
|
[(set_attr "type" "fmul")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_insn "*muldf3_ieee"
|
(define_insn "*muldf3_ieee"
|
[(set (match_operand:DF 0 "register_operand" "=&f")
|
[(set (match_operand:DF 0 "register_operand" "=&f")
|
(mult:DF (match_operand:DF 1 "reg_or_0_operand" "%fG")
|
(mult:DF (match_operand:DF 1 "reg_or_0_operand" "%fG")
|
(match_operand:DF 2 "reg_or_0_operand" "fG")))]
|
(match_operand:DF 2 "reg_or_0_operand" "fG")))]
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"mul%-%/ %R1,%R2,%0"
|
"mul%-%/ %R1,%R2,%0"
|
[(set_attr "type" "fmul")
|
[(set_attr "type" "fmul")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_insn "muldf3"
|
(define_insn "muldf3"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(mult:DF (match_operand:DF 1 "reg_or_0_operand" "%fG")
|
(mult:DF (match_operand:DF 1 "reg_or_0_operand" "%fG")
|
(match_operand:DF 2 "reg_or_0_operand" "fG")))]
|
(match_operand:DF 2 "reg_or_0_operand" "fG")))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"mul%-%/ %R1,%R2,%0"
|
"mul%-%/ %R1,%R2,%0"
|
[(set_attr "type" "fmul")
|
[(set_attr "type" "fmul")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_insn "*muldf_ext1"
|
(define_insn "*muldf_ext1"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(mult:DF (float_extend:DF
|
(mult:DF (float_extend:DF
|
(match_operand:SF 1 "reg_or_0_operand" "fG"))
|
(match_operand:SF 1 "reg_or_0_operand" "fG"))
|
(match_operand:DF 2 "reg_or_0_operand" "fG")))]
|
(match_operand:DF 2 "reg_or_0_operand" "fG")))]
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"mul%-%/ %R1,%R2,%0"
|
"mul%-%/ %R1,%R2,%0"
|
[(set_attr "type" "fmul")
|
[(set_attr "type" "fmul")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_insn "*muldf_ext2"
|
(define_insn "*muldf_ext2"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(mult:DF (float_extend:DF
|
(mult:DF (float_extend:DF
|
(match_operand:SF 1 "reg_or_0_operand" "%fG"))
|
(match_operand:SF 1 "reg_or_0_operand" "%fG"))
|
(float_extend:DF
|
(float_extend:DF
|
(match_operand:SF 2 "reg_or_0_operand" "fG"))))]
|
(match_operand:SF 2 "reg_or_0_operand" "fG"))))]
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"mul%-%/ %R1,%R2,%0"
|
"mul%-%/ %R1,%R2,%0"
|
[(set_attr "type" "fmul")
|
[(set_attr "type" "fmul")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_expand "multf3"
|
(define_expand "multf3"
|
[(use (match_operand 0 "register_operand" ""))
|
[(use (match_operand 0 "register_operand" ""))
|
(use (match_operand 1 "general_operand" ""))
|
(use (match_operand 1 "general_operand" ""))
|
(use (match_operand 2 "general_operand" ""))]
|
(use (match_operand 2 "general_operand" ""))]
|
"TARGET_HAS_XFLOATING_LIBS"
|
"TARGET_HAS_XFLOATING_LIBS"
|
"alpha_emit_xfloating_arith (MULT, operands); DONE;")
|
"alpha_emit_xfloating_arith (MULT, operands); DONE;")
|
|
|
(define_insn "*subsf3_ieee"
|
(define_insn "*subsf3_ieee"
|
[(set (match_operand:SF 0 "register_operand" "=&f")
|
[(set (match_operand:SF 0 "register_operand" "=&f")
|
(minus:SF (match_operand:SF 1 "reg_or_0_operand" "fG")
|
(minus:SF (match_operand:SF 1 "reg_or_0_operand" "fG")
|
(match_operand:SF 2 "reg_or_0_operand" "fG")))]
|
(match_operand:SF 2 "reg_or_0_operand" "fG")))]
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"sub%,%/ %R1,%R2,%0"
|
"sub%,%/ %R1,%R2,%0"
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_insn "subsf3"
|
(define_insn "subsf3"
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(minus:SF (match_operand:SF 1 "reg_or_0_operand" "fG")
|
(minus:SF (match_operand:SF 1 "reg_or_0_operand" "fG")
|
(match_operand:SF 2 "reg_or_0_operand" "fG")))]
|
(match_operand:SF 2 "reg_or_0_operand" "fG")))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"sub%,%/ %R1,%R2,%0"
|
"sub%,%/ %R1,%R2,%0"
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_insn "*subdf3_ieee"
|
(define_insn "*subdf3_ieee"
|
[(set (match_operand:DF 0 "register_operand" "=&f")
|
[(set (match_operand:DF 0 "register_operand" "=&f")
|
(minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
|
(minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
|
(match_operand:DF 2 "reg_or_0_operand" "fG")))]
|
(match_operand:DF 2 "reg_or_0_operand" "fG")))]
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"sub%-%/ %R1,%R2,%0"
|
"sub%-%/ %R1,%R2,%0"
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_insn "subdf3"
|
(define_insn "subdf3"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
|
(minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
|
(match_operand:DF 2 "reg_or_0_operand" "fG")))]
|
(match_operand:DF 2 "reg_or_0_operand" "fG")))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"sub%-%/ %R1,%R2,%0"
|
"sub%-%/ %R1,%R2,%0"
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_insn "*subdf_ext1"
|
(define_insn "*subdf_ext1"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(minus:DF (float_extend:DF
|
(minus:DF (float_extend:DF
|
(match_operand:SF 1 "reg_or_0_operand" "fG"))
|
(match_operand:SF 1 "reg_or_0_operand" "fG"))
|
(match_operand:DF 2 "reg_or_0_operand" "fG")))]
|
(match_operand:DF 2 "reg_or_0_operand" "fG")))]
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"sub%-%/ %R1,%R2,%0"
|
"sub%-%/ %R1,%R2,%0"
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_insn "*subdf_ext2"
|
(define_insn "*subdf_ext2"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
|
(minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
|
(float_extend:DF
|
(float_extend:DF
|
(match_operand:SF 2 "reg_or_0_operand" "fG"))))]
|
(match_operand:SF 2 "reg_or_0_operand" "fG"))))]
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"sub%-%/ %R1,%R2,%0"
|
"sub%-%/ %R1,%R2,%0"
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_insn "*subdf_ext3"
|
(define_insn "*subdf_ext3"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(minus:DF (float_extend:DF
|
(minus:DF (float_extend:DF
|
(match_operand:SF 1 "reg_or_0_operand" "fG"))
|
(match_operand:SF 1 "reg_or_0_operand" "fG"))
|
(float_extend:DF
|
(float_extend:DF
|
(match_operand:SF 2 "reg_or_0_operand" "fG"))))]
|
(match_operand:SF 2 "reg_or_0_operand" "fG"))))]
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"sub%-%/ %R1,%R2,%0"
|
"sub%-%/ %R1,%R2,%0"
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_expand "subtf3"
|
(define_expand "subtf3"
|
[(use (match_operand 0 "register_operand" ""))
|
[(use (match_operand 0 "register_operand" ""))
|
(use (match_operand 1 "general_operand" ""))
|
(use (match_operand 1 "general_operand" ""))
|
(use (match_operand 2 "general_operand" ""))]
|
(use (match_operand 2 "general_operand" ""))]
|
"TARGET_HAS_XFLOATING_LIBS"
|
"TARGET_HAS_XFLOATING_LIBS"
|
"alpha_emit_xfloating_arith (MINUS, operands); DONE;")
|
"alpha_emit_xfloating_arith (MINUS, operands); DONE;")
|
|
|
(define_insn "*sqrtsf2_ieee"
|
(define_insn "*sqrtsf2_ieee"
|
[(set (match_operand:SF 0 "register_operand" "=&f")
|
[(set (match_operand:SF 0 "register_operand" "=&f")
|
(sqrt:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))]
|
(sqrt:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))]
|
"TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU"
|
"TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU"
|
"sqrt%,%/ %R1,%0"
|
"sqrt%,%/ %R1,%0"
|
[(set_attr "type" "fsqrt")
|
[(set_attr "type" "fsqrt")
|
(set_attr "opsize" "si")
|
(set_attr "opsize" "si")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_insn "sqrtsf2"
|
(define_insn "sqrtsf2"
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
[(set (match_operand:SF 0 "register_operand" "=f")
|
(sqrt:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))]
|
(sqrt:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))]
|
"TARGET_FP && TARGET_FIX"
|
"TARGET_FP && TARGET_FIX"
|
"sqrt%,%/ %R1,%0"
|
"sqrt%,%/ %R1,%0"
|
[(set_attr "type" "fsqrt")
|
[(set_attr "type" "fsqrt")
|
(set_attr "opsize" "si")
|
(set_attr "opsize" "si")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_insn "*sqrtdf2_ieee"
|
(define_insn "*sqrtdf2_ieee"
|
[(set (match_operand:DF 0 "register_operand" "=&f")
|
[(set (match_operand:DF 0 "register_operand" "=&f")
|
(sqrt:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
|
(sqrt:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
|
"TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU"
|
"TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU"
|
"sqrt%-%/ %R1,%0"
|
"sqrt%-%/ %R1,%0"
|
[(set_attr "type" "fsqrt")
|
[(set_attr "type" "fsqrt")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
(define_insn "sqrtdf2"
|
(define_insn "sqrtdf2"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(sqrt:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
|
(sqrt:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
|
"TARGET_FP && TARGET_FIX"
|
"TARGET_FP && TARGET_FIX"
|
"sqrt%-%/ %R1,%0"
|
"sqrt%-%/ %R1,%0"
|
[(set_attr "type" "fsqrt")
|
[(set_attr "type" "fsqrt")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "round_suffix" "normal")
|
(set_attr "round_suffix" "normal")
|
(set_attr "trap_suffix" "u_su_sui")])
|
(set_attr "trap_suffix" "u_su_sui")])
|
|
|
;; Next are all the integer comparisons, and conditional moves and branches
|
;; Next are all the integer comparisons, and conditional moves and branches
|
;; and some of the related define_expand's and define_split's.
|
;; and some of the related define_expand's and define_split's.
|
|
|
(define_insn "*setcc_internal"
|
(define_insn "*setcc_internal"
|
[(set (match_operand 0 "register_operand" "=r")
|
[(set (match_operand 0 "register_operand" "=r")
|
(match_operator 1 "alpha_comparison_operator"
|
(match_operator 1 "alpha_comparison_operator"
|
[(match_operand:DI 2 "register_operand" "r")
|
[(match_operand:DI 2 "register_operand" "r")
|
(match_operand:DI 3 "reg_or_8bit_operand" "rI")]))]
|
(match_operand:DI 3 "reg_or_8bit_operand" "rI")]))]
|
"GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT
|
"GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT
|
&& GET_MODE_SIZE (GET_MODE (operands[0])) <= 8
|
&& GET_MODE_SIZE (GET_MODE (operands[0])) <= 8
|
&& GET_MODE (operands[0]) == GET_MODE (operands[1])"
|
&& GET_MODE (operands[0]) == GET_MODE (operands[1])"
|
"cmp%C1 %2,%3,%0"
|
"cmp%C1 %2,%3,%0"
|
[(set_attr "type" "icmp")])
|
[(set_attr "type" "icmp")])
|
|
|
;; Yes, we can technically support reg_or_8bit_operand in operand 2,
|
;; Yes, we can technically support reg_or_8bit_operand in operand 2,
|
;; but that's non-canonical rtl and allowing that causes inefficiencies
|
;; but that's non-canonical rtl and allowing that causes inefficiencies
|
;; from cse on.
|
;; from cse on.
|
(define_insn "*setcc_swapped_internal"
|
(define_insn "*setcc_swapped_internal"
|
[(set (match_operand 0 "register_operand" "=r")
|
[(set (match_operand 0 "register_operand" "=r")
|
(match_operator 1 "alpha_swapped_comparison_operator"
|
(match_operator 1 "alpha_swapped_comparison_operator"
|
[(match_operand:DI 2 "register_operand" "r")
|
[(match_operand:DI 2 "register_operand" "r")
|
(match_operand:DI 3 "reg_or_0_operand" "rJ")]))]
|
(match_operand:DI 3 "reg_or_0_operand" "rJ")]))]
|
"GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT
|
"GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT
|
&& GET_MODE_SIZE (GET_MODE (operands[0])) <= 8
|
&& GET_MODE_SIZE (GET_MODE (operands[0])) <= 8
|
&& GET_MODE (operands[0]) == GET_MODE (operands[1])"
|
&& GET_MODE (operands[0]) == GET_MODE (operands[1])"
|
"cmp%c1 %r3,%2,%0"
|
"cmp%c1 %r3,%2,%0"
|
[(set_attr "type" "icmp")])
|
[(set_attr "type" "icmp")])
|
|
|
;; Use match_operator rather than ne directly so that we can match
|
;; Use match_operator rather than ne directly so that we can match
|
;; multiple integer modes.
|
;; multiple integer modes.
|
(define_insn "*setne_internal"
|
(define_insn "*setne_internal"
|
[(set (match_operand 0 "register_operand" "=r")
|
[(set (match_operand 0 "register_operand" "=r")
|
(match_operator 1 "signed_comparison_operator"
|
(match_operator 1 "signed_comparison_operator"
|
[(match_operand:DI 2 "register_operand" "r")
|
[(match_operand:DI 2 "register_operand" "r")
|
(const_int 0)]))]
|
(const_int 0)]))]
|
"GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT
|
"GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT
|
&& GET_MODE_SIZE (GET_MODE (operands[0])) <= 8
|
&& GET_MODE_SIZE (GET_MODE (operands[0])) <= 8
|
&& GET_CODE (operands[1]) == NE
|
&& GET_CODE (operands[1]) == NE
|
&& GET_MODE (operands[0]) == GET_MODE (operands[1])"
|
&& GET_MODE (operands[0]) == GET_MODE (operands[1])"
|
"cmpult $31,%2,%0"
|
"cmpult $31,%2,%0"
|
[(set_attr "type" "icmp")])
|
[(set_attr "type" "icmp")])
|
|
|
;; The mode folding trick can't be used with const_int operands, since
|
;; The mode folding trick can't be used with const_int operands, since
|
;; reload needs to know the proper mode.
|
;; reload needs to know the proper mode.
|
;;
|
;;
|
;; Use add_operand instead of the more seemingly natural reg_or_8bit_operand
|
;; Use add_operand instead of the more seemingly natural reg_or_8bit_operand
|
;; in order to create more pairs of constants. As long as we're allowing
|
;; in order to create more pairs of constants. As long as we're allowing
|
;; two constants at the same time, and will have to reload one of them...
|
;; two constants at the same time, and will have to reload one of them...
|
|
|
(define_insn "*movqicc_internal"
|
(define_insn "*movqicc_internal"
|
[(set (match_operand:QI 0 "register_operand" "=r,r,r,r")
|
[(set (match_operand:QI 0 "register_operand" "=r,r,r,r")
|
(if_then_else:QI
|
(if_then_else:QI
|
(match_operator 2 "signed_comparison_operator"
|
(match_operator 2 "signed_comparison_operator"
|
[(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
|
[(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
|
(match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
|
(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 1 "add_operand" "rI,0,rI,0")
|
(match_operand:QI 5 "add_operand" "0,rI,0,rI")))]
|
(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%C2 %r3,%1,%0
|
cmov%D2 %r3,%5,%0
|
cmov%D2 %r3,%5,%0
|
cmov%c2 %r4,%1,%0
|
cmov%c2 %r4,%1,%0
|
cmov%d2 %r4,%5,%0"
|
cmov%d2 %r4,%5,%0"
|
[(set_attr "type" "icmov")])
|
[(set_attr "type" "icmov")])
|
|
|
(define_insn "*movhicc_internal"
|
(define_insn "*movhicc_internal"
|
[(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
|
[(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
|
(if_then_else:HI
|
(if_then_else:HI
|
(match_operator 2 "signed_comparison_operator"
|
(match_operator 2 "signed_comparison_operator"
|
[(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
|
[(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
|
(match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
|
(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 1 "add_operand" "rI,0,rI,0")
|
(match_operand:HI 5 "add_operand" "0,rI,0,rI")))]
|
(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%C2 %r3,%1,%0
|
cmov%D2 %r3,%5,%0
|
cmov%D2 %r3,%5,%0
|
cmov%c2 %r4,%1,%0
|
cmov%c2 %r4,%1,%0
|
cmov%d2 %r4,%5,%0"
|
cmov%d2 %r4,%5,%0"
|
[(set_attr "type" "icmov")])
|
[(set_attr "type" "icmov")])
|
|
|
(define_insn "*movsicc_internal"
|
(define_insn "*movsicc_internal"
|
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
|
(if_then_else:SI
|
(if_then_else:SI
|
(match_operator 2 "signed_comparison_operator"
|
(match_operator 2 "signed_comparison_operator"
|
[(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
|
[(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
|
(match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
|
(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 1 "add_operand" "rI,0,rI,0")
|
(match_operand:SI 5 "add_operand" "0,rI,0,rI")))]
|
(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%C2 %r3,%1,%0
|
cmov%D2 %r3,%5,%0
|
cmov%D2 %r3,%5,%0
|
cmov%c2 %r4,%1,%0
|
cmov%c2 %r4,%1,%0
|
cmov%d2 %r4,%5,%0"
|
cmov%d2 %r4,%5,%0"
|
[(set_attr "type" "icmov")])
|
[(set_attr "type" "icmov")])
|
|
|
(define_insn "*movdicc_internal"
|
(define_insn "*movdicc_internal"
|
[(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
|
(if_then_else:DI
|
(if_then_else:DI
|
(match_operator 2 "signed_comparison_operator"
|
(match_operator 2 "signed_comparison_operator"
|
[(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
|
[(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
|
(match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
|
(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 1 "add_operand" "rI,0,rI,0")
|
(match_operand:DI 5 "add_operand" "0,rI,0,rI")))]
|
(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%C2 %r3,%1,%0
|
cmov%D2 %r3,%5,%0
|
cmov%D2 %r3,%5,%0
|
cmov%c2 %r4,%1,%0
|
cmov%c2 %r4,%1,%0
|
cmov%d2 %r4,%5,%0"
|
cmov%d2 %r4,%5,%0"
|
[(set_attr "type" "icmov")])
|
[(set_attr "type" "icmov")])
|
|
|
(define_insn "*movqicc_lbc"
|
(define_insn "*movqicc_lbc"
|
[(set (match_operand:QI 0 "register_operand" "=r,r")
|
[(set (match_operand:QI 0 "register_operand" "=r,r")
|
(if_then_else:QI
|
(if_then_else:QI
|
(eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
|
(eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
|
(const_int 1)
|
(const_int 1)
|
(const_int 0))
|
(const_int 0))
|
(const_int 0))
|
(const_int 0))
|
(match_operand:QI 1 "reg_or_8bit_operand" "rI,0")
|
(match_operand:QI 1 "reg_or_8bit_operand" "rI,0")
|
(match_operand:QI 3 "reg_or_8bit_operand" "0,rI")))]
|
(match_operand:QI 3 "reg_or_8bit_operand" "0,rI")))]
|
""
|
""
|
"@
|
"@
|
cmovlbc %r2,%1,%0
|
cmovlbc %r2,%1,%0
|
cmovlbs %r2,%3,%0"
|
cmovlbs %r2,%3,%0"
|
[(set_attr "type" "icmov")])
|
[(set_attr "type" "icmov")])
|
|
|
(define_insn "*movhicc_lbc"
|
(define_insn "*movhicc_lbc"
|
[(set (match_operand:HI 0 "register_operand" "=r,r")
|
[(set (match_operand:HI 0 "register_operand" "=r,r")
|
(if_then_else:HI
|
(if_then_else:HI
|
(eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
|
(eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
|
(const_int 1)
|
(const_int 1)
|
(const_int 0))
|
(const_int 0))
|
(const_int 0))
|
(const_int 0))
|
(match_operand:HI 1 "reg_or_8bit_operand" "rI,0")
|
(match_operand:HI 1 "reg_or_8bit_operand" "rI,0")
|
(match_operand:HI 3 "reg_or_8bit_operand" "0,rI")))]
|
(match_operand:HI 3 "reg_or_8bit_operand" "0,rI")))]
|
""
|
""
|
"@
|
"@
|
cmovlbc %r2,%1,%0
|
cmovlbc %r2,%1,%0
|
cmovlbs %r2,%3,%0"
|
cmovlbs %r2,%3,%0"
|
[(set_attr "type" "icmov")])
|
[(set_attr "type" "icmov")])
|
|
|
(define_insn "*movsicc_lbc"
|
(define_insn "*movsicc_lbc"
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
(if_then_else:SI
|
(if_then_else:SI
|
(eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
|
(eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
|
(const_int 1)
|
(const_int 1)
|
(const_int 0))
|
(const_int 0))
|
(const_int 0))
|
(const_int 0))
|
(match_operand:SI 1 "reg_or_8bit_operand" "rI,0")
|
(match_operand:SI 1 "reg_or_8bit_operand" "rI,0")
|
(match_operand:SI 3 "reg_or_8bit_operand" "0,rI")))]
|
(match_operand:SI 3 "reg_or_8bit_operand" "0,rI")))]
|
""
|
""
|
"@
|
"@
|
cmovlbc %r2,%1,%0
|
cmovlbc %r2,%1,%0
|
cmovlbs %r2,%3,%0"
|
cmovlbs %r2,%3,%0"
|
[(set_attr "type" "icmov")])
|
[(set_attr "type" "icmov")])
|
|
|
(define_insn "*movdicc_lbc"
|
(define_insn "*movdicc_lbc"
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
(if_then_else:DI
|
(if_then_else:DI
|
(eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
|
(eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
|
(const_int 1)
|
(const_int 1)
|
(const_int 0))
|
(const_int 0))
|
(const_int 0))
|
(const_int 0))
|
(match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
|
(match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
|
(match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
|
(match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
|
""
|
""
|
"@
|
"@
|
cmovlbc %r2,%1,%0
|
cmovlbc %r2,%1,%0
|
cmovlbs %r2,%3,%0"
|
cmovlbs %r2,%3,%0"
|
[(set_attr "type" "icmov")])
|
[(set_attr "type" "icmov")])
|
|
|
(define_insn "*movqicc_lbs"
|
(define_insn "*movqicc_lbs"
|
[(set (match_operand:QI 0 "register_operand" "=r,r")
|
[(set (match_operand:QI 0 "register_operand" "=r,r")
|
(if_then_else:QI
|
(if_then_else:QI
|
(ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
|
(ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
|
(const_int 1)
|
(const_int 1)
|
(const_int 0))
|
(const_int 0))
|
(const_int 0))
|
(const_int 0))
|
(match_operand:QI 1 "reg_or_8bit_operand" "rI,0")
|
(match_operand:QI 1 "reg_or_8bit_operand" "rI,0")
|
(match_operand:QI 3 "reg_or_8bit_operand" "0,rI")))]
|
(match_operand:QI 3 "reg_or_8bit_operand" "0,rI")))]
|
""
|
""
|
"@
|
"@
|
cmovlbs %r2,%1,%0
|
cmovlbs %r2,%1,%0
|
cmovlbc %r2,%3,%0"
|
cmovlbc %r2,%3,%0"
|
[(set_attr "type" "icmov")])
|
[(set_attr "type" "icmov")])
|
|
|
(define_insn "*movhicc_lbs"
|
(define_insn "*movhicc_lbs"
|
[(set (match_operand:HI 0 "register_operand" "=r,r")
|
[(set (match_operand:HI 0 "register_operand" "=r,r")
|
(if_then_else:HI
|
(if_then_else:HI
|
(ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
|
(ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
|
(const_int 1)
|
(const_int 1)
|
(const_int 0))
|
(const_int 0))
|
(const_int 0))
|
(const_int 0))
|
(match_operand:HI 1 "reg_or_8bit_operand" "rI,0")
|
(match_operand:HI 1 "reg_or_8bit_operand" "rI,0")
|
(match_operand:HI 3 "reg_or_8bit_operand" "0,rI")))]
|
(match_operand:HI 3 "reg_or_8bit_operand" "0,rI")))]
|
""
|
""
|
"@
|
"@
|
cmovlbs %r2,%1,%0
|
cmovlbs %r2,%1,%0
|
cmovlbc %r2,%3,%0"
|
cmovlbc %r2,%3,%0"
|
[(set_attr "type" "icmov")])
|
[(set_attr "type" "icmov")])
|
|
|
(define_insn "*movsicc_lbs"
|
(define_insn "*movsicc_lbs"
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
(if_then_else:SI
|
(if_then_else:SI
|
(ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
|
(ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
|
(const_int 1)
|
(const_int 1)
|
(const_int 0))
|
(const_int 0))
|
(const_int 0))
|
(const_int 0))
|
(match_operand:SI 1 "reg_or_8bit_operand" "rI,0")
|
(match_operand:SI 1 "reg_or_8bit_operand" "rI,0")
|
(match_operand:SI 3 "reg_or_8bit_operand" "0,rI")))]
|
(match_operand:SI 3 "reg_or_8bit_operand" "0,rI")))]
|
""
|
""
|
"@
|
"@
|
cmovlbs %r2,%1,%0
|
cmovlbs %r2,%1,%0
|
cmovlbc %r2,%3,%0"
|
cmovlbc %r2,%3,%0"
|
[(set_attr "type" "icmov")])
|
[(set_attr "type" "icmov")])
|
|
|
(define_insn "*movdicc_lbs"
|
(define_insn "*movdicc_lbs"
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r")
|
(if_then_else:DI
|
(if_then_else:DI
|
(ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
|
(ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
|
(const_int 1)
|
(const_int 1)
|
(const_int 0))
|
(const_int 0))
|
(const_int 0))
|
(const_int 0))
|
(match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
|
(match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
|
(match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
|
(match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
|
""
|
""
|
"@
|
"@
|
cmovlbs %r2,%1,%0
|
cmovlbs %r2,%1,%0
|
cmovlbc %r2,%3,%0"
|
cmovlbc %r2,%3,%0"
|
[(set_attr "type" "icmov")])
|
[(set_attr "type" "icmov")])
|
|
|
;; For ABS, we have two choices, depending on whether the input and output
|
;; For ABS, we have two choices, depending on whether the input and output
|
;; registers are the same or not.
|
;; registers are the same or not.
|
(define_expand "absdi2"
|
(define_expand "absdi2"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(abs:DI (match_operand:DI 1 "register_operand" "")))]
|
(abs:DI (match_operand:DI 1 "register_operand" "")))]
|
""
|
""
|
{
|
{
|
if (rtx_equal_p (operands[0], operands[1]))
|
if (rtx_equal_p (operands[0], operands[1]))
|
emit_insn (gen_absdi2_same (operands[0], gen_reg_rtx (DImode)));
|
emit_insn (gen_absdi2_same (operands[0], gen_reg_rtx (DImode)));
|
else
|
else
|
emit_insn (gen_absdi2_diff (operands[0], operands[1]));
|
emit_insn (gen_absdi2_diff (operands[0], operands[1]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "absdi2_same"
|
(define_expand "absdi2_same"
|
[(set (match_operand:DI 1 "register_operand" "")
|
[(set (match_operand:DI 1 "register_operand" "")
|
(neg:DI (match_operand:DI 0 "register_operand" "")))
|
(neg:DI (match_operand:DI 0 "register_operand" "")))
|
(set (match_dup 0)
|
(set (match_dup 0)
|
(if_then_else:DI (ge (match_dup 0) (const_int 0))
|
(if_then_else:DI (ge (match_dup 0) (const_int 0))
|
(match_dup 0)
|
(match_dup 0)
|
(match_dup 1)))]
|
(match_dup 1)))]
|
""
|
""
|
"")
|
"")
|
|
|
(define_expand "absdi2_diff"
|
(define_expand "absdi2_diff"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(neg:DI (match_operand:DI 1 "register_operand" "")))
|
(neg:DI (match_operand:DI 1 "register_operand" "")))
|
(set (match_dup 0)
|
(set (match_dup 0)
|
(if_then_else:DI (lt (match_dup 1) (const_int 0))
|
(if_then_else:DI (lt (match_dup 1) (const_int 0))
|
(match_dup 0)
|
(match_dup 0)
|
(match_dup 1)))]
|
(match_dup 1)))]
|
""
|
""
|
"")
|
"")
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(abs:DI (match_dup 0)))
|
(abs:DI (match_dup 0)))
|
(clobber (match_operand:DI 1 "register_operand" ""))]
|
(clobber (match_operand:DI 1 "register_operand" ""))]
|
""
|
""
|
[(set (match_dup 1) (neg:DI (match_dup 0)))
|
[(set (match_dup 1) (neg:DI (match_dup 0)))
|
(set (match_dup 0) (if_then_else:DI (ge (match_dup 0) (const_int 0))
|
(set (match_dup 0) (if_then_else:DI (ge (match_dup 0) (const_int 0))
|
(match_dup 0) (match_dup 1)))]
|
(match_dup 0) (match_dup 1)))]
|
"")
|
"")
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(abs:DI (match_operand:DI 1 "register_operand" "")))]
|
(abs:DI (match_operand:DI 1 "register_operand" "")))]
|
"! rtx_equal_p (operands[0], operands[1])"
|
"! rtx_equal_p (operands[0], operands[1])"
|
[(set (match_dup 0) (neg:DI (match_dup 1)))
|
[(set (match_dup 0) (neg:DI (match_dup 1)))
|
(set (match_dup 0) (if_then_else:DI (lt (match_dup 1) (const_int 0))
|
(set (match_dup 0) (if_then_else:DI (lt (match_dup 1) (const_int 0))
|
(match_dup 0) (match_dup 1)))]
|
(match_dup 0) (match_dup 1)))]
|
"")
|
"")
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(neg:DI (abs:DI (match_dup 0))))
|
(neg:DI (abs:DI (match_dup 0))))
|
(clobber (match_operand:DI 1 "register_operand" ""))]
|
(clobber (match_operand:DI 1 "register_operand" ""))]
|
""
|
""
|
[(set (match_dup 1) (neg:DI (match_dup 0)))
|
[(set (match_dup 1) (neg:DI (match_dup 0)))
|
(set (match_dup 0) (if_then_else:DI (le (match_dup 0) (const_int 0))
|
(set (match_dup 0) (if_then_else:DI (le (match_dup 0) (const_int 0))
|
(match_dup 0) (match_dup 1)))]
|
(match_dup 0) (match_dup 1)))]
|
"")
|
"")
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(neg:DI (abs:DI (match_operand:DI 1 "register_operand" ""))))]
|
(neg:DI (abs:DI (match_operand:DI 1 "register_operand" ""))))]
|
"! rtx_equal_p (operands[0], operands[1])"
|
"! rtx_equal_p (operands[0], operands[1])"
|
[(set (match_dup 0) (neg:DI (match_dup 1)))
|
[(set (match_dup 0) (neg:DI (match_dup 1)))
|
(set (match_dup 0) (if_then_else:DI (gt (match_dup 1) (const_int 0))
|
(set (match_dup 0) (if_then_else:DI (gt (match_dup 1) (const_int 0))
|
(match_dup 0) (match_dup 1)))]
|
(match_dup 0) (match_dup 1)))]
|
"")
|
"")
|
|
|
(define_insn "sminqi3"
|
(define_insn "sminqi3"
|
[(set (match_operand:QI 0 "register_operand" "=r")
|
[(set (match_operand:QI 0 "register_operand" "=r")
|
(smin:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
|
(smin:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
|
(match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
|
(match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
"minsb8 %r1,%2,%0"
|
"minsb8 %r1,%2,%0"
|
[(set_attr "type" "mvi")])
|
[(set_attr "type" "mvi")])
|
|
|
(define_insn "uminqi3"
|
(define_insn "uminqi3"
|
[(set (match_operand:QI 0 "register_operand" "=r")
|
[(set (match_operand:QI 0 "register_operand" "=r")
|
(umin:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
|
(umin:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
|
(match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
|
(match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
"minub8 %r1,%2,%0"
|
"minub8 %r1,%2,%0"
|
[(set_attr "type" "mvi")])
|
[(set_attr "type" "mvi")])
|
|
|
(define_insn "smaxqi3"
|
(define_insn "smaxqi3"
|
[(set (match_operand:QI 0 "register_operand" "=r")
|
[(set (match_operand:QI 0 "register_operand" "=r")
|
(smax:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
|
(smax:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
|
(match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
|
(match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
"maxsb8 %r1,%2,%0"
|
"maxsb8 %r1,%2,%0"
|
[(set_attr "type" "mvi")])
|
[(set_attr "type" "mvi")])
|
|
|
(define_insn "umaxqi3"
|
(define_insn "umaxqi3"
|
[(set (match_operand:QI 0 "register_operand" "=r")
|
[(set (match_operand:QI 0 "register_operand" "=r")
|
(umax:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
|
(umax:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
|
(match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
|
(match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
"maxub8 %r1,%2,%0"
|
"maxub8 %r1,%2,%0"
|
[(set_attr "type" "mvi")])
|
[(set_attr "type" "mvi")])
|
|
|
(define_insn "sminhi3"
|
(define_insn "sminhi3"
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
(smin:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
|
(smin:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
|
(match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
|
(match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
"minsw4 %r1,%2,%0"
|
"minsw4 %r1,%2,%0"
|
[(set_attr "type" "mvi")])
|
[(set_attr "type" "mvi")])
|
|
|
(define_insn "uminhi3"
|
(define_insn "uminhi3"
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
(umin:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
|
(umin:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
|
(match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
|
(match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
"minuw4 %r1,%2,%0"
|
"minuw4 %r1,%2,%0"
|
[(set_attr "type" "mvi")])
|
[(set_attr "type" "mvi")])
|
|
|
(define_insn "smaxhi3"
|
(define_insn "smaxhi3"
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
(smax:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
|
(smax:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
|
(match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
|
(match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
"maxsw4 %r1,%2,%0"
|
"maxsw4 %r1,%2,%0"
|
[(set_attr "type" "mvi")])
|
[(set_attr "type" "mvi")])
|
|
|
(define_insn "umaxhi3"
|
(define_insn "umaxhi3"
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
(umax:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
|
(umax:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
|
(match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
|
(match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
"maxuw4 %r1,%2,%0"
|
"maxuw4 %r1,%2,%0"
|
[(set_attr "type" "mvi")])
|
[(set_attr "type" "mvi")])
|
|
|
(define_expand "smaxdi3"
|
(define_expand "smaxdi3"
|
[(set (match_dup 3)
|
[(set (match_dup 3)
|
(le:DI (match_operand:DI 1 "reg_or_0_operand" "")
|
(le:DI (match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")))
|
(match_operand:DI 2 "reg_or_8bit_operand" "")))
|
(set (match_operand:DI 0 "register_operand" "")
|
(set (match_operand:DI 0 "register_operand" "")
|
(if_then_else:DI (eq (match_dup 3) (const_int 0))
|
(if_then_else:DI (eq (match_dup 3) (const_int 0))
|
(match_dup 1) (match_dup 2)))]
|
(match_dup 1) (match_dup 2)))]
|
""
|
""
|
{ operands[3] = gen_reg_rtx (DImode); })
|
{ operands[3] = gen_reg_rtx (DImode); })
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(smax:DI (match_operand:DI 1 "reg_or_0_operand" "")
|
(smax:DI (match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")))
|
(match_operand:DI 2 "reg_or_8bit_operand" "")))
|
(clobber (match_operand:DI 3 "register_operand" ""))]
|
(clobber (match_operand:DI 3 "register_operand" ""))]
|
"operands[2] != const0_rtx"
|
"operands[2] != const0_rtx"
|
[(set (match_dup 3) (le:DI (match_dup 1) (match_dup 2)))
|
[(set (match_dup 3) (le:DI (match_dup 1) (match_dup 2)))
|
(set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
|
(set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
|
(match_dup 1) (match_dup 2)))]
|
(match_dup 1) (match_dup 2)))]
|
"")
|
"")
|
|
|
(define_insn "*smax_const0"
|
(define_insn "*smax_const0"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(smax:DI (match_operand:DI 1 "register_operand" "0")
|
(smax:DI (match_operand:DI 1 "register_operand" "0")
|
(const_int 0)))]
|
(const_int 0)))]
|
""
|
""
|
"cmovlt %0,0,%0"
|
"cmovlt %0,0,%0"
|
[(set_attr "type" "icmov")])
|
[(set_attr "type" "icmov")])
|
|
|
(define_expand "smindi3"
|
(define_expand "smindi3"
|
[(set (match_dup 3)
|
[(set (match_dup 3)
|
(lt:DI (match_operand:DI 1 "reg_or_0_operand" "")
|
(lt:DI (match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")))
|
(match_operand:DI 2 "reg_or_8bit_operand" "")))
|
(set (match_operand:DI 0 "register_operand" "")
|
(set (match_operand:DI 0 "register_operand" "")
|
(if_then_else:DI (ne (match_dup 3) (const_int 0))
|
(if_then_else:DI (ne (match_dup 3) (const_int 0))
|
(match_dup 1) (match_dup 2)))]
|
(match_dup 1) (match_dup 2)))]
|
""
|
""
|
{ operands[3] = gen_reg_rtx (DImode); })
|
{ operands[3] = gen_reg_rtx (DImode); })
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(smin:DI (match_operand:DI 1 "reg_or_0_operand" "")
|
(smin:DI (match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")))
|
(match_operand:DI 2 "reg_or_8bit_operand" "")))
|
(clobber (match_operand:DI 3 "register_operand" ""))]
|
(clobber (match_operand:DI 3 "register_operand" ""))]
|
"operands[2] != const0_rtx"
|
"operands[2] != const0_rtx"
|
[(set (match_dup 3) (lt:DI (match_dup 1) (match_dup 2)))
|
[(set (match_dup 3) (lt:DI (match_dup 1) (match_dup 2)))
|
(set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
|
(set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
|
(match_dup 1) (match_dup 2)))]
|
(match_dup 1) (match_dup 2)))]
|
"")
|
"")
|
|
|
(define_insn "*smin_const0"
|
(define_insn "*smin_const0"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(smin:DI (match_operand:DI 1 "register_operand" "0")
|
(smin:DI (match_operand:DI 1 "register_operand" "0")
|
(const_int 0)))]
|
(const_int 0)))]
|
""
|
""
|
"cmovgt %0,0,%0"
|
"cmovgt %0,0,%0"
|
[(set_attr "type" "icmov")])
|
[(set_attr "type" "icmov")])
|
|
|
(define_expand "umaxdi3"
|
(define_expand "umaxdi3"
|
[(set (match_dup 3)
|
[(set (match_dup 3)
|
(leu:DI (match_operand:DI 1 "reg_or_0_operand" "")
|
(leu:DI (match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")))
|
(match_operand:DI 2 "reg_or_8bit_operand" "")))
|
(set (match_operand:DI 0 "register_operand" "")
|
(set (match_operand:DI 0 "register_operand" "")
|
(if_then_else:DI (eq (match_dup 3) (const_int 0))
|
(if_then_else:DI (eq (match_dup 3) (const_int 0))
|
(match_dup 1) (match_dup 2)))]
|
(match_dup 1) (match_dup 2)))]
|
""
|
""
|
"operands[3] = gen_reg_rtx (DImode);")
|
"operands[3] = gen_reg_rtx (DImode);")
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(umax:DI (match_operand:DI 1 "reg_or_0_operand" "")
|
(umax:DI (match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")))
|
(match_operand:DI 2 "reg_or_8bit_operand" "")))
|
(clobber (match_operand:DI 3 "register_operand" ""))]
|
(clobber (match_operand:DI 3 "register_operand" ""))]
|
"operands[2] != const0_rtx"
|
"operands[2] != const0_rtx"
|
[(set (match_dup 3) (leu:DI (match_dup 1) (match_dup 2)))
|
[(set (match_dup 3) (leu:DI (match_dup 1) (match_dup 2)))
|
(set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
|
(set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
|
(match_dup 1) (match_dup 2)))]
|
(match_dup 1) (match_dup 2)))]
|
"")
|
"")
|
|
|
(define_expand "umindi3"
|
(define_expand "umindi3"
|
[(set (match_dup 3)
|
[(set (match_dup 3)
|
(ltu:DI (match_operand:DI 1 "reg_or_0_operand" "")
|
(ltu:DI (match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")))
|
(match_operand:DI 2 "reg_or_8bit_operand" "")))
|
(set (match_operand:DI 0 "register_operand" "")
|
(set (match_operand:DI 0 "register_operand" "")
|
(if_then_else:DI (ne (match_dup 3) (const_int 0))
|
(if_then_else:DI (ne (match_dup 3) (const_int 0))
|
(match_dup 1) (match_dup 2)))]
|
(match_dup 1) (match_dup 2)))]
|
""
|
""
|
"operands[3] = gen_reg_rtx (DImode);")
|
"operands[3] = gen_reg_rtx (DImode);")
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(umin:DI (match_operand:DI 1 "reg_or_0_operand" "")
|
(umin:DI (match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")))
|
(match_operand:DI 2 "reg_or_8bit_operand" "")))
|
(clobber (match_operand:DI 3 "register_operand" ""))]
|
(clobber (match_operand:DI 3 "register_operand" ""))]
|
"operands[2] != const0_rtx"
|
"operands[2] != const0_rtx"
|
[(set (match_dup 3) (ltu:DI (match_dup 1) (match_dup 2)))
|
[(set (match_dup 3) (ltu:DI (match_dup 1) (match_dup 2)))
|
(set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
|
(set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
|
(match_dup 1) (match_dup 2)))]
|
(match_dup 1) (match_dup 2)))]
|
"")
|
"")
|
|
|
(define_insn "*bcc_normal"
|
(define_insn "*bcc_normal"
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(match_operator 1 "signed_comparison_operator"
|
(match_operator 1 "signed_comparison_operator"
|
[(match_operand:DI 2 "reg_or_0_operand" "rJ")
|
[(match_operand:DI 2 "reg_or_0_operand" "rJ")
|
(const_int 0)])
|
(const_int 0)])
|
(label_ref (match_operand 0 "" ""))
|
(label_ref (match_operand 0 "" ""))
|
(pc)))]
|
(pc)))]
|
""
|
""
|
"b%C1 %r2,%0"
|
"b%C1 %r2,%0"
|
[(set_attr "type" "ibr")])
|
[(set_attr "type" "ibr")])
|
|
|
(define_insn "*bcc_reverse"
|
(define_insn "*bcc_reverse"
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(match_operator 1 "signed_comparison_operator"
|
(match_operator 1 "signed_comparison_operator"
|
[(match_operand:DI 2 "register_operand" "r")
|
[(match_operand:DI 2 "register_operand" "r")
|
(const_int 0)])
|
(const_int 0)])
|
|
|
(pc)
|
(pc)
|
(label_ref (match_operand 0 "" ""))))]
|
(label_ref (match_operand 0 "" ""))))]
|
""
|
""
|
"b%c1 %2,%0"
|
"b%c1 %2,%0"
|
[(set_attr "type" "ibr")])
|
[(set_attr "type" "ibr")])
|
|
|
(define_insn "*blbs_normal"
|
(define_insn "*blbs_normal"
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(ne (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(ne (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(const_int 1)
|
(const_int 1)
|
(const_int 0))
|
(const_int 0))
|
(const_int 0))
|
(const_int 0))
|
(label_ref (match_operand 0 "" ""))
|
(label_ref (match_operand 0 "" ""))
|
(pc)))]
|
(pc)))]
|
""
|
""
|
"blbs %r1,%0"
|
"blbs %r1,%0"
|
[(set_attr "type" "ibr")])
|
[(set_attr "type" "ibr")])
|
|
|
(define_insn "*blbc_normal"
|
(define_insn "*blbc_normal"
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(eq (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(eq (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(const_int 1)
|
(const_int 1)
|
(const_int 0))
|
(const_int 0))
|
(const_int 0))
|
(const_int 0))
|
(label_ref (match_operand 0 "" ""))
|
(label_ref (match_operand 0 "" ""))
|
(pc)))]
|
(pc)))]
|
""
|
""
|
"blbc %r1,%0"
|
"blbc %r1,%0"
|
[(set_attr "type" "ibr")])
|
[(set_attr "type" "ibr")])
|
|
|
(define_split
|
(define_split
|
[(parallel
|
[(parallel
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(match_operator 1 "comparison_operator"
|
(match_operator 1 "comparison_operator"
|
[(zero_extract:DI (match_operand:DI 2 "register_operand" "")
|
[(zero_extract:DI (match_operand:DI 2 "register_operand" "")
|
(const_int 1)
|
(const_int 1)
|
(match_operand:DI 3 "const_int_operand" ""))
|
(match_operand:DI 3 "const_int_operand" ""))
|
(const_int 0)])
|
(const_int 0)])
|
(label_ref (match_operand 0 "" ""))
|
(label_ref (match_operand 0 "" ""))
|
(pc)))
|
(pc)))
|
(clobber (match_operand:DI 4 "register_operand" ""))])]
|
(clobber (match_operand:DI 4 "register_operand" ""))])]
|
"INTVAL (operands[3]) != 0"
|
"INTVAL (operands[3]) != 0"
|
[(set (match_dup 4)
|
[(set (match_dup 4)
|
(lshiftrt:DI (match_dup 2) (match_dup 3)))
|
(lshiftrt:DI (match_dup 2) (match_dup 3)))
|
(set (pc)
|
(set (pc)
|
(if_then_else (match_op_dup 1
|
(if_then_else (match_op_dup 1
|
[(zero_extract:DI (match_dup 4)
|
[(zero_extract:DI (match_dup 4)
|
(const_int 1)
|
(const_int 1)
|
(const_int 0))
|
(const_int 0))
|
(const_int 0)])
|
(const_int 0)])
|
(label_ref (match_dup 0))
|
(label_ref (match_dup 0))
|
(pc)))]
|
(pc)))]
|
"")
|
"")
|
|
|
;; The following are the corresponding floating-point insns. Recall
|
;; The following are the corresponding floating-point insns. Recall
|
;; we need to have variants that expand the arguments from SFmode
|
;; we need to have variants that expand the arguments from SFmode
|
;; to DFmode.
|
;; to DFmode.
|
|
|
(define_insn "*cmpdf_ieee"
|
(define_insn "*cmpdf_ieee"
|
[(set (match_operand:DF 0 "register_operand" "=&f")
|
[(set (match_operand:DF 0 "register_operand" "=&f")
|
(match_operator:DF 1 "alpha_fp_comparison_operator"
|
(match_operator:DF 1 "alpha_fp_comparison_operator"
|
[(match_operand:DF 2 "reg_or_0_operand" "fG")
|
[(match_operand:DF 2 "reg_or_0_operand" "fG")
|
(match_operand:DF 3 "reg_or_0_operand" "fG")]))]
|
(match_operand:DF 3 "reg_or_0_operand" "fG")]))]
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
"cmp%-%C1%/ %R2,%R3,%0"
|
"cmp%-%C1%/ %R2,%R3,%0"
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "trap_suffix" "su")])
|
(set_attr "trap_suffix" "su")])
|
|
|
(define_insn "*cmpdf_internal"
|
(define_insn "*cmpdf_internal"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(match_operator:DF 1 "alpha_fp_comparison_operator"
|
(match_operator:DF 1 "alpha_fp_comparison_operator"
|
[(match_operand:DF 2 "reg_or_0_operand" "fG")
|
[(match_operand:DF 2 "reg_or_0_operand" "fG")
|
(match_operand:DF 3 "reg_or_0_operand" "fG")]))]
|
(match_operand:DF 3 "reg_or_0_operand" "fG")]))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"cmp%-%C1%/ %R2,%R3,%0"
|
"cmp%-%C1%/ %R2,%R3,%0"
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "trap_suffix" "su")])
|
(set_attr "trap_suffix" "su")])
|
|
|
(define_insn "*cmpdf_ext1"
|
(define_insn "*cmpdf_ext1"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(match_operator:DF 1 "alpha_fp_comparison_operator"
|
(match_operator:DF 1 "alpha_fp_comparison_operator"
|
[(float_extend:DF
|
[(float_extend:DF
|
(match_operand:SF 2 "reg_or_0_operand" "fG"))
|
(match_operand:SF 2 "reg_or_0_operand" "fG"))
|
(match_operand:DF 3 "reg_or_0_operand" "fG")]))]
|
(match_operand:DF 3 "reg_or_0_operand" "fG")]))]
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"cmp%-%C1%/ %R2,%R3,%0"
|
"cmp%-%C1%/ %R2,%R3,%0"
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "trap_suffix" "su")])
|
(set_attr "trap_suffix" "su")])
|
|
|
(define_insn "*cmpdf_ext2"
|
(define_insn "*cmpdf_ext2"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(match_operator:DF 1 "alpha_fp_comparison_operator"
|
(match_operator:DF 1 "alpha_fp_comparison_operator"
|
[(match_operand:DF 2 "reg_or_0_operand" "fG")
|
[(match_operand:DF 2 "reg_or_0_operand" "fG")
|
(float_extend:DF
|
(float_extend:DF
|
(match_operand:SF 3 "reg_or_0_operand" "fG"))]))]
|
(match_operand:SF 3 "reg_or_0_operand" "fG"))]))]
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"cmp%-%C1%/ %R2,%R3,%0"
|
"cmp%-%C1%/ %R2,%R3,%0"
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "trap_suffix" "su")])
|
(set_attr "trap_suffix" "su")])
|
|
|
(define_insn "*cmpdf_ext3"
|
(define_insn "*cmpdf_ext3"
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
(match_operator:DF 1 "alpha_fp_comparison_operator"
|
(match_operator:DF 1 "alpha_fp_comparison_operator"
|
[(float_extend:DF
|
[(float_extend:DF
|
(match_operand:SF 2 "reg_or_0_operand" "fG"))
|
(match_operand:SF 2 "reg_or_0_operand" "fG"))
|
(float_extend:DF
|
(float_extend:DF
|
(match_operand:SF 3 "reg_or_0_operand" "fG"))]))]
|
(match_operand:SF 3 "reg_or_0_operand" "fG"))]))]
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"cmp%-%C1%/ %R2,%R3,%0"
|
"cmp%-%C1%/ %R2,%R3,%0"
|
[(set_attr "type" "fadd")
|
[(set_attr "type" "fadd")
|
(set_attr "trap" "yes")
|
(set_attr "trap" "yes")
|
(set_attr "trap_suffix" "su")])
|
(set_attr "trap_suffix" "su")])
|
|
|
(define_insn "*movdfcc_internal"
|
(define_insn "*movdfcc_internal"
|
[(set (match_operand:DF 0 "register_operand" "=f,f")
|
[(set (match_operand:DF 0 "register_operand" "=f,f")
|
(if_then_else:DF
|
(if_then_else:DF
|
(match_operator 3 "signed_comparison_operator"
|
(match_operator 3 "signed_comparison_operator"
|
[(match_operand:DF 4 "reg_or_0_operand" "fG,fG")
|
[(match_operand:DF 4 "reg_or_0_operand" "fG,fG")
|
(match_operand:DF 2 "const0_operand" "G,G")])
|
(match_operand:DF 2 "const0_operand" "G,G")])
|
(match_operand:DF 1 "reg_or_0_operand" "fG,0")
|
(match_operand:DF 1 "reg_or_0_operand" "fG,0")
|
(match_operand:DF 5 "reg_or_0_operand" "0,fG")))]
|
(match_operand:DF 5 "reg_or_0_operand" "0,fG")))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"@
|
"@
|
fcmov%C3 %R4,%R1,%0
|
fcmov%C3 %R4,%R1,%0
|
fcmov%D3 %R4,%R5,%0"
|
fcmov%D3 %R4,%R5,%0"
|
[(set_attr "type" "fcmov")])
|
[(set_attr "type" "fcmov")])
|
|
|
(define_insn "*movsfcc_internal"
|
(define_insn "*movsfcc_internal"
|
[(set (match_operand:SF 0 "register_operand" "=f,f")
|
[(set (match_operand:SF 0 "register_operand" "=f,f")
|
(if_then_else:SF
|
(if_then_else:SF
|
(match_operator 3 "signed_comparison_operator"
|
(match_operator 3 "signed_comparison_operator"
|
[(match_operand:DF 4 "reg_or_0_operand" "fG,fG")
|
[(match_operand:DF 4 "reg_or_0_operand" "fG,fG")
|
(match_operand:DF 2 "const0_operand" "G,G")])
|
(match_operand:DF 2 "const0_operand" "G,G")])
|
(match_operand:SF 1 "reg_or_0_operand" "fG,0")
|
(match_operand:SF 1 "reg_or_0_operand" "fG,0")
|
(match_operand:SF 5 "reg_or_0_operand" "0,fG")))]
|
(match_operand:SF 5 "reg_or_0_operand" "0,fG")))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"@
|
"@
|
fcmov%C3 %R4,%R1,%0
|
fcmov%C3 %R4,%R1,%0
|
fcmov%D3 %R4,%R5,%0"
|
fcmov%D3 %R4,%R5,%0"
|
[(set_attr "type" "fcmov")])
|
[(set_attr "type" "fcmov")])
|
|
|
(define_insn "*movdfcc_ext1"
|
(define_insn "*movdfcc_ext1"
|
[(set (match_operand:DF 0 "register_operand" "=f,f")
|
[(set (match_operand:DF 0 "register_operand" "=f,f")
|
(if_then_else:DF
|
(if_then_else:DF
|
(match_operator 3 "signed_comparison_operator"
|
(match_operator 3 "signed_comparison_operator"
|
[(match_operand:DF 4 "reg_or_0_operand" "fG,fG")
|
[(match_operand:DF 4 "reg_or_0_operand" "fG,fG")
|
(match_operand:DF 2 "const0_operand" "G,G")])
|
(match_operand:DF 2 "const0_operand" "G,G")])
|
(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG,0"))
|
(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG,0"))
|
(match_operand:DF 5 "reg_or_0_operand" "0,fG")))]
|
(match_operand:DF 5 "reg_or_0_operand" "0,fG")))]
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"@
|
"@
|
fcmov%C3 %R4,%R1,%0
|
fcmov%C3 %R4,%R1,%0
|
fcmov%D3 %R4,%R5,%0"
|
fcmov%D3 %R4,%R5,%0"
|
[(set_attr "type" "fcmov")])
|
[(set_attr "type" "fcmov")])
|
|
|
(define_insn "*movdfcc_ext2"
|
(define_insn "*movdfcc_ext2"
|
[(set (match_operand:DF 0 "register_operand" "=f,f")
|
[(set (match_operand:DF 0 "register_operand" "=f,f")
|
(if_then_else:DF
|
(if_then_else:DF
|
(match_operator 3 "signed_comparison_operator"
|
(match_operator 3 "signed_comparison_operator"
|
[(float_extend:DF
|
[(float_extend:DF
|
(match_operand:SF 4 "reg_or_0_operand" "fG,fG"))
|
(match_operand:SF 4 "reg_or_0_operand" "fG,fG"))
|
(match_operand:DF 2 "const0_operand" "G,G")])
|
(match_operand:DF 2 "const0_operand" "G,G")])
|
(match_operand:DF 1 "reg_or_0_operand" "fG,0")
|
(match_operand:DF 1 "reg_or_0_operand" "fG,0")
|
(match_operand:DF 5 "reg_or_0_operand" "0,fG")))]
|
(match_operand:DF 5 "reg_or_0_operand" "0,fG")))]
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"@
|
"@
|
fcmov%C3 %R4,%R1,%0
|
fcmov%C3 %R4,%R1,%0
|
fcmov%D3 %R4,%R5,%0"
|
fcmov%D3 %R4,%R5,%0"
|
[(set_attr "type" "fcmov")])
|
[(set_attr "type" "fcmov")])
|
|
|
(define_insn "*movdfcc_ext3"
|
(define_insn "*movdfcc_ext3"
|
[(set (match_operand:SF 0 "register_operand" "=f,f")
|
[(set (match_operand:SF 0 "register_operand" "=f,f")
|
(if_then_else:SF
|
(if_then_else:SF
|
(match_operator 3 "signed_comparison_operator"
|
(match_operator 3 "signed_comparison_operator"
|
[(float_extend:DF
|
[(float_extend:DF
|
(match_operand:SF 4 "reg_or_0_operand" "fG,fG"))
|
(match_operand:SF 4 "reg_or_0_operand" "fG,fG"))
|
(match_operand:DF 2 "const0_operand" "G,G")])
|
(match_operand:DF 2 "const0_operand" "G,G")])
|
(match_operand:SF 1 "reg_or_0_operand" "fG,0")
|
(match_operand:SF 1 "reg_or_0_operand" "fG,0")
|
(match_operand:SF 5 "reg_or_0_operand" "0,fG")))]
|
(match_operand:SF 5 "reg_or_0_operand" "0,fG")))]
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"@
|
"@
|
fcmov%C3 %R4,%R1,%0
|
fcmov%C3 %R4,%R1,%0
|
fcmov%D3 %R4,%R5,%0"
|
fcmov%D3 %R4,%R5,%0"
|
[(set_attr "type" "fcmov")])
|
[(set_attr "type" "fcmov")])
|
|
|
(define_insn "*movdfcc_ext4"
|
(define_insn "*movdfcc_ext4"
|
[(set (match_operand:DF 0 "register_operand" "=f,f")
|
[(set (match_operand:DF 0 "register_operand" "=f,f")
|
(if_then_else:DF
|
(if_then_else:DF
|
(match_operator 3 "signed_comparison_operator"
|
(match_operator 3 "signed_comparison_operator"
|
[(float_extend:DF
|
[(float_extend:DF
|
(match_operand:SF 4 "reg_or_0_operand" "fG,fG"))
|
(match_operand:SF 4 "reg_or_0_operand" "fG,fG"))
|
(match_operand:DF 2 "const0_operand" "G,G")])
|
(match_operand:DF 2 "const0_operand" "G,G")])
|
(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG,0"))
|
(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG,0"))
|
(match_operand:DF 5 "reg_or_0_operand" "0,fG")))]
|
(match_operand:DF 5 "reg_or_0_operand" "0,fG")))]
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"@
|
"@
|
fcmov%C3 %R4,%R1,%0
|
fcmov%C3 %R4,%R1,%0
|
fcmov%D3 %R4,%R5,%0"
|
fcmov%D3 %R4,%R5,%0"
|
[(set_attr "type" "fcmov")])
|
[(set_attr "type" "fcmov")])
|
|
|
(define_expand "smaxdf3"
|
(define_expand "smaxdf3"
|
[(set (match_dup 3)
|
[(set (match_dup 3)
|
(le:DF (match_operand:DF 1 "reg_or_0_operand" "")
|
(le:DF (match_operand:DF 1 "reg_or_0_operand" "")
|
(match_operand:DF 2 "reg_or_0_operand" "")))
|
(match_operand:DF 2 "reg_or_0_operand" "")))
|
(set (match_operand:DF 0 "register_operand" "")
|
(set (match_operand:DF 0 "register_operand" "")
|
(if_then_else:DF (eq (match_dup 3) (match_dup 4))
|
(if_then_else:DF (eq (match_dup 3) (match_dup 4))
|
(match_dup 1) (match_dup 2)))]
|
(match_dup 1) (match_dup 2)))]
|
"TARGET_FP"
|
"TARGET_FP"
|
{
|
{
|
operands[3] = gen_reg_rtx (DFmode);
|
operands[3] = gen_reg_rtx (DFmode);
|
operands[4] = CONST0_RTX (DFmode);
|
operands[4] = CONST0_RTX (DFmode);
|
})
|
})
|
|
|
(define_expand "smindf3"
|
(define_expand "smindf3"
|
[(set (match_dup 3)
|
[(set (match_dup 3)
|
(lt:DF (match_operand:DF 1 "reg_or_0_operand" "")
|
(lt:DF (match_operand:DF 1 "reg_or_0_operand" "")
|
(match_operand:DF 2 "reg_or_0_operand" "")))
|
(match_operand:DF 2 "reg_or_0_operand" "")))
|
(set (match_operand:DF 0 "register_operand" "")
|
(set (match_operand:DF 0 "register_operand" "")
|
(if_then_else:DF (ne (match_dup 3) (match_dup 4))
|
(if_then_else:DF (ne (match_dup 3) (match_dup 4))
|
(match_dup 1) (match_dup 2)))]
|
(match_dup 1) (match_dup 2)))]
|
"TARGET_FP"
|
"TARGET_FP"
|
{
|
{
|
operands[3] = gen_reg_rtx (DFmode);
|
operands[3] = gen_reg_rtx (DFmode);
|
operands[4] = CONST0_RTX (DFmode);
|
operands[4] = CONST0_RTX (DFmode);
|
})
|
})
|
|
|
(define_expand "smaxsf3"
|
(define_expand "smaxsf3"
|
[(set (match_dup 3)
|
[(set (match_dup 3)
|
(le:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_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" ""))))
|
(float_extend:DF (match_operand:SF 2 "reg_or_0_operand" ""))))
|
(set (match_operand:SF 0 "register_operand" "")
|
(set (match_operand:SF 0 "register_operand" "")
|
(if_then_else:SF (eq (match_dup 3) (match_dup 4))
|
(if_then_else:SF (eq (match_dup 3) (match_dup 4))
|
(match_dup 1) (match_dup 2)))]
|
(match_dup 1) (match_dup 2)))]
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
{
|
{
|
operands[3] = gen_reg_rtx (DFmode);
|
operands[3] = gen_reg_rtx (DFmode);
|
operands[4] = CONST0_RTX (DFmode);
|
operands[4] = CONST0_RTX (DFmode);
|
})
|
})
|
|
|
(define_expand "sminsf3"
|
(define_expand "sminsf3"
|
[(set (match_dup 3)
|
[(set (match_dup 3)
|
(lt:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_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" ""))))
|
(float_extend:DF (match_operand:SF 2 "reg_or_0_operand" ""))))
|
(set (match_operand:SF 0 "register_operand" "")
|
(set (match_operand:SF 0 "register_operand" "")
|
(if_then_else:SF (ne (match_dup 3) (match_dup 4))
|
(if_then_else:SF (ne (match_dup 3) (match_dup 4))
|
(match_dup 1) (match_dup 2)))]
|
(match_dup 1) (match_dup 2)))]
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
|
{
|
{
|
operands[3] = gen_reg_rtx (DFmode);
|
operands[3] = gen_reg_rtx (DFmode);
|
operands[4] = CONST0_RTX (DFmode);
|
operands[4] = CONST0_RTX (DFmode);
|
})
|
})
|
|
|
(define_insn "*fbcc_normal"
|
(define_insn "*fbcc_normal"
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(match_operator 1 "signed_comparison_operator"
|
(match_operator 1 "signed_comparison_operator"
|
[(match_operand:DF 2 "reg_or_0_operand" "fG")
|
[(match_operand:DF 2 "reg_or_0_operand" "fG")
|
(match_operand:DF 3 "const0_operand" "G")])
|
(match_operand:DF 3 "const0_operand" "G")])
|
(label_ref (match_operand 0 "" ""))
|
(label_ref (match_operand 0 "" ""))
|
(pc)))]
|
(pc)))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"fb%C1 %R2,%0"
|
"fb%C1 %R2,%0"
|
[(set_attr "type" "fbr")])
|
[(set_attr "type" "fbr")])
|
|
|
(define_insn "*fbcc_ext_normal"
|
(define_insn "*fbcc_ext_normal"
|
[(set (pc)
|
[(set (pc)
|
(if_then_else
|
(if_then_else
|
(match_operator 1 "signed_comparison_operator"
|
(match_operator 1 "signed_comparison_operator"
|
[(float_extend:DF
|
[(float_extend:DF
|
(match_operand:SF 2 "reg_or_0_operand" "fG"))
|
(match_operand:SF 2 "reg_or_0_operand" "fG"))
|
(match_operand:DF 3 "const0_operand" "G")])
|
(match_operand:DF 3 "const0_operand" "G")])
|
(label_ref (match_operand 0 "" ""))
|
(label_ref (match_operand 0 "" ""))
|
(pc)))]
|
(pc)))]
|
"TARGET_FP"
|
"TARGET_FP"
|
"fb%C1 %R2,%0"
|
"fb%C1 %R2,%0"
|
[(set_attr "type" "fbr")])
|
[(set_attr "type" "fbr")])
|
|
|
;; These are the main define_expand's used to make conditional branches
|
;; These are the main define_expand's used to make conditional branches
|
;; and compares.
|
;; and compares.
|
|
|
(define_expand "cbranchdf4"
|
(define_expand "cbranchdf4"
|
[(use (match_operator 0 "alpha_cbranch_operator"
|
[(use (match_operator 0 "alpha_cbranch_operator"
|
[(match_operand:DF 1 "reg_or_0_operand" "")
|
[(match_operand:DF 1 "reg_or_0_operand" "")
|
(match_operand:DF 2 "reg_or_0_operand" "")]))
|
(match_operand:DF 2 "reg_or_0_operand" "")]))
|
(use (match_operand 3 ""))]
|
(use (match_operand 3 ""))]
|
"TARGET_FP"
|
"TARGET_FP"
|
{ alpha_emit_conditional_branch (operands, DFmode); DONE; })
|
{ alpha_emit_conditional_branch (operands, DFmode); DONE; })
|
|
|
(define_expand "cbranchtf4"
|
(define_expand "cbranchtf4"
|
[(use (match_operator 0 "alpha_cbranch_operator"
|
[(use (match_operator 0 "alpha_cbranch_operator"
|
[(match_operand:TF 1 "general_operand")
|
[(match_operand:TF 1 "general_operand")
|
(match_operand:TF 2 "general_operand")]))
|
(match_operand:TF 2 "general_operand")]))
|
(use (match_operand 3 ""))]
|
(use (match_operand 3 ""))]
|
"TARGET_HAS_XFLOATING_LIBS"
|
"TARGET_HAS_XFLOATING_LIBS"
|
{ alpha_emit_conditional_branch (operands, TFmode); DONE; })
|
{ alpha_emit_conditional_branch (operands, TFmode); DONE; })
|
|
|
(define_expand "cbranchdi4"
|
(define_expand "cbranchdi4"
|
[(use (match_operator 0 "alpha_cbranch_operator"
|
[(use (match_operator 0 "alpha_cbranch_operator"
|
[(match_operand:DI 1 "some_operand")
|
[(match_operand:DI 1 "some_operand")
|
(match_operand:DI 2 "some_operand")]))
|
(match_operand:DI 2 "some_operand")]))
|
(use (match_operand 3 ""))]
|
(use (match_operand 3 ""))]
|
""
|
""
|
{ alpha_emit_conditional_branch (operands, DImode); DONE; })
|
{ alpha_emit_conditional_branch (operands, DImode); DONE; })
|
|
|
(define_expand "cstoredf4"
|
(define_expand "cstoredf4"
|
[(use (match_operator:DI 1 "alpha_cbranch_operator"
|
[(use (match_operator:DI 1 "alpha_cbranch_operator"
|
[(match_operand:DF 2 "reg_or_0_operand")
|
[(match_operand:DF 2 "reg_or_0_operand")
|
(match_operand:DF 3 "reg_or_0_operand")]))
|
(match_operand:DF 3 "reg_or_0_operand")]))
|
(clobber (match_operand:DI 0 "register_operand"))]
|
(clobber (match_operand:DI 0 "register_operand"))]
|
"TARGET_FP"
|
"TARGET_FP"
|
{ if (!alpha_emit_setcc (operands, DFmode)) FAIL; else DONE; })
|
{ if (!alpha_emit_setcc (operands, DFmode)) FAIL; else DONE; })
|
|
|
(define_expand "cstoretf4"
|
(define_expand "cstoretf4"
|
[(use (match_operator:DI 1 "alpha_cbranch_operator"
|
[(use (match_operator:DI 1 "alpha_cbranch_operator"
|
[(match_operand:TF 2 "general_operand")
|
[(match_operand:TF 2 "general_operand")
|
(match_operand:TF 3 "general_operand")]))
|
(match_operand:TF 3 "general_operand")]))
|
(clobber (match_operand:DI 0 "register_operand"))]
|
(clobber (match_operand:DI 0 "register_operand"))]
|
"TARGET_HAS_XFLOATING_LIBS"
|
"TARGET_HAS_XFLOATING_LIBS"
|
{ if (!alpha_emit_setcc (operands, TFmode)) FAIL; else DONE; })
|
{ if (!alpha_emit_setcc (operands, TFmode)) FAIL; else DONE; })
|
|
|
(define_expand "cstoredi4"
|
(define_expand "cstoredi4"
|
[(use (match_operator:DI 1 "alpha_cbranch_operator"
|
[(use (match_operator:DI 1 "alpha_cbranch_operator"
|
[(match_operand:DI 2 "some_operand")
|
[(match_operand:DI 2 "some_operand")
|
(match_operand:DI 3 "some_operand")]))
|
(match_operand:DI 3 "some_operand")]))
|
(clobber (match_operand:DI 0 "register_operand"))]
|
(clobber (match_operand:DI 0 "register_operand"))]
|
""
|
""
|
{ if (!alpha_emit_setcc (operands, DImode)) FAIL; else DONE; })
|
{ if (!alpha_emit_setcc (operands, DImode)) FAIL; else DONE; })
|
|
|
;; These are the main define_expand's used to make conditional moves.
|
;; These are the main define_expand's used to make conditional moves.
|
|
|
(define_expand "movsicc"
|
(define_expand "movsicc"
|
[(set (match_operand:SI 0 "register_operand" "")
|
[(set (match_operand:SI 0 "register_operand" "")
|
(if_then_else:SI (match_operand 1 "comparison_operator" "")
|
(if_then_else:SI (match_operand 1 "comparison_operator" "")
|
(match_operand:SI 2 "reg_or_8bit_operand" "")
|
(match_operand:SI 2 "reg_or_8bit_operand" "")
|
(match_operand:SI 3 "reg_or_8bit_operand" "")))]
|
(match_operand:SI 3 "reg_or_8bit_operand" "")))]
|
""
|
""
|
{
|
{
|
if ((operands[1] = alpha_emit_conditional_move (operands[1], SImode)) == 0)
|
if ((operands[1] = alpha_emit_conditional_move (operands[1], SImode)) == 0)
|
FAIL;
|
FAIL;
|
})
|
})
|
|
|
(define_expand "movdicc"
|
(define_expand "movdicc"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(if_then_else:DI (match_operand 1 "comparison_operator" "")
|
(if_then_else:DI (match_operand 1 "comparison_operator" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")
|
(match_operand:DI 3 "reg_or_8bit_operand" "")))]
|
(match_operand:DI 3 "reg_or_8bit_operand" "")))]
|
""
|
""
|
{
|
{
|
if ((operands[1] = alpha_emit_conditional_move (operands[1], DImode)) == 0)
|
if ((operands[1] = alpha_emit_conditional_move (operands[1], DImode)) == 0)
|
FAIL;
|
FAIL;
|
})
|
})
|
|
|
(define_expand "movsfcc"
|
(define_expand "movsfcc"
|
[(set (match_operand:SF 0 "register_operand" "")
|
[(set (match_operand:SF 0 "register_operand" "")
|
(if_then_else:SF (match_operand 1 "comparison_operator" "")
|
(if_then_else:SF (match_operand 1 "comparison_operator" "")
|
(match_operand:SF 2 "reg_or_8bit_operand" "")
|
(match_operand:SF 2 "reg_or_8bit_operand" "")
|
(match_operand:SF 3 "reg_or_8bit_operand" "")))]
|
(match_operand:SF 3 "reg_or_8bit_operand" "")))]
|
""
|
""
|
{
|
{
|
if ((operands[1] = alpha_emit_conditional_move (operands[1], SFmode)) == 0)
|
if ((operands[1] = alpha_emit_conditional_move (operands[1], SFmode)) == 0)
|
FAIL;
|
FAIL;
|
})
|
})
|
|
|
(define_expand "movdfcc"
|
(define_expand "movdfcc"
|
[(set (match_operand:DF 0 "register_operand" "")
|
[(set (match_operand:DF 0 "register_operand" "")
|
(if_then_else:DF (match_operand 1 "comparison_operator" "")
|
(if_then_else:DF (match_operand 1 "comparison_operator" "")
|
(match_operand:DF 2 "reg_or_8bit_operand" "")
|
(match_operand:DF 2 "reg_or_8bit_operand" "")
|
(match_operand:DF 3 "reg_or_8bit_operand" "")))]
|
(match_operand:DF 3 "reg_or_8bit_operand" "")))]
|
""
|
""
|
{
|
{
|
if ((operands[1] = alpha_emit_conditional_move (operands[1], DFmode)) == 0)
|
if ((operands[1] = alpha_emit_conditional_move (operands[1], DFmode)) == 0)
|
FAIL;
|
FAIL;
|
})
|
})
|
|
|
;; These define_split definitions are used in cases when comparisons have
|
;; These define_split definitions are used in cases when comparisons have
|
;; not be stated in the correct way and we need to reverse the second
|
;; not be stated in the correct way and we need to reverse the second
|
;; comparison. For example, x >= 7 has to be done as x < 6 with the
|
;; comparison. For example, x >= 7 has to be done as x < 6 with the
|
;; comparison that tests the result being reversed. We have one define_split
|
;; comparison that tests the result being reversed. We have one define_split
|
;; for each use of a comparison. They do not match valid insns and need
|
;; for each use of a comparison. They do not match valid insns and need
|
;; not generate valid insns.
|
;; not generate valid insns.
|
;;
|
;;
|
;; We can also handle equality comparisons (and inequality comparisons in
|
;; We can also handle equality comparisons (and inequality comparisons in
|
;; cases where the resulting add cannot overflow) by doing an add followed by
|
;; cases where the resulting add cannot overflow) by doing an add followed by
|
;; a comparison with zero. This is faster since the addition takes one
|
;; a comparison with zero. This is faster since the addition takes one
|
;; less cycle than a compare when feeding into a conditional move.
|
;; less cycle than a compare when feeding into a conditional move.
|
;; For this case, we also have an SImode pattern since we can merge the add
|
;; For this case, we also have an SImode pattern since we can merge the add
|
;; and sign extend and the order doesn't matter.
|
;; and sign extend and the order doesn't matter.
|
;;
|
;;
|
;; We do not do this for floating-point, since it isn't clear how the "wrong"
|
;; We do not do this for floating-point, since it isn't clear how the "wrong"
|
;; operation could have been generated.
|
;; operation could have been generated.
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(if_then_else:DI
|
(if_then_else:DI
|
(match_operator 1 "comparison_operator"
|
(match_operator 1 "comparison_operator"
|
[(match_operand:DI 2 "reg_or_0_operand" "")
|
[(match_operand:DI 2 "reg_or_0_operand" "")
|
(match_operand:DI 3 "reg_or_cint_operand" "")])
|
(match_operand:DI 3 "reg_or_cint_operand" "")])
|
(match_operand:DI 4 "reg_or_cint_operand" "")
|
(match_operand:DI 4 "reg_or_cint_operand" "")
|
(match_operand:DI 5 "reg_or_cint_operand" "")))
|
(match_operand:DI 5 "reg_or_cint_operand" "")))
|
(clobber (match_operand:DI 6 "register_operand" ""))]
|
(clobber (match_operand:DI 6 "register_operand" ""))]
|
"operands[3] != const0_rtx"
|
"operands[3] != const0_rtx"
|
[(set (match_dup 6) (match_dup 7))
|
[(set (match_dup 6) (match_dup 7))
|
(set (match_dup 0)
|
(set (match_dup 0)
|
(if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
|
(if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
|
{
|
{
|
enum rtx_code code = GET_CODE (operands[1]);
|
enum rtx_code code = GET_CODE (operands[1]);
|
int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
|
int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
|
|
|
/* If we are comparing for equality with a constant and that constant
|
/* If we are comparing for equality with a constant and that constant
|
appears in the arm when the register equals the constant, use the
|
appears in the arm when the register equals the constant, use the
|
register since that is more likely to match (and to produce better code
|
register since that is more likely to match (and to produce better code
|
if both would). */
|
if both would). */
|
|
|
if (code == EQ && CONST_INT_P (operands[3])
|
if (code == EQ && CONST_INT_P (operands[3])
|
&& rtx_equal_p (operands[4], operands[3]))
|
&& rtx_equal_p (operands[4], operands[3]))
|
operands[4] = operands[2];
|
operands[4] = operands[2];
|
|
|
else if (code == NE && CONST_INT_P (operands[3])
|
else if (code == NE && CONST_INT_P (operands[3])
|
&& rtx_equal_p (operands[5], operands[3]))
|
&& rtx_equal_p (operands[5], operands[3]))
|
operands[5] = operands[2];
|
operands[5] = operands[2];
|
|
|
if (code == NE || code == EQ
|
if (code == NE || code == EQ
|
|| (extended_count (operands[2], DImode, unsignedp) >= 1
|
|| (extended_count (operands[2], DImode, unsignedp) >= 1
|
&& extended_count (operands[3], DImode, unsignedp) >= 1))
|
&& extended_count (operands[3], DImode, unsignedp) >= 1))
|
{
|
{
|
if (CONST_INT_P (operands[3]))
|
if (CONST_INT_P (operands[3]))
|
operands[7] = gen_rtx_PLUS (DImode, operands[2],
|
operands[7] = gen_rtx_PLUS (DImode, operands[2],
|
GEN_INT (- INTVAL (operands[3])));
|
GEN_INT (- INTVAL (operands[3])));
|
else
|
else
|
operands[7] = gen_rtx_MINUS (DImode, operands[2], operands[3]);
|
operands[7] = gen_rtx_MINUS (DImode, operands[2], operands[3]);
|
|
|
operands[8] = gen_rtx_fmt_ee (code, VOIDmode, operands[6], const0_rtx);
|
operands[8] = gen_rtx_fmt_ee (code, VOIDmode, operands[6], const0_rtx);
|
}
|
}
|
|
|
else if (code == EQ || code == LE || code == LT
|
else if (code == EQ || code == LE || code == LT
|
|| code == LEU || code == LTU)
|
|| code == LEU || code == LTU)
|
{
|
{
|
operands[7] = gen_rtx_fmt_ee (code, DImode, operands[2], operands[3]);
|
operands[7] = gen_rtx_fmt_ee (code, DImode, operands[2], operands[3]);
|
operands[8] = gen_rtx_NE (VOIDmode, operands[6], const0_rtx);
|
operands[8] = gen_rtx_NE (VOIDmode, operands[6], const0_rtx);
|
}
|
}
|
else
|
else
|
{
|
{
|
operands[7] = gen_rtx_fmt_ee (reverse_condition (code), DImode,
|
operands[7] = gen_rtx_fmt_ee (reverse_condition (code), DImode,
|
operands[2], operands[3]);
|
operands[2], operands[3]);
|
operands[8] = gen_rtx_EQ (VOIDmode, operands[6], const0_rtx);
|
operands[8] = gen_rtx_EQ (VOIDmode, operands[6], const0_rtx);
|
}
|
}
|
})
|
})
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(if_then_else:DI
|
(if_then_else:DI
|
(match_operator 1 "comparison_operator"
|
(match_operator 1 "comparison_operator"
|
[(match_operand:SI 2 "reg_or_0_operand" "")
|
[(match_operand:SI 2 "reg_or_0_operand" "")
|
(match_operand:SI 3 "reg_or_cint_operand" "")])
|
(match_operand:SI 3 "reg_or_cint_operand" "")])
|
(match_operand:DI 4 "reg_or_8bit_operand" "")
|
(match_operand:DI 4 "reg_or_8bit_operand" "")
|
(match_operand:DI 5 "reg_or_8bit_operand" "")))
|
(match_operand:DI 5 "reg_or_8bit_operand" "")))
|
(clobber (match_operand:DI 6 "register_operand" ""))]
|
(clobber (match_operand:DI 6 "register_operand" ""))]
|
"operands[3] != const0_rtx
|
"operands[3] != const0_rtx
|
&& (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
|
&& (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
|
[(set (match_dup 6) (match_dup 7))
|
[(set (match_dup 6) (match_dup 7))
|
(set (match_dup 0)
|
(set (match_dup 0)
|
(if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
|
(if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
|
{
|
{
|
enum rtx_code code = GET_CODE (operands[1]);
|
enum rtx_code code = GET_CODE (operands[1]);
|
int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
|
int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
|
rtx tem;
|
rtx tem;
|
|
|
if ((code != NE && code != EQ
|
if ((code != NE && code != EQ
|
&& ! (extended_count (operands[2], DImode, unsignedp) >= 1
|
&& ! (extended_count (operands[2], DImode, unsignedp) >= 1
|
&& extended_count (operands[3], DImode, unsignedp) >= 1)))
|
&& extended_count (operands[3], DImode, unsignedp) >= 1)))
|
FAIL;
|
FAIL;
|
|
|
if (CONST_INT_P (operands[3]))
|
if (CONST_INT_P (operands[3]))
|
tem = gen_rtx_PLUS (SImode, operands[2],
|
tem = gen_rtx_PLUS (SImode, operands[2],
|
GEN_INT (- INTVAL (operands[3])));
|
GEN_INT (- INTVAL (operands[3])));
|
else
|
else
|
tem = gen_rtx_MINUS (SImode, operands[2], operands[3]);
|
tem = gen_rtx_MINUS (SImode, operands[2], operands[3]);
|
|
|
operands[7] = gen_rtx_SIGN_EXTEND (DImode, tem);
|
operands[7] = gen_rtx_SIGN_EXTEND (DImode, tem);
|
operands[8] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
|
operands[8] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
|
operands[6], const0_rtx);
|
operands[6], const0_rtx);
|
})
|
})
|
|
|
;; Prefer to use cmp and arithmetic when possible instead of a cmove.
|
;; Prefer to use cmp and arithmetic when possible instead of a cmove.
|
|
|
(define_split
|
(define_split
|
[(set (match_operand 0 "register_operand" "")
|
[(set (match_operand 0 "register_operand" "")
|
(if_then_else (match_operator 1 "signed_comparison_operator"
|
(if_then_else (match_operator 1 "signed_comparison_operator"
|
[(match_operand:DI 2 "reg_or_0_operand" "")
|
[(match_operand:DI 2 "reg_or_0_operand" "")
|
(const_int 0)])
|
(const_int 0)])
|
(match_operand 3 "const_int_operand" "")
|
(match_operand 3 "const_int_operand" "")
|
(match_operand 4 "const_int_operand" "")))]
|
(match_operand 4 "const_int_operand" "")))]
|
""
|
""
|
[(const_int 0)]
|
[(const_int 0)]
|
{
|
{
|
if (alpha_split_conditional_move (GET_CODE (operands[1]), operands[0],
|
if (alpha_split_conditional_move (GET_CODE (operands[1]), operands[0],
|
operands[2], operands[3], operands[4]))
|
operands[2], operands[3], operands[4]))
|
DONE;
|
DONE;
|
else
|
else
|
FAIL;
|
FAIL;
|
})
|
})
|
|
|
;; ??? Why combine is allowed to create such non-canonical rtl, I don't know.
|
;; ??? Why combine is allowed to create such non-canonical rtl, I don't know.
|
;; Oh well, we match it in movcc, so it must be partially our fault.
|
;; Oh well, we match it in movcc, so it must be partially our fault.
|
(define_split
|
(define_split
|
[(set (match_operand 0 "register_operand" "")
|
[(set (match_operand 0 "register_operand" "")
|
(if_then_else (match_operator 1 "signed_comparison_operator"
|
(if_then_else (match_operator 1 "signed_comparison_operator"
|
[(const_int 0)
|
[(const_int 0)
|
(match_operand:DI 2 "reg_or_0_operand" "")])
|
(match_operand:DI 2 "reg_or_0_operand" "")])
|
(match_operand 3 "const_int_operand" "")
|
(match_operand 3 "const_int_operand" "")
|
(match_operand 4 "const_int_operand" "")))]
|
(match_operand 4 "const_int_operand" "")))]
|
""
|
""
|
[(const_int 0)]
|
[(const_int 0)]
|
{
|
{
|
if (alpha_split_conditional_move (swap_condition (GET_CODE (operands[1])),
|
if (alpha_split_conditional_move (swap_condition (GET_CODE (operands[1])),
|
operands[0], operands[2], operands[3],
|
operands[0], operands[2], operands[3],
|
operands[4]))
|
operands[4]))
|
DONE;
|
DONE;
|
else
|
else
|
FAIL;
|
FAIL;
|
})
|
})
|
|
|
(define_insn_and_split "*cmp_sadd_di"
|
(define_insn_and_split "*cmp_sadd_di"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(plus:DI (if_then_else:DI
|
(plus:DI (if_then_else:DI
|
(match_operator 1 "alpha_zero_comparison_operator"
|
(match_operator 1 "alpha_zero_comparison_operator"
|
[(match_operand:DI 2 "reg_or_0_operand" "rJ")
|
[(match_operand:DI 2 "reg_or_0_operand" "rJ")
|
(const_int 0)])
|
(const_int 0)])
|
(match_operand:DI 3 "const48_operand" "I")
|
(match_operand:DI 3 "const48_operand" "I")
|
(const_int 0))
|
(const_int 0))
|
(match_operand:DI 4 "sext_add_operand" "rIO")))
|
(match_operand:DI 4 "sext_add_operand" "rIO")))
|
(clobber (match_scratch:DI 5 "=r"))]
|
(clobber (match_scratch:DI 5 "=r"))]
|
""
|
""
|
"#"
|
"#"
|
""
|
""
|
[(set (match_dup 5)
|
[(set (match_dup 5)
|
(match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
|
(match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
|
(set (match_dup 0)
|
(set (match_dup 0)
|
(plus:DI (mult:DI (match_dup 5) (match_dup 3))
|
(plus:DI (mult:DI (match_dup 5) (match_dup 3))
|
(match_dup 4)))]
|
(match_dup 4)))]
|
{
|
{
|
if (can_create_pseudo_p ())
|
if (can_create_pseudo_p ())
|
operands[5] = gen_reg_rtx (DImode);
|
operands[5] = gen_reg_rtx (DImode);
|
else if (reg_overlap_mentioned_p (operands[5], operands[4]))
|
else if (reg_overlap_mentioned_p (operands[5], operands[4]))
|
operands[5] = operands[0];
|
operands[5] = operands[0];
|
})
|
})
|
|
|
(define_insn_and_split "*cmp_sadd_si"
|
(define_insn_and_split "*cmp_sadd_si"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(plus:SI (if_then_else:SI
|
(plus:SI (if_then_else:SI
|
(match_operator 1 "alpha_zero_comparison_operator"
|
(match_operator 1 "alpha_zero_comparison_operator"
|
[(match_operand:DI 2 "reg_or_0_operand" "rJ")
|
[(match_operand:DI 2 "reg_or_0_operand" "rJ")
|
(const_int 0)])
|
(const_int 0)])
|
(match_operand:SI 3 "const48_operand" "I")
|
(match_operand:SI 3 "const48_operand" "I")
|
(const_int 0))
|
(const_int 0))
|
(match_operand:SI 4 "sext_add_operand" "rIO")))
|
(match_operand:SI 4 "sext_add_operand" "rIO")))
|
(clobber (match_scratch:DI 5 "=r"))]
|
(clobber (match_scratch:DI 5 "=r"))]
|
""
|
""
|
"#"
|
"#"
|
""
|
""
|
[(set (match_dup 5)
|
[(set (match_dup 5)
|
(match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
|
(match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
|
(set (match_dup 0)
|
(set (match_dup 0)
|
(plus:SI (mult:SI (match_dup 6) (match_dup 3))
|
(plus:SI (mult:SI (match_dup 6) (match_dup 3))
|
(match_dup 4)))]
|
(match_dup 4)))]
|
{
|
{
|
if (can_create_pseudo_p ())
|
if (can_create_pseudo_p ())
|
operands[5] = gen_reg_rtx (DImode);
|
operands[5] = gen_reg_rtx (DImode);
|
else if (reg_overlap_mentioned_p (operands[5], operands[4]))
|
else if (reg_overlap_mentioned_p (operands[5], operands[4]))
|
operands[5] = gen_lowpart (DImode, operands[0]);
|
operands[5] = gen_lowpart (DImode, operands[0]);
|
|
|
operands[6] = gen_lowpart (SImode, operands[5]);
|
operands[6] = gen_lowpart (SImode, operands[5]);
|
})
|
})
|
|
|
(define_insn_and_split "*cmp_sadd_sidi"
|
(define_insn_and_split "*cmp_sadd_sidi"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(sign_extend:DI
|
(sign_extend:DI
|
(plus:SI (if_then_else:SI
|
(plus:SI (if_then_else:SI
|
(match_operator 1 "alpha_zero_comparison_operator"
|
(match_operator 1 "alpha_zero_comparison_operator"
|
[(match_operand:DI 2 "reg_or_0_operand" "rJ")
|
[(match_operand:DI 2 "reg_or_0_operand" "rJ")
|
(const_int 0)])
|
(const_int 0)])
|
(match_operand:SI 3 "const48_operand" "I")
|
(match_operand:SI 3 "const48_operand" "I")
|
(const_int 0))
|
(const_int 0))
|
(match_operand:SI 4 "sext_add_operand" "rIO"))))
|
(match_operand:SI 4 "sext_add_operand" "rIO"))))
|
(clobber (match_scratch:DI 5 "=r"))]
|
(clobber (match_scratch:DI 5 "=r"))]
|
""
|
""
|
"#"
|
"#"
|
""
|
""
|
[(set (match_dup 5)
|
[(set (match_dup 5)
|
(match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
|
(match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
|
(set (match_dup 0)
|
(set (match_dup 0)
|
(sign_extend:DI (plus:SI (mult:SI (match_dup 6) (match_dup 3))
|
(sign_extend:DI (plus:SI (mult:SI (match_dup 6) (match_dup 3))
|
(match_dup 4))))]
|
(match_dup 4))))]
|
{
|
{
|
if (can_create_pseudo_p ())
|
if (can_create_pseudo_p ())
|
operands[5] = gen_reg_rtx (DImode);
|
operands[5] = gen_reg_rtx (DImode);
|
else if (reg_overlap_mentioned_p (operands[5], operands[4]))
|
else if (reg_overlap_mentioned_p (operands[5], operands[4]))
|
operands[5] = operands[0];
|
operands[5] = operands[0];
|
|
|
operands[6] = gen_lowpart (SImode, operands[5]);
|
operands[6] = gen_lowpart (SImode, operands[5]);
|
})
|
})
|
|
|
(define_insn_and_split "*cmp_ssub_di"
|
(define_insn_and_split "*cmp_ssub_di"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(minus:DI (if_then_else:DI
|
(minus:DI (if_then_else:DI
|
(match_operator 1 "alpha_zero_comparison_operator"
|
(match_operator 1 "alpha_zero_comparison_operator"
|
[(match_operand:DI 2 "reg_or_0_operand" "rJ")
|
[(match_operand:DI 2 "reg_or_0_operand" "rJ")
|
(const_int 0)])
|
(const_int 0)])
|
(match_operand:DI 3 "const48_operand" "I")
|
(match_operand:DI 3 "const48_operand" "I")
|
(const_int 0))
|
(const_int 0))
|
(match_operand:DI 4 "reg_or_8bit_operand" "rI")))
|
(match_operand:DI 4 "reg_or_8bit_operand" "rI")))
|
(clobber (match_scratch:DI 5 "=r"))]
|
(clobber (match_scratch:DI 5 "=r"))]
|
""
|
""
|
"#"
|
"#"
|
""
|
""
|
[(set (match_dup 5)
|
[(set (match_dup 5)
|
(match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
|
(match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
|
(set (match_dup 0)
|
(set (match_dup 0)
|
(minus:DI (mult:DI (match_dup 5) (match_dup 3))
|
(minus:DI (mult:DI (match_dup 5) (match_dup 3))
|
(match_dup 4)))]
|
(match_dup 4)))]
|
{
|
{
|
if (can_create_pseudo_p ())
|
if (can_create_pseudo_p ())
|
operands[5] = gen_reg_rtx (DImode);
|
operands[5] = gen_reg_rtx (DImode);
|
else if (reg_overlap_mentioned_p (operands[5], operands[4]))
|
else if (reg_overlap_mentioned_p (operands[5], operands[4]))
|
operands[5] = operands[0];
|
operands[5] = operands[0];
|
})
|
})
|
|
|
(define_insn_and_split "*cmp_ssub_si"
|
(define_insn_and_split "*cmp_ssub_si"
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
(minus:SI (if_then_else:SI
|
(minus:SI (if_then_else:SI
|
(match_operator 1 "alpha_zero_comparison_operator"
|
(match_operator 1 "alpha_zero_comparison_operator"
|
[(match_operand:DI 2 "reg_or_0_operand" "rJ")
|
[(match_operand:DI 2 "reg_or_0_operand" "rJ")
|
(const_int 0)])
|
(const_int 0)])
|
(match_operand:SI 3 "const48_operand" "I")
|
(match_operand:SI 3 "const48_operand" "I")
|
(const_int 0))
|
(const_int 0))
|
(match_operand:SI 4 "reg_or_8bit_operand" "rI")))
|
(match_operand:SI 4 "reg_or_8bit_operand" "rI")))
|
(clobber (match_scratch:DI 5 "=r"))]
|
(clobber (match_scratch:DI 5 "=r"))]
|
""
|
""
|
"#"
|
"#"
|
""
|
""
|
[(set (match_dup 5)
|
[(set (match_dup 5)
|
(match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
|
(match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
|
(set (match_dup 0)
|
(set (match_dup 0)
|
(minus:SI (mult:SI (match_dup 6) (match_dup 3))
|
(minus:SI (mult:SI (match_dup 6) (match_dup 3))
|
(match_dup 4)))]
|
(match_dup 4)))]
|
{
|
{
|
if (can_create_pseudo_p ())
|
if (can_create_pseudo_p ())
|
operands[5] = gen_reg_rtx (DImode);
|
operands[5] = gen_reg_rtx (DImode);
|
else if (reg_overlap_mentioned_p (operands[5], operands[4]))
|
else if (reg_overlap_mentioned_p (operands[5], operands[4]))
|
operands[5] = gen_lowpart (DImode, operands[0]);
|
operands[5] = gen_lowpart (DImode, operands[0]);
|
|
|
operands[6] = gen_lowpart (SImode, operands[5]);
|
operands[6] = gen_lowpart (SImode, operands[5]);
|
})
|
})
|
|
|
(define_insn_and_split "*cmp_ssub_sidi"
|
(define_insn_and_split "*cmp_ssub_sidi"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(sign_extend:DI
|
(sign_extend:DI
|
(minus:SI (if_then_else:SI
|
(minus:SI (if_then_else:SI
|
(match_operator 1 "alpha_zero_comparison_operator"
|
(match_operator 1 "alpha_zero_comparison_operator"
|
[(match_operand:DI 2 "reg_or_0_operand" "rJ")
|
[(match_operand:DI 2 "reg_or_0_operand" "rJ")
|
(const_int 0)])
|
(const_int 0)])
|
(match_operand:SI 3 "const48_operand" "I")
|
(match_operand:SI 3 "const48_operand" "I")
|
(const_int 0))
|
(const_int 0))
|
(match_operand:SI 4 "reg_or_8bit_operand" "rI"))))
|
(match_operand:SI 4 "reg_or_8bit_operand" "rI"))))
|
(clobber (match_scratch:DI 5 "=r"))]
|
(clobber (match_scratch:DI 5 "=r"))]
|
""
|
""
|
"#"
|
"#"
|
""
|
""
|
[(set (match_dup 5)
|
[(set (match_dup 5)
|
(match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
|
(match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
|
(set (match_dup 0)
|
(set (match_dup 0)
|
(sign_extend:DI (minus:SI (mult:SI (match_dup 6) (match_dup 3))
|
(sign_extend:DI (minus:SI (mult:SI (match_dup 6) (match_dup 3))
|
(match_dup 4))))]
|
(match_dup 4))))]
|
{
|
{
|
if (can_create_pseudo_p ())
|
if (can_create_pseudo_p ())
|
operands[5] = gen_reg_rtx (DImode);
|
operands[5] = gen_reg_rtx (DImode);
|
else if (reg_overlap_mentioned_p (operands[5], operands[4]))
|
else if (reg_overlap_mentioned_p (operands[5], operands[4]))
|
operands[5] = operands[0];
|
operands[5] = operands[0];
|
|
|
operands[6] = gen_lowpart (SImode, operands[5]);
|
operands[6] = gen_lowpart (SImode, operands[5]);
|
})
|
})
|
|
|
;; Here are the CALL and unconditional branch insns. Calls on NT and OSF
|
;; Here are the CALL and unconditional branch insns. Calls on NT and OSF
|
;; work differently, so we have different patterns for each.
|
;; work differently, so we have different patterns for each.
|
|
|
;; On Unicos/Mk a call information word (CIW) must be generated for each
|
;; On Unicos/Mk a call information word (CIW) must be generated for each
|
;; call. The CIW contains information about arguments passed in registers
|
;; call. The CIW contains information about arguments passed in registers
|
;; and is stored in the caller's SSIB. Its offset relative to the beginning
|
;; and is stored in the caller's SSIB. Its offset relative to the beginning
|
;; of the SSIB is passed in $25. Handling this properly is quite complicated
|
;; of the SSIB is passed in $25. Handling this properly is quite complicated
|
;; in the presence of inlining since the CIWs for calls performed by the
|
;; in the presence of inlining since the CIWs for calls performed by the
|
;; inlined function must be stored in the SSIB of the function it is inlined
|
;; inlined function must be stored in the SSIB of the function it is inlined
|
;; into as well. We encode the CIW in an unspec and append it to the list
|
;; into as well. We encode the CIW in an unspec and append it to the list
|
;; of the CIWs for the current function only when the instruction for loading
|
;; of the CIWs for the current function only when the instruction for loading
|
;; $25 is generated.
|
;; $25 is generated.
|
|
|
(define_expand "call"
|
(define_expand "call"
|
[(use (match_operand:DI 0 "" ""))
|
[(use (match_operand:DI 0 "" ""))
|
(use (match_operand 1 "" ""))
|
(use (match_operand 1 "" ""))
|
(use (match_operand 2 "" ""))
|
(use (match_operand 2 "" ""))
|
(use (match_operand 3 "" ""))]
|
(use (match_operand 3 "" ""))]
|
""
|
""
|
{
|
{
|
if (TARGET_ABI_WINDOWS_NT)
|
if (TARGET_ABI_WINDOWS_NT)
|
emit_call_insn (gen_call_nt (operands[0], operands[1]));
|
emit_call_insn (gen_call_nt (operands[0], operands[1]));
|
else if (TARGET_ABI_OPEN_VMS)
|
else if (TARGET_ABI_OPEN_VMS)
|
emit_call_insn (gen_call_vms (operands[0], operands[2]));
|
emit_call_insn (gen_call_vms (operands[0], operands[2]));
|
else if (TARGET_ABI_UNICOSMK)
|
else if (TARGET_ABI_UNICOSMK)
|
emit_call_insn (gen_call_umk (operands[0], operands[2]));
|
emit_call_insn (gen_call_umk (operands[0], operands[2]));
|
else
|
else
|
emit_call_insn (gen_call_osf (operands[0], operands[1]));
|
emit_call_insn (gen_call_osf (operands[0], operands[1]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "sibcall"
|
(define_expand "sibcall"
|
[(parallel [(call (mem:DI (match_operand 0 "" ""))
|
[(parallel [(call (mem:DI (match_operand 0 "" ""))
|
(match_operand 1 "" ""))
|
(match_operand 1 "" ""))
|
(unspec [(reg:DI 29)] UNSPEC_SIBCALL)])]
|
(unspec [(reg:DI 29)] UNSPEC_SIBCALL)])]
|
"TARGET_ABI_OSF"
|
"TARGET_ABI_OSF"
|
{
|
{
|
gcc_assert (MEM_P (operands[0]));
|
gcc_assert (MEM_P (operands[0]));
|
operands[0] = XEXP (operands[0], 0);
|
operands[0] = XEXP (operands[0], 0);
|
})
|
})
|
|
|
(define_expand "call_osf"
|
(define_expand "call_osf"
|
[(parallel [(call (mem:DI (match_operand 0 "" ""))
|
[(parallel [(call (mem:DI (match_operand 0 "" ""))
|
(match_operand 1 "" ""))
|
(match_operand 1 "" ""))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(clobber (reg:DI 26))])]
|
(clobber (reg:DI 26))])]
|
""
|
""
|
{
|
{
|
gcc_assert (MEM_P (operands[0]));
|
gcc_assert (MEM_P (operands[0]));
|
|
|
operands[0] = XEXP (operands[0], 0);
|
operands[0] = XEXP (operands[0], 0);
|
if (! call_operand (operands[0], Pmode))
|
if (! call_operand (operands[0], Pmode))
|
operands[0] = copy_to_mode_reg (Pmode, operands[0]);
|
operands[0] = copy_to_mode_reg (Pmode, operands[0]);
|
})
|
})
|
|
|
(define_expand "call_nt"
|
(define_expand "call_nt"
|
[(parallel [(call (mem:DI (match_operand 0 "" ""))
|
[(parallel [(call (mem:DI (match_operand 0 "" ""))
|
(match_operand 1 "" ""))
|
(match_operand 1 "" ""))
|
(clobber (reg:DI 26))])]
|
(clobber (reg:DI 26))])]
|
""
|
""
|
{
|
{
|
gcc_assert (MEM_P (operands[0]));
|
gcc_assert (MEM_P (operands[0]));
|
|
|
operands[0] = XEXP (operands[0], 0);
|
operands[0] = XEXP (operands[0], 0);
|
if (GET_CODE (operands[0]) != SYMBOL_REF && !REG_P (operands[0]))
|
if (GET_CODE (operands[0]) != SYMBOL_REF && !REG_P (operands[0]))
|
operands[0] = force_reg (DImode, operands[0]);
|
operands[0] = force_reg (DImode, operands[0]);
|
})
|
})
|
|
|
;; Calls on Unicos/Mk are always indirect.
|
;; Calls on Unicos/Mk are always indirect.
|
;; op 0: symbol ref for called function
|
;; op 0: symbol ref for called function
|
;; op 1: CIW for $25 represented by an unspec
|
;; op 1: CIW for $25 represented by an unspec
|
|
|
(define_expand "call_umk"
|
(define_expand "call_umk"
|
[(parallel [(call (mem:DI (match_operand 0 "" ""))
|
[(parallel [(call (mem:DI (match_operand 0 "" ""))
|
(match_operand 1 "" ""))
|
(match_operand 1 "" ""))
|
(use (reg:DI 25))
|
(use (reg:DI 25))
|
(clobber (reg:DI 26))])]
|
(clobber (reg:DI 26))])]
|
""
|
""
|
{
|
{
|
gcc_assert (MEM_P (operands[0]));
|
gcc_assert (MEM_P (operands[0]));
|
|
|
/* Always load the address of the called function into a register;
|
/* Always load the address of the called function into a register;
|
load the CIW in $25. */
|
load the CIW in $25. */
|
|
|
operands[0] = XEXP (operands[0], 0);
|
operands[0] = XEXP (operands[0], 0);
|
if (!REG_P (operands[0]))
|
if (!REG_P (operands[0]))
|
operands[0] = force_reg (DImode, operands[0]);
|
operands[0] = force_reg (DImode, operands[0]);
|
|
|
emit_move_insn (gen_rtx_REG (DImode, 25), operands[1]);
|
emit_move_insn (gen_rtx_REG (DImode, 25), operands[1]);
|
})
|
})
|
|
|
;;
|
;;
|
;; call openvms/alpha
|
;; call openvms/alpha
|
;; op 0: symbol ref for called function
|
;; op 0: symbol ref for called function
|
;; op 1: next_arg_reg (argument information value for R25)
|
;; op 1: next_arg_reg (argument information value for R25)
|
;;
|
;;
|
(define_expand "call_vms"
|
(define_expand "call_vms"
|
[(parallel [(call (mem:DI (match_operand 0 "" ""))
|
[(parallel [(call (mem:DI (match_operand 0 "" ""))
|
(match_operand 1 "" ""))
|
(match_operand 1 "" ""))
|
(use (match_dup 2))
|
(use (match_dup 2))
|
(use (reg:DI 25))
|
(use (reg:DI 25))
|
(use (reg:DI 26))
|
(use (reg:DI 26))
|
(clobber (reg:DI 27))])]
|
(clobber (reg:DI 27))])]
|
""
|
""
|
{
|
{
|
gcc_assert (MEM_P (operands[0]));
|
gcc_assert (MEM_P (operands[0]));
|
|
|
operands[0] = XEXP (operands[0], 0);
|
operands[0] = XEXP (operands[0], 0);
|
|
|
/* Always load AI with argument information, then handle symbolic and
|
/* Always load AI with argument information, then handle symbolic and
|
indirect call differently. Load RA and set operands[2] to PV in
|
indirect call differently. Load RA and set operands[2] to PV in
|
both cases. */
|
both cases. */
|
|
|
emit_move_insn (gen_rtx_REG (DImode, 25), operands[1]);
|
emit_move_insn (gen_rtx_REG (DImode, 25), operands[1]);
|
if (GET_CODE (operands[0]) == SYMBOL_REF)
|
if (GET_CODE (operands[0]) == SYMBOL_REF)
|
{
|
{
|
alpha_need_linkage (XSTR (operands[0], 0), 0);
|
alpha_need_linkage (XSTR (operands[0], 0), 0);
|
|
|
operands[2] = const0_rtx;
|
operands[2] = const0_rtx;
|
}
|
}
|
else
|
else
|
{
|
{
|
emit_move_insn (gen_rtx_REG (Pmode, 26),
|
emit_move_insn (gen_rtx_REG (Pmode, 26),
|
gen_rtx_MEM (Pmode, plus_constant (operands[0], 8)));
|
gen_rtx_MEM (Pmode, plus_constant (operands[0], 8)));
|
operands[2] = operands[0];
|
operands[2] = operands[0];
|
}
|
}
|
|
|
})
|
})
|
|
|
(define_expand "call_value"
|
(define_expand "call_value"
|
[(use (match_operand 0 "" ""))
|
[(use (match_operand 0 "" ""))
|
(use (match_operand:DI 1 "" ""))
|
(use (match_operand:DI 1 "" ""))
|
(use (match_operand 2 "" ""))
|
(use (match_operand 2 "" ""))
|
(use (match_operand 3 "" ""))
|
(use (match_operand 3 "" ""))
|
(use (match_operand 4 "" ""))]
|
(use (match_operand 4 "" ""))]
|
""
|
""
|
{
|
{
|
if (TARGET_ABI_WINDOWS_NT)
|
if (TARGET_ABI_WINDOWS_NT)
|
emit_call_insn (gen_call_value_nt (operands[0], operands[1], operands[2]));
|
emit_call_insn (gen_call_value_nt (operands[0], operands[1], operands[2]));
|
else if (TARGET_ABI_OPEN_VMS)
|
else if (TARGET_ABI_OPEN_VMS)
|
emit_call_insn (gen_call_value_vms (operands[0], operands[1],
|
emit_call_insn (gen_call_value_vms (operands[0], operands[1],
|
operands[3]));
|
operands[3]));
|
else if (TARGET_ABI_UNICOSMK)
|
else if (TARGET_ABI_UNICOSMK)
|
emit_call_insn (gen_call_value_umk (operands[0], operands[1],
|
emit_call_insn (gen_call_value_umk (operands[0], operands[1],
|
operands[3]));
|
operands[3]));
|
else
|
else
|
emit_call_insn (gen_call_value_osf (operands[0], operands[1],
|
emit_call_insn (gen_call_value_osf (operands[0], operands[1],
|
operands[2]));
|
operands[2]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "sibcall_value"
|
(define_expand "sibcall_value"
|
[(parallel [(set (match_operand 0 "" "")
|
[(parallel [(set (match_operand 0 "" "")
|
(call (mem:DI (match_operand 1 "" ""))
|
(call (mem:DI (match_operand 1 "" ""))
|
(match_operand 2 "" "")))
|
(match_operand 2 "" "")))
|
(unspec [(reg:DI 29)] UNSPEC_SIBCALL)])]
|
(unspec [(reg:DI 29)] UNSPEC_SIBCALL)])]
|
"TARGET_ABI_OSF"
|
"TARGET_ABI_OSF"
|
{
|
{
|
gcc_assert (MEM_P (operands[1]));
|
gcc_assert (MEM_P (operands[1]));
|
operands[1] = XEXP (operands[1], 0);
|
operands[1] = XEXP (operands[1], 0);
|
})
|
})
|
|
|
(define_expand "call_value_osf"
|
(define_expand "call_value_osf"
|
[(parallel [(set (match_operand 0 "" "")
|
[(parallel [(set (match_operand 0 "" "")
|
(call (mem:DI (match_operand 1 "" ""))
|
(call (mem:DI (match_operand 1 "" ""))
|
(match_operand 2 "" "")))
|
(match_operand 2 "" "")))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(clobber (reg:DI 26))])]
|
(clobber (reg:DI 26))])]
|
""
|
""
|
{
|
{
|
gcc_assert (MEM_P (operands[1]));
|
gcc_assert (MEM_P (operands[1]));
|
|
|
operands[1] = XEXP (operands[1], 0);
|
operands[1] = XEXP (operands[1], 0);
|
if (! call_operand (operands[1], Pmode))
|
if (! call_operand (operands[1], Pmode))
|
operands[1] = copy_to_mode_reg (Pmode, operands[1]);
|
operands[1] = copy_to_mode_reg (Pmode, operands[1]);
|
})
|
})
|
|
|
(define_expand "call_value_nt"
|
(define_expand "call_value_nt"
|
[(parallel [(set (match_operand 0 "" "")
|
[(parallel [(set (match_operand 0 "" "")
|
(call (mem:DI (match_operand 1 "" ""))
|
(call (mem:DI (match_operand 1 "" ""))
|
(match_operand 2 "" "")))
|
(match_operand 2 "" "")))
|
(clobber (reg:DI 26))])]
|
(clobber (reg:DI 26))])]
|
""
|
""
|
{
|
{
|
gcc_assert (MEM_P (operands[1]));
|
gcc_assert (MEM_P (operands[1]));
|
|
|
operands[1] = XEXP (operands[1], 0);
|
operands[1] = XEXP (operands[1], 0);
|
if (GET_CODE (operands[1]) != SYMBOL_REF && !REG_P (operands[1]))
|
if (GET_CODE (operands[1]) != SYMBOL_REF && !REG_P (operands[1]))
|
operands[1] = force_reg (DImode, operands[1]);
|
operands[1] = force_reg (DImode, operands[1]);
|
})
|
})
|
|
|
(define_expand "call_value_vms"
|
(define_expand "call_value_vms"
|
[(parallel [(set (match_operand 0 "" "")
|
[(parallel [(set (match_operand 0 "" "")
|
(call (mem:DI (match_operand:DI 1 "" ""))
|
(call (mem:DI (match_operand:DI 1 "" ""))
|
(match_operand 2 "" "")))
|
(match_operand 2 "" "")))
|
(use (match_dup 3))
|
(use (match_dup 3))
|
(use (reg:DI 25))
|
(use (reg:DI 25))
|
(use (reg:DI 26))
|
(use (reg:DI 26))
|
(clobber (reg:DI 27))])]
|
(clobber (reg:DI 27))])]
|
""
|
""
|
{
|
{
|
gcc_assert (MEM_P (operands[1]));
|
gcc_assert (MEM_P (operands[1]));
|
|
|
operands[1] = XEXP (operands[1], 0);
|
operands[1] = XEXP (operands[1], 0);
|
|
|
/* Always load AI with argument information, then handle symbolic and
|
/* Always load AI with argument information, then handle symbolic and
|
indirect call differently. Load RA and set operands[3] to PV in
|
indirect call differently. Load RA and set operands[3] to PV in
|
both cases. */
|
both cases. */
|
|
|
emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]);
|
emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]);
|
if (GET_CODE (operands[1]) == SYMBOL_REF)
|
if (GET_CODE (operands[1]) == SYMBOL_REF)
|
{
|
{
|
alpha_need_linkage (XSTR (operands[1], 0), 0);
|
alpha_need_linkage (XSTR (operands[1], 0), 0);
|
|
|
operands[3] = const0_rtx;
|
operands[3] = const0_rtx;
|
}
|
}
|
else
|
else
|
{
|
{
|
emit_move_insn (gen_rtx_REG (Pmode, 26),
|
emit_move_insn (gen_rtx_REG (Pmode, 26),
|
gen_rtx_MEM (Pmode, plus_constant (operands[1], 8)));
|
gen_rtx_MEM (Pmode, plus_constant (operands[1], 8)));
|
operands[3] = operands[1];
|
operands[3] = operands[1];
|
}
|
}
|
})
|
})
|
|
|
(define_expand "call_value_umk"
|
(define_expand "call_value_umk"
|
[(parallel [(set (match_operand 0 "" "")
|
[(parallel [(set (match_operand 0 "" "")
|
(call (mem:DI (match_operand 1 "" ""))
|
(call (mem:DI (match_operand 1 "" ""))
|
(match_operand 2 "" "")))
|
(match_operand 2 "" "")))
|
(use (reg:DI 25))
|
(use (reg:DI 25))
|
(clobber (reg:DI 26))])]
|
(clobber (reg:DI 26))])]
|
""
|
""
|
{
|
{
|
gcc_assert (MEM_P (operands[1]));
|
gcc_assert (MEM_P (operands[1]));
|
|
|
operands[1] = XEXP (operands[1], 0);
|
operands[1] = XEXP (operands[1], 0);
|
if (!REG_P (operands[1]))
|
if (!REG_P (operands[1]))
|
operands[1] = force_reg (DImode, operands[1]);
|
operands[1] = force_reg (DImode, operands[1]);
|
|
|
emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]);
|
emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]);
|
})
|
})
|
|
|
(define_insn "*call_osf_1_er_noreturn"
|
(define_insn "*call_osf_1_er_noreturn"
|
[(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
|
[(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
|
(match_operand 1 "" ""))
|
(match_operand 1 "" ""))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(clobber (reg:DI 26))]
|
(clobber (reg:DI 26))]
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
|
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
|
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
|
"@
|
"@
|
jsr $26,($27),0
|
jsr $26,($27),0
|
bsr $26,%0\t\t!samegp
|
bsr $26,%0\t\t!samegp
|
ldq $27,%0($29)\t\t!literal!%#\;jsr $26,($27),%0\t\t!lituse_jsr!%#"
|
ldq $27,%0($29)\t\t!literal!%#\;jsr $26,($27),%0\t\t!lituse_jsr!%#"
|
[(set_attr "type" "jsr")
|
[(set_attr "type" "jsr")
|
(set_attr "length" "*,*,8")])
|
(set_attr "length" "*,*,8")])
|
|
|
(define_insn "*call_osf_1_er"
|
(define_insn "*call_osf_1_er"
|
[(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
|
[(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
|
(match_operand 1 "" ""))
|
(match_operand 1 "" ""))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(clobber (reg:DI 26))]
|
(clobber (reg:DI 26))]
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
"@
|
"@
|
jsr $26,(%0),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
|
jsr $26,(%0),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
|
bsr $26,%0\t\t!samegp
|
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!%*"
|
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 "type" "jsr")
|
(set_attr "length" "12,*,16")])
|
(set_attr "length" "12,*,16")])
|
|
|
;; We must use peep2 instead of a split because we need accurate life
|
;; We must use peep2 instead of a split because we need accurate life
|
;; information for $gp. Consider the case of { bar(); while (1); }.
|
;; information for $gp. Consider the case of { bar(); while (1); }.
|
(define_peephole2
|
(define_peephole2
|
[(parallel [(call (mem:DI (match_operand:DI 0 "call_operand" ""))
|
[(parallel [(call (mem:DI (match_operand:DI 0 "call_operand" ""))
|
(match_operand 1 "" ""))
|
(match_operand 1 "" ""))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(clobber (reg:DI 26))])]
|
(clobber (reg:DI 26))])]
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
|
&& ! samegp_function_operand (operands[0], Pmode)
|
&& ! samegp_function_operand (operands[0], Pmode)
|
&& (peep2_regno_dead_p (1, 29)
|
&& (peep2_regno_dead_p (1, 29)
|
|| find_reg_note (insn, REG_NORETURN, NULL_RTX))"
|
|| find_reg_note (insn, REG_NORETURN, NULL_RTX))"
|
[(parallel [(call (mem:DI (match_dup 2))
|
[(parallel [(call (mem:DI (match_dup 2))
|
(match_dup 1))
|
(match_dup 1))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(use (match_dup 0))
|
(use (match_dup 0))
|
(use (match_dup 3))
|
(use (match_dup 3))
|
(clobber (reg:DI 26))])]
|
(clobber (reg:DI 26))])]
|
{
|
{
|
if (CONSTANT_P (operands[0]))
|
if (CONSTANT_P (operands[0]))
|
{
|
{
|
operands[2] = gen_rtx_REG (Pmode, 27);
|
operands[2] = gen_rtx_REG (Pmode, 27);
|
operands[3] = GEN_INT (alpha_next_sequence_number++);
|
operands[3] = GEN_INT (alpha_next_sequence_number++);
|
emit_insn (gen_movdi_er_high_g (operands[2], pic_offset_table_rtx,
|
emit_insn (gen_movdi_er_high_g (operands[2], pic_offset_table_rtx,
|
operands[0], operands[3]));
|
operands[0], operands[3]));
|
}
|
}
|
else
|
else
|
{
|
{
|
operands[2] = operands[0];
|
operands[2] = operands[0];
|
operands[0] = const0_rtx;
|
operands[0] = const0_rtx;
|
operands[3] = const0_rtx;
|
operands[3] = const0_rtx;
|
}
|
}
|
})
|
})
|
|
|
(define_peephole2
|
(define_peephole2
|
[(parallel [(call (mem:DI (match_operand:DI 0 "call_operand" ""))
|
[(parallel [(call (mem:DI (match_operand:DI 0 "call_operand" ""))
|
(match_operand 1 "" ""))
|
(match_operand 1 "" ""))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(clobber (reg:DI 26))])]
|
(clobber (reg:DI 26))])]
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
|
&& ! samegp_function_operand (operands[0], Pmode)
|
&& ! samegp_function_operand (operands[0], Pmode)
|
&& ! (peep2_regno_dead_p (1, 29)
|
&& ! (peep2_regno_dead_p (1, 29)
|
|| find_reg_note (insn, REG_NORETURN, NULL_RTX))"
|
|| find_reg_note (insn, REG_NORETURN, NULL_RTX))"
|
[(parallel [(call (mem:DI (match_dup 2))
|
[(parallel [(call (mem:DI (match_dup 2))
|
(match_dup 1))
|
(match_dup 1))
|
(set (match_dup 5)
|
(set (match_dup 5)
|
(unspec:DI [(match_dup 5) (match_dup 3)] UNSPEC_LDGP1))
|
(unspec:DI [(match_dup 5) (match_dup 3)] UNSPEC_LDGP1))
|
(use (match_dup 0))
|
(use (match_dup 0))
|
(use (match_dup 4))
|
(use (match_dup 4))
|
(clobber (reg:DI 26))])
|
(clobber (reg:DI 26))])
|
(set (match_dup 5)
|
(set (match_dup 5)
|
(unspec:DI [(match_dup 5) (match_dup 3)] UNSPEC_LDGP2))]
|
(unspec:DI [(match_dup 5) (match_dup 3)] UNSPEC_LDGP2))]
|
{
|
{
|
if (CONSTANT_P (operands[0]))
|
if (CONSTANT_P (operands[0]))
|
{
|
{
|
operands[2] = gen_rtx_REG (Pmode, 27);
|
operands[2] = gen_rtx_REG (Pmode, 27);
|
operands[4] = GEN_INT (alpha_next_sequence_number++);
|
operands[4] = GEN_INT (alpha_next_sequence_number++);
|
emit_insn (gen_movdi_er_high_g (operands[2], pic_offset_table_rtx,
|
emit_insn (gen_movdi_er_high_g (operands[2], pic_offset_table_rtx,
|
operands[0], operands[4]));
|
operands[0], operands[4]));
|
}
|
}
|
else
|
else
|
{
|
{
|
operands[2] = operands[0];
|
operands[2] = operands[0];
|
operands[0] = const0_rtx;
|
operands[0] = const0_rtx;
|
operands[4] = const0_rtx;
|
operands[4] = const0_rtx;
|
}
|
}
|
operands[3] = GEN_INT (alpha_next_sequence_number++);
|
operands[3] = GEN_INT (alpha_next_sequence_number++);
|
operands[5] = pic_offset_table_rtx;
|
operands[5] = pic_offset_table_rtx;
|
})
|
})
|
|
|
(define_insn "*call_osf_2_er_nogp"
|
(define_insn "*call_osf_2_er_nogp"
|
[(call (mem:DI (match_operand:DI 0 "register_operand" "c"))
|
[(call (mem:DI (match_operand:DI 0 "register_operand" "c"))
|
(match_operand 1 "" ""))
|
(match_operand 1 "" ""))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(use (match_operand 2 "" ""))
|
(use (match_operand 2 "" ""))
|
(use (match_operand 3 "const_int_operand" ""))
|
(use (match_operand 3 "const_int_operand" ""))
|
(clobber (reg:DI 26))]
|
(clobber (reg:DI 26))]
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
"jsr $26,(%0),%2%J3"
|
"jsr $26,(%0),%2%J3"
|
[(set_attr "type" "jsr")])
|
[(set_attr "type" "jsr")])
|
|
|
(define_insn "*call_osf_2_er"
|
(define_insn "*call_osf_2_er"
|
[(call (mem:DI (match_operand:DI 0 "register_operand" "c"))
|
[(call (mem:DI (match_operand:DI 0 "register_operand" "c"))
|
(match_operand 1 "" ""))
|
(match_operand 1 "" ""))
|
(set (reg:DI 29)
|
(set (reg:DI 29)
|
(unspec:DI [(reg:DI 29) (match_operand 4 "const_int_operand" "")]
|
(unspec:DI [(reg:DI 29) (match_operand 4 "const_int_operand" "")]
|
UNSPEC_LDGP1))
|
UNSPEC_LDGP1))
|
(use (match_operand 2 "" ""))
|
(use (match_operand 2 "" ""))
|
(use (match_operand 3 "const_int_operand" ""))
|
(use (match_operand 3 "const_int_operand" ""))
|
(clobber (reg:DI 26))]
|
(clobber (reg:DI 26))]
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
"jsr $26,(%0),%2%J3\;ldah $29,0($26)\t\t!gpdisp!%4"
|
"jsr $26,(%0),%2%J3\;ldah $29,0($26)\t\t!gpdisp!%4"
|
[(set_attr "type" "jsr")
|
[(set_attr "type" "jsr")
|
(set_attr "cannot_copy" "true")
|
(set_attr "cannot_copy" "true")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn "*call_osf_1_noreturn"
|
(define_insn "*call_osf_1_noreturn"
|
[(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
|
[(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
|
(match_operand 1 "" ""))
|
(match_operand 1 "" ""))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(clobber (reg:DI 26))]
|
(clobber (reg:DI 26))]
|
"! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
|
"! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
|
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
|
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
|
"@
|
"@
|
jsr $26,($27),0
|
jsr $26,($27),0
|
bsr $26,$%0..ng
|
bsr $26,$%0..ng
|
jsr $26,%0"
|
jsr $26,%0"
|
[(set_attr "type" "jsr")
|
[(set_attr "type" "jsr")
|
(set_attr "length" "*,*,8")])
|
(set_attr "length" "*,*,8")])
|
|
|
(define_insn "*call_osf_1"
|
(define_insn "*call_osf_1"
|
[(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
|
[(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
|
(match_operand 1 "" ""))
|
(match_operand 1 "" ""))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(clobber (reg:DI 26))]
|
(clobber (reg:DI 26))]
|
"! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
"! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
"@
|
"@
|
jsr $26,($27),0\;ldgp $29,0($26)
|
jsr $26,($27),0\;ldgp $29,0($26)
|
bsr $26,$%0..ng
|
bsr $26,$%0..ng
|
jsr $26,%0\;ldgp $29,0($26)"
|
jsr $26,%0\;ldgp $29,0($26)"
|
[(set_attr "type" "jsr")
|
[(set_attr "type" "jsr")
|
(set_attr "length" "12,*,16")])
|
(set_attr "length" "12,*,16")])
|
|
|
(define_insn "*sibcall_osf_1_er"
|
(define_insn "*sibcall_osf_1_er"
|
[(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s"))
|
[(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s"))
|
(match_operand 1 "" ""))
|
(match_operand 1 "" ""))
|
(unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
|
(unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
"@
|
"@
|
br $31,%0\t\t!samegp
|
br $31,%0\t\t!samegp
|
ldq $27,%0($29)\t\t!literal!%#\;jmp $31,($27),%0\t\t!lituse_jsr!%#"
|
ldq $27,%0($29)\t\t!literal!%#\;jmp $31,($27),%0\t\t!lituse_jsr!%#"
|
[(set_attr "type" "jsr")
|
[(set_attr "type" "jsr")
|
(set_attr "length" "*,8")])
|
(set_attr "length" "*,8")])
|
|
|
;; Note that the DEC assembler expands "jmp foo" with $at, which
|
;; Note that the DEC assembler expands "jmp foo" with $at, which
|
;; doesn't do what we want.
|
;; doesn't do what we want.
|
(define_insn "*sibcall_osf_1"
|
(define_insn "*sibcall_osf_1"
|
[(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s"))
|
[(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s"))
|
(match_operand 1 "" ""))
|
(match_operand 1 "" ""))
|
(unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
|
(unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
|
"! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
"! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
"@
|
"@
|
br $31,$%0..ng
|
br $31,$%0..ng
|
lda $27,%0\;jmp $31,($27),%0"
|
lda $27,%0\;jmp $31,($27),%0"
|
[(set_attr "type" "jsr")
|
[(set_attr "type" "jsr")
|
(set_attr "length" "*,8")])
|
(set_attr "length" "*,8")])
|
|
|
(define_insn "*call_nt_1"
|
(define_insn "*call_nt_1"
|
[(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,s"))
|
[(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,s"))
|
(match_operand 1 "" ""))
|
(match_operand 1 "" ""))
|
(clobber (reg:DI 26))]
|
(clobber (reg:DI 26))]
|
"TARGET_ABI_WINDOWS_NT"
|
"TARGET_ABI_WINDOWS_NT"
|
"@
|
"@
|
jsr $26,(%0)
|
jsr $26,(%0)
|
bsr $26,%0
|
bsr $26,%0
|
jsr $26,%0"
|
jsr $26,%0"
|
[(set_attr "type" "jsr")
|
[(set_attr "type" "jsr")
|
(set_attr "length" "*,*,12")])
|
(set_attr "length" "*,*,12")])
|
|
|
; GAS relies on the order and position of instructions output below in order
|
; GAS relies on the order and position of instructions output below in order
|
; to generate relocs for VMS link to potentially optimize the call.
|
; to generate relocs for VMS link to potentially optimize the call.
|
; Please do not molest.
|
; Please do not molest.
|
(define_insn "*call_vms_1"
|
(define_insn "*call_vms_1"
|
[(call (mem:DI (match_operand:DI 0 "call_operand" "r,s"))
|
[(call (mem:DI (match_operand:DI 0 "call_operand" "r,s"))
|
(match_operand 1 "" ""))
|
(match_operand 1 "" ""))
|
(use (match_operand:DI 2 "nonmemory_operand" "r,n"))
|
(use (match_operand:DI 2 "nonmemory_operand" "r,n"))
|
(use (reg:DI 25))
|
(use (reg:DI 25))
|
(use (reg:DI 26))
|
(use (reg:DI 26))
|
(clobber (reg:DI 27))]
|
(clobber (reg:DI 27))]
|
"TARGET_ABI_OPEN_VMS"
|
"TARGET_ABI_OPEN_VMS"
|
{
|
{
|
switch (which_alternative)
|
switch (which_alternative)
|
{
|
{
|
case 0:
|
case 0:
|
return "mov %2,$27\;jsr $26,0\;ldq $27,0($29)";
|
return "mov %2,$27\;jsr $26,0\;ldq $27,0($29)";
|
case 1:
|
case 1:
|
operands [2] = alpha_use_linkage (operands [0], cfun->decl, 1, 0);
|
operands [2] = alpha_use_linkage (operands [0], cfun->decl, 1, 0);
|
operands [3] = alpha_use_linkage (operands [0], cfun->decl, 0, 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)";
|
return "ldq $26,%3\;ldq $27,%2\;jsr $26,%0\;ldq $27,0($29)";
|
default:
|
default:
|
gcc_unreachable ();
|
gcc_unreachable ();
|
}
|
}
|
}
|
}
|
[(set_attr "type" "jsr")
|
[(set_attr "type" "jsr")
|
(set_attr "length" "12,16")])
|
(set_attr "length" "12,16")])
|
|
|
(define_insn "*call_umk_1"
|
(define_insn "*call_umk_1"
|
[(call (mem:DI (match_operand:DI 0 "call_operand" "r"))
|
[(call (mem:DI (match_operand:DI 0 "call_operand" "r"))
|
(match_operand 1 "" ""))
|
(match_operand 1 "" ""))
|
(use (reg:DI 25))
|
(use (reg:DI 25))
|
(clobber (reg:DI 26))]
|
(clobber (reg:DI 26))]
|
"TARGET_ABI_UNICOSMK"
|
"TARGET_ABI_UNICOSMK"
|
"jsr $26,(%0)"
|
"jsr $26,(%0)"
|
[(set_attr "type" "jsr")])
|
[(set_attr "type" "jsr")])
|
|
|
;; Call subroutine returning any type.
|
;; Call subroutine returning any type.
|
|
|
(define_expand "untyped_call"
|
(define_expand "untyped_call"
|
[(parallel [(call (match_operand 0 "" "")
|
[(parallel [(call (match_operand 0 "" "")
|
(const_int 0))
|
(const_int 0))
|
(match_operand 1 "" "")
|
(match_operand 1 "" "")
|
(match_operand 2 "" "")])]
|
(match_operand 2 "" "")])]
|
""
|
""
|
{
|
{
|
int i;
|
int i;
|
|
|
emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
|
emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
|
|
|
for (i = 0; i < XVECLEN (operands[2], 0); i++)
|
for (i = 0; i < XVECLEN (operands[2], 0); i++)
|
{
|
{
|
rtx set = XVECEXP (operands[2], 0, i);
|
rtx set = XVECEXP (operands[2], 0, i);
|
emit_move_insn (SET_DEST (set), SET_SRC (set));
|
emit_move_insn (SET_DEST (set), SET_SRC (set));
|
}
|
}
|
|
|
/* The optimizer does not know that the call sets the function value
|
/* The optimizer does not know that the call sets the function value
|
registers we stored in the result block. We avoid problems by
|
registers we stored in the result block. We avoid problems by
|
claiming that all hard registers are used and clobbered at this
|
claiming that all hard registers are used and clobbered at this
|
point. */
|
point. */
|
emit_insn (gen_blockage ());
|
emit_insn (gen_blockage ());
|
|
|
DONE;
|
DONE;
|
})
|
})
|
|
|
;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
|
;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
|
;; all of memory. This blocks insns from being moved across this point.
|
;; all of memory. This blocks insns from being moved across this point.
|
|
|
(define_insn "blockage"
|
(define_insn "blockage"
|
[(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
|
[(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
|
""
|
""
|
""
|
""
|
[(set_attr "length" "0")
|
[(set_attr "length" "0")
|
(set_attr "type" "none")])
|
(set_attr "type" "none")])
|
|
|
(define_insn "jump"
|
(define_insn "jump"
|
[(set (pc)
|
[(set (pc)
|
(label_ref (match_operand 0 "" "")))]
|
(label_ref (match_operand 0 "" "")))]
|
""
|
""
|
"br $31,%l0"
|
"br $31,%l0"
|
[(set_attr "type" "ibr")])
|
[(set_attr "type" "ibr")])
|
|
|
(define_expand "return"
|
(define_expand "return"
|
[(return)]
|
[(return)]
|
"direct_return ()"
|
"direct_return ()"
|
"")
|
"")
|
|
|
(define_insn "*return_internal"
|
(define_insn "*return_internal"
|
[(return)]
|
[(return)]
|
"reload_completed"
|
"reload_completed"
|
"ret $31,($26),1"
|
"ret $31,($26),1"
|
[(set_attr "type" "ibr")])
|
[(set_attr "type" "ibr")])
|
|
|
(define_insn "indirect_jump"
|
(define_insn "indirect_jump"
|
[(set (pc) (match_operand:DI 0 "register_operand" "r"))]
|
[(set (pc) (match_operand:DI 0 "register_operand" "r"))]
|
""
|
""
|
"jmp $31,(%0),0"
|
"jmp $31,(%0),0"
|
[(set_attr "type" "ibr")])
|
[(set_attr "type" "ibr")])
|
|
|
(define_expand "tablejump"
|
(define_expand "tablejump"
|
[(parallel [(set (pc)
|
[(parallel [(set (pc)
|
(match_operand 0 "register_operand" ""))
|
(match_operand 0 "register_operand" ""))
|
(use (label_ref:DI (match_operand 1 "" "")))])]
|
(use (label_ref:DI (match_operand 1 "" "")))])]
|
""
|
""
|
{
|
{
|
if (TARGET_ABI_WINDOWS_NT)
|
if (TARGET_ABI_WINDOWS_NT)
|
{
|
{
|
rtx dest = gen_reg_rtx (DImode);
|
rtx dest = gen_reg_rtx (DImode);
|
emit_insn (gen_extendsidi2 (dest, operands[0]));
|
emit_insn (gen_extendsidi2 (dest, operands[0]));
|
operands[0] = dest;
|
operands[0] = dest;
|
}
|
}
|
else if (TARGET_ABI_OSF)
|
else if (TARGET_ABI_OSF)
|
{
|
{
|
rtx dest = gen_reg_rtx (DImode);
|
rtx dest = gen_reg_rtx (DImode);
|
emit_insn (gen_extendsidi2 (dest, operands[0]));
|
emit_insn (gen_extendsidi2 (dest, operands[0]));
|
emit_insn (gen_adddi3 (dest, pic_offset_table_rtx, dest));
|
emit_insn (gen_adddi3 (dest, pic_offset_table_rtx, dest));
|
operands[0] = dest;
|
operands[0] = dest;
|
}
|
}
|
})
|
})
|
|
|
(define_insn "*tablejump_osf_nt_internal"
|
(define_insn "*tablejump_osf_nt_internal"
|
[(set (pc)
|
[(set (pc)
|
(match_operand:DI 0 "register_operand" "r"))
|
(match_operand:DI 0 "register_operand" "r"))
|
(use (label_ref:DI (match_operand 1 "" "")))]
|
(use (label_ref:DI (match_operand 1 "" "")))]
|
"(TARGET_ABI_OSF || TARGET_ABI_WINDOWS_NT)
|
"(TARGET_ABI_OSF || TARGET_ABI_WINDOWS_NT)
|
&& alpha_tablejump_addr_vec (insn)"
|
&& alpha_tablejump_addr_vec (insn)"
|
{
|
{
|
operands[2] = alpha_tablejump_best_label (insn);
|
operands[2] = alpha_tablejump_best_label (insn);
|
return "jmp $31,(%0),%2";
|
return "jmp $31,(%0),%2";
|
}
|
}
|
[(set_attr "type" "ibr")])
|
[(set_attr "type" "ibr")])
|
|
|
(define_insn "*tablejump_internal"
|
(define_insn "*tablejump_internal"
|
[(set (pc)
|
[(set (pc)
|
(match_operand:DI 0 "register_operand" "r"))
|
(match_operand:DI 0 "register_operand" "r"))
|
(use (label_ref (match_operand 1 "" "")))]
|
(use (label_ref (match_operand 1 "" "")))]
|
""
|
""
|
"jmp $31,(%0),0"
|
"jmp $31,(%0),0"
|
[(set_attr "type" "ibr")])
|
[(set_attr "type" "ibr")])
|
|
|
;; Cache flush. Used by alpha_trampoline_init. 0x86 is PAL_imb, but we don't
|
;; Cache flush. Used by alpha_trampoline_init. 0x86 is PAL_imb, but we don't
|
;; want to have to include pal.h in our .s file.
|
;; want to have to include pal.h in our .s file.
|
(define_insn "imb"
|
(define_insn "imb"
|
[(unspec_volatile [(const_int 0)] UNSPECV_IMB)]
|
[(unspec_volatile [(const_int 0)] UNSPECV_IMB)]
|
""
|
""
|
"call_pal 0x86"
|
"call_pal 0x86"
|
[(set_attr "type" "callpal")])
|
[(set_attr "type" "callpal")])
|
|
|
;; BUGCHK is documented common to OSF/1 and VMS PALcode.
|
;; BUGCHK is documented common to OSF/1 and VMS PALcode.
|
;; NT does not document anything at 0x81 -- presumably it would generate
|
;; NT does not document anything at 0x81 -- presumably it would generate
|
;; the equivalent of SIGILL, but this isn't that important.
|
;; the equivalent of SIGILL, but this isn't that important.
|
;; ??? Presuming unicosmk uses either OSF/1 or VMS PALcode.
|
;; ??? Presuming unicosmk uses either OSF/1 or VMS PALcode.
|
(define_insn "trap"
|
(define_insn "trap"
|
[(trap_if (const_int 1) (const_int 0))]
|
[(trap_if (const_int 1) (const_int 0))]
|
"!TARGET_ABI_WINDOWS_NT"
|
"!TARGET_ABI_WINDOWS_NT"
|
"call_pal 0x81"
|
"call_pal 0x81"
|
[(set_attr "type" "callpal")])
|
[(set_attr "type" "callpal")])
|
|
|
;; For userland, we load the thread pointer from the TCB.
|
;; For userland, we load the thread pointer from the TCB.
|
;; For the kernel, we load the per-cpu private value.
|
;; For the kernel, we load the per-cpu private value.
|
|
|
(define_insn "load_tp"
|
(define_insn "load_tp"
|
[(set (match_operand:DI 0 "register_operand" "=v")
|
[(set (match_operand:DI 0 "register_operand" "=v")
|
(unspec:DI [(const_int 0)] UNSPEC_TP))]
|
(unspec:DI [(const_int 0)] UNSPEC_TP))]
|
"TARGET_ABI_OSF"
|
"TARGET_ABI_OSF"
|
{
|
{
|
if (TARGET_TLS_KERNEL)
|
if (TARGET_TLS_KERNEL)
|
return "call_pal 0x32";
|
return "call_pal 0x32";
|
else
|
else
|
return "call_pal 0x9e";
|
return "call_pal 0x9e";
|
}
|
}
|
[(set_attr "type" "callpal")])
|
[(set_attr "type" "callpal")])
|
|
|
;; For completeness, and possibly a __builtin function, here's how to
|
;; For completeness, and possibly a __builtin function, here's how to
|
;; set the thread pointer. Since we don't describe enough of this
|
;; 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
|
;; quantity for CSE, we have to use a volatile unspec, and then there's
|
;; not much point in creating an R16_REG register class.
|
;; not much point in creating an R16_REG register class.
|
|
|
(define_expand "set_tp"
|
(define_expand "set_tp"
|
[(set (reg:DI 16) (match_operand:DI 0 "input_operand" ""))
|
[(set (reg:DI 16) (match_operand:DI 0 "input_operand" ""))
|
(unspec_volatile [(reg:DI 16)] UNSPECV_SET_TP)]
|
(unspec_volatile [(reg:DI 16)] UNSPECV_SET_TP)]
|
"TARGET_ABI_OSF"
|
"TARGET_ABI_OSF"
|
"")
|
"")
|
|
|
(define_insn "*set_tp"
|
(define_insn "*set_tp"
|
[(unspec_volatile [(reg:DI 16)] UNSPECV_SET_TP)]
|
[(unspec_volatile [(reg:DI 16)] UNSPECV_SET_TP)]
|
"TARGET_ABI_OSF"
|
"TARGET_ABI_OSF"
|
{
|
{
|
if (TARGET_TLS_KERNEL)
|
if (TARGET_TLS_KERNEL)
|
return "call_pal 0x31";
|
return "call_pal 0x31";
|
else
|
else
|
return "call_pal 0x9f";
|
return "call_pal 0x9f";
|
}
|
}
|
[(set_attr "type" "callpal")])
|
[(set_attr "type" "callpal")])
|
|
|
;; Special builtins for establishing and reverting VMS condition handlers.
|
;; Special builtins for establishing and reverting VMS condition handlers.
|
|
|
(define_expand "builtin_establish_vms_condition_handler"
|
(define_expand "builtin_establish_vms_condition_handler"
|
[(set (reg:DI 0) (match_operand:DI 0 "register_operand" ""))
|
[(set (reg:DI 0) (match_operand:DI 0 "register_operand" ""))
|
(use (match_operand:DI 1 "address_operand" ""))]
|
(use (match_operand:DI 1 "address_operand" ""))]
|
"TARGET_ABI_OPEN_VMS"
|
"TARGET_ABI_OPEN_VMS"
|
{
|
{
|
alpha_expand_builtin_establish_vms_condition_handler (operands[0],
|
alpha_expand_builtin_establish_vms_condition_handler (operands[0],
|
operands[1]);
|
operands[1]);
|
})
|
})
|
|
|
(define_expand "builtin_revert_vms_condition_handler"
|
(define_expand "builtin_revert_vms_condition_handler"
|
[(set (reg:DI 0) (match_operand:DI 0 "register_operand" ""))]
|
[(set (reg:DI 0) (match_operand:DI 0 "register_operand" ""))]
|
"TARGET_ABI_OPEN_VMS"
|
"TARGET_ABI_OPEN_VMS"
|
{
|
{
|
alpha_expand_builtin_revert_vms_condition_handler (operands[0]);
|
alpha_expand_builtin_revert_vms_condition_handler (operands[0]);
|
})
|
})
|
|
|
;; Finally, we have the basic data motion insns. The byte and word insns
|
;; 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
|
;; are done via define_expand. Start with the floating-point insns, since
|
;; they are simpler.
|
;; they are simpler.
|
|
|
(define_insn "*movsf_nofix"
|
(define_insn "*movsf_nofix"
|
[(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m")
|
[(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m")
|
(match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r"))]
|
(match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r"))]
|
"TARGET_FPREGS && ! TARGET_FIX
|
"TARGET_FPREGS && ! TARGET_FIX
|
&& (register_operand (operands[0], SFmode)
|
&& (register_operand (operands[0], SFmode)
|
|| reg_or_0_operand (operands[1], SFmode))"
|
|| reg_or_0_operand (operands[1], SFmode))"
|
"@
|
"@
|
cpys %R1,%R1,%0
|
cpys %R1,%R1,%0
|
ld%, %0,%1
|
ld%, %0,%1
|
bis $31,%r1,%0
|
bis $31,%r1,%0
|
ldl %0,%1
|
ldl %0,%1
|
st%, %R1,%0
|
st%, %R1,%0
|
stl %r1,%0"
|
stl %r1,%0"
|
[(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")])
|
[(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")])
|
|
|
(define_insn "*movsf_fix"
|
(define_insn "*movsf_fix"
|
[(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r")
|
[(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r")
|
(match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
|
(match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
|
"TARGET_FPREGS && TARGET_FIX
|
"TARGET_FPREGS && TARGET_FIX
|
&& (register_operand (operands[0], SFmode)
|
&& (register_operand (operands[0], SFmode)
|
|| reg_or_0_operand (operands[1], SFmode))"
|
|| reg_or_0_operand (operands[1], SFmode))"
|
"@
|
"@
|
cpys %R1,%R1,%0
|
cpys %R1,%R1,%0
|
ld%, %0,%1
|
ld%, %0,%1
|
bis $31,%r1,%0
|
bis $31,%r1,%0
|
ldl %0,%1
|
ldl %0,%1
|
st%, %R1,%0
|
st%, %R1,%0
|
stl %r1,%0
|
stl %r1,%0
|
itofs %1,%0
|
itofs %1,%0
|
ftois %1,%0"
|
ftois %1,%0"
|
[(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")])
|
[(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")])
|
|
|
(define_insn "*movsf_nofp"
|
(define_insn "*movsf_nofp"
|
[(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
|
[(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
|
(match_operand:SF 1 "input_operand" "rG,m,r"))]
|
(match_operand:SF 1 "input_operand" "rG,m,r"))]
|
"! TARGET_FPREGS
|
"! TARGET_FPREGS
|
&& (register_operand (operands[0], SFmode)
|
&& (register_operand (operands[0], SFmode)
|
|| reg_or_0_operand (operands[1], SFmode))"
|
|| reg_or_0_operand (operands[1], SFmode))"
|
"@
|
"@
|
bis $31,%r1,%0
|
bis $31,%r1,%0
|
ldl %0,%1
|
ldl %0,%1
|
stl %r1,%0"
|
stl %r1,%0"
|
[(set_attr "type" "ilog,ild,ist")])
|
[(set_attr "type" "ilog,ild,ist")])
|
|
|
(define_insn "*movdf_nofix"
|
(define_insn "*movdf_nofix"
|
[(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m")
|
[(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m")
|
(match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r"))]
|
(match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r"))]
|
"TARGET_FPREGS && ! TARGET_FIX
|
"TARGET_FPREGS && ! TARGET_FIX
|
&& (register_operand (operands[0], DFmode)
|
&& (register_operand (operands[0], DFmode)
|
|| reg_or_0_operand (operands[1], DFmode))"
|
|| reg_or_0_operand (operands[1], DFmode))"
|
"@
|
"@
|
cpys %R1,%R1,%0
|
cpys %R1,%R1,%0
|
ld%- %0,%1
|
ld%- %0,%1
|
bis $31,%r1,%0
|
bis $31,%r1,%0
|
ldq %0,%1
|
ldq %0,%1
|
st%- %R1,%0
|
st%- %R1,%0
|
stq %r1,%0"
|
stq %r1,%0"
|
[(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")])
|
[(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")])
|
|
|
(define_insn "*movdf_fix"
|
(define_insn "*movdf_fix"
|
[(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r")
|
[(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r")
|
(match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
|
(match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
|
"TARGET_FPREGS && TARGET_FIX
|
"TARGET_FPREGS && TARGET_FIX
|
&& (register_operand (operands[0], DFmode)
|
&& (register_operand (operands[0], DFmode)
|
|| reg_or_0_operand (operands[1], DFmode))"
|
|| reg_or_0_operand (operands[1], DFmode))"
|
"@
|
"@
|
cpys %R1,%R1,%0
|
cpys %R1,%R1,%0
|
ld%- %0,%1
|
ld%- %0,%1
|
bis $31,%r1,%0
|
bis $31,%r1,%0
|
ldq %0,%1
|
ldq %0,%1
|
st%- %R1,%0
|
st%- %R1,%0
|
stq %r1,%0
|
stq %r1,%0
|
itoft %1,%0
|
itoft %1,%0
|
ftoit %1,%0"
|
ftoit %1,%0"
|
[(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")])
|
[(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")])
|
|
|
(define_insn "*movdf_nofp"
|
(define_insn "*movdf_nofp"
|
[(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
|
[(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
|
(match_operand:DF 1 "input_operand" "rG,m,r"))]
|
(match_operand:DF 1 "input_operand" "rG,m,r"))]
|
"! TARGET_FPREGS
|
"! TARGET_FPREGS
|
&& (register_operand (operands[0], DFmode)
|
&& (register_operand (operands[0], DFmode)
|
|| reg_or_0_operand (operands[1], DFmode))"
|
|| reg_or_0_operand (operands[1], DFmode))"
|
"@
|
"@
|
bis $31,%r1,%0
|
bis $31,%r1,%0
|
ldq %0,%1
|
ldq %0,%1
|
stq %r1,%0"
|
stq %r1,%0"
|
[(set_attr "type" "ilog,ild,ist")])
|
[(set_attr "type" "ilog,ild,ist")])
|
|
|
;; Subregs suck for register allocation. Pretend we can move TFmode
|
;; Subregs suck for register allocation. Pretend we can move TFmode
|
;; data between general registers until after reload.
|
;; data between general registers until after reload.
|
|
|
(define_insn_and_split "*movtf_internal"
|
(define_insn_and_split "*movtf_internal"
|
[(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
|
[(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
|
(match_operand:TF 1 "input_operand" "roG,rG"))]
|
(match_operand:TF 1 "input_operand" "roG,rG"))]
|
"register_operand (operands[0], TFmode)
|
"register_operand (operands[0], TFmode)
|
|| reg_or_0_operand (operands[1], TFmode)"
|
|| reg_or_0_operand (operands[1], TFmode)"
|
"#"
|
"#"
|
"reload_completed"
|
"reload_completed"
|
[(set (match_dup 0) (match_dup 2))
|
[(set (match_dup 0) (match_dup 2))
|
(set (match_dup 1) (match_dup 3))]
|
(set (match_dup 1) (match_dup 3))]
|
{
|
{
|
alpha_split_tmode_pair (operands, TFmode, true);
|
alpha_split_tmode_pair (operands, TFmode, true);
|
})
|
})
|
|
|
(define_expand "movsf"
|
(define_expand "movsf"
|
[(set (match_operand:SF 0 "nonimmediate_operand" "")
|
[(set (match_operand:SF 0 "nonimmediate_operand" "")
|
(match_operand:SF 1 "general_operand" ""))]
|
(match_operand:SF 1 "general_operand" ""))]
|
""
|
""
|
{
|
{
|
if (MEM_P (operands[0])
|
if (MEM_P (operands[0])
|
&& ! reg_or_0_operand (operands[1], SFmode))
|
&& ! reg_or_0_operand (operands[1], SFmode))
|
operands[1] = force_reg (SFmode, operands[1]);
|
operands[1] = force_reg (SFmode, operands[1]);
|
})
|
})
|
|
|
(define_expand "movdf"
|
(define_expand "movdf"
|
[(set (match_operand:DF 0 "nonimmediate_operand" "")
|
[(set (match_operand:DF 0 "nonimmediate_operand" "")
|
(match_operand:DF 1 "general_operand" ""))]
|
(match_operand:DF 1 "general_operand" ""))]
|
""
|
""
|
{
|
{
|
if (MEM_P (operands[0])
|
if (MEM_P (operands[0])
|
&& ! reg_or_0_operand (operands[1], DFmode))
|
&& ! reg_or_0_operand (operands[1], DFmode))
|
operands[1] = force_reg (DFmode, operands[1]);
|
operands[1] = force_reg (DFmode, operands[1]);
|
})
|
})
|
|
|
(define_expand "movtf"
|
(define_expand "movtf"
|
[(set (match_operand:TF 0 "nonimmediate_operand" "")
|
[(set (match_operand:TF 0 "nonimmediate_operand" "")
|
(match_operand:TF 1 "general_operand" ""))]
|
(match_operand:TF 1 "general_operand" ""))]
|
""
|
""
|
{
|
{
|
if (MEM_P (operands[0])
|
if (MEM_P (operands[0])
|
&& ! reg_or_0_operand (operands[1], TFmode))
|
&& ! reg_or_0_operand (operands[1], TFmode))
|
operands[1] = force_reg (TFmode, operands[1]);
|
operands[1] = force_reg (TFmode, operands[1]);
|
})
|
})
|
|
|
(define_insn "*movsi"
|
(define_insn "*movsi"
|
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m")
|
[(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"))]
|
(match_operand:SI 1 "input_operand" "rJ,K,L,n,m,rJ"))]
|
"(TARGET_ABI_OSF || TARGET_ABI_UNICOSMK)
|
"(TARGET_ABI_OSF || TARGET_ABI_UNICOSMK)
|
&& (register_operand (operands[0], SImode)
|
&& (register_operand (operands[0], SImode)
|
|| reg_or_0_operand (operands[1], SImode))"
|
|| reg_or_0_operand (operands[1], SImode))"
|
"@
|
"@
|
bis $31,%r1,%0
|
bis $31,%r1,%0
|
lda %0,%1($31)
|
lda %0,%1($31)
|
ldah %0,%h1($31)
|
ldah %0,%h1($31)
|
#
|
#
|
ldl %0,%1
|
ldl %0,%1
|
stl %r1,%0"
|
stl %r1,%0"
|
[(set_attr "type" "ilog,iadd,iadd,multi,ild,ist")])
|
[(set_attr "type" "ilog,iadd,iadd,multi,ild,ist")])
|
|
|
(define_insn "*movsi_nt_vms"
|
(define_insn "*movsi_nt_vms"
|
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m")
|
[(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"))]
|
(match_operand:SI 1 "input_operand" "rJ,K,L,s,n,m,rJ"))]
|
"(TARGET_ABI_WINDOWS_NT || TARGET_ABI_OPEN_VMS)
|
"(TARGET_ABI_WINDOWS_NT || TARGET_ABI_OPEN_VMS)
|
&& (register_operand (operands[0], SImode)
|
&& (register_operand (operands[0], SImode)
|
|| reg_or_0_operand (operands[1], SImode))"
|
|| reg_or_0_operand (operands[1], SImode))"
|
"@
|
"@
|
bis $31,%1,%0
|
bis $31,%1,%0
|
lda %0,%1
|
lda %0,%1
|
ldah %0,%h1
|
ldah %0,%h1
|
lda %0,%1
|
lda %0,%1
|
#
|
#
|
ldl %0,%1
|
ldl %0,%1
|
stl %r1,%0"
|
stl %r1,%0"
|
[(set_attr "type" "ilog,iadd,iadd,ldsym,multi,ild,ist")])
|
[(set_attr "type" "ilog,iadd,iadd,ldsym,multi,ild,ist")])
|
|
|
(define_insn "*movhi_nobwx"
|
(define_insn "*movhi_nobwx"
|
[(set (match_operand:HI 0 "register_operand" "=r,r")
|
[(set (match_operand:HI 0 "register_operand" "=r,r")
|
(match_operand:HI 1 "input_operand" "rJ,n"))]
|
(match_operand:HI 1 "input_operand" "rJ,n"))]
|
"! TARGET_BWX
|
"! TARGET_BWX
|
&& (register_operand (operands[0], HImode)
|
&& (register_operand (operands[0], HImode)
|
|| register_operand (operands[1], HImode))"
|
|| register_operand (operands[1], HImode))"
|
"@
|
"@
|
bis $31,%r1,%0
|
bis $31,%r1,%0
|
lda %0,%L1($31)"
|
lda %0,%L1($31)"
|
[(set_attr "type" "ilog,iadd")])
|
[(set_attr "type" "ilog,iadd")])
|
|
|
(define_insn "*movhi_bwx"
|
(define_insn "*movhi_bwx"
|
[(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
|
[(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
|
(match_operand:HI 1 "input_operand" "rJ,n,m,rJ"))]
|
(match_operand:HI 1 "input_operand" "rJ,n,m,rJ"))]
|
"TARGET_BWX
|
"TARGET_BWX
|
&& (register_operand (operands[0], HImode)
|
&& (register_operand (operands[0], HImode)
|
|| reg_or_0_operand (operands[1], HImode))"
|
|| reg_or_0_operand (operands[1], HImode))"
|
"@
|
"@
|
bis $31,%r1,%0
|
bis $31,%r1,%0
|
lda %0,%L1($31)
|
lda %0,%L1($31)
|
ldwu %0,%1
|
ldwu %0,%1
|
stw %r1,%0"
|
stw %r1,%0"
|
[(set_attr "type" "ilog,iadd,ild,ist")])
|
[(set_attr "type" "ilog,iadd,ild,ist")])
|
|
|
(define_insn "*movqi_nobwx"
|
(define_insn "*movqi_nobwx"
|
[(set (match_operand:QI 0 "register_operand" "=r,r")
|
[(set (match_operand:QI 0 "register_operand" "=r,r")
|
(match_operand:QI 1 "input_operand" "rJ,n"))]
|
(match_operand:QI 1 "input_operand" "rJ,n"))]
|
"! TARGET_BWX
|
"! TARGET_BWX
|
&& (register_operand (operands[0], QImode)
|
&& (register_operand (operands[0], QImode)
|
|| register_operand (operands[1], QImode))"
|
|| register_operand (operands[1], QImode))"
|
"@
|
"@
|
bis $31,%r1,%0
|
bis $31,%r1,%0
|
lda %0,%L1($31)"
|
lda %0,%L1($31)"
|
[(set_attr "type" "ilog,iadd")])
|
[(set_attr "type" "ilog,iadd")])
|
|
|
(define_insn "*movqi_bwx"
|
(define_insn "*movqi_bwx"
|
[(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m")
|
[(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m")
|
(match_operand:QI 1 "input_operand" "rJ,n,m,rJ"))]
|
(match_operand:QI 1 "input_operand" "rJ,n,m,rJ"))]
|
"TARGET_BWX
|
"TARGET_BWX
|
&& (register_operand (operands[0], QImode)
|
&& (register_operand (operands[0], QImode)
|
|| reg_or_0_operand (operands[1], QImode))"
|
|| reg_or_0_operand (operands[1], QImode))"
|
"@
|
"@
|
bis $31,%r1,%0
|
bis $31,%r1,%0
|
lda %0,%L1($31)
|
lda %0,%L1($31)
|
ldbu %0,%1
|
ldbu %0,%1
|
stb %r1,%0"
|
stb %r1,%0"
|
[(set_attr "type" "ilog,iadd,ild,ist")])
|
[(set_attr "type" "ilog,iadd,ild,ist")])
|
|
|
;; We do two major things here: handle mem->mem and construct long
|
;; We do two major things here: handle mem->mem and construct long
|
;; constants.
|
;; constants.
|
|
|
(define_expand "movsi"
|
(define_expand "movsi"
|
[(set (match_operand:SI 0 "nonimmediate_operand" "")
|
[(set (match_operand:SI 0 "nonimmediate_operand" "")
|
(match_operand:SI 1 "general_operand" ""))]
|
(match_operand:SI 1 "general_operand" ""))]
|
""
|
""
|
{
|
{
|
if (alpha_expand_mov (SImode, operands))
|
if (alpha_expand_mov (SImode, operands))
|
DONE;
|
DONE;
|
})
|
})
|
|
|
;; Split a load of a large constant into the appropriate two-insn
|
;; Split a load of a large constant into the appropriate two-insn
|
;; sequence.
|
;; sequence.
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:SI 0 "register_operand" "")
|
[(set (match_operand:SI 0 "register_operand" "")
|
(match_operand:SI 1 "non_add_const_operand" ""))]
|
(match_operand:SI 1 "non_add_const_operand" ""))]
|
""
|
""
|
[(const_int 0)]
|
[(const_int 0)]
|
{
|
{
|
if (alpha_split_const_mov (SImode, operands))
|
if (alpha_split_const_mov (SImode, operands))
|
DONE;
|
DONE;
|
else
|
else
|
FAIL;
|
FAIL;
|
})
|
})
|
|
|
;; Split the load of an address into a four-insn sequence on Unicos/Mk.
|
;; 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
|
;; Always generate a REG_EQUAL note for the last instruction to facilitate
|
;; optimizations. If the symbolic operand is a label_ref, generate
|
;; optimizations. If the symbolic operand is a label_ref, generate
|
;; REG_LABEL_OPERAND notes and update LABEL_NUSES because this is not done
|
;; 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.
|
;; automatically. Labels may be incorrectly deleted if we don't do this.
|
;;
|
;;
|
;; Describing what the individual instructions do correctly is too complicated
|
;; Describing what the individual instructions do correctly is too complicated
|
;; so use UNSPECs for each of the three parts of an address.
|
;; so use UNSPECs for each of the three parts of an address.
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "symbolic_operand" ""))]
|
(match_operand:DI 1 "symbolic_operand" ""))]
|
"TARGET_ABI_UNICOSMK && reload_completed"
|
"TARGET_ABI_UNICOSMK && reload_completed"
|
[(const_int 0)]
|
[(const_int 0)]
|
{
|
{
|
rtx insn1, insn2, insn3;
|
rtx insn1, insn2, insn3;
|
|
|
insn1 = emit_insn (gen_umk_laum (operands[0], operands[1]));
|
insn1 = emit_insn (gen_umk_laum (operands[0], operands[1]));
|
emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
|
emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
|
insn2 = emit_insn (gen_umk_lalm (operands[0], operands[0], operands[1]));
|
insn2 = emit_insn (gen_umk_lalm (operands[0], operands[0], operands[1]));
|
insn3 = emit_insn (gen_umk_lal (operands[0], operands[0], operands[1]));
|
insn3 = emit_insn (gen_umk_lal (operands[0], operands[0], operands[1]));
|
set_unique_reg_note (insn3, REG_EQUAL, operands[1]);
|
set_unique_reg_note (insn3, REG_EQUAL, operands[1]);
|
|
|
if (GET_CODE (operands[1]) == LABEL_REF)
|
if (GET_CODE (operands[1]) == LABEL_REF)
|
{
|
{
|
rtx label;
|
rtx label;
|
|
|
label = XEXP (operands[1], 0);
|
label = XEXP (operands[1], 0);
|
add_reg_note (insn1, REG_LABEL_OPERAND, label);
|
add_reg_note (insn1, REG_LABEL_OPERAND, label);
|
add_reg_note (insn2, REG_LABEL_OPERAND, label);
|
add_reg_note (insn2, REG_LABEL_OPERAND, label);
|
add_reg_note (insn3, REG_LABEL_OPERAND, label);
|
add_reg_note (insn3, REG_LABEL_OPERAND, label);
|
LABEL_NUSES (label) += 3;
|
LABEL_NUSES (label) += 3;
|
}
|
}
|
DONE;
|
DONE;
|
})
|
})
|
|
|
;; Instructions for loading the three parts of an address on Unicos/Mk.
|
;; Instructions for loading the three parts of an address on Unicos/Mk.
|
|
|
(define_insn "umk_laum"
|
(define_insn "umk_laum"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
|
(unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
|
UNSPEC_UMK_LAUM))]
|
UNSPEC_UMK_LAUM))]
|
"TARGET_ABI_UNICOSMK"
|
"TARGET_ABI_UNICOSMK"
|
"laum %r0,%t1($31)"
|
"laum %r0,%t1($31)"
|
[(set_attr "type" "iadd")])
|
[(set_attr "type" "iadd")])
|
|
|
(define_insn "umk_lalm"
|
(define_insn "umk_lalm"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(plus:DI (match_operand:DI 1 "register_operand" "r")
|
(plus:DI (match_operand:DI 1 "register_operand" "r")
|
(unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
|
(unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
|
UNSPEC_UMK_LALM)))]
|
UNSPEC_UMK_LALM)))]
|
"TARGET_ABI_UNICOSMK"
|
"TARGET_ABI_UNICOSMK"
|
"lalm %r0,%t2(%r1)"
|
"lalm %r0,%t2(%r1)"
|
[(set_attr "type" "iadd")])
|
[(set_attr "type" "iadd")])
|
|
|
(define_insn "umk_lal"
|
(define_insn "umk_lal"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(plus:DI (match_operand:DI 1 "register_operand" "r")
|
(plus:DI (match_operand:DI 1 "register_operand" "r")
|
(unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
|
(unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
|
UNSPEC_UMK_LAL)))]
|
UNSPEC_UMK_LAL)))]
|
"TARGET_ABI_UNICOSMK"
|
"TARGET_ABI_UNICOSMK"
|
"lal %r0,%t2(%r1)"
|
"lal %r0,%t2(%r1)"
|
[(set_attr "type" "iadd")])
|
[(set_attr "type" "iadd")])
|
|
|
;; Add a new call information word to the current function's list of CIWs
|
;; Add a new call information word to the current function's list of CIWs
|
;; and load its index into $25. Doing it here ensures that the CIW will be
|
;; and load its index into $25. Doing it here ensures that the CIW will be
|
;; associated with the correct function even in the presence of inlining.
|
;; associated with the correct function even in the presence of inlining.
|
|
|
(define_insn "*umk_load_ciw"
|
(define_insn "*umk_load_ciw"
|
[(set (reg:DI 25)
|
[(set (reg:DI 25)
|
(unspec:DI [(match_operand 0 "" "")] UNSPEC_UMK_LOAD_CIW))]
|
(unspec:DI [(match_operand 0 "" "")] UNSPEC_UMK_LOAD_CIW))]
|
"TARGET_ABI_UNICOSMK"
|
"TARGET_ABI_UNICOSMK"
|
{
|
{
|
operands[0] = unicosmk_add_call_info_word (operands[0]);
|
operands[0] = unicosmk_add_call_info_word (operands[0]);
|
return "lda $25,%0";
|
return "lda $25,%0";
|
}
|
}
|
[(set_attr "type" "iadd")])
|
[(set_attr "type" "iadd")])
|
|
|
(define_insn "*movdi_er_low_l"
|
(define_insn "*movdi_er_low_l"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
|
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
|
(match_operand:DI 2 "local_symbolic_operand" "")))]
|
(match_operand:DI 2 "local_symbolic_operand" "")))]
|
"TARGET_EXPLICIT_RELOCS"
|
"TARGET_EXPLICIT_RELOCS"
|
{
|
{
|
if (true_regnum (operands[1]) == 29)
|
if (true_regnum (operands[1]) == 29)
|
return "lda %0,%2(%1)\t\t!gprel";
|
return "lda %0,%2(%1)\t\t!gprel";
|
else
|
else
|
return "lda %0,%2(%1)\t\t!gprellow";
|
return "lda %0,%2(%1)\t\t!gprellow";
|
}
|
}
|
[(set_attr "usegp" "yes")])
|
[(set_attr "usegp" "yes")])
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "small_symbolic_operand" ""))]
|
(match_operand:DI 1 "small_symbolic_operand" ""))]
|
"TARGET_EXPLICIT_RELOCS && reload_completed"
|
"TARGET_EXPLICIT_RELOCS && reload_completed"
|
[(set (match_dup 0)
|
[(set (match_dup 0)
|
(lo_sum:DI (match_dup 2) (match_dup 1)))]
|
(lo_sum:DI (match_dup 2) (match_dup 1)))]
|
"operands[2] = pic_offset_table_rtx;")
|
"operands[2] = pic_offset_table_rtx;")
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "local_symbolic_operand" ""))]
|
(match_operand:DI 1 "local_symbolic_operand" ""))]
|
"TARGET_EXPLICIT_RELOCS && reload_completed"
|
"TARGET_EXPLICIT_RELOCS && reload_completed"
|
[(set (match_dup 0)
|
[(set (match_dup 0)
|
(plus:DI (match_dup 2) (high:DI (match_dup 1))))
|
(plus:DI (match_dup 2) (high:DI (match_dup 1))))
|
(set (match_dup 0)
|
(set (match_dup 0)
|
(lo_sum:DI (match_dup 0) (match_dup 1)))]
|
(lo_sum:DI (match_dup 0) (match_dup 1)))]
|
"operands[2] = pic_offset_table_rtx;")
|
"operands[2] = pic_offset_table_rtx;")
|
|
|
(define_split
|
(define_split
|
[(match_operand 0 "some_small_symbolic_operand" "")]
|
[(match_operand 0 "some_small_symbolic_operand" "")]
|
""
|
""
|
[(match_dup 0)]
|
[(match_dup 0)]
|
"operands[0] = split_small_symbolic_operand (operands[0]);")
|
"operands[0] = split_small_symbolic_operand (operands[0]);")
|
|
|
;; Accepts any symbolic, not just global, since function calls that
|
;; Accepts any symbolic, not just global, since function calls that
|
;; don't go via bsr still use !literal in hopes of linker relaxation.
|
;; don't go via bsr still use !literal in hopes of linker relaxation.
|
(define_insn "movdi_er_high_g"
|
(define_insn "movdi_er_high_g"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
|
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
|
(match_operand:DI 2 "symbolic_operand" "")
|
(match_operand:DI 2 "symbolic_operand" "")
|
(match_operand 3 "const_int_operand" "")]
|
(match_operand 3 "const_int_operand" "")]
|
UNSPEC_LITERAL))]
|
UNSPEC_LITERAL))]
|
"TARGET_EXPLICIT_RELOCS"
|
"TARGET_EXPLICIT_RELOCS"
|
{
|
{
|
if (INTVAL (operands[3]) == 0)
|
if (INTVAL (operands[3]) == 0)
|
return "ldq %0,%2(%1)\t\t!literal";
|
return "ldq %0,%2(%1)\t\t!literal";
|
else
|
else
|
return "ldq %0,%2(%1)\t\t!literal!%3";
|
return "ldq %0,%2(%1)\t\t!literal!%3";
|
}
|
}
|
[(set_attr "type" "ldsym")])
|
[(set_attr "type" "ldsym")])
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "global_symbolic_operand" ""))]
|
(match_operand:DI 1 "global_symbolic_operand" ""))]
|
"TARGET_EXPLICIT_RELOCS && reload_completed"
|
"TARGET_EXPLICIT_RELOCS && reload_completed"
|
[(set (match_dup 0)
|
[(set (match_dup 0)
|
(unspec:DI [(match_dup 2)
|
(unspec:DI [(match_dup 2)
|
(match_dup 1)
|
(match_dup 1)
|
(const_int 0)] UNSPEC_LITERAL))]
|
(const_int 0)] UNSPEC_LITERAL))]
|
"operands[2] = pic_offset_table_rtx;")
|
"operands[2] = pic_offset_table_rtx;")
|
|
|
(define_insn "movdi_er_tlsgd"
|
(define_insn "movdi_er_tlsgd"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
|
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
|
(match_operand:DI 2 "symbolic_operand" "")
|
(match_operand:DI 2 "symbolic_operand" "")
|
(match_operand 3 "const_int_operand" "")]
|
(match_operand 3 "const_int_operand" "")]
|
UNSPEC_TLSGD))]
|
UNSPEC_TLSGD))]
|
"HAVE_AS_TLS"
|
"HAVE_AS_TLS"
|
{
|
{
|
if (INTVAL (operands[3]) == 0)
|
if (INTVAL (operands[3]) == 0)
|
return "lda %0,%2(%1)\t\t!tlsgd";
|
return "lda %0,%2(%1)\t\t!tlsgd";
|
else
|
else
|
return "lda %0,%2(%1)\t\t!tlsgd!%3";
|
return "lda %0,%2(%1)\t\t!tlsgd!%3";
|
})
|
})
|
|
|
(define_insn "movdi_er_tlsldm"
|
(define_insn "movdi_er_tlsldm"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
|
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
|
(match_operand 2 "const_int_operand" "")]
|
(match_operand 2 "const_int_operand" "")]
|
UNSPEC_TLSLDM))]
|
UNSPEC_TLSLDM))]
|
"HAVE_AS_TLS"
|
"HAVE_AS_TLS"
|
{
|
{
|
if (INTVAL (operands[2]) == 0)
|
if (INTVAL (operands[2]) == 0)
|
return "lda %0,%&(%1)\t\t!tlsldm";
|
return "lda %0,%&(%1)\t\t!tlsldm";
|
else
|
else
|
return "lda %0,%&(%1)\t\t!tlsldm!%2";
|
return "lda %0,%&(%1)\t\t!tlsldm!%2";
|
})
|
})
|
|
|
(define_insn "*movdi_er_gotdtp"
|
(define_insn "*movdi_er_gotdtp"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
|
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
|
(match_operand:DI 2 "symbolic_operand" "")]
|
(match_operand:DI 2 "symbolic_operand" "")]
|
UNSPEC_DTPREL))]
|
UNSPEC_DTPREL))]
|
"HAVE_AS_TLS"
|
"HAVE_AS_TLS"
|
"ldq %0,%2(%1)\t\t!gotdtprel"
|
"ldq %0,%2(%1)\t\t!gotdtprel"
|
[(set_attr "type" "ild")
|
[(set_attr "type" "ild")
|
(set_attr "usegp" "yes")])
|
(set_attr "usegp" "yes")])
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "gotdtp_symbolic_operand" ""))]
|
(match_operand:DI 1 "gotdtp_symbolic_operand" ""))]
|
"HAVE_AS_TLS && reload_completed"
|
"HAVE_AS_TLS && reload_completed"
|
[(set (match_dup 0)
|
[(set (match_dup 0)
|
(unspec:DI [(match_dup 2)
|
(unspec:DI [(match_dup 2)
|
(match_dup 1)] UNSPEC_DTPREL))]
|
(match_dup 1)] UNSPEC_DTPREL))]
|
{
|
{
|
operands[1] = XVECEXP (XEXP (operands[1], 0), 0, 0);
|
operands[1] = XVECEXP (XEXP (operands[1], 0), 0, 0);
|
operands[2] = pic_offset_table_rtx;
|
operands[2] = pic_offset_table_rtx;
|
})
|
})
|
|
|
(define_insn "*movdi_er_gottp"
|
(define_insn "*movdi_er_gottp"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
|
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
|
(match_operand:DI 2 "symbolic_operand" "")]
|
(match_operand:DI 2 "symbolic_operand" "")]
|
UNSPEC_TPREL))]
|
UNSPEC_TPREL))]
|
"HAVE_AS_TLS"
|
"HAVE_AS_TLS"
|
"ldq %0,%2(%1)\t\t!gottprel"
|
"ldq %0,%2(%1)\t\t!gottprel"
|
[(set_attr "type" "ild")
|
[(set_attr "type" "ild")
|
(set_attr "usegp" "yes")])
|
(set_attr "usegp" "yes")])
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "gottp_symbolic_operand" ""))]
|
(match_operand:DI 1 "gottp_symbolic_operand" ""))]
|
"HAVE_AS_TLS && reload_completed"
|
"HAVE_AS_TLS && reload_completed"
|
[(set (match_dup 0)
|
[(set (match_dup 0)
|
(unspec:DI [(match_dup 2)
|
(unspec:DI [(match_dup 2)
|
(match_dup 1)] UNSPEC_TPREL))]
|
(match_dup 1)] UNSPEC_TPREL))]
|
{
|
{
|
operands[1] = XVECEXP (XEXP (operands[1], 0), 0, 0);
|
operands[1] = XVECEXP (XEXP (operands[1], 0), 0, 0);
|
operands[2] = pic_offset_table_rtx;
|
operands[2] = pic_offset_table_rtx;
|
})
|
})
|
|
|
(define_insn "*movdi_er_nofix"
|
(define_insn "*movdi_er_nofix"
|
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,r,m,*f,*f,Q")
|
[(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"))]
|
(match_operand:DI 1 "input_operand" "rJ,K,L,T,s,n,m,rJ,*fJ,Q,*f"))]
|
"TARGET_EXPLICIT_RELOCS && ! TARGET_FIX
|
"TARGET_EXPLICIT_RELOCS && ! TARGET_FIX
|
&& (register_operand (operands[0], DImode)
|
&& (register_operand (operands[0], DImode)
|
|| reg_or_0_operand (operands[1], DImode))"
|
|| reg_or_0_operand (operands[1], DImode))"
|
"@
|
"@
|
mov %r1,%0
|
mov %r1,%0
|
lda %0,%1($31)
|
lda %0,%1($31)
|
ldah %0,%h1($31)
|
ldah %0,%h1($31)
|
#
|
#
|
#
|
#
|
#
|
#
|
ldq%A1 %0,%1
|
ldq%A1 %0,%1
|
stq%A0 %r1,%0
|
stq%A0 %r1,%0
|
fmov %R1,%0
|
fmov %R1,%0
|
ldt %0,%1
|
ldt %0,%1
|
stt %R1,%0"
|
stt %R1,%0"
|
[(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,multi,ild,ist,fcpys,fld,fst")
|
[(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,multi,ild,ist,fcpys,fld,fst")
|
(set_attr "usegp" "*,*,*,yes,*,*,*,*,*,*,*")])
|
(set_attr "usegp" "*,*,*,yes,*,*,*,*,*,*,*")])
|
|
|
;; The 'U' constraint matches symbolic operands on Unicos/Mk. Those should
|
;; 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
|
;; have been split up by the rules above but we shouldn't reject the
|
;; possibility of them getting through.
|
;; possibility of them getting through.
|
|
|
(define_insn "*movdi_nofix"
|
(define_insn "*movdi_nofix"
|
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,r,m,*f,*f,Q")
|
[(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"))]
|
(match_operand:DI 1 "input_operand" "rJ,K,L,U,s,n,m,rJ,*fJ,Q,*f"))]
|
"! TARGET_FIX
|
"! TARGET_FIX
|
&& (register_operand (operands[0], DImode)
|
&& (register_operand (operands[0], DImode)
|
|| reg_or_0_operand (operands[1], DImode))"
|
|| reg_or_0_operand (operands[1], DImode))"
|
"@
|
"@
|
bis $31,%r1,%0
|
bis $31,%r1,%0
|
lda %0,%1($31)
|
lda %0,%1($31)
|
ldah %0,%h1($31)
|
ldah %0,%h1($31)
|
laum %0,%t1($31)\;sll %0,32,%0\;lalm %0,%t1(%0)\;lal %0,%t1(%0)
|
laum %0,%t1($31)\;sll %0,32,%0\;lalm %0,%t1(%0)\;lal %0,%t1(%0)
|
lda %0,%1
|
lda %0,%1
|
#
|
#
|
ldq%A1 %0,%1
|
ldq%A1 %0,%1
|
stq%A0 %r1,%0
|
stq%A0 %r1,%0
|
cpys %R1,%R1,%0
|
cpys %R1,%R1,%0
|
ldt %0,%1
|
ldt %0,%1
|
stt %R1,%0"
|
stt %R1,%0"
|
[(set_attr "type" "ilog,iadd,iadd,ldsym,ldsym,multi,ild,ist,fcpys,fld,fst")
|
[(set_attr "type" "ilog,iadd,iadd,ldsym,ldsym,multi,ild,ist,fcpys,fld,fst")
|
(set_attr "length" "*,*,*,16,*,*,*,*,*,*,*")])
|
(set_attr "length" "*,*,*,16,*,*,*,*,*,*,*")])
|
|
|
(define_insn "*movdi_er_fix"
|
(define_insn "*movdi_er_fix"
|
[(set (match_operand:DI 0 "nonimmediate_operand"
|
[(set (match_operand:DI 0 "nonimmediate_operand"
|
"=r,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"
|
(match_operand:DI 1 "input_operand"
|
"rJ,K,L,T,s,n,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
|
"TARGET_EXPLICIT_RELOCS && TARGET_FIX
|
&& (register_operand (operands[0], DImode)
|
&& (register_operand (operands[0], DImode)
|
|| reg_or_0_operand (operands[1], DImode))"
|
|| reg_or_0_operand (operands[1], DImode))"
|
"@
|
"@
|
mov %r1,%0
|
mov %r1,%0
|
lda %0,%1($31)
|
lda %0,%1($31)
|
ldah %0,%h1($31)
|
ldah %0,%h1($31)
|
#
|
#
|
#
|
#
|
#
|
#
|
ldq%A1 %0,%1
|
ldq%A1 %0,%1
|
stq%A0 %r1,%0
|
stq%A0 %r1,%0
|
fmov %R1,%0
|
fmov %R1,%0
|
ldt %0,%1
|
ldt %0,%1
|
stt %R1,%0
|
stt %R1,%0
|
ftoit %1,%0
|
ftoit %1,%0
|
itoft %1,%0"
|
itoft %1,%0"
|
[(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,multi,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,*,*,*,*,*,*,*,*,*")])
|
(set_attr "usegp" "*,*,*,yes,*,*,*,*,*,*,*,*,*")])
|
|
|
(define_insn "*movdi_fix"
|
(define_insn "*movdi_fix"
|
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,*f,*f,Q,r,*f")
|
[(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"))]
|
(match_operand:DI 1 "input_operand" "rJ,K,L,s,n,m,rJ,*fJ,Q,*f,*f,r"))]
|
"! TARGET_EXPLICIT_RELOCS && TARGET_FIX
|
"! TARGET_EXPLICIT_RELOCS && TARGET_FIX
|
&& (register_operand (operands[0], DImode)
|
&& (register_operand (operands[0], DImode)
|
|| reg_or_0_operand (operands[1], DImode))"
|
|| reg_or_0_operand (operands[1], DImode))"
|
"@
|
"@
|
bis $31,%r1,%0
|
bis $31,%r1,%0
|
lda %0,%1($31)
|
lda %0,%1($31)
|
ldah %0,%h1($31)
|
ldah %0,%h1($31)
|
lda %0,%1
|
lda %0,%1
|
#
|
#
|
ldq%A1 %0,%1
|
ldq%A1 %0,%1
|
stq%A0 %r1,%0
|
stq%A0 %r1,%0
|
cpys %R1,%R1,%0
|
cpys %R1,%R1,%0
|
ldt %0,%1
|
ldt %0,%1
|
stt %R1,%0
|
stt %R1,%0
|
ftoit %1,%0
|
ftoit %1,%0
|
itoft %1,%0"
|
itoft %1,%0"
|
[(set_attr "type" "ilog,iadd,iadd,ldsym,multi,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
|
;; VMS needs to set up "vms_base_regno" for unwinding. This move
|
;; often appears dead to the life analysis code, at which point we
|
;; often appears dead to the life analysis code, at which point we
|
;; die for emitting dead prologue instructions. Force this live.
|
;; die for emitting dead prologue instructions. Force this live.
|
|
|
(define_insn "force_movdi"
|
(define_insn "force_movdi"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")]
|
(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")]
|
UNSPECV_FORCE_MOV))]
|
UNSPECV_FORCE_MOV))]
|
""
|
""
|
"mov %1,%0"
|
"mov %1,%0"
|
[(set_attr "type" "ilog")])
|
[(set_attr "type" "ilog")])
|
|
|
;; We do three major things here: handle mem->mem, put 64-bit constants in
|
;; We do three major things here: handle mem->mem, put 64-bit constants in
|
;; memory, and construct long 32-bit constants.
|
;; memory, and construct long 32-bit constants.
|
|
|
(define_expand "movdi"
|
(define_expand "movdi"
|
[(set (match_operand:DI 0 "nonimmediate_operand" "")
|
[(set (match_operand:DI 0 "nonimmediate_operand" "")
|
(match_operand:DI 1 "general_operand" ""))]
|
(match_operand:DI 1 "general_operand" ""))]
|
""
|
""
|
{
|
{
|
if (alpha_expand_mov (DImode, operands))
|
if (alpha_expand_mov (DImode, operands))
|
DONE;
|
DONE;
|
})
|
})
|
|
|
;; Split a load of a large constant into the appropriate two-insn
|
;; Split a load of a large constant into the appropriate two-insn
|
;; sequence.
|
;; sequence.
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "non_add_const_operand" ""))]
|
(match_operand:DI 1 "non_add_const_operand" ""))]
|
""
|
""
|
[(const_int 0)]
|
[(const_int 0)]
|
{
|
{
|
if (alpha_split_const_mov (DImode, operands))
|
if (alpha_split_const_mov (DImode, operands))
|
DONE;
|
DONE;
|
else
|
else
|
FAIL;
|
FAIL;
|
})
|
})
|
|
|
;; We need to prevent reload from splitting TImode moves, because it
|
;; We need to prevent reload from splitting TImode moves, because it
|
;; might decide to overwrite a pointer with the value it points to.
|
;; 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
|
;; In that case we have to do the loads in the appropriate order so
|
;; that the pointer is not destroyed too early.
|
;; that the pointer is not destroyed too early.
|
|
|
(define_insn_and_split "*movti_internal"
|
(define_insn_and_split "*movti_internal"
|
[(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
|
[(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
|
(match_operand:TI 1 "input_operand" "roJ,rJ"))]
|
(match_operand:TI 1 "input_operand" "roJ,rJ"))]
|
"(register_operand (operands[0], TImode)
|
"(register_operand (operands[0], TImode)
|
/* Prevent rematerialization of constants. */
|
/* Prevent rematerialization of constants. */
|
&& ! CONSTANT_P (operands[1]))
|
&& ! CONSTANT_P (operands[1]))
|
|| reg_or_0_operand (operands[1], TImode)"
|
|| reg_or_0_operand (operands[1], TImode)"
|
"#"
|
"#"
|
"reload_completed"
|
"reload_completed"
|
[(set (match_dup 0) (match_dup 2))
|
[(set (match_dup 0) (match_dup 2))
|
(set (match_dup 1) (match_dup 3))]
|
(set (match_dup 1) (match_dup 3))]
|
{
|
{
|
alpha_split_tmode_pair (operands, TImode, true);
|
alpha_split_tmode_pair (operands, TImode, true);
|
})
|
})
|
|
|
(define_expand "movti"
|
(define_expand "movti"
|
[(set (match_operand:TI 0 "nonimmediate_operand" "")
|
[(set (match_operand:TI 0 "nonimmediate_operand" "")
|
(match_operand:TI 1 "general_operand" ""))]
|
(match_operand:TI 1 "general_operand" ""))]
|
""
|
""
|
{
|
{
|
if (MEM_P (operands[0])
|
if (MEM_P (operands[0])
|
&& ! reg_or_0_operand (operands[1], TImode))
|
&& ! reg_or_0_operand (operands[1], TImode))
|
operands[1] = force_reg (TImode, operands[1]);
|
operands[1] = force_reg (TImode, operands[1]);
|
|
|
if (operands[1] == const0_rtx)
|
if (operands[1] == const0_rtx)
|
;
|
;
|
/* We must put 64-bit constants in memory. We could keep the
|
/* We must put 64-bit constants in memory. We could keep the
|
32-bit constants in TImode and rely on the splitter, but
|
32-bit constants in TImode and rely on the splitter, but
|
this doesn't seem to be worth the pain. */
|
this doesn't seem to be worth the pain. */
|
else if (CONST_INT_P (operands[1])
|
else if (CONST_INT_P (operands[1])
|
|| GET_CODE (operands[1]) == CONST_DOUBLE)
|
|| GET_CODE (operands[1]) == CONST_DOUBLE)
|
{
|
{
|
rtx in[2], out[2], target;
|
rtx in[2], out[2], target;
|
|
|
gcc_assert (can_create_pseudo_p ());
|
gcc_assert (can_create_pseudo_p ());
|
|
|
split_double (operands[1], &in[0], &in[1]);
|
split_double (operands[1], &in[0], &in[1]);
|
|
|
if (in[0] == const0_rtx)
|
if (in[0] == const0_rtx)
|
out[0] = const0_rtx;
|
out[0] = const0_rtx;
|
else
|
else
|
{
|
{
|
out[0] = gen_reg_rtx (DImode);
|
out[0] = gen_reg_rtx (DImode);
|
emit_insn (gen_movdi (out[0], in[0]));
|
emit_insn (gen_movdi (out[0], in[0]));
|
}
|
}
|
|
|
if (in[1] == const0_rtx)
|
if (in[1] == const0_rtx)
|
out[1] = const0_rtx;
|
out[1] = const0_rtx;
|
else
|
else
|
{
|
{
|
out[1] = gen_reg_rtx (DImode);
|
out[1] = gen_reg_rtx (DImode);
|
emit_insn (gen_movdi (out[1], in[1]));
|
emit_insn (gen_movdi (out[1], in[1]));
|
}
|
}
|
|
|
if (!REG_P (operands[0]))
|
if (!REG_P (operands[0]))
|
target = gen_reg_rtx (TImode);
|
target = gen_reg_rtx (TImode);
|
else
|
else
|
target = operands[0];
|
target = operands[0];
|
|
|
emit_insn (gen_movdi (operand_subword (target, 0, 0, TImode), out[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]));
|
emit_insn (gen_movdi (operand_subword (target, 1, 0, TImode), out[1]));
|
|
|
if (target != operands[0])
|
if (target != operands[0])
|
emit_insn (gen_rtx_SET (VOIDmode, operands[0], target));
|
emit_insn (gen_rtx_SET (VOIDmode, operands[0], target));
|
|
|
DONE;
|
DONE;
|
}
|
}
|
})
|
})
|
|
|
;; These are the partial-word cases.
|
;; These are the partial-word cases.
|
;;
|
;;
|
;; First we have the code to load an aligned word. Operand 0 is the register
|
;; First we have the code to load an aligned word. Operand 0 is the register
|
;; in which to place the result. It's mode is QImode or HImode. Operand 1
|
;; in which to place the result. It's mode is QImode or HImode. Operand 1
|
;; is an SImode MEM at the low-order byte of the proper word. Operand 2 is the
|
;; is an SImode MEM at the low-order byte of the proper word. Operand 2 is the
|
;; number of bits within the word that the value is. Operand 3 is an SImode
|
;; number of bits within the word that the value is. Operand 3 is an SImode
|
;; scratch register. If operand 0 is a hard register, operand 3 may be the
|
;; scratch register. If operand 0 is a hard register, operand 3 may be the
|
;; same register. It is allowed to conflict with operand 1 as well.
|
;; same register. It is allowed to conflict with operand 1 as well.
|
|
|
(define_expand "aligned_loadqi"
|
(define_expand "aligned_loadqi"
|
[(set (match_operand:SI 3 "register_operand" "")
|
[(set (match_operand:SI 3 "register_operand" "")
|
(match_operand:SI 1 "memory_operand" ""))
|
(match_operand:SI 1 "memory_operand" ""))
|
(set (match_operand:DI 0 "register_operand" "")
|
(set (match_operand:DI 0 "register_operand" "")
|
(zero_extract:DI (subreg:DI (match_dup 3) 0)
|
(zero_extract:DI (subreg:DI (match_dup 3) 0)
|
(const_int 8)
|
(const_int 8)
|
(match_operand:DI 2 "const_int_operand" "")))]
|
(match_operand:DI 2 "const_int_operand" "")))]
|
|
|
""
|
""
|
"")
|
"")
|
|
|
(define_expand "aligned_loadhi"
|
(define_expand "aligned_loadhi"
|
[(set (match_operand:SI 3 "register_operand" "")
|
[(set (match_operand:SI 3 "register_operand" "")
|
(match_operand:SI 1 "memory_operand" ""))
|
(match_operand:SI 1 "memory_operand" ""))
|
(set (match_operand:DI 0 "register_operand" "")
|
(set (match_operand:DI 0 "register_operand" "")
|
(zero_extract:DI (subreg:DI (match_dup 3) 0)
|
(zero_extract:DI (subreg:DI (match_dup 3) 0)
|
(const_int 16)
|
(const_int 16)
|
(match_operand:DI 2 "const_int_operand" "")))]
|
(match_operand:DI 2 "const_int_operand" "")))]
|
|
|
""
|
""
|
"")
|
"")
|
|
|
;; Similar for unaligned loads, where we use the sequence from the
|
;; Similar for unaligned loads, where we use the sequence from the
|
;; Alpha Architecture manual. We have to distinguish between little-endian
|
;; Alpha Architecture manual. We have to distinguish between little-endian
|
;; and big-endian systems as the sequences are different.
|
;; and big-endian systems as the sequences are different.
|
;;
|
;;
|
;; Operand 1 is the address. Operands 2 and 3 are temporaries, where
|
;; Operand 1 is the address. Operands 2 and 3 are temporaries, where
|
;; operand 3 can overlap the input and output registers.
|
;; operand 3 can overlap the input and output registers.
|
|
|
(define_expand "unaligned_loadqi"
|
(define_expand "unaligned_loadqi"
|
[(use (match_operand:DI 0 "register_operand" ""))
|
[(use (match_operand:DI 0 "register_operand" ""))
|
(use (match_operand:DI 1 "address_operand" ""))
|
(use (match_operand:DI 1 "address_operand" ""))
|
(use (match_operand:DI 2 "register_operand" ""))
|
(use (match_operand:DI 2 "register_operand" ""))
|
(use (match_operand:DI 3 "register_operand" ""))]
|
(use (match_operand:DI 3 "register_operand" ""))]
|
""
|
""
|
{
|
{
|
if (WORDS_BIG_ENDIAN)
|
if (WORDS_BIG_ENDIAN)
|
emit_insn (gen_unaligned_loadqi_be (operands[0], operands[1],
|
emit_insn (gen_unaligned_loadqi_be (operands[0], operands[1],
|
operands[2], operands[3]));
|
operands[2], operands[3]));
|
else
|
else
|
emit_insn (gen_unaligned_loadqi_le (operands[0], operands[1],
|
emit_insn (gen_unaligned_loadqi_le (operands[0], operands[1],
|
operands[2], operands[3]));
|
operands[2], operands[3]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "unaligned_loadqi_le"
|
(define_expand "unaligned_loadqi_le"
|
[(set (match_operand:DI 2 "register_operand" "")
|
[(set (match_operand:DI 2 "register_operand" "")
|
(mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
|
(mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
|
(const_int -8))))
|
(const_int -8))))
|
(set (match_operand:DI 3 "register_operand" "")
|
(set (match_operand:DI 3 "register_operand" "")
|
(match_dup 1))
|
(match_dup 1))
|
(set (match_operand:DI 0 "register_operand" "")
|
(set (match_operand:DI 0 "register_operand" "")
|
(zero_extract:DI (match_dup 2)
|
(zero_extract:DI (match_dup 2)
|
(const_int 8)
|
(const_int 8)
|
(ashift:DI (match_dup 3) (const_int 3))))]
|
(ashift:DI (match_dup 3) (const_int 3))))]
|
"! WORDS_BIG_ENDIAN"
|
"! WORDS_BIG_ENDIAN"
|
"")
|
"")
|
|
|
(define_expand "unaligned_loadqi_be"
|
(define_expand "unaligned_loadqi_be"
|
[(set (match_operand:DI 2 "register_operand" "")
|
[(set (match_operand:DI 2 "register_operand" "")
|
(mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
|
(mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
|
(const_int -8))))
|
(const_int -8))))
|
(set (match_operand:DI 3 "register_operand" "")
|
(set (match_operand:DI 3 "register_operand" "")
|
(match_dup 1))
|
(match_dup 1))
|
(set (match_operand:DI 0 "register_operand" "")
|
(set (match_operand:DI 0 "register_operand" "")
|
(zero_extract:DI (match_dup 2)
|
(zero_extract:DI (match_dup 2)
|
(const_int 8)
|
(const_int 8)
|
(minus:DI
|
(minus:DI
|
(const_int 56)
|
(const_int 56)
|
(ashift:DI (match_dup 3) (const_int 3)))))]
|
(ashift:DI (match_dup 3) (const_int 3)))))]
|
"WORDS_BIG_ENDIAN"
|
"WORDS_BIG_ENDIAN"
|
"")
|
"")
|
|
|
(define_expand "unaligned_loadhi"
|
(define_expand "unaligned_loadhi"
|
[(use (match_operand:DI 0 "register_operand" ""))
|
[(use (match_operand:DI 0 "register_operand" ""))
|
(use (match_operand:DI 1 "address_operand" ""))
|
(use (match_operand:DI 1 "address_operand" ""))
|
(use (match_operand:DI 2 "register_operand" ""))
|
(use (match_operand:DI 2 "register_operand" ""))
|
(use (match_operand:DI 3 "register_operand" ""))]
|
(use (match_operand:DI 3 "register_operand" ""))]
|
""
|
""
|
{
|
{
|
if (WORDS_BIG_ENDIAN)
|
if (WORDS_BIG_ENDIAN)
|
emit_insn (gen_unaligned_loadhi_be (operands[0], operands[1],
|
emit_insn (gen_unaligned_loadhi_be (operands[0], operands[1],
|
operands[2], operands[3]));
|
operands[2], operands[3]));
|
else
|
else
|
emit_insn (gen_unaligned_loadhi_le (operands[0], operands[1],
|
emit_insn (gen_unaligned_loadhi_le (operands[0], operands[1],
|
operands[2], operands[3]));
|
operands[2], operands[3]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "unaligned_loadhi_le"
|
(define_expand "unaligned_loadhi_le"
|
[(set (match_operand:DI 2 "register_operand" "")
|
[(set (match_operand:DI 2 "register_operand" "")
|
(mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
|
(mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
|
(const_int -8))))
|
(const_int -8))))
|
(set (match_operand:DI 3 "register_operand" "")
|
(set (match_operand:DI 3 "register_operand" "")
|
(match_dup 1))
|
(match_dup 1))
|
(set (match_operand:DI 0 "register_operand" "")
|
(set (match_operand:DI 0 "register_operand" "")
|
(zero_extract:DI (match_dup 2)
|
(zero_extract:DI (match_dup 2)
|
(const_int 16)
|
(const_int 16)
|
(ashift:DI (match_dup 3) (const_int 3))))]
|
(ashift:DI (match_dup 3) (const_int 3))))]
|
"! WORDS_BIG_ENDIAN"
|
"! WORDS_BIG_ENDIAN"
|
"")
|
"")
|
|
|
(define_expand "unaligned_loadhi_be"
|
(define_expand "unaligned_loadhi_be"
|
[(set (match_operand:DI 2 "register_operand" "")
|
[(set (match_operand:DI 2 "register_operand" "")
|
(mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
|
(mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
|
(const_int -8))))
|
(const_int -8))))
|
(set (match_operand:DI 3 "register_operand" "")
|
(set (match_operand:DI 3 "register_operand" "")
|
(plus:DI (match_dup 1) (const_int 1)))
|
(plus:DI (match_dup 1) (const_int 1)))
|
(set (match_operand:DI 0 "register_operand" "")
|
(set (match_operand:DI 0 "register_operand" "")
|
(zero_extract:DI (match_dup 2)
|
(zero_extract:DI (match_dup 2)
|
(const_int 16)
|
(const_int 16)
|
(minus:DI
|
(minus:DI
|
(const_int 56)
|
(const_int 56)
|
(ashift:DI (match_dup 3) (const_int 3)))))]
|
(ashift:DI (match_dup 3) (const_int 3)))))]
|
"WORDS_BIG_ENDIAN"
|
"WORDS_BIG_ENDIAN"
|
"")
|
"")
|
|
|
;; Storing an aligned byte or word requires two temporaries. Operand 0 is the
|
;; Storing an aligned byte or word requires two temporaries. Operand 0 is the
|
;; aligned SImode MEM. Operand 1 is the register containing the
|
;; aligned SImode MEM. Operand 1 is the register containing the
|
;; byte or word to store. Operand 2 is the number of bits within the word that
|
;; byte or word to store. Operand 2 is the number of bits within the word that
|
;; the value should be placed. Operands 3 and 4 are SImode temporaries.
|
;; the value should be placed. Operands 3 and 4 are SImode temporaries.
|
|
|
(define_expand "aligned_store"
|
(define_expand "aligned_store"
|
[(set (match_operand:SI 3 "register_operand" "")
|
[(set (match_operand:SI 3 "register_operand" "")
|
(match_operand:SI 0 "memory_operand" ""))
|
(match_operand:SI 0 "memory_operand" ""))
|
(set (subreg:DI (match_dup 3) 0)
|
(set (subreg:DI (match_dup 3) 0)
|
(and:DI (subreg:DI (match_dup 3) 0) (match_dup 5)))
|
(and:DI (subreg:DI (match_dup 3) 0) (match_dup 5)))
|
(set (subreg:DI (match_operand:SI 4 "register_operand" "") 0)
|
(set (subreg:DI (match_operand:SI 4 "register_operand" "") 0)
|
(ashift:DI (zero_extend:DI (match_operand 1 "register_operand" ""))
|
(ashift:DI (zero_extend:DI (match_operand 1 "register_operand" ""))
|
(match_operand:DI 2 "const_int_operand" "")))
|
(match_operand:DI 2 "const_int_operand" "")))
|
(set (subreg:DI (match_dup 4) 0)
|
(set (subreg:DI (match_dup 4) 0)
|
(ior:DI (subreg:DI (match_dup 4) 0) (subreg:DI (match_dup 3) 0)))
|
(ior:DI (subreg:DI (match_dup 4) 0) (subreg:DI (match_dup 3) 0)))
|
(set (match_dup 0) (match_dup 4))]
|
(set (match_dup 0) (match_dup 4))]
|
""
|
""
|
{
|
{
|
operands[5] = GEN_INT (~ (GET_MODE_MASK (GET_MODE (operands[1]))
|
operands[5] = GEN_INT (~ (GET_MODE_MASK (GET_MODE (operands[1]))
|
<< INTVAL (operands[2])));
|
<< INTVAL (operands[2])));
|
})
|
})
|
|
|
;; For the unaligned byte and halfword cases, we use code similar to that
|
;; For the unaligned byte and halfword cases, we use code similar to that
|
;; in the ;; Architecture book, but reordered to lower the number of registers
|
;; in the ;; Architecture book, but reordered to lower the number of registers
|
;; required. Operand 0 is the address. Operand 1 is the data to store.
|
;; required. Operand 0 is the address. Operand 1 is the data to store.
|
;; Operands 2, 3, and 4 are DImode temporaries, where operands 2 and 4 may
|
;; Operands 2, 3, and 4 are DImode temporaries, where operands 2 and 4 may
|
;; be the same temporary, if desired. If the address is in a register,
|
;; be the same temporary, if desired. If the address is in a register,
|
;; operand 2 can be that register.
|
;; operand 2 can be that register.
|
|
|
(define_expand "unaligned_storeqi"
|
(define_expand "unaligned_storeqi"
|
[(use (match_operand:DI 0 "address_operand" ""))
|
[(use (match_operand:DI 0 "address_operand" ""))
|
(use (match_operand:QI 1 "register_operand" ""))
|
(use (match_operand:QI 1 "register_operand" ""))
|
(use (match_operand:DI 2 "register_operand" ""))
|
(use (match_operand:DI 2 "register_operand" ""))
|
(use (match_operand:DI 3 "register_operand" ""))
|
(use (match_operand:DI 3 "register_operand" ""))
|
(use (match_operand:DI 4 "register_operand" ""))]
|
(use (match_operand:DI 4 "register_operand" ""))]
|
""
|
""
|
{
|
{
|
if (WORDS_BIG_ENDIAN)
|
if (WORDS_BIG_ENDIAN)
|
emit_insn (gen_unaligned_storeqi_be (operands[0], operands[1],
|
emit_insn (gen_unaligned_storeqi_be (operands[0], operands[1],
|
operands[2], operands[3],
|
operands[2], operands[3],
|
operands[4]));
|
operands[4]));
|
else
|
else
|
emit_insn (gen_unaligned_storeqi_le (operands[0], operands[1],
|
emit_insn (gen_unaligned_storeqi_le (operands[0], operands[1],
|
operands[2], operands[3],
|
operands[2], operands[3],
|
operands[4]));
|
operands[4]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "unaligned_storeqi_le"
|
(define_expand "unaligned_storeqi_le"
|
[(set (match_operand:DI 3 "register_operand" "")
|
[(set (match_operand:DI 3 "register_operand" "")
|
(mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
|
(mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
|
(const_int -8))))
|
(const_int -8))))
|
(set (match_operand:DI 2 "register_operand" "")
|
(set (match_operand:DI 2 "register_operand" "")
|
(match_dup 0))
|
(match_dup 0))
|
(set (match_dup 3)
|
(set (match_dup 3)
|
(and:DI (not:DI (ashift:DI (const_int 255)
|
(and:DI (not:DI (ashift:DI (const_int 255)
|
(ashift:DI (match_dup 2) (const_int 3))))
|
(ashift:DI (match_dup 2) (const_int 3))))
|
(match_dup 3)))
|
(match_dup 3)))
|
(set (match_operand:DI 4 "register_operand" "")
|
(set (match_operand:DI 4 "register_operand" "")
|
(ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" ""))
|
(ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" ""))
|
(ashift:DI (match_dup 2) (const_int 3))))
|
(ashift:DI (match_dup 2) (const_int 3))))
|
(set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
|
(set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
|
(set (mem:DI (and:DI (match_dup 0) (const_int -8)))
|
(set (mem:DI (and:DI (match_dup 0) (const_int -8)))
|
(match_dup 4))]
|
(match_dup 4))]
|
"! WORDS_BIG_ENDIAN"
|
"! WORDS_BIG_ENDIAN"
|
"")
|
"")
|
|
|
(define_expand "unaligned_storeqi_be"
|
(define_expand "unaligned_storeqi_be"
|
[(set (match_operand:DI 3 "register_operand" "")
|
[(set (match_operand:DI 3 "register_operand" "")
|
(mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
|
(mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
|
(const_int -8))))
|
(const_int -8))))
|
(set (match_operand:DI 2 "register_operand" "")
|
(set (match_operand:DI 2 "register_operand" "")
|
(match_dup 0))
|
(match_dup 0))
|
(set (match_dup 3)
|
(set (match_dup 3)
|
(and:DI (not:DI (ashift:DI (const_int 255)
|
(and:DI (not:DI (ashift:DI (const_int 255)
|
(minus:DI (const_int 56)
|
(minus:DI (const_int 56)
|
(ashift:DI (match_dup 2) (const_int 3)))))
|
(ashift:DI (match_dup 2) (const_int 3)))))
|
(match_dup 3)))
|
(match_dup 3)))
|
(set (match_operand:DI 4 "register_operand" "")
|
(set (match_operand:DI 4 "register_operand" "")
|
(ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" ""))
|
(ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" ""))
|
(minus:DI (const_int 56)
|
(minus:DI (const_int 56)
|
(ashift:DI (match_dup 2) (const_int 3)))))
|
(ashift:DI (match_dup 2) (const_int 3)))))
|
(set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
|
(set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
|
(set (mem:DI (and:DI (match_dup 0) (const_int -8)))
|
(set (mem:DI (and:DI (match_dup 0) (const_int -8)))
|
(match_dup 4))]
|
(match_dup 4))]
|
"WORDS_BIG_ENDIAN"
|
"WORDS_BIG_ENDIAN"
|
"")
|
"")
|
|
|
(define_expand "unaligned_storehi"
|
(define_expand "unaligned_storehi"
|
[(use (match_operand:DI 0 "address_operand" ""))
|
[(use (match_operand:DI 0 "address_operand" ""))
|
(use (match_operand:HI 1 "register_operand" ""))
|
(use (match_operand:HI 1 "register_operand" ""))
|
(use (match_operand:DI 2 "register_operand" ""))
|
(use (match_operand:DI 2 "register_operand" ""))
|
(use (match_operand:DI 3 "register_operand" ""))
|
(use (match_operand:DI 3 "register_operand" ""))
|
(use (match_operand:DI 4 "register_operand" ""))]
|
(use (match_operand:DI 4 "register_operand" ""))]
|
""
|
""
|
{
|
{
|
if (WORDS_BIG_ENDIAN)
|
if (WORDS_BIG_ENDIAN)
|
emit_insn (gen_unaligned_storehi_be (operands[0], operands[1],
|
emit_insn (gen_unaligned_storehi_be (operands[0], operands[1],
|
operands[2], operands[3],
|
operands[2], operands[3],
|
operands[4]));
|
operands[4]));
|
else
|
else
|
emit_insn (gen_unaligned_storehi_le (operands[0], operands[1],
|
emit_insn (gen_unaligned_storehi_le (operands[0], operands[1],
|
operands[2], operands[3],
|
operands[2], operands[3],
|
operands[4]));
|
operands[4]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "unaligned_storehi_le"
|
(define_expand "unaligned_storehi_le"
|
[(set (match_operand:DI 3 "register_operand" "")
|
[(set (match_operand:DI 3 "register_operand" "")
|
(mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
|
(mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
|
(const_int -8))))
|
(const_int -8))))
|
(set (match_operand:DI 2 "register_operand" "")
|
(set (match_operand:DI 2 "register_operand" "")
|
(match_dup 0))
|
(match_dup 0))
|
(set (match_dup 3)
|
(set (match_dup 3)
|
(and:DI (not:DI (ashift:DI (const_int 65535)
|
(and:DI (not:DI (ashift:DI (const_int 65535)
|
(ashift:DI (match_dup 2) (const_int 3))))
|
(ashift:DI (match_dup 2) (const_int 3))))
|
(match_dup 3)))
|
(match_dup 3)))
|
(set (match_operand:DI 4 "register_operand" "")
|
(set (match_operand:DI 4 "register_operand" "")
|
(ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" ""))
|
(ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" ""))
|
(ashift:DI (match_dup 2) (const_int 3))))
|
(ashift:DI (match_dup 2) (const_int 3))))
|
(set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
|
(set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
|
(set (mem:DI (and:DI (match_dup 0) (const_int -8)))
|
(set (mem:DI (and:DI (match_dup 0) (const_int -8)))
|
(match_dup 4))]
|
(match_dup 4))]
|
"! WORDS_BIG_ENDIAN"
|
"! WORDS_BIG_ENDIAN"
|
"")
|
"")
|
|
|
(define_expand "unaligned_storehi_be"
|
(define_expand "unaligned_storehi_be"
|
[(set (match_operand:DI 3 "register_operand" "")
|
[(set (match_operand:DI 3 "register_operand" "")
|
(mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
|
(mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
|
(const_int -8))))
|
(const_int -8))))
|
(set (match_operand:DI 2 "register_operand" "")
|
(set (match_operand:DI 2 "register_operand" "")
|
(plus:DI (match_dup 5) (const_int 1)))
|
(plus:DI (match_dup 5) (const_int 1)))
|
(set (match_dup 3)
|
(set (match_dup 3)
|
(and:DI (not:DI (ashift:DI
|
(and:DI (not:DI (ashift:DI
|
(const_int 65535)
|
(const_int 65535)
|
(minus:DI (const_int 56)
|
(minus:DI (const_int 56)
|
(ashift:DI (match_dup 2) (const_int 3)))))
|
(ashift:DI (match_dup 2) (const_int 3)))))
|
(match_dup 3)))
|
(match_dup 3)))
|
(set (match_operand:DI 4 "register_operand" "")
|
(set (match_operand:DI 4 "register_operand" "")
|
(ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" ""))
|
(ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" ""))
|
(minus:DI (const_int 56)
|
(minus:DI (const_int 56)
|
(ashift:DI (match_dup 2) (const_int 3)))))
|
(ashift:DI (match_dup 2) (const_int 3)))))
|
(set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
|
(set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
|
(set (mem:DI (and:DI (match_dup 0) (const_int -8)))
|
(set (mem:DI (and:DI (match_dup 0) (const_int -8)))
|
(match_dup 4))]
|
(match_dup 4))]
|
"WORDS_BIG_ENDIAN"
|
"WORDS_BIG_ENDIAN"
|
"operands[5] = force_reg (DImode, operands[0]);")
|
"operands[5] = force_reg (DImode, operands[0]);")
|
|
|
;; Here are the define_expand's for QI and HI moves that use the above
|
;; 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
|
;; patterns. We have the normal sets, plus the ones that need scratch
|
;; registers for reload.
|
;; registers for reload.
|
|
|
(define_expand "movqi"
|
(define_expand "movqi"
|
[(set (match_operand:QI 0 "nonimmediate_operand" "")
|
[(set (match_operand:QI 0 "nonimmediate_operand" "")
|
(match_operand:QI 1 "general_operand" ""))]
|
(match_operand:QI 1 "general_operand" ""))]
|
""
|
""
|
{
|
{
|
if (TARGET_BWX
|
if (TARGET_BWX
|
? alpha_expand_mov (QImode, operands)
|
? alpha_expand_mov (QImode, operands)
|
: alpha_expand_mov_nobwx (QImode, operands))
|
: alpha_expand_mov_nobwx (QImode, operands))
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "movhi"
|
(define_expand "movhi"
|
[(set (match_operand:HI 0 "nonimmediate_operand" "")
|
[(set (match_operand:HI 0 "nonimmediate_operand" "")
|
(match_operand:HI 1 "general_operand" ""))]
|
(match_operand:HI 1 "general_operand" ""))]
|
""
|
""
|
{
|
{
|
if (TARGET_BWX
|
if (TARGET_BWX
|
? alpha_expand_mov (HImode, operands)
|
? alpha_expand_mov (HImode, operands)
|
: alpha_expand_mov_nobwx (HImode, operands))
|
: alpha_expand_mov_nobwx (HImode, operands))
|
DONE;
|
DONE;
|
})
|
})
|
|
|
;; We need to hook into the extra support that we have for HImode
|
;; We need to hook into the extra support that we have for HImode
|
;; reloads when BWX insns are not available.
|
;; reloads when BWX insns are not available.
|
(define_expand "movcqi"
|
(define_expand "movcqi"
|
[(set (match_operand:CQI 0 "nonimmediate_operand" "")
|
[(set (match_operand:CQI 0 "nonimmediate_operand" "")
|
(match_operand:CQI 1 "general_operand" ""))]
|
(match_operand:CQI 1 "general_operand" ""))]
|
"!TARGET_BWX"
|
"!TARGET_BWX"
|
{
|
{
|
if (GET_CODE (operands[0]) == CONCAT || GET_CODE (operands[1]) == CONCAT)
|
if (GET_CODE (operands[0]) == CONCAT || GET_CODE (operands[1]) == CONCAT)
|
;
|
;
|
else if (!any_memory_operand (operands[0], CQImode))
|
else if (!any_memory_operand (operands[0], CQImode))
|
{
|
{
|
if (!any_memory_operand (operands[1], CQImode))
|
if (!any_memory_operand (operands[1], CQImode))
|
{
|
{
|
emit_move_insn (gen_lowpart (HImode, operands[0]),
|
emit_move_insn (gen_lowpart (HImode, operands[0]),
|
gen_lowpart (HImode, operands[1]));
|
gen_lowpart (HImode, operands[1]));
|
DONE;
|
DONE;
|
}
|
}
|
if (aligned_memory_operand (operands[1], CQImode))
|
if (aligned_memory_operand (operands[1], CQImode))
|
{
|
{
|
bool done;
|
bool done;
|
do_aligned1:
|
do_aligned1:
|
operands[1] = gen_lowpart (HImode, operands[1]);
|
operands[1] = gen_lowpart (HImode, operands[1]);
|
do_aligned2:
|
do_aligned2:
|
operands[0] = gen_lowpart (HImode, operands[0]);
|
operands[0] = gen_lowpart (HImode, operands[0]);
|
done = alpha_expand_mov_nobwx (HImode, operands);
|
done = alpha_expand_mov_nobwx (HImode, operands);
|
gcc_assert (done);
|
gcc_assert (done);
|
DONE;
|
DONE;
|
}
|
}
|
}
|
}
|
else if (aligned_memory_operand (operands[0], CQImode))
|
else if (aligned_memory_operand (operands[0], CQImode))
|
{
|
{
|
if (MEM_P (operands[1]))
|
if (MEM_P (operands[1]))
|
{
|
{
|
rtx x = gen_reg_rtx (HImode);
|
rtx x = gen_reg_rtx (HImode);
|
emit_move_insn (gen_lowpart (CQImode, x), operands[1]);
|
emit_move_insn (gen_lowpart (CQImode, x), operands[1]);
|
operands[1] = x;
|
operands[1] = x;
|
goto do_aligned2;
|
goto do_aligned2;
|
}
|
}
|
goto do_aligned1;
|
goto do_aligned1;
|
}
|
}
|
|
|
gcc_assert (!reload_in_progress);
|
gcc_assert (!reload_in_progress);
|
emit_move_complex_parts (operands[0], operands[1]);
|
emit_move_complex_parts (operands[0], operands[1]);
|
DONE;
|
DONE;
|
})
|
})
|
|
|
;; Here are the versions for reload.
|
;; Here are the versions for reload.
|
;;
|
;;
|
;; The aligned input case is recognized early in alpha_secondary_reload
|
;; The aligned input case is recognized early in alpha_secondary_reload
|
;; in order to avoid allocating an unnecessary scratch register.
|
;; in order to avoid allocating an unnecessary scratch register.
|
;;
|
;;
|
;; Note that in the unaligned cases we know that the operand must not be
|
;; Note that in the unaligned cases we know that the operand must not be
|
;; a pseudo-register because stack slots are always aligned references.
|
;; a pseudo-register because stack slots are always aligned references.
|
|
|
(define_expand "reload_in"
|
(define_expand "reload_in"
|
[(parallel [(match_operand:RELOAD12 0 "register_operand" "=r")
|
[(parallel [(match_operand:RELOAD12 0 "register_operand" "=r")
|
(match_operand:RELOAD12 1 "any_memory_operand" "m")
|
(match_operand:RELOAD12 1 "any_memory_operand" "m")
|
(match_operand:TI 2 "register_operand" "=&r")])]
|
(match_operand:TI 2 "register_operand" "=&r")])]
|
"!TARGET_BWX"
|
"!TARGET_BWX"
|
{
|
{
|
rtx scratch, seq, addr;
|
rtx scratch, seq, addr;
|
unsigned regno = REGNO (operands[2]);
|
unsigned regno = REGNO (operands[2]);
|
|
|
/* It is possible that one of the registers we got for operands[2]
|
/* 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
|
might coincide with that of operands[0] (which is why we made
|
it TImode). Pick the other one to use as our scratch. */
|
it TImode). Pick the other one to use as our scratch. */
|
if (regno == REGNO (operands[0]))
|
if (regno == REGNO (operands[0]))
|
regno++;
|
regno++;
|
scratch = gen_rtx_REG (DImode, regno);
|
scratch = gen_rtx_REG (DImode, regno);
|
|
|
addr = get_unaligned_address (operands[1]);
|
addr = get_unaligned_address (operands[1]);
|
operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
|
operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
|
seq = gen_unaligned_load (operands[0], addr,
|
seq = gen_unaligned_load (operands[0], addr,
|
scratch, operands[0]);
|
scratch, operands[0]);
|
alpha_set_memflags (seq, operands[1]);
|
alpha_set_memflags (seq, operands[1]);
|
|
|
emit_insn (seq);
|
emit_insn (seq);
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "reload_out"
|
(define_expand "reload_out"
|
[(parallel [(match_operand:RELOAD12 0 "any_memory_operand" "=m")
|
[(parallel [(match_operand:RELOAD12 0 "any_memory_operand" "=m")
|
(match_operand:RELOAD12 1 "register_operand" "r")
|
(match_operand:RELOAD12 1 "register_operand" "r")
|
(match_operand:TI 2 "register_operand" "=&r")])]
|
(match_operand:TI 2 "register_operand" "=&r")])]
|
"! TARGET_BWX"
|
"! TARGET_BWX"
|
{
|
{
|
unsigned regno = REGNO (operands[2]);
|
unsigned regno = REGNO (operands[2]);
|
|
|
if (mode == CQImode)
|
if (mode == CQImode)
|
{
|
{
|
operands[0] = gen_lowpart (HImode, operands[0]);
|
operands[0] = gen_lowpart (HImode, operands[0]);
|
operands[1] = gen_lowpart (HImode, operands[1]);
|
operands[1] = gen_lowpart (HImode, operands[1]);
|
}
|
}
|
|
|
if (aligned_memory_operand (operands[0], mode))
|
if (aligned_memory_operand (operands[0], mode))
|
{
|
{
|
emit_insn (gen_reload_out_aligned
|
emit_insn (gen_reload_out_aligned
|
(operands[0], operands[1],
|
(operands[0], operands[1],
|
gen_rtx_REG (SImode, regno),
|
gen_rtx_REG (SImode, regno),
|
gen_rtx_REG (SImode, regno + 1)));
|
gen_rtx_REG (SImode, regno + 1)));
|
}
|
}
|
else
|
else
|
{
|
{
|
rtx addr = get_unaligned_address (operands[0]);
|
rtx addr = get_unaligned_address (operands[0]);
|
rtx scratch1 = gen_rtx_REG (DImode, regno);
|
rtx scratch1 = gen_rtx_REG (DImode, regno);
|
rtx scratch2 = gen_rtx_REG (DImode, regno + 1);
|
rtx scratch2 = gen_rtx_REG (DImode, regno + 1);
|
rtx scratch3 = scratch1;
|
rtx scratch3 = scratch1;
|
rtx seq;
|
rtx seq;
|
|
|
if (REG_P (addr))
|
if (REG_P (addr))
|
scratch1 = addr;
|
scratch1 = addr;
|
|
|
seq = gen_unaligned_store (addr, operands[1], scratch1,
|
seq = gen_unaligned_store (addr, operands[1], scratch1,
|
scratch2, scratch3);
|
scratch2, scratch3);
|
alpha_set_memflags (seq, operands[0]);
|
alpha_set_memflags (seq, operands[0]);
|
emit_insn (seq);
|
emit_insn (seq);
|
}
|
}
|
DONE;
|
DONE;
|
})
|
})
|
|
|
;; Helpers for the above. The way reload is structured, we can't
|
;; Helpers for the above. The way reload is structured, we can't
|
;; always get a proper address for a stack slot during reload_foo
|
;; always get a proper address for a stack slot during reload_foo
|
;; expansion, so we must delay our address manipulations until after.
|
;; expansion, so we must delay our address manipulations until after.
|
|
|
(define_insn_and_split "reload_in_aligned"
|
(define_insn_and_split "reload_in_aligned"
|
[(set (match_operand:I12MODE 0 "register_operand" "=r")
|
[(set (match_operand:I12MODE 0 "register_operand" "=r")
|
(match_operand:I12MODE 1 "memory_operand" "m"))]
|
(match_operand:I12MODE 1 "memory_operand" "m"))]
|
"!TARGET_BWX && (reload_in_progress || reload_completed)"
|
"!TARGET_BWX && (reload_in_progress || reload_completed)"
|
"#"
|
"#"
|
"!TARGET_BWX && reload_completed"
|
"!TARGET_BWX && reload_completed"
|
[(const_int 0)]
|
[(const_int 0)]
|
{
|
{
|
rtx aligned_mem, bitnum;
|
rtx aligned_mem, bitnum;
|
get_aligned_mem (operands[1], &aligned_mem, &bitnum);
|
get_aligned_mem (operands[1], &aligned_mem, &bitnum);
|
emit_insn (gen_aligned_load
|
emit_insn (gen_aligned_load
|
(gen_lowpart (DImode, operands[0]), aligned_mem, bitnum,
|
(gen_lowpart (DImode, operands[0]), aligned_mem, bitnum,
|
gen_rtx_REG (SImode, REGNO (operands[0]))));
|
gen_rtx_REG (SImode, REGNO (operands[0]))));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_insn_and_split "reload_out_aligned"
|
(define_insn_and_split "reload_out_aligned"
|
[(set (match_operand:I12MODE 0 "memory_operand" "=m")
|
[(set (match_operand:I12MODE 0 "memory_operand" "=m")
|
(match_operand:I12MODE 1 "register_operand" "r"))
|
(match_operand:I12MODE 1 "register_operand" "r"))
|
(clobber (match_operand:SI 2 "register_operand" "=r"))
|
(clobber (match_operand:SI 2 "register_operand" "=r"))
|
(clobber (match_operand:SI 3 "register_operand" "=r"))]
|
(clobber (match_operand:SI 3 "register_operand" "=r"))]
|
"!TARGET_BWX && (reload_in_progress || reload_completed)"
|
"!TARGET_BWX && (reload_in_progress || reload_completed)"
|
"#"
|
"#"
|
"!TARGET_BWX && reload_completed"
|
"!TARGET_BWX && reload_completed"
|
[(const_int 0)]
|
[(const_int 0)]
|
{
|
{
|
rtx aligned_mem, bitnum;
|
rtx aligned_mem, bitnum;
|
get_aligned_mem (operands[0], &aligned_mem, &bitnum);
|
get_aligned_mem (operands[0], &aligned_mem, &bitnum);
|
emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
|
emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
|
operands[2], operands[3]));
|
operands[2], operands[3]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
;; Vector operations
|
;; Vector operations
|
|
|
(define_mode_iterator VEC [V8QI V4HI V2SI])
|
(define_mode_iterator VEC [V8QI V4HI V2SI])
|
|
|
(define_expand "mov"
|
(define_expand "mov"
|
[(set (match_operand:VEC 0 "nonimmediate_operand" "")
|
[(set (match_operand:VEC 0 "nonimmediate_operand" "")
|
(match_operand:VEC 1 "general_operand" ""))]
|
(match_operand:VEC 1 "general_operand" ""))]
|
""
|
""
|
{
|
{
|
if (alpha_expand_mov (mode, operands))
|
if (alpha_expand_mov (mode, operands))
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:VEC 0 "register_operand" "")
|
[(set (match_operand:VEC 0 "register_operand" "")
|
(match_operand:VEC 1 "non_zero_const_operand" ""))]
|
(match_operand:VEC 1 "non_zero_const_operand" ""))]
|
""
|
""
|
[(const_int 0)]
|
[(const_int 0)]
|
{
|
{
|
if (alpha_split_const_mov (mode, operands))
|
if (alpha_split_const_mov (mode, operands))
|
DONE;
|
DONE;
|
else
|
else
|
FAIL;
|
FAIL;
|
})
|
})
|
|
|
|
|
(define_expand "movmisalign"
|
(define_expand "movmisalign"
|
[(set (match_operand:VEC 0 "nonimmediate_operand" "")
|
[(set (match_operand:VEC 0 "nonimmediate_operand" "")
|
(match_operand:VEC 1 "general_operand" ""))]
|
(match_operand:VEC 1 "general_operand" ""))]
|
""
|
""
|
{
|
{
|
alpha_expand_movmisalign (mode, operands);
|
alpha_expand_movmisalign (mode, operands);
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_insn "*mov_fix"
|
(define_insn "*mov_fix"
|
[(set (match_operand:VEC 0 "nonimmediate_operand" "=r,r,r,m,*f,*f,m,r,*f")
|
[(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"))]
|
(match_operand:VEC 1 "input_operand" "rW,i,m,rW,*fW,m,*f,*f,r"))]
|
"TARGET_FIX
|
"TARGET_FIX
|
&& (register_operand (operands[0], mode)
|
&& (register_operand (operands[0], mode)
|
|| reg_or_0_operand (operands[1], mode))"
|
|| reg_or_0_operand (operands[1], mode))"
|
"@
|
"@
|
bis $31,%r1,%0
|
bis $31,%r1,%0
|
#
|
#
|
ldq %0,%1
|
ldq %0,%1
|
stq %r1,%0
|
stq %r1,%0
|
cpys %R1,%R1,%0
|
cpys %R1,%R1,%0
|
ldt %0,%1
|
ldt %0,%1
|
stt %R1,%0
|
stt %R1,%0
|
ftoit %1,%0
|
ftoit %1,%0
|
itoft %1,%0"
|
itoft %1,%0"
|
[(set_attr "type" "ilog,multi,ild,ist,fcpys,fld,fst,ftoi,itof")])
|
[(set_attr "type" "ilog,multi,ild,ist,fcpys,fld,fst,ftoi,itof")])
|
|
|
(define_insn "*mov_nofix"
|
(define_insn "*mov_nofix"
|
[(set (match_operand:VEC 0 "nonimmediate_operand" "=r,r,r,m,*f,*f,m")
|
[(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"))]
|
(match_operand:VEC 1 "input_operand" "rW,i,m,rW,*fW,m,*f"))]
|
"! TARGET_FIX
|
"! TARGET_FIX
|
&& (register_operand (operands[0], mode)
|
&& (register_operand (operands[0], mode)
|
|| reg_or_0_operand (operands[1], mode))"
|
|| reg_or_0_operand (operands[1], mode))"
|
"@
|
"@
|
bis $31,%r1,%0
|
bis $31,%r1,%0
|
#
|
#
|
ldq %0,%1
|
ldq %0,%1
|
stq %r1,%0
|
stq %r1,%0
|
cpys %R1,%R1,%0
|
cpys %R1,%R1,%0
|
ldt %0,%1
|
ldt %0,%1
|
stt %R1,%0"
|
stt %R1,%0"
|
[(set_attr "type" "ilog,multi,ild,ist,fcpys,fld,fst")])
|
[(set_attr "type" "ilog,multi,ild,ist,fcpys,fld,fst")])
|
|
|
(define_insn "uminv8qi3"
|
(define_insn "uminv8qi3"
|
[(set (match_operand:V8QI 0 "register_operand" "=r")
|
[(set (match_operand:V8QI 0 "register_operand" "=r")
|
(umin:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
|
(umin:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
|
(match_operand:V8QI 2 "reg_or_0_operand" "rW")))]
|
(match_operand:V8QI 2 "reg_or_0_operand" "rW")))]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
"minub8 %r1,%r2,%0"
|
"minub8 %r1,%r2,%0"
|
[(set_attr "type" "mvi")])
|
[(set_attr "type" "mvi")])
|
|
|
(define_insn "sminv8qi3"
|
(define_insn "sminv8qi3"
|
[(set (match_operand:V8QI 0 "register_operand" "=r")
|
[(set (match_operand:V8QI 0 "register_operand" "=r")
|
(smin:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
|
(smin:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
|
(match_operand:V8QI 2 "reg_or_0_operand" "rW")))]
|
(match_operand:V8QI 2 "reg_or_0_operand" "rW")))]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
"minsb8 %r1,%r2,%0"
|
"minsb8 %r1,%r2,%0"
|
[(set_attr "type" "mvi")])
|
[(set_attr "type" "mvi")])
|
|
|
(define_insn "uminv4hi3"
|
(define_insn "uminv4hi3"
|
[(set (match_operand:V4HI 0 "register_operand" "=r")
|
[(set (match_operand:V4HI 0 "register_operand" "=r")
|
(umin:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW")
|
(umin:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW")
|
(match_operand:V4HI 2 "reg_or_0_operand" "rW")))]
|
(match_operand:V4HI 2 "reg_or_0_operand" "rW")))]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
"minuw4 %r1,%r2,%0"
|
"minuw4 %r1,%r2,%0"
|
[(set_attr "type" "mvi")])
|
[(set_attr "type" "mvi")])
|
|
|
(define_insn "sminv4hi3"
|
(define_insn "sminv4hi3"
|
[(set (match_operand:V4HI 0 "register_operand" "=r")
|
[(set (match_operand:V4HI 0 "register_operand" "=r")
|
(smin:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW")
|
(smin:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW")
|
(match_operand:V4HI 2 "reg_or_0_operand" "rW")))]
|
(match_operand:V4HI 2 "reg_or_0_operand" "rW")))]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
"minsw4 %r1,%r2,%0"
|
"minsw4 %r1,%r2,%0"
|
[(set_attr "type" "mvi")])
|
[(set_attr "type" "mvi")])
|
|
|
(define_insn "umaxv8qi3"
|
(define_insn "umaxv8qi3"
|
[(set (match_operand:V8QI 0 "register_operand" "=r")
|
[(set (match_operand:V8QI 0 "register_operand" "=r")
|
(umax:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
|
(umax:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
|
(match_operand:V8QI 2 "reg_or_0_operand" "rW")))]
|
(match_operand:V8QI 2 "reg_or_0_operand" "rW")))]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
"maxub8 %r1,%r2,%0"
|
"maxub8 %r1,%r2,%0"
|
[(set_attr "type" "mvi")])
|
[(set_attr "type" "mvi")])
|
|
|
(define_insn "smaxv8qi3"
|
(define_insn "smaxv8qi3"
|
[(set (match_operand:V8QI 0 "register_operand" "=r")
|
[(set (match_operand:V8QI 0 "register_operand" "=r")
|
(smax:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
|
(smax:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
|
(match_operand:V8QI 2 "reg_or_0_operand" "rW")))]
|
(match_operand:V8QI 2 "reg_or_0_operand" "rW")))]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
"maxsb8 %r1,%r2,%0"
|
"maxsb8 %r1,%r2,%0"
|
[(set_attr "type" "mvi")])
|
[(set_attr "type" "mvi")])
|
|
|
(define_insn "umaxv4hi3"
|
(define_insn "umaxv4hi3"
|
[(set (match_operand:V4HI 0 "register_operand" "=r")
|
[(set (match_operand:V4HI 0 "register_operand" "=r")
|
(umax:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW")
|
(umax:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW")
|
(match_operand:V4HI 2 "reg_or_0_operand" "rW")))]
|
(match_operand:V4HI 2 "reg_or_0_operand" "rW")))]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
"maxuw4 %r1,%r2,%0"
|
"maxuw4 %r1,%r2,%0"
|
[(set_attr "type" "mvi")])
|
[(set_attr "type" "mvi")])
|
|
|
(define_insn "smaxv4hi3"
|
(define_insn "smaxv4hi3"
|
[(set (match_operand:V4HI 0 "register_operand" "=r")
|
[(set (match_operand:V4HI 0 "register_operand" "=r")
|
(smax:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW")
|
(smax:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW")
|
(match_operand:V4HI 2 "reg_or_0_operand" "rW")))]
|
(match_operand:V4HI 2 "reg_or_0_operand" "rW")))]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
"maxsw4 %r1,%r2,%0"
|
"maxsw4 %r1,%r2,%0"
|
[(set_attr "type" "mvi")])
|
[(set_attr "type" "mvi")])
|
|
|
(define_insn "one_cmpl2"
|
(define_insn "one_cmpl2"
|
[(set (match_operand:VEC 0 "register_operand" "=r")
|
[(set (match_operand:VEC 0 "register_operand" "=r")
|
(not:VEC (match_operand:VEC 1 "register_operand" "r")))]
|
(not:VEC (match_operand:VEC 1 "register_operand" "r")))]
|
""
|
""
|
"ornot $31,%1,%0"
|
"ornot $31,%1,%0"
|
[(set_attr "type" "ilog")])
|
[(set_attr "type" "ilog")])
|
|
|
(define_insn "and3"
|
(define_insn "and3"
|
[(set (match_operand:VEC 0 "register_operand" "=r")
|
[(set (match_operand:VEC 0 "register_operand" "=r")
|
(and:VEC (match_operand:VEC 1 "register_operand" "r")
|
(and:VEC (match_operand:VEC 1 "register_operand" "r")
|
(match_operand:VEC 2 "register_operand" "r")))]
|
(match_operand:VEC 2 "register_operand" "r")))]
|
""
|
""
|
"and %1,%2,%0"
|
"and %1,%2,%0"
|
[(set_attr "type" "ilog")])
|
[(set_attr "type" "ilog")])
|
|
|
(define_insn "*andnot3"
|
(define_insn "*andnot3"
|
[(set (match_operand:VEC 0 "register_operand" "=r")
|
[(set (match_operand:VEC 0 "register_operand" "=r")
|
(and:VEC (not:VEC (match_operand:VEC 1 "register_operand" "r"))
|
(and:VEC (not:VEC (match_operand:VEC 1 "register_operand" "r"))
|
(match_operand:VEC 2 "register_operand" "r")))]
|
(match_operand:VEC 2 "register_operand" "r")))]
|
""
|
""
|
"bic %2,%1,%0"
|
"bic %2,%1,%0"
|
[(set_attr "type" "ilog")])
|
[(set_attr "type" "ilog")])
|
|
|
(define_insn "ior3"
|
(define_insn "ior3"
|
[(set (match_operand:VEC 0 "register_operand" "=r")
|
[(set (match_operand:VEC 0 "register_operand" "=r")
|
(ior:VEC (match_operand:VEC 1 "register_operand" "r")
|
(ior:VEC (match_operand:VEC 1 "register_operand" "r")
|
(match_operand:VEC 2 "register_operand" "r")))]
|
(match_operand:VEC 2 "register_operand" "r")))]
|
""
|
""
|
"bis %1,%2,%0"
|
"bis %1,%2,%0"
|
[(set_attr "type" "ilog")])
|
[(set_attr "type" "ilog")])
|
|
|
(define_insn "*iornot3"
|
(define_insn "*iornot3"
|
[(set (match_operand:VEC 0 "register_operand" "=r")
|
[(set (match_operand:VEC 0 "register_operand" "=r")
|
(ior:VEC (not:DI (match_operand:VEC 1 "register_operand" "r"))
|
(ior:VEC (not:DI (match_operand:VEC 1 "register_operand" "r"))
|
(match_operand:VEC 2 "register_operand" "r")))]
|
(match_operand:VEC 2 "register_operand" "r")))]
|
""
|
""
|
"ornot %2,%1,%0"
|
"ornot %2,%1,%0"
|
[(set_attr "type" "ilog")])
|
[(set_attr "type" "ilog")])
|
|
|
(define_insn "xor3"
|
(define_insn "xor3"
|
[(set (match_operand:VEC 0 "register_operand" "=r")
|
[(set (match_operand:VEC 0 "register_operand" "=r")
|
(xor:VEC (match_operand:VEC 1 "register_operand" "r")
|
(xor:VEC (match_operand:VEC 1 "register_operand" "r")
|
(match_operand:VEC 2 "register_operand" "r")))]
|
(match_operand:VEC 2 "register_operand" "r")))]
|
""
|
""
|
"xor %1,%2,%0"
|
"xor %1,%2,%0"
|
[(set_attr "type" "ilog")])
|
[(set_attr "type" "ilog")])
|
|
|
(define_insn "*xornot3"
|
(define_insn "*xornot3"
|
[(set (match_operand:VEC 0 "register_operand" "=r")
|
[(set (match_operand:VEC 0 "register_operand" "=r")
|
(not:VEC (xor:VEC (match_operand:VEC 1 "register_operand" "r")
|
(not:VEC (xor:VEC (match_operand:VEC 1 "register_operand" "r")
|
(match_operand:VEC 2 "register_operand" "r"))))]
|
(match_operand:VEC 2 "register_operand" "r"))))]
|
""
|
""
|
"eqv %1,%2,%0"
|
"eqv %1,%2,%0"
|
[(set_attr "type" "ilog")])
|
[(set_attr "type" "ilog")])
|
|
|
(define_expand "vec_shl_"
|
(define_expand "vec_shl_"
|
[(set (match_operand:VEC 0 "register_operand" "")
|
[(set (match_operand:VEC 0 "register_operand" "")
|
(ashift:DI (match_operand:VEC 1 "register_operand" "")
|
(ashift:DI (match_operand:VEC 1 "register_operand" "")
|
(match_operand:DI 2 "reg_or_6bit_operand" "")))]
|
(match_operand:DI 2 "reg_or_6bit_operand" "")))]
|
""
|
""
|
{
|
{
|
operands[0] = gen_lowpart (DImode, operands[0]);
|
operands[0] = gen_lowpart (DImode, operands[0]);
|
operands[1] = gen_lowpart (DImode, operands[1]);
|
operands[1] = gen_lowpart (DImode, operands[1]);
|
})
|
})
|
|
|
(define_expand "vec_shr_"
|
(define_expand "vec_shr_"
|
[(set (match_operand:VEC 0 "register_operand" "")
|
[(set (match_operand:VEC 0 "register_operand" "")
|
(lshiftrt:DI (match_operand:VEC 1 "register_operand" "")
|
(lshiftrt:DI (match_operand:VEC 1 "register_operand" "")
|
(match_operand:DI 2 "reg_or_6bit_operand" "")))]
|
(match_operand:DI 2 "reg_or_6bit_operand" "")))]
|
""
|
""
|
{
|
{
|
operands[0] = gen_lowpart (DImode, operands[0]);
|
operands[0] = gen_lowpart (DImode, operands[0]);
|
operands[1] = gen_lowpart (DImode, operands[1]);
|
operands[1] = gen_lowpart (DImode, operands[1]);
|
})
|
})
|
|
|
;; Bit field extract patterns which use ext[wlq][lh]
|
;; Bit field extract patterns which use ext[wlq][lh]
|
|
|
(define_expand "extv"
|
(define_expand "extv"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(sign_extract:DI (match_operand:QI 1 "memory_operand" "")
|
(sign_extract:DI (match_operand:QI 1 "memory_operand" "")
|
(match_operand:DI 2 "immediate_operand" "")
|
(match_operand:DI 2 "immediate_operand" "")
|
(match_operand:DI 3 "immediate_operand" "")))]
|
(match_operand:DI 3 "immediate_operand" "")))]
|
""
|
""
|
{
|
{
|
int ofs;
|
int ofs;
|
|
|
/* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */
|
/* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */
|
if (INTVAL (operands[3]) % 8 != 0
|
if (INTVAL (operands[3]) % 8 != 0
|
|| (INTVAL (operands[2]) != 16
|
|| (INTVAL (operands[2]) != 16
|
&& INTVAL (operands[2]) != 32
|
&& INTVAL (operands[2]) != 32
|
&& INTVAL (operands[2]) != 64))
|
&& INTVAL (operands[2]) != 64))
|
FAIL;
|
FAIL;
|
|
|
/* From mips.md: extract_bit_field doesn't verify that our source
|
/* From mips.md: extract_bit_field doesn't verify that our source
|
matches the predicate, so we force it to be a MEM here. */
|
matches the predicate, so we force it to be a MEM here. */
|
if (!MEM_P (operands[1]))
|
if (!MEM_P (operands[1]))
|
FAIL;
|
FAIL;
|
|
|
/* The bit number is relative to the mode of operand 1 which is
|
/* The bit number is relative to the mode of operand 1 which is
|
usually QImode (this might actually be a bug in expmed.c). Note
|
usually QImode (this might actually be a bug in expmed.c). Note
|
that the bit number is negative in big-endian mode in this case.
|
that the bit number is negative in big-endian mode in this case.
|
We have to convert that to the offset. */
|
We have to convert that to the offset. */
|
if (WORDS_BIG_ENDIAN)
|
if (WORDS_BIG_ENDIAN)
|
ofs = GET_MODE_BITSIZE (GET_MODE (operands[1]))
|
ofs = GET_MODE_BITSIZE (GET_MODE (operands[1]))
|
- INTVAL (operands[2]) - INTVAL (operands[3]);
|
- INTVAL (operands[2]) - INTVAL (operands[3]);
|
else
|
else
|
ofs = INTVAL (operands[3]);
|
ofs = INTVAL (operands[3]);
|
|
|
ofs = ofs / 8;
|
ofs = ofs / 8;
|
|
|
alpha_expand_unaligned_load (operands[0], operands[1],
|
alpha_expand_unaligned_load (operands[0], operands[1],
|
INTVAL (operands[2]) / 8,
|
INTVAL (operands[2]) / 8,
|
ofs, 1);
|
ofs, 1);
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "extzv"
|
(define_expand "extzv"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(zero_extract:DI (match_operand:DI 1 "nonimmediate_operand" "")
|
(zero_extract:DI (match_operand:DI 1 "nonimmediate_operand" "")
|
(match_operand:DI 2 "immediate_operand" "")
|
(match_operand:DI 2 "immediate_operand" "")
|
(match_operand:DI 3 "immediate_operand" "")))]
|
(match_operand:DI 3 "immediate_operand" "")))]
|
""
|
""
|
{
|
{
|
/* We can do 8, 16, 32 and 64 bit fields, if aligned on byte boundaries. */
|
/* We can do 8, 16, 32 and 64 bit fields, if aligned on byte boundaries. */
|
if (INTVAL (operands[3]) % 8 != 0
|
if (INTVAL (operands[3]) % 8 != 0
|
|| (INTVAL (operands[2]) != 8
|
|| (INTVAL (operands[2]) != 8
|
&& INTVAL (operands[2]) != 16
|
&& INTVAL (operands[2]) != 16
|
&& INTVAL (operands[2]) != 32
|
&& INTVAL (operands[2]) != 32
|
&& INTVAL (operands[2]) != 64))
|
&& INTVAL (operands[2]) != 64))
|
FAIL;
|
FAIL;
|
|
|
if (MEM_P (operands[1]))
|
if (MEM_P (operands[1]))
|
{
|
{
|
int ofs;
|
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)
|
if (INTVAL (operands[2]) == 8)
|
FAIL;
|
FAIL;
|
|
|
/* The bit number is relative to the mode of operand 1 which is
|
/* The bit number is relative to the mode of operand 1 which is
|
usually QImode (this might actually be a bug in expmed.c). Note
|
usually QImode (this might actually be a bug in expmed.c). Note
|
that the bit number is negative in big-endian mode in this case.
|
that the bit number is negative in big-endian mode in this case.
|
We have to convert that to the offset. */
|
We have to convert that to the offset. */
|
if (WORDS_BIG_ENDIAN)
|
if (WORDS_BIG_ENDIAN)
|
ofs = GET_MODE_BITSIZE (GET_MODE (operands[1]))
|
ofs = GET_MODE_BITSIZE (GET_MODE (operands[1]))
|
- INTVAL (operands[2]) - INTVAL (operands[3]);
|
- INTVAL (operands[2]) - INTVAL (operands[3]);
|
else
|
else
|
ofs = INTVAL (operands[3]);
|
ofs = INTVAL (operands[3]);
|
|
|
ofs = ofs / 8;
|
ofs = ofs / 8;
|
|
|
alpha_expand_unaligned_load (operands[0], operands[1],
|
alpha_expand_unaligned_load (operands[0], operands[1],
|
INTVAL (operands[2]) / 8,
|
INTVAL (operands[2]) / 8,
|
ofs, 0);
|
ofs, 0);
|
DONE;
|
DONE;
|
}
|
}
|
})
|
})
|
|
|
(define_expand "insv"
|
(define_expand "insv"
|
[(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "")
|
[(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "")
|
(match_operand:DI 1 "immediate_operand" "")
|
(match_operand:DI 1 "immediate_operand" "")
|
(match_operand:DI 2 "immediate_operand" ""))
|
(match_operand:DI 2 "immediate_operand" ""))
|
(match_operand:DI 3 "register_operand" ""))]
|
(match_operand:DI 3 "register_operand" ""))]
|
""
|
""
|
{
|
{
|
int ofs;
|
int ofs;
|
|
|
/* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */
|
/* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */
|
if (INTVAL (operands[2]) % 8 != 0
|
if (INTVAL (operands[2]) % 8 != 0
|
|| (INTVAL (operands[1]) != 16
|
|| (INTVAL (operands[1]) != 16
|
&& INTVAL (operands[1]) != 32
|
&& INTVAL (operands[1]) != 32
|
&& INTVAL (operands[1]) != 64))
|
&& INTVAL (operands[1]) != 64))
|
FAIL;
|
FAIL;
|
|
|
/* From mips.md: store_bit_field doesn't verify that our source
|
/* From mips.md: store_bit_field doesn't verify that our source
|
matches the predicate, so we force it to be a MEM here. */
|
matches the predicate, so we force it to be a MEM here. */
|
if (!MEM_P (operands[0]))
|
if (!MEM_P (operands[0]))
|
FAIL;
|
FAIL;
|
|
|
/* The bit number is relative to the mode of operand 1 which is
|
/* The bit number is relative to the mode of operand 1 which is
|
usually QImode (this might actually be a bug in expmed.c). Note
|
usually QImode (this might actually be a bug in expmed.c). Note
|
that the bit number is negative in big-endian mode in this case.
|
that the bit number is negative in big-endian mode in this case.
|
We have to convert that to the offset. */
|
We have to convert that to the offset. */
|
if (WORDS_BIG_ENDIAN)
|
if (WORDS_BIG_ENDIAN)
|
ofs = GET_MODE_BITSIZE (GET_MODE (operands[0]))
|
ofs = GET_MODE_BITSIZE (GET_MODE (operands[0]))
|
- INTVAL (operands[1]) - INTVAL (operands[2]);
|
- INTVAL (operands[1]) - INTVAL (operands[2]);
|
else
|
else
|
ofs = INTVAL (operands[2]);
|
ofs = INTVAL (operands[2]);
|
|
|
ofs = ofs / 8;
|
ofs = ofs / 8;
|
|
|
alpha_expand_unaligned_store (operands[0], operands[3],
|
alpha_expand_unaligned_store (operands[0], operands[3],
|
INTVAL (operands[1]) / 8, ofs);
|
INTVAL (operands[1]) / 8, ofs);
|
DONE;
|
DONE;
|
})
|
})
|
|
|
;; Block move/clear, see alpha.c for more details.
|
;; Block move/clear, see alpha.c for more details.
|
;; Argument 0 is the destination
|
;; Argument 0 is the destination
|
;; Argument 1 is the source
|
;; Argument 1 is the source
|
;; Argument 2 is the length
|
;; Argument 2 is the length
|
;; Argument 3 is the alignment
|
;; Argument 3 is the alignment
|
|
|
(define_expand "movmemqi"
|
(define_expand "movmemqi"
|
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
|
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
|
(match_operand:BLK 1 "memory_operand" ""))
|
(match_operand:BLK 1 "memory_operand" ""))
|
(use (match_operand:DI 2 "immediate_operand" ""))
|
(use (match_operand:DI 2 "immediate_operand" ""))
|
(use (match_operand:DI 3 "immediate_operand" ""))])]
|
(use (match_operand:DI 3 "immediate_operand" ""))])]
|
""
|
""
|
{
|
{
|
if (alpha_expand_block_move (operands))
|
if (alpha_expand_block_move (operands))
|
DONE;
|
DONE;
|
else
|
else
|
FAIL;
|
FAIL;
|
})
|
})
|
|
|
(define_expand "movmemdi"
|
(define_expand "movmemdi"
|
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
|
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
|
(match_operand:BLK 1 "memory_operand" ""))
|
(match_operand:BLK 1 "memory_operand" ""))
|
(use (match_operand:DI 2 "immediate_operand" ""))
|
(use (match_operand:DI 2 "immediate_operand" ""))
|
(use (match_operand:DI 3 "immediate_operand" ""))
|
(use (match_operand:DI 3 "immediate_operand" ""))
|
(use (match_dup 4))
|
(use (match_dup 4))
|
(clobber (reg:DI 25))
|
(clobber (reg:DI 25))
|
(clobber (reg:DI 16))
|
(clobber (reg:DI 16))
|
(clobber (reg:DI 17))
|
(clobber (reg:DI 17))
|
(clobber (reg:DI 18))
|
(clobber (reg:DI 18))
|
(clobber (reg:DI 19))
|
(clobber (reg:DI 19))
|
(clobber (reg:DI 20))
|
(clobber (reg:DI 20))
|
(clobber (reg:DI 26))
|
(clobber (reg:DI 26))
|
(clobber (reg:DI 27))])]
|
(clobber (reg:DI 27))])]
|
"TARGET_ABI_OPEN_VMS"
|
"TARGET_ABI_OPEN_VMS"
|
{
|
{
|
operands[4] = alpha_need_linkage ("OTS$MOVE", 0);
|
operands[4] = alpha_need_linkage ("OTS$MOVE", 0);
|
})
|
})
|
|
|
(define_insn "*movmemdi_1"
|
(define_insn "*movmemdi_1"
|
[(set (match_operand:BLK 0 "memory_operand" "=m,=m")
|
[(set (match_operand:BLK 0 "memory_operand" "=m,=m")
|
(match_operand:BLK 1 "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 2 "nonmemory_operand" "r,i"))
|
(use (match_operand:DI 3 "immediate_operand" ""))
|
(use (match_operand:DI 3 "immediate_operand" ""))
|
(use (match_operand:DI 4 "call_operand" "i,i"))
|
(use (match_operand:DI 4 "call_operand" "i,i"))
|
(clobber (reg:DI 25))
|
(clobber (reg:DI 25))
|
(clobber (reg:DI 16))
|
(clobber (reg:DI 16))
|
(clobber (reg:DI 17))
|
(clobber (reg:DI 17))
|
(clobber (reg:DI 18))
|
(clobber (reg:DI 18))
|
(clobber (reg:DI 19))
|
(clobber (reg:DI 19))
|
(clobber (reg:DI 20))
|
(clobber (reg:DI 20))
|
(clobber (reg:DI 26))
|
(clobber (reg:DI 26))
|
(clobber (reg:DI 27))]
|
(clobber (reg:DI 27))]
|
"TARGET_ABI_OPEN_VMS"
|
"TARGET_ABI_OPEN_VMS"
|
{
|
{
|
operands [5] = alpha_use_linkage (operands [4], cfun->decl, 0, 1);
|
operands [5] = alpha_use_linkage (operands [4], cfun->decl, 0, 1);
|
switch (which_alternative)
|
switch (which_alternative)
|
{
|
{
|
case 0:
|
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)";
|
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:
|
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)";
|
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:
|
default:
|
gcc_unreachable ();
|
gcc_unreachable ();
|
}
|
}
|
}
|
}
|
[(set_attr "type" "multi")
|
[(set_attr "type" "multi")
|
(set_attr "length" "28")])
|
(set_attr "length" "28")])
|
|
|
(define_expand "setmemqi"
|
(define_expand "setmemqi"
|
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
|
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
|
(match_operand 2 "const_int_operand" ""))
|
(match_operand 2 "const_int_operand" ""))
|
(use (match_operand:DI 1 "immediate_operand" ""))
|
(use (match_operand:DI 1 "immediate_operand" ""))
|
(use (match_operand:DI 3 "immediate_operand" ""))])]
|
(use (match_operand:DI 3 "immediate_operand" ""))])]
|
""
|
""
|
{
|
{
|
/* If value to set is not zero, use the library routine. */
|
/* If value to set is not zero, use the library routine. */
|
if (operands[2] != const0_rtx)
|
if (operands[2] != const0_rtx)
|
FAIL;
|
FAIL;
|
|
|
if (alpha_expand_block_clear (operands))
|
if (alpha_expand_block_clear (operands))
|
DONE;
|
DONE;
|
else
|
else
|
FAIL;
|
FAIL;
|
})
|
})
|
|
|
(define_expand "setmemdi"
|
(define_expand "setmemdi"
|
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
|
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
|
(match_operand 2 "const_int_operand" ""))
|
(match_operand 2 "const_int_operand" ""))
|
(use (match_operand:DI 1 "immediate_operand" ""))
|
(use (match_operand:DI 1 "immediate_operand" ""))
|
(use (match_operand:DI 3 "immediate_operand" ""))
|
(use (match_operand:DI 3 "immediate_operand" ""))
|
(use (match_dup 4))
|
(use (match_dup 4))
|
(clobber (reg:DI 25))
|
(clobber (reg:DI 25))
|
(clobber (reg:DI 16))
|
(clobber (reg:DI 16))
|
(clobber (reg:DI 17))
|
(clobber (reg:DI 17))
|
(clobber (reg:DI 26))
|
(clobber (reg:DI 26))
|
(clobber (reg:DI 27))])]
|
(clobber (reg:DI 27))])]
|
"TARGET_ABI_OPEN_VMS"
|
"TARGET_ABI_OPEN_VMS"
|
{
|
{
|
/* If value to set is not zero, use the library routine. */
|
/* If value to set is not zero, use the library routine. */
|
if (operands[2] != const0_rtx)
|
if (operands[2] != const0_rtx)
|
FAIL;
|
FAIL;
|
|
|
operands[4] = alpha_need_linkage ("OTS$ZERO", 0);
|
operands[4] = alpha_need_linkage ("OTS$ZERO", 0);
|
})
|
})
|
|
|
(define_insn "*clrmemdi_1"
|
(define_insn "*clrmemdi_1"
|
[(set (match_operand:BLK 0 "memory_operand" "=m,=m")
|
[(set (match_operand:BLK 0 "memory_operand" "=m,=m")
|
(const_int 0))
|
(const_int 0))
|
(use (match_operand:DI 1 "nonmemory_operand" "r,i"))
|
(use (match_operand:DI 1 "nonmemory_operand" "r,i"))
|
(use (match_operand:DI 2 "immediate_operand" ""))
|
(use (match_operand:DI 2 "immediate_operand" ""))
|
(use (match_operand:DI 3 "call_operand" "i,i"))
|
(use (match_operand:DI 3 "call_operand" "i,i"))
|
(clobber (reg:DI 25))
|
(clobber (reg:DI 25))
|
(clobber (reg:DI 16))
|
(clobber (reg:DI 16))
|
(clobber (reg:DI 17))
|
(clobber (reg:DI 17))
|
(clobber (reg:DI 26))
|
(clobber (reg:DI 26))
|
(clobber (reg:DI 27))]
|
(clobber (reg:DI 27))]
|
"TARGET_ABI_OPEN_VMS"
|
"TARGET_ABI_OPEN_VMS"
|
{
|
{
|
operands [4] = alpha_use_linkage (operands [3], cfun->decl, 0, 1);
|
operands [4] = alpha_use_linkage (operands [3], cfun->decl, 0, 1);
|
switch (which_alternative)
|
switch (which_alternative)
|
{
|
{
|
case 0:
|
case 0:
|
return "lda $16,%0\;bis $31,%1,$17\;ldq $26,%4\;lda $25,2($31)\;jsr $26,%3\;ldq $27,0($29)";
|
return "lda $16,%0\;bis $31,%1,$17\;ldq $26,%4\;lda $25,2($31)\;jsr $26,%3\;ldq $27,0($29)";
|
case 1:
|
case 1:
|
return "lda $16,%0\;lda $17,%1($31)\;ldq $26,%4\;lda $25,2($31)\;jsr $26,%3\;ldq $27,0($29)";
|
return "lda $16,%0\;lda $17,%1($31)\;ldq $26,%4\;lda $25,2($31)\;jsr $26,%3\;ldq $27,0($29)";
|
default:
|
default:
|
gcc_unreachable ();
|
gcc_unreachable ();
|
}
|
}
|
}
|
}
|
[(set_attr "type" "multi")
|
[(set_attr "type" "multi")
|
(set_attr "length" "24")])
|
(set_attr "length" "24")])
|
|
|
|
|
;; Subroutine of stack space allocation. Perform a stack probe.
|
;; Subroutine of stack space allocation. Perform a stack probe.
|
(define_expand "probe_stack"
|
(define_expand "probe_stack"
|
[(set (match_dup 1) (match_operand:DI 0 "const_int_operand" ""))]
|
[(set (match_dup 1) (match_operand:DI 0 "const_int_operand" ""))]
|
""
|
""
|
{
|
{
|
operands[1] = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx,
|
operands[1] = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx,
|
INTVAL (operands[0])));
|
INTVAL (operands[0])));
|
MEM_VOLATILE_P (operands[1]) = 1;
|
MEM_VOLATILE_P (operands[1]) = 1;
|
|
|
operands[0] = const0_rtx;
|
operands[0] = const0_rtx;
|
})
|
})
|
|
|
;; This is how we allocate stack space. If we are allocating a
|
;; This is how we allocate stack space. If we are allocating a
|
;; constant amount of space and we know it is less than 4096
|
;; constant amount of space and we know it is less than 4096
|
;; bytes, we need do nothing.
|
;; bytes, we need do nothing.
|
;;
|
;;
|
;; If it is more than 4096 bytes, we need to probe the stack
|
;; If it is more than 4096 bytes, we need to probe the stack
|
;; periodically.
|
;; periodically.
|
(define_expand "allocate_stack"
|
(define_expand "allocate_stack"
|
[(set (reg:DI 30)
|
[(set (reg:DI 30)
|
(plus:DI (reg:DI 30)
|
(plus:DI (reg:DI 30)
|
(match_operand:DI 1 "reg_or_cint_operand" "")))
|
(match_operand:DI 1 "reg_or_cint_operand" "")))
|
(set (match_operand:DI 0 "register_operand" "=r")
|
(set (match_operand:DI 0 "register_operand" "=r")
|
(match_dup 2))]
|
(match_dup 2))]
|
""
|
""
|
{
|
{
|
if (CONST_INT_P (operands[1])
|
if (CONST_INT_P (operands[1])
|
&& INTVAL (operands[1]) < 32768)
|
&& INTVAL (operands[1]) < 32768)
|
{
|
{
|
if (INTVAL (operands[1]) >= 4096)
|
if (INTVAL (operands[1]) >= 4096)
|
{
|
{
|
/* We do this the same way as in the prologue and generate explicit
|
/* We do this the same way as in the prologue and generate explicit
|
probes. Then we update the stack by the constant. */
|
probes. Then we update the stack by the constant. */
|
|
|
int probed = 4096;
|
int probed = 4096;
|
|
|
emit_insn (gen_probe_stack (GEN_INT (- probed)));
|
emit_insn (gen_probe_stack (GEN_INT (- probed)));
|
while (probed + 8192 < INTVAL (operands[1]))
|
while (probed + 8192 < INTVAL (operands[1]))
|
emit_insn (gen_probe_stack (GEN_INT (- (probed += 8192))));
|
emit_insn (gen_probe_stack (GEN_INT (- (probed += 8192))));
|
|
|
if (probed + 4096 < INTVAL (operands[1]))
|
if (probed + 4096 < INTVAL (operands[1]))
|
emit_insn (gen_probe_stack (GEN_INT (- INTVAL(operands[1]))));
|
emit_insn (gen_probe_stack (GEN_INT (- INTVAL(operands[1]))));
|
}
|
}
|
|
|
operands[1] = GEN_INT (- INTVAL (operands[1]));
|
operands[1] = GEN_INT (- INTVAL (operands[1]));
|
operands[2] = virtual_stack_dynamic_rtx;
|
operands[2] = virtual_stack_dynamic_rtx;
|
}
|
}
|
else
|
else
|
{
|
{
|
rtx out_label = 0;
|
rtx out_label = 0;
|
rtx loop_label = gen_label_rtx ();
|
rtx loop_label = gen_label_rtx ();
|
rtx want = gen_reg_rtx (Pmode);
|
rtx want = gen_reg_rtx (Pmode);
|
rtx tmp = gen_reg_rtx (Pmode);
|
rtx tmp = gen_reg_rtx (Pmode);
|
rtx memref, test;
|
rtx memref, test;
|
|
|
emit_insn (gen_subdi3 (want, stack_pointer_rtx,
|
emit_insn (gen_subdi3 (want, stack_pointer_rtx,
|
force_reg (Pmode, operands[1])));
|
force_reg (Pmode, operands[1])));
|
emit_insn (gen_adddi3 (tmp, stack_pointer_rtx, GEN_INT (-4096)));
|
emit_insn (gen_adddi3 (tmp, stack_pointer_rtx, GEN_INT (-4096)));
|
|
|
if (!CONST_INT_P (operands[1]))
|
if (!CONST_INT_P (operands[1]))
|
{
|
{
|
out_label = gen_label_rtx ();
|
out_label = gen_label_rtx ();
|
test = gen_rtx_GEU (VOIDmode, want, tmp);
|
test = gen_rtx_GEU (VOIDmode, want, tmp);
|
emit_jump_insn (gen_cbranchdi4 (test, want, tmp, out_label));
|
emit_jump_insn (gen_cbranchdi4 (test, want, tmp, out_label));
|
}
|
}
|
|
|
emit_label (loop_label);
|
emit_label (loop_label);
|
memref = gen_rtx_MEM (DImode, tmp);
|
memref = gen_rtx_MEM (DImode, tmp);
|
MEM_VOLATILE_P (memref) = 1;
|
MEM_VOLATILE_P (memref) = 1;
|
emit_move_insn (memref, const0_rtx);
|
emit_move_insn (memref, const0_rtx);
|
emit_insn (gen_adddi3 (tmp, tmp, GEN_INT(-8192)));
|
emit_insn (gen_adddi3 (tmp, tmp, GEN_INT(-8192)));
|
test = gen_rtx_GTU (VOIDmode, tmp, want);
|
test = gen_rtx_GTU (VOIDmode, tmp, want);
|
emit_jump_insn (gen_cbranchdi4 (test, tmp, want, loop_label));
|
emit_jump_insn (gen_cbranchdi4 (test, tmp, want, loop_label));
|
|
|
memref = gen_rtx_MEM (DImode, want);
|
memref = gen_rtx_MEM (DImode, want);
|
MEM_VOLATILE_P (memref) = 1;
|
MEM_VOLATILE_P (memref) = 1;
|
emit_move_insn (memref, const0_rtx);
|
emit_move_insn (memref, const0_rtx);
|
|
|
if (out_label)
|
if (out_label)
|
emit_label (out_label);
|
emit_label (out_label);
|
|
|
emit_move_insn (stack_pointer_rtx, want);
|
emit_move_insn (stack_pointer_rtx, want);
|
emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
|
emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
|
DONE;
|
DONE;
|
}
|
}
|
})
|
})
|
|
|
;; This is used by alpha_expand_prolog to do the same thing as above,
|
;; This is used by alpha_expand_prolog to do the same thing as above,
|
;; except we cannot at that time generate new basic blocks, so we hide
|
;; except we cannot at that time generate new basic blocks, so we hide
|
;; the loop in this one insn.
|
;; the loop in this one insn.
|
|
|
(define_insn "prologue_stack_probe_loop"
|
(define_insn "prologue_stack_probe_loop"
|
[(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
|
[(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
|
(match_operand:DI 1 "register_operand" "r")]
|
(match_operand:DI 1 "register_operand" "r")]
|
UNSPECV_PSPL)]
|
UNSPECV_PSPL)]
|
""
|
""
|
{
|
{
|
operands[2] = gen_label_rtx ();
|
operands[2] = gen_label_rtx ();
|
(*targetm.asm_out.internal_label) (asm_out_file, "L",
|
(*targetm.asm_out.internal_label) (asm_out_file, "L",
|
CODE_LABEL_NUMBER (operands[2]));
|
CODE_LABEL_NUMBER (operands[2]));
|
|
|
return "stq $31,-8192(%1)\;subq %0,1,%0\;lda %1,-8192(%1)\;bne %0,%l2";
|
return "stq $31,-8192(%1)\;subq %0,1,%0\;lda %1,-8192(%1)\;bne %0,%l2";
|
}
|
}
|
[(set_attr "length" "16")
|
[(set_attr "length" "16")
|
(set_attr "type" "multi")])
|
(set_attr "type" "multi")])
|
|
|
(define_expand "prologue"
|
(define_expand "prologue"
|
[(clobber (const_int 0))]
|
[(clobber (const_int 0))]
|
""
|
""
|
{
|
{
|
alpha_expand_prologue ();
|
alpha_expand_prologue ();
|
DONE;
|
DONE;
|
})
|
})
|
|
|
;; These take care of emitting the ldgp insn in the prologue. This will be
|
;; These take care of emitting the ldgp insn in the prologue. This will be
|
;; an lda/ldah pair and we want to align them properly. So we have two
|
;; an lda/ldah pair and we want to align them properly. So we have two
|
;; unspec_volatile insns, the first of which emits the ldgp assembler macro
|
;; unspec_volatile insns, the first of which emits the ldgp assembler macro
|
;; and the second of which emits nothing. However, both are marked as type
|
;; and the second of which emits nothing. However, both are marked as type
|
;; IADD (the default) so the alignment code in alpha.c does the right thing
|
;; IADD (the default) so the alignment code in alpha.c does the right thing
|
;; with them.
|
;; with them.
|
|
|
(define_expand "prologue_ldgp"
|
(define_expand "prologue_ldgp"
|
[(set (match_dup 0)
|
[(set (match_dup 0)
|
(unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1))
|
(unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1))
|
(set (match_dup 0)
|
(set (match_dup 0)
|
(unspec_volatile:DI [(match_dup 0) (match_dup 2)] UNSPECV_PLDGP2))]
|
(unspec_volatile:DI [(match_dup 0) (match_dup 2)] UNSPECV_PLDGP2))]
|
""
|
""
|
{
|
{
|
operands[0] = pic_offset_table_rtx;
|
operands[0] = pic_offset_table_rtx;
|
operands[1] = gen_rtx_REG (Pmode, 27);
|
operands[1] = gen_rtx_REG (Pmode, 27);
|
operands[2] = (TARGET_EXPLICIT_RELOCS
|
operands[2] = (TARGET_EXPLICIT_RELOCS
|
? GEN_INT (alpha_next_sequence_number++)
|
? GEN_INT (alpha_next_sequence_number++)
|
: const0_rtx);
|
: const0_rtx);
|
})
|
})
|
|
|
(define_insn "*ldgp_er_1"
|
(define_insn "*ldgp_er_1"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
|
(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
|
(match_operand 2 "const_int_operand" "")]
|
(match_operand 2 "const_int_operand" "")]
|
UNSPECV_LDGP1))]
|
UNSPECV_LDGP1))]
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
"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")])
|
[(set_attr "cannot_copy" "true")])
|
|
|
(define_insn "*ldgp_er_2"
|
(define_insn "*ldgp_er_2"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
|
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
|
(match_operand 2 "const_int_operand" "")]
|
(match_operand 2 "const_int_operand" "")]
|
UNSPEC_LDGP2))]
|
UNSPEC_LDGP2))]
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
"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")])
|
[(set_attr "cannot_copy" "true")])
|
|
|
(define_insn "*prologue_ldgp_er_2"
|
(define_insn "*prologue_ldgp_er_2"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
|
(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
|
(match_operand 2 "const_int_operand" "")]
|
(match_operand 2 "const_int_operand" "")]
|
UNSPECV_PLDGP2))]
|
UNSPECV_PLDGP2))]
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
"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")])
|
[(set_attr "cannot_copy" "true")])
|
|
|
(define_insn "*prologue_ldgp_1"
|
(define_insn "*prologue_ldgp_1"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
|
(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
|
(match_operand 2 "const_int_operand" "")]
|
(match_operand 2 "const_int_operand" "")]
|
UNSPECV_LDGP1))]
|
UNSPECV_LDGP1))]
|
""
|
""
|
"ldgp %0,0(%1)\n$%~..ng:"
|
"ldgp %0,0(%1)\n$%~..ng:"
|
[(set_attr "cannot_copy" "true")])
|
[(set_attr "cannot_copy" "true")])
|
|
|
(define_insn "*prologue_ldgp_2"
|
(define_insn "*prologue_ldgp_2"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
|
(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
|
(match_operand 2 "const_int_operand" "")]
|
(match_operand 2 "const_int_operand" "")]
|
UNSPECV_PLDGP2))]
|
UNSPECV_PLDGP2))]
|
""
|
""
|
"")
|
"")
|
|
|
;; The _mcount profiling hook has special calling conventions, and
|
;; The _mcount profiling hook has special calling conventions, and
|
;; does not clobber all the registers that a normal call would. So
|
;; does not clobber all the registers that a normal call would. So
|
;; hide the fact this is a call at all.
|
;; hide the fact this is a call at all.
|
|
|
(define_insn "prologue_mcount"
|
(define_insn "prologue_mcount"
|
[(unspec_volatile [(const_int 0)] UNSPECV_MCOUNT)]
|
[(unspec_volatile [(const_int 0)] UNSPECV_MCOUNT)]
|
""
|
""
|
{
|
{
|
if (TARGET_EXPLICIT_RELOCS)
|
if (TARGET_EXPLICIT_RELOCS)
|
/* Note that we cannot use a lituse_jsr reloc, since _mcount
|
/* Note that we cannot use a lituse_jsr reloc, since _mcount
|
cannot be called via the PLT. */
|
cannot be called via the PLT. */
|
return "ldq $28,_mcount($29)\t\t!literal\;jsr $28,($28),_mcount";
|
return "ldq $28,_mcount($29)\t\t!literal\;jsr $28,($28),_mcount";
|
else
|
else
|
return "lda $28,_mcount\;jsr $28,($28),_mcount";
|
return "lda $28,_mcount\;jsr $28,($28),_mcount";
|
}
|
}
|
[(set_attr "type" "multi")
|
[(set_attr "type" "multi")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn "init_fp"
|
(define_insn "init_fp"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(match_operand:DI 1 "register_operand" "r"))
|
(match_operand:DI 1 "register_operand" "r"))
|
(clobber (mem:BLK (match_operand:DI 2 "register_operand" "=r")))]
|
(clobber (mem:BLK (match_operand:DI 2 "register_operand" "=r")))]
|
""
|
""
|
"bis $31,%1,%0")
|
"bis $31,%1,%0")
|
|
|
(define_expand "epilogue"
|
(define_expand "epilogue"
|
[(return)]
|
[(return)]
|
""
|
""
|
{
|
{
|
alpha_expand_epilogue ();
|
alpha_expand_epilogue ();
|
})
|
})
|
|
|
(define_expand "sibcall_epilogue"
|
(define_expand "sibcall_epilogue"
|
[(return)]
|
[(return)]
|
"TARGET_ABI_OSF"
|
"TARGET_ABI_OSF"
|
{
|
{
|
alpha_expand_epilogue ();
|
alpha_expand_epilogue ();
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "builtin_longjmp"
|
(define_expand "builtin_longjmp"
|
[(use (match_operand:DI 0 "register_operand" "r"))]
|
[(use (match_operand:DI 0 "register_operand" "r"))]
|
"TARGET_ABI_OSF"
|
"TARGET_ABI_OSF"
|
{
|
{
|
/* The elements of the buffer are, in order: */
|
/* The elements of the buffer are, in order: */
|
rtx fp = gen_rtx_MEM (Pmode, operands[0]);
|
rtx fp = gen_rtx_MEM (Pmode, operands[0]);
|
rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 8));
|
rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 8));
|
rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 16));
|
rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 16));
|
rtx pv = gen_rtx_REG (Pmode, 27);
|
rtx pv = gen_rtx_REG (Pmode, 27);
|
|
|
/* This bit is the same as expand_builtin_longjmp. */
|
/* This bit is the same as expand_builtin_longjmp. */
|
emit_move_insn (hard_frame_pointer_rtx, fp);
|
emit_move_insn (hard_frame_pointer_rtx, fp);
|
emit_move_insn (pv, lab);
|
emit_move_insn (pv, lab);
|
emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
|
emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
|
emit_use (hard_frame_pointer_rtx);
|
emit_use (hard_frame_pointer_rtx);
|
emit_use (stack_pointer_rtx);
|
emit_use (stack_pointer_rtx);
|
|
|
/* Load the label we are jumping through into $27 so that we know
|
/* 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
|
where to look for it when we get back to setjmp's function for
|
restoring the gp. */
|
restoring the gp. */
|
emit_jump_insn (gen_builtin_longjmp_internal (pv));
|
emit_jump_insn (gen_builtin_longjmp_internal (pv));
|
emit_barrier ();
|
emit_barrier ();
|
DONE;
|
DONE;
|
})
|
})
|
|
|
;; This is effectively a copy of indirect_jump, but constrained such
|
;; This is effectively a copy of indirect_jump, but constrained such
|
;; that register renaming cannot foil our cunning plan with $27.
|
;; that register renaming cannot foil our cunning plan with $27.
|
(define_insn "builtin_longjmp_internal"
|
(define_insn "builtin_longjmp_internal"
|
[(set (pc)
|
[(set (pc)
|
(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
|
(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
|
UNSPECV_LONGJMP))]
|
UNSPECV_LONGJMP))]
|
""
|
""
|
"jmp $31,(%0),0"
|
"jmp $31,(%0),0"
|
[(set_attr "type" "ibr")])
|
[(set_attr "type" "ibr")])
|
|
|
(define_expand "builtin_setjmp_receiver"
|
(define_expand "builtin_setjmp_receiver"
|
[(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
|
[(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
|
"TARGET_ABI_OSF"
|
"TARGET_ABI_OSF"
|
"")
|
"")
|
|
|
(define_insn_and_split "*builtin_setjmp_receiver_1"
|
(define_insn_and_split "*builtin_setjmp_receiver_1"
|
[(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR)]
|
[(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR)]
|
"TARGET_ABI_OSF"
|
"TARGET_ABI_OSF"
|
{
|
{
|
if (TARGET_EXPLICIT_RELOCS)
|
if (TARGET_EXPLICIT_RELOCS)
|
return "#";
|
return "#";
|
else
|
else
|
return "br $27,$LSJ%=\n$LSJ%=:\;ldgp $29,0($27)";
|
return "br $27,$LSJ%=\n$LSJ%=:\;ldgp $29,0($27)";
|
}
|
}
|
"&& TARGET_EXPLICIT_RELOCS && reload_completed"
|
"&& TARGET_EXPLICIT_RELOCS && reload_completed"
|
[(set (match_dup 1)
|
[(set (match_dup 1)
|
(unspec_volatile:DI [(match_dup 2) (match_dup 3)] UNSPECV_LDGP1))
|
(unspec_volatile:DI [(match_dup 2) (match_dup 3)] UNSPECV_LDGP1))
|
(set (match_dup 1)
|
(set (match_dup 1)
|
(unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_LDGP2))]
|
(unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_LDGP2))]
|
{
|
{
|
if (prev_nonnote_insn (curr_insn) != XEXP (operands[0], 0))
|
if (prev_nonnote_insn (curr_insn) != XEXP (operands[0], 0))
|
emit_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, operands[0]),
|
emit_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, operands[0]),
|
UNSPECV_SETJMPR_ER));
|
UNSPECV_SETJMPR_ER));
|
operands[1] = pic_offset_table_rtx;
|
operands[1] = pic_offset_table_rtx;
|
operands[2] = gen_rtx_REG (Pmode, 27);
|
operands[2] = gen_rtx_REG (Pmode, 27);
|
operands[3] = GEN_INT (alpha_next_sequence_number++);
|
operands[3] = GEN_INT (alpha_next_sequence_number++);
|
}
|
}
|
[(set_attr "length" "12")
|
[(set_attr "length" "12")
|
(set_attr "type" "multi")])
|
(set_attr "type" "multi")])
|
|
|
(define_insn "*builtin_setjmp_receiver_er_sl_1"
|
(define_insn "*builtin_setjmp_receiver_er_sl_1"
|
[(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR_ER)]
|
[(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR_ER)]
|
"TARGET_ABI_OSF && TARGET_EXPLICIT_RELOCS && TARGET_AS_CAN_SUBTRACT_LABELS"
|
"TARGET_ABI_OSF && TARGET_EXPLICIT_RELOCS && TARGET_AS_CAN_SUBTRACT_LABELS"
|
"lda $27,$LSJ%=-%l0($27)\n$LSJ%=:")
|
"lda $27,$LSJ%=-%l0($27)\n$LSJ%=:")
|
|
|
(define_insn "*builtin_setjmp_receiver_er_1"
|
(define_insn "*builtin_setjmp_receiver_er_1"
|
[(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR_ER)]
|
[(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR_ER)]
|
"TARGET_ABI_OSF && TARGET_EXPLICIT_RELOCS"
|
"TARGET_ABI_OSF && TARGET_EXPLICIT_RELOCS"
|
"br $27,$LSJ%=\n$LSJ%=:"
|
"br $27,$LSJ%=\n$LSJ%=:"
|
[(set_attr "type" "ibr")])
|
[(set_attr "type" "ibr")])
|
|
|
;; When flag_reorder_blocks_and_partition is in effect, compiler puts
|
;; When flag_reorder_blocks_and_partition is in effect, compiler puts
|
;; exception landing pads in a cold section. To prevent inter-section offset
|
;; exception landing pads in a cold section. To prevent inter-section offset
|
;; calculation, a jump to original landing pad is emitted in the place of the
|
;; calculation, a jump to original landing pad is emitted in the place of the
|
;; original landing pad. Since landing pad is moved, RA-relative GP
|
;; original landing pad. Since landing pad is moved, RA-relative GP
|
;; calculation in the prologue of landing pad breaks. To solve this problem,
|
;; calculation in the prologue of landing pad breaks. To solve this problem,
|
;; we use alternative GP load approach, as in the case of TARGET_LD_BUGGY_LDGP.
|
;; we use alternative GP load approach, as in the case of TARGET_LD_BUGGY_LDGP.
|
|
|
(define_expand "exception_receiver"
|
(define_expand "exception_receiver"
|
[(unspec_volatile [(match_dup 0)] UNSPECV_EHR)]
|
[(unspec_volatile [(match_dup 0)] UNSPECV_EHR)]
|
"TARGET_ABI_OSF"
|
"TARGET_ABI_OSF"
|
{
|
{
|
if (TARGET_LD_BUGGY_LDGP || flag_reorder_blocks_and_partition)
|
if (TARGET_LD_BUGGY_LDGP || flag_reorder_blocks_and_partition)
|
operands[0] = alpha_gp_save_rtx ();
|
operands[0] = alpha_gp_save_rtx ();
|
else
|
else
|
operands[0] = const0_rtx;
|
operands[0] = const0_rtx;
|
})
|
})
|
|
|
(define_insn "*exception_receiver_2"
|
(define_insn "*exception_receiver_2"
|
[(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_EHR)]
|
[(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_EHR)]
|
"TARGET_ABI_OSF
|
"TARGET_ABI_OSF
|
&& (TARGET_LD_BUGGY_LDGP || flag_reorder_blocks_and_partition)"
|
&& (TARGET_LD_BUGGY_LDGP || flag_reorder_blocks_and_partition)"
|
"ldq $29,%0"
|
"ldq $29,%0"
|
[(set_attr "type" "ild")])
|
[(set_attr "type" "ild")])
|
|
|
(define_insn_and_split "*exception_receiver_1"
|
(define_insn_and_split "*exception_receiver_1"
|
[(unspec_volatile [(const_int 0)] UNSPECV_EHR)]
|
[(unspec_volatile [(const_int 0)] UNSPECV_EHR)]
|
"TARGET_ABI_OSF"
|
"TARGET_ABI_OSF"
|
{
|
{
|
if (TARGET_EXPLICIT_RELOCS)
|
if (TARGET_EXPLICIT_RELOCS)
|
return "ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*";
|
return "ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*";
|
else
|
else
|
return "ldgp $29,0($26)";
|
return "ldgp $29,0($26)";
|
}
|
}
|
"&& TARGET_EXPLICIT_RELOCS && reload_completed"
|
"&& TARGET_EXPLICIT_RELOCS && reload_completed"
|
[(set (match_dup 0)
|
[(set (match_dup 0)
|
(unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1))
|
(unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1))
|
(set (match_dup 0)
|
(set (match_dup 0)
|
(unspec:DI [(match_dup 0) (match_dup 2)] UNSPEC_LDGP2))]
|
(unspec:DI [(match_dup 0) (match_dup 2)] UNSPEC_LDGP2))]
|
{
|
{
|
operands[0] = pic_offset_table_rtx;
|
operands[0] = pic_offset_table_rtx;
|
operands[1] = gen_rtx_REG (Pmode, 26);
|
operands[1] = gen_rtx_REG (Pmode, 26);
|
operands[2] = GEN_INT (alpha_next_sequence_number++);
|
operands[2] = GEN_INT (alpha_next_sequence_number++);
|
}
|
}
|
[(set_attr "length" "8")
|
[(set_attr "length" "8")
|
(set_attr "type" "multi")])
|
(set_attr "type" "multi")])
|
|
|
(define_expand "nonlocal_goto_receiver"
|
(define_expand "nonlocal_goto_receiver"
|
[(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
|
[(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
|
(set (reg:DI 27) (mem:DI (reg:DI 29)))
|
(set (reg:DI 27) (mem:DI (reg:DI 29)))
|
(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
|
(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
|
(use (reg:DI 27))]
|
(use (reg:DI 27))]
|
"TARGET_ABI_OPEN_VMS"
|
"TARGET_ABI_OPEN_VMS"
|
"")
|
"")
|
|
|
(define_insn "arg_home"
|
(define_insn "arg_home"
|
[(unspec [(const_int 0)] UNSPEC_ARG_HOME)
|
[(unspec [(const_int 0)] UNSPEC_ARG_HOME)
|
(use (reg:DI 1))
|
(use (reg:DI 1))
|
(use (reg:DI 25))
|
(use (reg:DI 25))
|
(use (reg:DI 16))
|
(use (reg:DI 16))
|
(use (reg:DI 17))
|
(use (reg:DI 17))
|
(use (reg:DI 18))
|
(use (reg:DI 18))
|
(use (reg:DI 19))
|
(use (reg:DI 19))
|
(use (reg:DI 20))
|
(use (reg:DI 20))
|
(use (reg:DI 21))
|
(use (reg:DI 21))
|
(use (reg:DI 48))
|
(use (reg:DI 48))
|
(use (reg:DI 49))
|
(use (reg:DI 49))
|
(use (reg:DI 50))
|
(use (reg:DI 50))
|
(use (reg:DI 51))
|
(use (reg:DI 51))
|
(use (reg:DI 52))
|
(use (reg:DI 52))
|
(use (reg:DI 53))
|
(use (reg:DI 53))
|
(clobber (mem:BLK (const_int 0)))
|
(clobber (mem:BLK (const_int 0)))
|
(clobber (reg:DI 24))
|
(clobber (reg:DI 24))
|
(clobber (reg:DI 25))
|
(clobber (reg:DI 25))
|
(clobber (reg:DI 0))]
|
(clobber (reg:DI 0))]
|
"TARGET_ABI_OPEN_VMS"
|
"TARGET_ABI_OPEN_VMS"
|
"lda $0,OTS$HOME_ARGS\;ldq $0,8($0)\;jsr $0,OTS$HOME_ARGS"
|
"lda $0,OTS$HOME_ARGS\;ldq $0,8($0)\;jsr $0,OTS$HOME_ARGS"
|
[(set_attr "length" "16")
|
[(set_attr "length" "16")
|
(set_attr "type" "multi")])
|
(set_attr "type" "multi")])
|
|
|
;; Load the CIW into r2 for calling __T3E_MISMATCH
|
;; Load the CIW into r2 for calling __T3E_MISMATCH
|
|
|
(define_expand "umk_mismatch_args"
|
(define_expand "umk_mismatch_args"
|
[(set:DI (match_dup 1) (mem:DI (plus:DI (reg:DI 15) (const_int -16))))
|
[(set:DI (match_dup 1) (mem:DI (plus:DI (reg:DI 15) (const_int -16))))
|
(set:DI (match_dup 2) (mem:DI (plus:DI (match_dup 1) (const_int -32))))
|
(set:DI (match_dup 2) (mem:DI (plus:DI (match_dup 1) (const_int -32))))
|
(set:DI (reg:DI 1) (match_operand:DI 0 "const_int_operand" ""))
|
(set:DI (reg:DI 1) (match_operand:DI 0 "const_int_operand" ""))
|
(set:DI (match_dup 3) (plus:DI (mult:DI (reg:DI 25)
|
(set:DI (match_dup 3) (plus:DI (mult:DI (reg:DI 25)
|
(const_int 8))
|
(const_int 8))
|
(match_dup 2)))
|
(match_dup 2)))
|
(set:DI (reg:DI 2) (mem:DI (match_dup 3)))]
|
(set:DI (reg:DI 2) (mem:DI (match_dup 3)))]
|
"TARGET_ABI_UNICOSMK"
|
"TARGET_ABI_UNICOSMK"
|
{
|
{
|
operands[1] = gen_reg_rtx (DImode);
|
operands[1] = gen_reg_rtx (DImode);
|
operands[2] = gen_reg_rtx (DImode);
|
operands[2] = gen_reg_rtx (DImode);
|
operands[3] = gen_reg_rtx (DImode);
|
operands[3] = gen_reg_rtx (DImode);
|
})
|
})
|
|
|
(define_insn "arg_home_umk"
|
(define_insn "arg_home_umk"
|
[(unspec [(const_int 0)] UNSPEC_ARG_HOME)
|
[(unspec [(const_int 0)] UNSPEC_ARG_HOME)
|
(use (reg:DI 1))
|
(use (reg:DI 1))
|
(use (reg:DI 2))
|
(use (reg:DI 2))
|
(use (reg:DI 16))
|
(use (reg:DI 16))
|
(use (reg:DI 17))
|
(use (reg:DI 17))
|
(use (reg:DI 18))
|
(use (reg:DI 18))
|
(use (reg:DI 19))
|
(use (reg:DI 19))
|
(use (reg:DI 20))
|
(use (reg:DI 20))
|
(use (reg:DI 21))
|
(use (reg:DI 21))
|
(use (reg:DI 48))
|
(use (reg:DI 48))
|
(use (reg:DI 49))
|
(use (reg:DI 49))
|
(use (reg:DI 50))
|
(use (reg:DI 50))
|
(use (reg:DI 51))
|
(use (reg:DI 51))
|
(use (reg:DI 52))
|
(use (reg:DI 52))
|
(use (reg:DI 53))
|
(use (reg:DI 53))
|
(clobber (mem:BLK (const_int 0)))
|
(clobber (mem:BLK (const_int 0)))
|
(parallel [
|
(parallel [
|
(clobber (reg:DI 22))
|
(clobber (reg:DI 22))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 23))
|
(clobber (reg:DI 24))
|
(clobber (reg:DI 24))
|
(clobber (reg:DI 0))
|
(clobber (reg:DI 0))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 1))
|
(clobber (reg:DI 2))
|
(clobber (reg:DI 2))
|
(clobber (reg:DI 3))
|
(clobber (reg:DI 3))
|
(clobber (reg:DI 4))
|
(clobber (reg:DI 4))
|
(clobber (reg:DI 5))
|
(clobber (reg:DI 5))
|
(clobber (reg:DI 6))
|
(clobber (reg:DI 6))
|
(clobber (reg:DI 7))
|
(clobber (reg:DI 7))
|
(clobber (reg:DI 8))])]
|
(clobber (reg:DI 8))])]
|
"TARGET_ABI_UNICOSMK"
|
"TARGET_ABI_UNICOSMK"
|
"laum $4,__T3E_MISMATCH($31)\;sll $4,32,$4\;lalm $4,__T3E_MISMATCH($4)\;lal $4,__T3E_MISMATCH($4)\;jsr $3,($4)"
|
"laum $4,__T3E_MISMATCH($31)\;sll $4,32,$4\;lalm $4,__T3E_MISMATCH($4)\;lal $4,__T3E_MISMATCH($4)\;jsr $3,($4)"
|
[(set_attr "length" "16")
|
[(set_attr "length" "16")
|
(set_attr "type" "multi")])
|
(set_attr "type" "multi")])
|
|
|
;; Prefetch data.
|
;; Prefetch data.
|
;;
|
;;
|
;; On EV4, these instructions are nops -- no load occurs.
|
;; On EV4, these instructions are nops -- no load occurs.
|
;;
|
;;
|
;; On EV5, these instructions act as a normal load, and thus can trap
|
;; On EV5, these instructions act as a normal load, and thus can trap
|
;; if the address is invalid. The OS may (or may not) handle this in
|
;; if the address is invalid. The OS may (or may not) handle this in
|
;; the entMM fault handler and suppress the fault. If so, then this
|
;; the entMM fault handler and suppress the fault. If so, then this
|
;; has the effect of a read prefetch instruction.
|
;; has the effect of a read prefetch instruction.
|
;;
|
;;
|
;; On EV6, these become official prefetch instructions.
|
;; On EV6, these become official prefetch instructions.
|
|
|
(define_insn "prefetch"
|
(define_insn "prefetch"
|
[(prefetch (match_operand:DI 0 "address_operand" "p")
|
[(prefetch (match_operand:DI 0 "address_operand" "p")
|
(match_operand:DI 1 "const_int_operand" "n")
|
(match_operand:DI 1 "const_int_operand" "n")
|
(match_operand:DI 2 "const_int_operand" "n"))]
|
(match_operand:DI 2 "const_int_operand" "n"))]
|
"TARGET_FIXUP_EV5_PREFETCH || alpha_cpu == PROCESSOR_EV6"
|
"TARGET_FIXUP_EV5_PREFETCH || alpha_cpu == PROCESSOR_EV6"
|
{
|
{
|
/* Interpret "no temporal locality" as this data should be evicted once
|
/* Interpret "no temporal locality" as this data should be evicted once
|
it is used. The "evict next" alternatives load the data into the cache
|
it is used. The "evict next" alternatives load the data into the cache
|
and leave the LRU eviction counter pointing to that block. */
|
and leave the LRU eviction counter pointing to that block. */
|
static const char * const alt[2][2] = {
|
static const char * const alt[2][2] = {
|
{
|
{
|
"ldq $31,%a0", /* read, evict next */
|
"ldq $31,%a0", /* read, evict next */
|
"ldl $31,%a0", /* read, evict last */
|
"ldl $31,%a0", /* read, evict last */
|
},
|
},
|
{
|
{
|
"ldt $f31,%a0", /* write, evict next */
|
"ldt $f31,%a0", /* write, evict next */
|
"lds $f31,%a0", /* write, evict last */
|
"lds $f31,%a0", /* write, evict last */
|
}
|
}
|
};
|
};
|
|
|
bool write = INTVAL (operands[1]) != 0;
|
bool write = INTVAL (operands[1]) != 0;
|
bool lru = INTVAL (operands[2]) != 0;
|
bool lru = INTVAL (operands[2]) != 0;
|
|
|
return alt[write][lru];
|
return alt[write][lru];
|
}
|
}
|
[(set_attr "type" "ild")])
|
[(set_attr "type" "ild")])
|
|
|
;; Close the trap shadow of preceding instructions. This is generated
|
;; Close the trap shadow of preceding instructions. This is generated
|
;; by alpha_reorg.
|
;; by alpha_reorg.
|
|
|
(define_insn "trapb"
|
(define_insn "trapb"
|
[(unspec_volatile [(const_int 0)] UNSPECV_TRAPB)]
|
[(unspec_volatile [(const_int 0)] UNSPECV_TRAPB)]
|
""
|
""
|
"trapb"
|
"trapb"
|
[(set_attr "type" "misc")])
|
[(set_attr "type" "misc")])
|
|
|
;; No-op instructions used by machine-dependent reorg to preserve
|
;; No-op instructions used by machine-dependent reorg to preserve
|
;; alignment for instruction issue.
|
;; alignment for instruction issue.
|
;; The Unicos/Mk assembler does not support these opcodes.
|
;; The Unicos/Mk assembler does not support these opcodes.
|
|
|
(define_insn "nop"
|
(define_insn "nop"
|
[(const_int 0)]
|
[(const_int 0)]
|
""
|
""
|
"bis $31,$31,$31"
|
"bis $31,$31,$31"
|
[(set_attr "type" "ilog")])
|
[(set_attr "type" "ilog")])
|
|
|
(define_insn "fnop"
|
(define_insn "fnop"
|
[(const_int 1)]
|
[(const_int 1)]
|
"TARGET_FP"
|
"TARGET_FP"
|
"cpys $f31,$f31,$f31"
|
"cpys $f31,$f31,$f31"
|
[(set_attr "type" "fcpys")])
|
[(set_attr "type" "fcpys")])
|
|
|
(define_insn "unop"
|
(define_insn "unop"
|
[(const_int 2)]
|
[(const_int 2)]
|
""
|
""
|
"ldq_u $31,0($30)")
|
"ldq_u $31,0($30)")
|
|
|
;; On Unicos/Mk we use a macro for aligning code.
|
;; On Unicos/Mk we use a macro for aligning code.
|
|
|
(define_insn "realign"
|
(define_insn "realign"
|
[(unspec_volatile [(match_operand 0 "immediate_operand" "i")]
|
[(unspec_volatile [(match_operand 0 "immediate_operand" "i")]
|
UNSPECV_REALIGN)]
|
UNSPECV_REALIGN)]
|
""
|
""
|
{
|
{
|
if (TARGET_ABI_UNICOSMK)
|
if (TARGET_ABI_UNICOSMK)
|
return "gcc@code@align %0";
|
return "gcc@code@align %0";
|
else
|
else
|
return ".align %0 #realign";
|
return ".align %0 #realign";
|
})
|
})
|
|
|
;; Instructions to be emitted from __builtins.
|
;; Instructions to be emitted from __builtins.
|
|
|
(define_insn "builtin_cmpbge"
|
(define_insn "builtin_cmpbge"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rJ")
|
(match_operand:DI 2 "reg_or_8bit_operand" "rI")]
|
(match_operand:DI 2 "reg_or_8bit_operand" "rI")]
|
UNSPEC_CMPBGE))]
|
UNSPEC_CMPBGE))]
|
""
|
""
|
"cmpbge %r1,%2,%0"
|
"cmpbge %r1,%2,%0"
|
;; The EV6 data sheets list this as ILOG. OTOH, EV6 doesn't
|
;; The EV6 data sheets list this as ILOG. OTOH, EV6 doesn't
|
;; actually differentiate between ILOG and ICMP in the schedule.
|
;; actually differentiate between ILOG and ICMP in the schedule.
|
[(set_attr "type" "icmp")])
|
[(set_attr "type" "icmp")])
|
|
|
(define_expand "builtin_extbl"
|
(define_expand "builtin_extbl"
|
[(match_operand:DI 0 "register_operand" "")
|
[(match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
""
|
""
|
{
|
{
|
rtx (*gen) (rtx, rtx, rtx, rtx);
|
rtx (*gen) (rtx, rtx, rtx, rtx);
|
if (WORDS_BIG_ENDIAN)
|
if (WORDS_BIG_ENDIAN)
|
gen = gen_extxl_be;
|
gen = gen_extxl_be;
|
else
|
else
|
gen = gen_extxl_le;
|
gen = gen_extxl_le;
|
emit_insn ((*gen) (operands[0], operands[1], GEN_INT (8), operands[2]));
|
emit_insn ((*gen) (operands[0], operands[1], GEN_INT (8), operands[2]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "builtin_extwl"
|
(define_expand "builtin_extwl"
|
[(match_operand:DI 0 "register_operand" "")
|
[(match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
""
|
""
|
{
|
{
|
rtx (*gen) (rtx, rtx, rtx, rtx);
|
rtx (*gen) (rtx, rtx, rtx, rtx);
|
if (WORDS_BIG_ENDIAN)
|
if (WORDS_BIG_ENDIAN)
|
gen = gen_extxl_be;
|
gen = gen_extxl_be;
|
else
|
else
|
gen = gen_extxl_le;
|
gen = gen_extxl_le;
|
emit_insn ((*gen) (operands[0], operands[1], GEN_INT (16), operands[2]));
|
emit_insn ((*gen) (operands[0], operands[1], GEN_INT (16), operands[2]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "builtin_extll"
|
(define_expand "builtin_extll"
|
[(match_operand:DI 0 "register_operand" "")
|
[(match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
""
|
""
|
{
|
{
|
rtx (*gen) (rtx, rtx, rtx, rtx);
|
rtx (*gen) (rtx, rtx, rtx, rtx);
|
if (WORDS_BIG_ENDIAN)
|
if (WORDS_BIG_ENDIAN)
|
gen = gen_extxl_be;
|
gen = gen_extxl_be;
|
else
|
else
|
gen = gen_extxl_le;
|
gen = gen_extxl_le;
|
emit_insn ((*gen) (operands[0], operands[1], GEN_INT (32), operands[2]));
|
emit_insn ((*gen) (operands[0], operands[1], GEN_INT (32), operands[2]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "builtin_extql"
|
(define_expand "builtin_extql"
|
[(match_operand:DI 0 "register_operand" "")
|
[(match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
""
|
""
|
{
|
{
|
rtx (*gen) (rtx, rtx, rtx, rtx);
|
rtx (*gen) (rtx, rtx, rtx, rtx);
|
if (WORDS_BIG_ENDIAN)
|
if (WORDS_BIG_ENDIAN)
|
gen = gen_extxl_be;
|
gen = gen_extxl_be;
|
else
|
else
|
gen = gen_extxl_le;
|
gen = gen_extxl_le;
|
emit_insn ((*gen) (operands[0], operands[1], GEN_INT (64), operands[2]));
|
emit_insn ((*gen) (operands[0], operands[1], GEN_INT (64), operands[2]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "builtin_extwh"
|
(define_expand "builtin_extwh"
|
[(match_operand:DI 0 "register_operand" "")
|
[(match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
""
|
""
|
{
|
{
|
rtx (*gen) (rtx, rtx, rtx);
|
rtx (*gen) (rtx, rtx, rtx);
|
if (WORDS_BIG_ENDIAN)
|
if (WORDS_BIG_ENDIAN)
|
gen = gen_extwh_be;
|
gen = gen_extwh_be;
|
else
|
else
|
gen = gen_extwh_le;
|
gen = gen_extwh_le;
|
emit_insn ((*gen) (operands[0], operands[1], operands[2]));
|
emit_insn ((*gen) (operands[0], operands[1], operands[2]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "builtin_extlh"
|
(define_expand "builtin_extlh"
|
[(match_operand:DI 0 "register_operand" "")
|
[(match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
""
|
""
|
{
|
{
|
rtx (*gen) (rtx, rtx, rtx);
|
rtx (*gen) (rtx, rtx, rtx);
|
if (WORDS_BIG_ENDIAN)
|
if (WORDS_BIG_ENDIAN)
|
gen = gen_extlh_be;
|
gen = gen_extlh_be;
|
else
|
else
|
gen = gen_extlh_le;
|
gen = gen_extlh_le;
|
emit_insn ((*gen) (operands[0], operands[1], operands[2]));
|
emit_insn ((*gen) (operands[0], operands[1], operands[2]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "builtin_extqh"
|
(define_expand "builtin_extqh"
|
[(match_operand:DI 0 "register_operand" "")
|
[(match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
""
|
""
|
{
|
{
|
rtx (*gen) (rtx, rtx, rtx);
|
rtx (*gen) (rtx, rtx, rtx);
|
if (WORDS_BIG_ENDIAN)
|
if (WORDS_BIG_ENDIAN)
|
gen = gen_extqh_be;
|
gen = gen_extqh_be;
|
else
|
else
|
gen = gen_extqh_le;
|
gen = gen_extqh_le;
|
emit_insn ((*gen) (operands[0], operands[1], operands[2]));
|
emit_insn ((*gen) (operands[0], operands[1], operands[2]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "builtin_insbl"
|
(define_expand "builtin_insbl"
|
[(match_operand:DI 0 "register_operand" "")
|
[(match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
""
|
""
|
{
|
{
|
rtx (*gen) (rtx, rtx, rtx);
|
rtx (*gen) (rtx, rtx, rtx);
|
if (WORDS_BIG_ENDIAN)
|
if (WORDS_BIG_ENDIAN)
|
gen = gen_insbl_be;
|
gen = gen_insbl_be;
|
else
|
else
|
gen = gen_insbl_le;
|
gen = gen_insbl_le;
|
operands[1] = gen_lowpart (QImode, operands[1]);
|
operands[1] = gen_lowpart (QImode, operands[1]);
|
emit_insn ((*gen) (operands[0], operands[1], operands[2]));
|
emit_insn ((*gen) (operands[0], operands[1], operands[2]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "builtin_inswl"
|
(define_expand "builtin_inswl"
|
[(match_operand:DI 0 "register_operand" "")
|
[(match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
""
|
""
|
{
|
{
|
rtx (*gen) (rtx, rtx, rtx);
|
rtx (*gen) (rtx, rtx, rtx);
|
if (WORDS_BIG_ENDIAN)
|
if (WORDS_BIG_ENDIAN)
|
gen = gen_inswl_be;
|
gen = gen_inswl_be;
|
else
|
else
|
gen = gen_inswl_le;
|
gen = gen_inswl_le;
|
operands[1] = gen_lowpart (HImode, operands[1]);
|
operands[1] = gen_lowpart (HImode, operands[1]);
|
emit_insn ((*gen) (operands[0], operands[1], operands[2]));
|
emit_insn ((*gen) (operands[0], operands[1], operands[2]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "builtin_insll"
|
(define_expand "builtin_insll"
|
[(match_operand:DI 0 "register_operand" "")
|
[(match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
""
|
""
|
{
|
{
|
rtx (*gen) (rtx, rtx, rtx);
|
rtx (*gen) (rtx, rtx, rtx);
|
if (WORDS_BIG_ENDIAN)
|
if (WORDS_BIG_ENDIAN)
|
gen = gen_insll_be;
|
gen = gen_insll_be;
|
else
|
else
|
gen = gen_insll_le;
|
gen = gen_insll_le;
|
operands[1] = gen_lowpart (SImode, operands[1]);
|
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]));
|
emit_insn ((*gen) (operands[0], operands[1], operands[2]));
|
emit_insn ((*gen) (operands[0], operands[1], operands[2]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "builtin_insql"
|
(define_expand "builtin_insql"
|
[(match_operand:DI 0 "register_operand" "")
|
[(match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
""
|
""
|
{
|
{
|
rtx (*gen) (rtx, rtx, rtx);
|
rtx (*gen) (rtx, rtx, rtx);
|
if (WORDS_BIG_ENDIAN)
|
if (WORDS_BIG_ENDIAN)
|
gen = gen_insql_be;
|
gen = gen_insql_be;
|
else
|
else
|
gen = gen_insql_le;
|
gen = gen_insql_le;
|
emit_insn ((*gen) (operands[0], operands[1], operands[2]));
|
emit_insn ((*gen) (operands[0], operands[1], operands[2]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "builtin_inswh"
|
(define_expand "builtin_inswh"
|
[(match_operand:DI 0 "register_operand" "")
|
[(match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
""
|
""
|
{
|
{
|
emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (16), operands[2]));
|
emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (16), operands[2]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "builtin_inslh"
|
(define_expand "builtin_inslh"
|
[(match_operand:DI 0 "register_operand" "")
|
[(match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
""
|
""
|
{
|
{
|
emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (32), operands[2]));
|
emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (32), operands[2]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "builtin_insqh"
|
(define_expand "builtin_insqh"
|
[(match_operand:DI 0 "register_operand" "")
|
[(match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
""
|
""
|
{
|
{
|
emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (64), operands[2]));
|
emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (64), operands[2]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "builtin_mskbl"
|
(define_expand "builtin_mskbl"
|
[(match_operand:DI 0 "register_operand" "")
|
[(match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
""
|
""
|
{
|
{
|
rtx (*gen) (rtx, rtx, rtx, rtx);
|
rtx (*gen) (rtx, rtx, rtx, rtx);
|
rtx mask;
|
rtx mask;
|
if (WORDS_BIG_ENDIAN)
|
if (WORDS_BIG_ENDIAN)
|
gen = gen_mskxl_be;
|
gen = gen_mskxl_be;
|
else
|
else
|
gen = gen_mskxl_le;
|
gen = gen_mskxl_le;
|
mask = GEN_INT (0xff);
|
mask = GEN_INT (0xff);
|
emit_insn ((*gen) (operands[0], operands[1], mask, operands[2]));
|
emit_insn ((*gen) (operands[0], operands[1], mask, operands[2]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "builtin_mskwl"
|
(define_expand "builtin_mskwl"
|
[(match_operand:DI 0 "register_operand" "")
|
[(match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
""
|
""
|
{
|
{
|
rtx (*gen) (rtx, rtx, rtx, rtx);
|
rtx (*gen) (rtx, rtx, rtx, rtx);
|
rtx mask;
|
rtx mask;
|
if (WORDS_BIG_ENDIAN)
|
if (WORDS_BIG_ENDIAN)
|
gen = gen_mskxl_be;
|
gen = gen_mskxl_be;
|
else
|
else
|
gen = gen_mskxl_le;
|
gen = gen_mskxl_le;
|
mask = GEN_INT (0xffff);
|
mask = GEN_INT (0xffff);
|
emit_insn ((*gen) (operands[0], operands[1], mask, operands[2]));
|
emit_insn ((*gen) (operands[0], operands[1], mask, operands[2]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "builtin_mskll"
|
(define_expand "builtin_mskll"
|
[(match_operand:DI 0 "register_operand" "")
|
[(match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
""
|
""
|
{
|
{
|
rtx (*gen) (rtx, rtx, rtx, rtx);
|
rtx (*gen) (rtx, rtx, rtx, rtx);
|
rtx mask;
|
rtx mask;
|
if (WORDS_BIG_ENDIAN)
|
if (WORDS_BIG_ENDIAN)
|
gen = gen_mskxl_be;
|
gen = gen_mskxl_be;
|
else
|
else
|
gen = gen_mskxl_le;
|
gen = gen_mskxl_le;
|
mask = immed_double_const (0xffffffff, 0, DImode);
|
mask = immed_double_const (0xffffffff, 0, DImode);
|
emit_insn ((*gen) (operands[0], operands[1], mask, operands[2]));
|
emit_insn ((*gen) (operands[0], operands[1], mask, operands[2]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "builtin_mskql"
|
(define_expand "builtin_mskql"
|
[(match_operand:DI 0 "register_operand" "")
|
[(match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
""
|
""
|
{
|
{
|
rtx (*gen) (rtx, rtx, rtx, rtx);
|
rtx (*gen) (rtx, rtx, rtx, rtx);
|
rtx mask;
|
rtx mask;
|
if (WORDS_BIG_ENDIAN)
|
if (WORDS_BIG_ENDIAN)
|
gen = gen_mskxl_be;
|
gen = gen_mskxl_be;
|
else
|
else
|
gen = gen_mskxl_le;
|
gen = gen_mskxl_le;
|
mask = constm1_rtx;
|
mask = constm1_rtx;
|
emit_insn ((*gen) (operands[0], operands[1], mask, operands[2]));
|
emit_insn ((*gen) (operands[0], operands[1], mask, operands[2]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "builtin_mskwh"
|
(define_expand "builtin_mskwh"
|
[(match_operand:DI 0 "register_operand" "")
|
[(match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
""
|
""
|
{
|
{
|
emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (16), operands[2]));
|
emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (16), operands[2]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "builtin_msklh"
|
(define_expand "builtin_msklh"
|
[(match_operand:DI 0 "register_operand" "")
|
[(match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
""
|
""
|
{
|
{
|
emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (32), operands[2]));
|
emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (32), operands[2]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "builtin_mskqh"
|
(define_expand "builtin_mskqh"
|
[(match_operand:DI 0 "register_operand" "")
|
[(match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 1 "register_operand" "")
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
(match_operand:DI 2 "reg_or_8bit_operand" "")]
|
""
|
""
|
{
|
{
|
emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (64), operands[2]));
|
emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (64), operands[2]));
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "builtin_zap"
|
(define_expand "builtin_zap"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(and:DI (unspec:DI
|
(and:DI (unspec:DI
|
[(match_operand:DI 2 "reg_or_cint_operand" "")]
|
[(match_operand:DI 2 "reg_or_cint_operand" "")]
|
UNSPEC_ZAP)
|
UNSPEC_ZAP)
|
(match_operand:DI 1 "reg_or_cint_operand" "")))]
|
(match_operand:DI 1 "reg_or_cint_operand" "")))]
|
""
|
""
|
{
|
{
|
if (CONST_INT_P (operands[2]))
|
if (CONST_INT_P (operands[2]))
|
{
|
{
|
rtx mask = alpha_expand_zap_mask (INTVAL (operands[2]));
|
rtx mask = alpha_expand_zap_mask (INTVAL (operands[2]));
|
|
|
if (mask == const0_rtx)
|
if (mask == const0_rtx)
|
{
|
{
|
emit_move_insn (operands[0], const0_rtx);
|
emit_move_insn (operands[0], const0_rtx);
|
DONE;
|
DONE;
|
}
|
}
|
if (mask == constm1_rtx)
|
if (mask == constm1_rtx)
|
{
|
{
|
emit_move_insn (operands[0], operands[1]);
|
emit_move_insn (operands[0], operands[1]);
|
DONE;
|
DONE;
|
}
|
}
|
|
|
operands[1] = force_reg (DImode, operands[1]);
|
operands[1] = force_reg (DImode, operands[1]);
|
emit_insn (gen_anddi3 (operands[0], operands[1], mask));
|
emit_insn (gen_anddi3 (operands[0], operands[1], mask));
|
DONE;
|
DONE;
|
}
|
}
|
|
|
operands[1] = force_reg (DImode, operands[1]);
|
operands[1] = force_reg (DImode, operands[1]);
|
operands[2] = gen_lowpart (QImode, operands[2]);
|
operands[2] = gen_lowpart (QImode, operands[2]);
|
})
|
})
|
|
|
(define_insn "*builtin_zap_1"
|
(define_insn "*builtin_zap_1"
|
[(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
|
[(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
|
(and:DI (unspec:DI
|
(and:DI (unspec:DI
|
[(match_operand:QI 2 "reg_or_cint_operand" "n,n,r,r")]
|
[(match_operand:QI 2 "reg_or_cint_operand" "n,n,r,r")]
|
UNSPEC_ZAP)
|
UNSPEC_ZAP)
|
(match_operand:DI 1 "reg_or_cint_operand" "n,r,J,r")))]
|
(match_operand:DI 1 "reg_or_cint_operand" "n,r,J,r")))]
|
""
|
""
|
"@
|
"@
|
#
|
#
|
#
|
#
|
bis $31,$31,%0
|
bis $31,$31,%0
|
zap %r1,%2,%0"
|
zap %r1,%2,%0"
|
[(set_attr "type" "shift,shift,ilog,shift")])
|
[(set_attr "type" "shift,shift,ilog,shift")])
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(and:DI (unspec:DI
|
(and:DI (unspec:DI
|
[(match_operand:QI 2 "const_int_operand" "")]
|
[(match_operand:QI 2 "const_int_operand" "")]
|
UNSPEC_ZAP)
|
UNSPEC_ZAP)
|
(match_operand:DI 1 "const_int_operand" "")))]
|
(match_operand:DI 1 "const_int_operand" "")))]
|
""
|
""
|
[(const_int 0)]
|
[(const_int 0)]
|
{
|
{
|
rtx mask = alpha_expand_zap_mask (INTVAL (operands[2]));
|
rtx mask = alpha_expand_zap_mask (INTVAL (operands[2]));
|
if (HOST_BITS_PER_WIDE_INT >= 64 || CONST_INT_P (mask))
|
if (HOST_BITS_PER_WIDE_INT >= 64 || CONST_INT_P (mask))
|
operands[1] = gen_int_mode (INTVAL (operands[1]) & INTVAL (mask), DImode);
|
operands[1] = gen_int_mode (INTVAL (operands[1]) & INTVAL (mask), DImode);
|
else
|
else
|
{
|
{
|
HOST_WIDE_INT c_lo = INTVAL (operands[1]);
|
HOST_WIDE_INT c_lo = INTVAL (operands[1]);
|
HOST_WIDE_INT c_hi = (c_lo < 0 ? -1 : 0);
|
HOST_WIDE_INT c_hi = (c_lo < 0 ? -1 : 0);
|
operands[1] = immed_double_const (c_lo & CONST_DOUBLE_LOW (mask),
|
operands[1] = immed_double_const (c_lo & CONST_DOUBLE_LOW (mask),
|
c_hi & CONST_DOUBLE_HIGH (mask),
|
c_hi & CONST_DOUBLE_HIGH (mask),
|
DImode);
|
DImode);
|
}
|
}
|
emit_move_insn (operands[0], operands[1]);
|
emit_move_insn (operands[0], operands[1]);
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_split
|
(define_split
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(and:DI (unspec:DI
|
(and:DI (unspec:DI
|
[(match_operand:QI 2 "const_int_operand" "")]
|
[(match_operand:QI 2 "const_int_operand" "")]
|
UNSPEC_ZAP)
|
UNSPEC_ZAP)
|
(match_operand:DI 1 "register_operand" "")))]
|
(match_operand:DI 1 "register_operand" "")))]
|
""
|
""
|
[(set (match_dup 0)
|
[(set (match_dup 0)
|
(and:DI (match_dup 1) (match_dup 2)))]
|
(and:DI (match_dup 1) (match_dup 2)))]
|
{
|
{
|
operands[2] = alpha_expand_zap_mask (INTVAL (operands[2]));
|
operands[2] = alpha_expand_zap_mask (INTVAL (operands[2]));
|
if (operands[2] == const0_rtx)
|
if (operands[2] == const0_rtx)
|
{
|
{
|
emit_move_insn (operands[0], const0_rtx);
|
emit_move_insn (operands[0], const0_rtx);
|
DONE;
|
DONE;
|
}
|
}
|
if (operands[2] == constm1_rtx)
|
if (operands[2] == constm1_rtx)
|
{
|
{
|
emit_move_insn (operands[0], operands[1]);
|
emit_move_insn (operands[0], operands[1]);
|
DONE;
|
DONE;
|
}
|
}
|
})
|
})
|
|
|
(define_expand "builtin_zapnot"
|
(define_expand "builtin_zapnot"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(and:DI (unspec:DI
|
(and:DI (unspec:DI
|
[(not:QI (match_operand:DI 2 "reg_or_cint_operand" ""))]
|
[(not:QI (match_operand:DI 2 "reg_or_cint_operand" ""))]
|
UNSPEC_ZAP)
|
UNSPEC_ZAP)
|
(match_operand:DI 1 "reg_or_cint_operand" "")))]
|
(match_operand:DI 1 "reg_or_cint_operand" "")))]
|
""
|
""
|
{
|
{
|
if (CONST_INT_P (operands[2]))
|
if (CONST_INT_P (operands[2]))
|
{
|
{
|
rtx mask = alpha_expand_zap_mask (~ INTVAL (operands[2]));
|
rtx mask = alpha_expand_zap_mask (~ INTVAL (operands[2]));
|
|
|
if (mask == const0_rtx)
|
if (mask == const0_rtx)
|
{
|
{
|
emit_move_insn (operands[0], const0_rtx);
|
emit_move_insn (operands[0], const0_rtx);
|
DONE;
|
DONE;
|
}
|
}
|
if (mask == constm1_rtx)
|
if (mask == constm1_rtx)
|
{
|
{
|
emit_move_insn (operands[0], operands[1]);
|
emit_move_insn (operands[0], operands[1]);
|
DONE;
|
DONE;
|
}
|
}
|
|
|
operands[1] = force_reg (DImode, operands[1]);
|
operands[1] = force_reg (DImode, operands[1]);
|
emit_insn (gen_anddi3 (operands[0], operands[1], mask));
|
emit_insn (gen_anddi3 (operands[0], operands[1], mask));
|
DONE;
|
DONE;
|
}
|
}
|
|
|
operands[1] = force_reg (DImode, operands[1]);
|
operands[1] = force_reg (DImode, operands[1]);
|
operands[2] = gen_lowpart (QImode, operands[2]);
|
operands[2] = gen_lowpart (QImode, operands[2]);
|
})
|
})
|
|
|
(define_insn "*builtin_zapnot_1"
|
(define_insn "*builtin_zapnot_1"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(and:DI (unspec:DI
|
(and:DI (unspec:DI
|
[(not:QI (match_operand:QI 2 "register_operand" "r"))]
|
[(not:QI (match_operand:QI 2 "register_operand" "r"))]
|
UNSPEC_ZAP)
|
UNSPEC_ZAP)
|
(match_operand:DI 1 "reg_or_0_operand" "rJ")))]
|
(match_operand:DI 1 "reg_or_0_operand" "rJ")))]
|
""
|
""
|
"zapnot %r1,%2,%0"
|
"zapnot %r1,%2,%0"
|
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
|
|
(define_insn "builtin_amask"
|
(define_insn "builtin_amask"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(unspec:DI [(match_operand:DI 1 "reg_or_8bit_operand" "rI")]
|
(unspec:DI [(match_operand:DI 1 "reg_or_8bit_operand" "rI")]
|
UNSPEC_AMASK))]
|
UNSPEC_AMASK))]
|
""
|
""
|
"amask %1,%0"
|
"amask %1,%0"
|
[(set_attr "type" "ilog")])
|
[(set_attr "type" "ilog")])
|
|
|
(define_insn "builtin_implver"
|
(define_insn "builtin_implver"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(unspec:DI [(const_int 0)] UNSPEC_IMPLVER))]
|
(unspec:DI [(const_int 0)] UNSPEC_IMPLVER))]
|
""
|
""
|
"implver %0"
|
"implver %0"
|
[(set_attr "type" "ilog")])
|
[(set_attr "type" "ilog")])
|
|
|
(define_insn "builtin_rpcc"
|
(define_insn "builtin_rpcc"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(unspec_volatile:DI [(const_int 0)] UNSPECV_RPCC))]
|
(unspec_volatile:DI [(const_int 0)] UNSPECV_RPCC))]
|
""
|
""
|
"rpcc %0"
|
"rpcc %0"
|
[(set_attr "type" "ilog")])
|
[(set_attr "type" "ilog")])
|
|
|
(define_expand "builtin_minub8"
|
(define_expand "builtin_minub8"
|
[(match_operand:DI 0 "register_operand" "")
|
[(match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 2 "reg_or_0_operand" "")]
|
(match_operand:DI 2 "reg_or_0_operand" "")]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
{
|
{
|
alpha_expand_builtin_vector_binop (gen_uminv8qi3, V8QImode, operands[0],
|
alpha_expand_builtin_vector_binop (gen_uminv8qi3, V8QImode, operands[0],
|
operands[1], operands[2]);
|
operands[1], operands[2]);
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "builtin_minsb8"
|
(define_expand "builtin_minsb8"
|
[(match_operand:DI 0 "register_operand" "")
|
[(match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 2 "reg_or_0_operand" "")]
|
(match_operand:DI 2 "reg_or_0_operand" "")]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
{
|
{
|
alpha_expand_builtin_vector_binop (gen_sminv8qi3, V8QImode, operands[0],
|
alpha_expand_builtin_vector_binop (gen_sminv8qi3, V8QImode, operands[0],
|
operands[1], operands[2]);
|
operands[1], operands[2]);
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "builtin_minuw4"
|
(define_expand "builtin_minuw4"
|
[(match_operand:DI 0 "register_operand" "")
|
[(match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 2 "reg_or_0_operand" "")]
|
(match_operand:DI 2 "reg_or_0_operand" "")]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
{
|
{
|
alpha_expand_builtin_vector_binop (gen_uminv4hi3, V4HImode, operands[0],
|
alpha_expand_builtin_vector_binop (gen_uminv4hi3, V4HImode, operands[0],
|
operands[1], operands[2]);
|
operands[1], operands[2]);
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "builtin_minsw4"
|
(define_expand "builtin_minsw4"
|
[(match_operand:DI 0 "register_operand" "")
|
[(match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 2 "reg_or_0_operand" "")]
|
(match_operand:DI 2 "reg_or_0_operand" "")]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
{
|
{
|
alpha_expand_builtin_vector_binop (gen_sminv4hi3, V4HImode, operands[0],
|
alpha_expand_builtin_vector_binop (gen_sminv4hi3, V4HImode, operands[0],
|
operands[1], operands[2]);
|
operands[1], operands[2]);
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "builtin_maxub8"
|
(define_expand "builtin_maxub8"
|
[(match_operand:DI 0 "register_operand" "")
|
[(match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 2 "reg_or_0_operand" "")]
|
(match_operand:DI 2 "reg_or_0_operand" "")]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
{
|
{
|
alpha_expand_builtin_vector_binop (gen_umaxv8qi3, V8QImode, operands[0],
|
alpha_expand_builtin_vector_binop (gen_umaxv8qi3, V8QImode, operands[0],
|
operands[1], operands[2]);
|
operands[1], operands[2]);
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "builtin_maxsb8"
|
(define_expand "builtin_maxsb8"
|
[(match_operand:DI 0 "register_operand" "")
|
[(match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 2 "reg_or_0_operand" "")]
|
(match_operand:DI 2 "reg_or_0_operand" "")]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
{
|
{
|
alpha_expand_builtin_vector_binop (gen_smaxv8qi3, V8QImode, operands[0],
|
alpha_expand_builtin_vector_binop (gen_smaxv8qi3, V8QImode, operands[0],
|
operands[1], operands[2]);
|
operands[1], operands[2]);
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "builtin_maxuw4"
|
(define_expand "builtin_maxuw4"
|
[(match_operand:DI 0 "register_operand" "")
|
[(match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 2 "reg_or_0_operand" "")]
|
(match_operand:DI 2 "reg_or_0_operand" "")]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
{
|
{
|
alpha_expand_builtin_vector_binop (gen_umaxv4hi3, V4HImode, operands[0],
|
alpha_expand_builtin_vector_binop (gen_umaxv4hi3, V4HImode, operands[0],
|
operands[1], operands[2]);
|
operands[1], operands[2]);
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_expand "builtin_maxsw4"
|
(define_expand "builtin_maxsw4"
|
[(match_operand:DI 0 "register_operand" "")
|
[(match_operand:DI 0 "register_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 1 "reg_or_0_operand" "")
|
(match_operand:DI 2 "reg_or_0_operand" "")]
|
(match_operand:DI 2 "reg_or_0_operand" "")]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
{
|
{
|
alpha_expand_builtin_vector_binop (gen_smaxv4hi3, V4HImode, operands[0],
|
alpha_expand_builtin_vector_binop (gen_smaxv4hi3, V4HImode, operands[0],
|
operands[1], operands[2]);
|
operands[1], operands[2]);
|
DONE;
|
DONE;
|
})
|
})
|
|
|
(define_insn "builtin_perr"
|
(define_insn "builtin_perr"
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
(unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "%rJ")
|
(unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "%rJ")
|
(match_operand:DI 2 "reg_or_8bit_operand" "rJ")]
|
(match_operand:DI 2 "reg_or_8bit_operand" "rJ")]
|
UNSPEC_PERR))]
|
UNSPEC_PERR))]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
"perr %r1,%r2,%0"
|
"perr %r1,%r2,%0"
|
[(set_attr "type" "mvi")])
|
[(set_attr "type" "mvi")])
|
|
|
(define_expand "builtin_pklb"
|
(define_expand "builtin_pklb"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(vec_concat:V8QI
|
(vec_concat:V8QI
|
(vec_concat:V4QI
|
(vec_concat:V4QI
|
(truncate:V2QI (match_operand:DI 1 "register_operand" ""))
|
(truncate:V2QI (match_operand:DI 1 "register_operand" ""))
|
(match_dup 2))
|
(match_dup 2))
|
(match_dup 3)))]
|
(match_dup 3)))]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
{
|
{
|
operands[0] = gen_lowpart (V8QImode, operands[0]);
|
operands[0] = gen_lowpart (V8QImode, operands[0]);
|
operands[1] = gen_lowpart (V2SImode, operands[1]);
|
operands[1] = gen_lowpart (V2SImode, operands[1]);
|
operands[2] = CONST0_RTX (V2QImode);
|
operands[2] = CONST0_RTX (V2QImode);
|
operands[3] = CONST0_RTX (V4QImode);
|
operands[3] = CONST0_RTX (V4QImode);
|
})
|
})
|
|
|
(define_insn "*pklb"
|
(define_insn "*pklb"
|
[(set (match_operand:V8QI 0 "register_operand" "=r")
|
[(set (match_operand:V8QI 0 "register_operand" "=r")
|
(vec_concat:V8QI
|
(vec_concat:V8QI
|
(vec_concat:V4QI
|
(vec_concat:V4QI
|
(truncate:V2QI (match_operand:V2SI 1 "register_operand" "r"))
|
(truncate:V2QI (match_operand:V2SI 1 "register_operand" "r"))
|
(match_operand:V2QI 2 "const0_operand" ""))
|
(match_operand:V2QI 2 "const0_operand" ""))
|
(match_operand:V4QI 3 "const0_operand" "")))]
|
(match_operand:V4QI 3 "const0_operand" "")))]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
"pklb %r1,%0"
|
"pklb %r1,%0"
|
[(set_attr "type" "mvi")])
|
[(set_attr "type" "mvi")])
|
|
|
(define_expand "builtin_pkwb"
|
(define_expand "builtin_pkwb"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(vec_concat:V8QI
|
(vec_concat:V8QI
|
(truncate:V4QI (match_operand:DI 1 "register_operand" ""))
|
(truncate:V4QI (match_operand:DI 1 "register_operand" ""))
|
(match_dup 2)))]
|
(match_dup 2)))]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
{
|
{
|
operands[0] = gen_lowpart (V8QImode, operands[0]);
|
operands[0] = gen_lowpart (V8QImode, operands[0]);
|
operands[1] = gen_lowpart (V4HImode, operands[1]);
|
operands[1] = gen_lowpart (V4HImode, operands[1]);
|
operands[2] = CONST0_RTX (V4QImode);
|
operands[2] = CONST0_RTX (V4QImode);
|
})
|
})
|
|
|
(define_insn "*pkwb"
|
(define_insn "*pkwb"
|
[(set (match_operand:V8QI 0 "register_operand" "=r")
|
[(set (match_operand:V8QI 0 "register_operand" "=r")
|
(vec_concat:V8QI
|
(vec_concat:V8QI
|
(truncate:V4QI (match_operand:V4HI 1 "register_operand" "r"))
|
(truncate:V4QI (match_operand:V4HI 1 "register_operand" "r"))
|
(match_operand:V4QI 2 "const0_operand" "")))]
|
(match_operand:V4QI 2 "const0_operand" "")))]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
"pkwb %r1,%0"
|
"pkwb %r1,%0"
|
[(set_attr "type" "mvi")])
|
[(set_attr "type" "mvi")])
|
|
|
(define_expand "builtin_unpkbl"
|
(define_expand "builtin_unpkbl"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(zero_extend:V2SI
|
(zero_extend:V2SI
|
(vec_select:V2QI (match_operand:DI 1 "register_operand" "")
|
(vec_select:V2QI (match_operand:DI 1 "register_operand" "")
|
(parallel [(const_int 0) (const_int 1)]))))]
|
(parallel [(const_int 0) (const_int 1)]))))]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
{
|
{
|
operands[0] = gen_lowpart (V2SImode, operands[0]);
|
operands[0] = gen_lowpart (V2SImode, operands[0]);
|
operands[1] = gen_lowpart (V8QImode, operands[1]);
|
operands[1] = gen_lowpart (V8QImode, operands[1]);
|
})
|
})
|
|
|
(define_insn "*unpkbl"
|
(define_insn "*unpkbl"
|
[(set (match_operand:V2SI 0 "register_operand" "=r")
|
[(set (match_operand:V2SI 0 "register_operand" "=r")
|
(zero_extend:V2SI
|
(zero_extend:V2SI
|
(vec_select:V2QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
|
(vec_select:V2QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
|
(parallel [(const_int 0) (const_int 1)]))))]
|
(parallel [(const_int 0) (const_int 1)]))))]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
"unpkbl %r1,%0"
|
"unpkbl %r1,%0"
|
[(set_attr "type" "mvi")])
|
[(set_attr "type" "mvi")])
|
|
|
(define_expand "builtin_unpkbw"
|
(define_expand "builtin_unpkbw"
|
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
(zero_extend:V4HI
|
(zero_extend:V4HI
|
(vec_select:V4QI (match_operand:DI 1 "register_operand" "")
|
(vec_select:V4QI (match_operand:DI 1 "register_operand" "")
|
(parallel [(const_int 0)
|
(parallel [(const_int 0)
|
(const_int 1)
|
(const_int 1)
|
(const_int 2)
|
(const_int 2)
|
(const_int 3)]))))]
|
(const_int 3)]))))]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
{
|
{
|
operands[0] = gen_lowpart (V4HImode, operands[0]);
|
operands[0] = gen_lowpart (V4HImode, operands[0]);
|
operands[1] = gen_lowpart (V8QImode, operands[1]);
|
operands[1] = gen_lowpart (V8QImode, operands[1]);
|
})
|
})
|
|
|
(define_insn "*unpkbw"
|
(define_insn "*unpkbw"
|
[(set (match_operand:V4HI 0 "register_operand" "=r")
|
[(set (match_operand:V4HI 0 "register_operand" "=r")
|
(zero_extend:V4HI
|
(zero_extend:V4HI
|
(vec_select:V4QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
|
(vec_select:V4QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
|
(parallel [(const_int 0)
|
(parallel [(const_int 0)
|
(const_int 1)
|
(const_int 1)
|
(const_int 2)
|
(const_int 2)
|
(const_int 3)]))))]
|
(const_int 3)]))))]
|
"TARGET_MAX"
|
"TARGET_MAX"
|
"unpkbw %r1,%0"
|
"unpkbw %r1,%0"
|
[(set_attr "type" "mvi")])
|
[(set_attr "type" "mvi")])
|
|
|
(include "sync.md")
|
(include "sync.md")
|
|
|
;; The call patterns are at the end of the file because their
|
;; The call patterns are at the end of the file because their
|
;; wildcard operand0 interferes with nice recognition.
|
;; wildcard operand0 interferes with nice recognition.
|
|
|
(define_insn "*call_value_osf_1_er_noreturn"
|
(define_insn "*call_value_osf_1_er_noreturn"
|
[(set (match_operand 0 "" "")
|
[(set (match_operand 0 "" "")
|
(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
|
(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
|
(match_operand 2 "" "")))
|
(match_operand 2 "" "")))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(clobber (reg:DI 26))]
|
(clobber (reg:DI 26))]
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
|
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
|
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
|
"@
|
"@
|
jsr $26,($27),0
|
jsr $26,($27),0
|
bsr $26,%1\t\t!samegp
|
bsr $26,%1\t\t!samegp
|
ldq $27,%1($29)\t\t!literal!%#\;jsr $26,($27),%1\t\t!lituse_jsr!%#"
|
ldq $27,%1($29)\t\t!literal!%#\;jsr $26,($27),%1\t\t!lituse_jsr!%#"
|
[(set_attr "type" "jsr")
|
[(set_attr "type" "jsr")
|
(set_attr "length" "*,*,8")])
|
(set_attr "length" "*,*,8")])
|
|
|
(define_insn "*call_value_osf_1_er"
|
(define_insn "*call_value_osf_1_er"
|
[(set (match_operand 0 "" "")
|
[(set (match_operand 0 "" "")
|
(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
|
(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
|
(match_operand 2 "" "")))
|
(match_operand 2 "" "")))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(clobber (reg:DI 26))]
|
(clobber (reg:DI 26))]
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
"@
|
"@
|
jsr $26,(%1),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
|
jsr $26,(%1),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
|
bsr $26,%1\t\t!samegp
|
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!%*"
|
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 "type" "jsr")
|
(set_attr "length" "12,*,16")])
|
(set_attr "length" "12,*,16")])
|
|
|
;; We must use peep2 instead of a split because we need accurate life
|
;; We must use peep2 instead of a split because we need accurate life
|
;; information for $gp. Consider the case of { bar(); while (1); }.
|
;; information for $gp. Consider the case of { bar(); while (1); }.
|
(define_peephole2
|
(define_peephole2
|
[(parallel [(set (match_operand 0 "" "")
|
[(parallel [(set (match_operand 0 "" "")
|
(call (mem:DI (match_operand:DI 1 "call_operand" ""))
|
(call (mem:DI (match_operand:DI 1 "call_operand" ""))
|
(match_operand 2 "" "")))
|
(match_operand 2 "" "")))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(clobber (reg:DI 26))])]
|
(clobber (reg:DI 26))])]
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
|
&& ! samegp_function_operand (operands[1], Pmode)
|
&& ! samegp_function_operand (operands[1], Pmode)
|
&& (peep2_regno_dead_p (1, 29)
|
&& (peep2_regno_dead_p (1, 29)
|
|| find_reg_note (insn, REG_NORETURN, NULL_RTX))"
|
|| find_reg_note (insn, REG_NORETURN, NULL_RTX))"
|
[(parallel [(set (match_dup 0)
|
[(parallel [(set (match_dup 0)
|
(call (mem:DI (match_dup 3))
|
(call (mem:DI (match_dup 3))
|
(match_dup 2)))
|
(match_dup 2)))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(use (match_dup 1))
|
(use (match_dup 1))
|
(use (match_dup 4))
|
(use (match_dup 4))
|
(clobber (reg:DI 26))])]
|
(clobber (reg:DI 26))])]
|
{
|
{
|
if (CONSTANT_P (operands[1]))
|
if (CONSTANT_P (operands[1]))
|
{
|
{
|
operands[3] = gen_rtx_REG (Pmode, 27);
|
operands[3] = gen_rtx_REG (Pmode, 27);
|
operands[4] = GEN_INT (alpha_next_sequence_number++);
|
operands[4] = GEN_INT (alpha_next_sequence_number++);
|
emit_insn (gen_movdi_er_high_g (operands[3], pic_offset_table_rtx,
|
emit_insn (gen_movdi_er_high_g (operands[3], pic_offset_table_rtx,
|
operands[1], operands[4]));
|
operands[1], operands[4]));
|
}
|
}
|
else
|
else
|
{
|
{
|
operands[3] = operands[1];
|
operands[3] = operands[1];
|
operands[1] = const0_rtx;
|
operands[1] = const0_rtx;
|
operands[4] = const0_rtx;
|
operands[4] = const0_rtx;
|
}
|
}
|
})
|
})
|
|
|
(define_peephole2
|
(define_peephole2
|
[(parallel [(set (match_operand 0 "" "")
|
[(parallel [(set (match_operand 0 "" "")
|
(call (mem:DI (match_operand:DI 1 "call_operand" ""))
|
(call (mem:DI (match_operand:DI 1 "call_operand" ""))
|
(match_operand 2 "" "")))
|
(match_operand 2 "" "")))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(clobber (reg:DI 26))])]
|
(clobber (reg:DI 26))])]
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
|
&& ! samegp_function_operand (operands[1], Pmode)
|
&& ! samegp_function_operand (operands[1], Pmode)
|
&& ! (peep2_regno_dead_p (1, 29)
|
&& ! (peep2_regno_dead_p (1, 29)
|
|| find_reg_note (insn, REG_NORETURN, NULL_RTX))"
|
|| find_reg_note (insn, REG_NORETURN, NULL_RTX))"
|
[(parallel [(set (match_dup 0)
|
[(parallel [(set (match_dup 0)
|
(call (mem:DI (match_dup 3))
|
(call (mem:DI (match_dup 3))
|
(match_dup 2)))
|
(match_dup 2)))
|
(set (match_dup 6)
|
(set (match_dup 6)
|
(unspec:DI [(match_dup 6) (match_dup 4)] UNSPEC_LDGP1))
|
(unspec:DI [(match_dup 6) (match_dup 4)] UNSPEC_LDGP1))
|
(use (match_dup 1))
|
(use (match_dup 1))
|
(use (match_dup 5))
|
(use (match_dup 5))
|
(clobber (reg:DI 26))])
|
(clobber (reg:DI 26))])
|
(set (match_dup 6)
|
(set (match_dup 6)
|
(unspec:DI [(match_dup 6) (match_dup 4)] UNSPEC_LDGP2))]
|
(unspec:DI [(match_dup 6) (match_dup 4)] UNSPEC_LDGP2))]
|
{
|
{
|
if (CONSTANT_P (operands[1]))
|
if (CONSTANT_P (operands[1]))
|
{
|
{
|
operands[3] = gen_rtx_REG (Pmode, 27);
|
operands[3] = gen_rtx_REG (Pmode, 27);
|
operands[5] = GEN_INT (alpha_next_sequence_number++);
|
operands[5] = GEN_INT (alpha_next_sequence_number++);
|
emit_insn (gen_movdi_er_high_g (operands[3], pic_offset_table_rtx,
|
emit_insn (gen_movdi_er_high_g (operands[3], pic_offset_table_rtx,
|
operands[1], operands[5]));
|
operands[1], operands[5]));
|
}
|
}
|
else
|
else
|
{
|
{
|
operands[3] = operands[1];
|
operands[3] = operands[1];
|
operands[1] = const0_rtx;
|
operands[1] = const0_rtx;
|
operands[5] = const0_rtx;
|
operands[5] = const0_rtx;
|
}
|
}
|
operands[4] = GEN_INT (alpha_next_sequence_number++);
|
operands[4] = GEN_INT (alpha_next_sequence_number++);
|
operands[6] = pic_offset_table_rtx;
|
operands[6] = pic_offset_table_rtx;
|
})
|
})
|
|
|
(define_insn "*call_value_osf_2_er_nogp"
|
(define_insn "*call_value_osf_2_er_nogp"
|
[(set (match_operand 0 "" "")
|
[(set (match_operand 0 "" "")
|
(call (mem:DI (match_operand:DI 1 "register_operand" "c"))
|
(call (mem:DI (match_operand:DI 1 "register_operand" "c"))
|
(match_operand 2 "" "")))
|
(match_operand 2 "" "")))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(use (match_operand 3 "" ""))
|
(use (match_operand 3 "" ""))
|
(use (match_operand 4 "" ""))
|
(use (match_operand 4 "" ""))
|
(clobber (reg:DI 26))]
|
(clobber (reg:DI 26))]
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
"jsr $26,(%1),%3%J4"
|
"jsr $26,(%1),%3%J4"
|
[(set_attr "type" "jsr")])
|
[(set_attr "type" "jsr")])
|
|
|
(define_insn "*call_value_osf_2_er"
|
(define_insn "*call_value_osf_2_er"
|
[(set (match_operand 0 "" "")
|
[(set (match_operand 0 "" "")
|
(call (mem:DI (match_operand:DI 1 "register_operand" "c"))
|
(call (mem:DI (match_operand:DI 1 "register_operand" "c"))
|
(match_operand 2 "" "")))
|
(match_operand 2 "" "")))
|
(set (reg:DI 29)
|
(set (reg:DI 29)
|
(unspec:DI [(reg:DI 29) (match_operand 5 "const_int_operand" "")]
|
(unspec:DI [(reg:DI 29) (match_operand 5 "const_int_operand" "")]
|
UNSPEC_LDGP1))
|
UNSPEC_LDGP1))
|
(use (match_operand 3 "" ""))
|
(use (match_operand 3 "" ""))
|
(use (match_operand 4 "" ""))
|
(use (match_operand 4 "" ""))
|
(clobber (reg:DI 26))]
|
(clobber (reg:DI 26))]
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
"jsr $26,(%1),%3%J4\;ldah $29,0($26)\t\t!gpdisp!%5"
|
"jsr $26,(%1),%3%J4\;ldah $29,0($26)\t\t!gpdisp!%5"
|
[(set_attr "type" "jsr")
|
[(set_attr "type" "jsr")
|
(set_attr "cannot_copy" "true")
|
(set_attr "cannot_copy" "true")
|
(set_attr "length" "8")])
|
(set_attr "length" "8")])
|
|
|
(define_insn "*call_value_osf_1_noreturn"
|
(define_insn "*call_value_osf_1_noreturn"
|
[(set (match_operand 0 "" "")
|
[(set (match_operand 0 "" "")
|
(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
|
(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
|
(match_operand 2 "" "")))
|
(match_operand 2 "" "")))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(clobber (reg:DI 26))]
|
(clobber (reg:DI 26))]
|
"! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
|
"! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
|
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
|
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
|
"@
|
"@
|
jsr $26,($27),0
|
jsr $26,($27),0
|
bsr $26,$%1..ng
|
bsr $26,$%1..ng
|
jsr $26,%1"
|
jsr $26,%1"
|
[(set_attr "type" "jsr")
|
[(set_attr "type" "jsr")
|
(set_attr "length" "*,*,8")])
|
(set_attr "length" "*,*,8")])
|
|
|
(define_insn_and_split "call_value_osf_tlsgd"
|
(define_insn_and_split "call_value_osf_tlsgd"
|
[(set (match_operand 0 "" "")
|
[(set (match_operand 0 "" "")
|
(call (mem:DI (match_operand:DI 1 "symbolic_operand" ""))
|
(call (mem:DI (match_operand:DI 1 "symbolic_operand" ""))
|
(const_int 0)))
|
(const_int 0)))
|
(unspec [(match_operand:DI 2 "const_int_operand" "")] UNSPEC_TLSGD_CALL)
|
(unspec [(match_operand:DI 2 "const_int_operand" "")] UNSPEC_TLSGD_CALL)
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(clobber (reg:DI 26))]
|
(clobber (reg:DI 26))]
|
"HAVE_AS_TLS"
|
"HAVE_AS_TLS"
|
"#"
|
"#"
|
"&& reload_completed"
|
"&& reload_completed"
|
[(set (match_dup 3)
|
[(set (match_dup 3)
|
(unspec:DI [(match_dup 5)
|
(unspec:DI [(match_dup 5)
|
(match_dup 1)
|
(match_dup 1)
|
(match_dup 2)] UNSPEC_LITERAL))
|
(match_dup 2)] UNSPEC_LITERAL))
|
(parallel [(set (match_dup 0)
|
(parallel [(set (match_dup 0)
|
(call (mem:DI (match_dup 3))
|
(call (mem:DI (match_dup 3))
|
(const_int 0)))
|
(const_int 0)))
|
(set (match_dup 5)
|
(set (match_dup 5)
|
(unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP1))
|
(unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP1))
|
(use (match_dup 1))
|
(use (match_dup 1))
|
(use (unspec [(match_dup 2)] UNSPEC_TLSGD_CALL))
|
(use (unspec [(match_dup 2)] UNSPEC_TLSGD_CALL))
|
(clobber (reg:DI 26))])
|
(clobber (reg:DI 26))])
|
(set (match_dup 5)
|
(set (match_dup 5)
|
(unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP2))]
|
(unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP2))]
|
{
|
{
|
operands[3] = gen_rtx_REG (Pmode, 27);
|
operands[3] = gen_rtx_REG (Pmode, 27);
|
operands[4] = GEN_INT (alpha_next_sequence_number++);
|
operands[4] = GEN_INT (alpha_next_sequence_number++);
|
operands[5] = pic_offset_table_rtx;
|
operands[5] = pic_offset_table_rtx;
|
}
|
}
|
[(set_attr "type" "multi")])
|
[(set_attr "type" "multi")])
|
|
|
(define_insn_and_split "call_value_osf_tlsldm"
|
(define_insn_and_split "call_value_osf_tlsldm"
|
[(set (match_operand 0 "" "")
|
[(set (match_operand 0 "" "")
|
(call (mem:DI (match_operand:DI 1 "symbolic_operand" ""))
|
(call (mem:DI (match_operand:DI 1 "symbolic_operand" ""))
|
(const_int 0)))
|
(const_int 0)))
|
(unspec [(match_operand:DI 2 "const_int_operand" "")] UNSPEC_TLSLDM_CALL)
|
(unspec [(match_operand:DI 2 "const_int_operand" "")] UNSPEC_TLSLDM_CALL)
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(clobber (reg:DI 26))]
|
(clobber (reg:DI 26))]
|
"HAVE_AS_TLS"
|
"HAVE_AS_TLS"
|
"#"
|
"#"
|
"&& reload_completed"
|
"&& reload_completed"
|
[(set (match_dup 3)
|
[(set (match_dup 3)
|
(unspec:DI [(match_dup 5)
|
(unspec:DI [(match_dup 5)
|
(match_dup 1)
|
(match_dup 1)
|
(match_dup 2)] UNSPEC_LITERAL))
|
(match_dup 2)] UNSPEC_LITERAL))
|
(parallel [(set (match_dup 0)
|
(parallel [(set (match_dup 0)
|
(call (mem:DI (match_dup 3))
|
(call (mem:DI (match_dup 3))
|
(const_int 0)))
|
(const_int 0)))
|
(set (match_dup 5)
|
(set (match_dup 5)
|
(unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP1))
|
(unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP1))
|
(use (match_dup 1))
|
(use (match_dup 1))
|
(use (unspec [(match_dup 2)] UNSPEC_TLSLDM_CALL))
|
(use (unspec [(match_dup 2)] UNSPEC_TLSLDM_CALL))
|
(clobber (reg:DI 26))])
|
(clobber (reg:DI 26))])
|
(set (match_dup 5)
|
(set (match_dup 5)
|
(unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP2))]
|
(unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP2))]
|
{
|
{
|
operands[3] = gen_rtx_REG (Pmode, 27);
|
operands[3] = gen_rtx_REG (Pmode, 27);
|
operands[4] = GEN_INT (alpha_next_sequence_number++);
|
operands[4] = GEN_INT (alpha_next_sequence_number++);
|
operands[5] = pic_offset_table_rtx;
|
operands[5] = pic_offset_table_rtx;
|
}
|
}
|
[(set_attr "type" "multi")])
|
[(set_attr "type" "multi")])
|
|
|
(define_insn "*call_value_osf_1"
|
(define_insn "*call_value_osf_1"
|
[(set (match_operand 0 "" "")
|
[(set (match_operand 0 "" "")
|
(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
|
(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
|
(match_operand 2 "" "")))
|
(match_operand 2 "" "")))
|
(use (reg:DI 29))
|
(use (reg:DI 29))
|
(clobber (reg:DI 26))]
|
(clobber (reg:DI 26))]
|
"! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
"! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
"@
|
"@
|
jsr $26,($27),0\;ldgp $29,0($26)
|
jsr $26,($27),0\;ldgp $29,0($26)
|
bsr $26,$%1..ng
|
bsr $26,$%1..ng
|
jsr $26,%1\;ldgp $29,0($26)"
|
jsr $26,%1\;ldgp $29,0($26)"
|
[(set_attr "type" "jsr")
|
[(set_attr "type" "jsr")
|
(set_attr "length" "12,*,16")])
|
(set_attr "length" "12,*,16")])
|
|
|
(define_insn "*sibcall_value_osf_1_er"
|
(define_insn "*sibcall_value_osf_1_er"
|
[(set (match_operand 0 "" "")
|
[(set (match_operand 0 "" "")
|
(call (mem:DI (match_operand:DI 1 "symbolic_operand" "R,s"))
|
(call (mem:DI (match_operand:DI 1 "symbolic_operand" "R,s"))
|
(match_operand 2 "" "")))
|
(match_operand 2 "" "")))
|
(unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
|
(unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
"@
|
"@
|
br $31,%1\t\t!samegp
|
br $31,%1\t\t!samegp
|
ldq $27,%1($29)\t\t!literal!%#\;jmp $31,($27),%1\t\t!lituse_jsr!%#"
|
ldq $27,%1($29)\t\t!literal!%#\;jmp $31,($27),%1\t\t!lituse_jsr!%#"
|
[(set_attr "type" "jsr")
|
[(set_attr "type" "jsr")
|
(set_attr "length" "*,8")])
|
(set_attr "length" "*,8")])
|
|
|
(define_insn "*sibcall_value_osf_1"
|
(define_insn "*sibcall_value_osf_1"
|
[(set (match_operand 0 "" "")
|
[(set (match_operand 0 "" "")
|
(call (mem:DI (match_operand:DI 1 "symbolic_operand" "R,s"))
|
(call (mem:DI (match_operand:DI 1 "symbolic_operand" "R,s"))
|
(match_operand 2 "" "")))
|
(match_operand 2 "" "")))
|
(unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
|
(unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
|
"! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
"! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
"@
|
"@
|
br $31,$%1..ng
|
br $31,$%1..ng
|
lda $27,%1\;jmp $31,($27),%1"
|
lda $27,%1\;jmp $31,($27),%1"
|
[(set_attr "type" "jsr")
|
[(set_attr "type" "jsr")
|
(set_attr "length" "*,8")])
|
(set_attr "length" "*,8")])
|
|
|
(define_insn "*call_value_nt_1"
|
(define_insn "*call_value_nt_1"
|
[(set (match_operand 0 "" "")
|
[(set (match_operand 0 "" "")
|
(call (mem:DI (match_operand:DI 1 "call_operand" "r,R,s"))
|
(call (mem:DI (match_operand:DI 1 "call_operand" "r,R,s"))
|
(match_operand 2 "" "")))
|
(match_operand 2 "" "")))
|
(clobber (reg:DI 26))]
|
(clobber (reg:DI 26))]
|
"TARGET_ABI_WINDOWS_NT"
|
"TARGET_ABI_WINDOWS_NT"
|
"@
|
"@
|
jsr $26,(%1)
|
jsr $26,(%1)
|
bsr $26,%1
|
bsr $26,%1
|
jsr $26,%1"
|
jsr $26,%1"
|
[(set_attr "type" "jsr")
|
[(set_attr "type" "jsr")
|
(set_attr "length" "*,*,12")])
|
(set_attr "length" "*,*,12")])
|
|
|
; GAS relies on the order and position of instructions output below in order
|
; GAS relies on the order and position of instructions output below in order
|
; to generate relocs for VMS link to potentially optimize the call.
|
; to generate relocs for VMS link to potentially optimize the call.
|
; Please do not molest.
|
; Please do not molest.
|
(define_insn "*call_value_vms_1"
|
(define_insn "*call_value_vms_1"
|
[(set (match_operand 0 "" "")
|
[(set (match_operand 0 "" "")
|
(call (mem:DI (match_operand:DI 1 "call_operand" "r,s"))
|
(call (mem:DI (match_operand:DI 1 "call_operand" "r,s"))
|
(match_operand 2 "" "")))
|
(match_operand 2 "" "")))
|
(use (match_operand:DI 3 "nonmemory_operand" "r,n"))
|
(use (match_operand:DI 3 "nonmemory_operand" "r,n"))
|
(use (reg:DI 25))
|
(use (reg:DI 25))
|
(use (reg:DI 26))
|
(use (reg:DI 26))
|
(clobber (reg:DI 27))]
|
(clobber (reg:DI 27))]
|
"TARGET_ABI_OPEN_VMS"
|
"TARGET_ABI_OPEN_VMS"
|
{
|
{
|
switch (which_alternative)
|
switch (which_alternative)
|
{
|
{
|
case 0:
|
case 0:
|
return "mov %3,$27\;jsr $26,0\;ldq $27,0($29)";
|
return "mov %3,$27\;jsr $26,0\;ldq $27,0($29)";
|
case 1:
|
case 1:
|
operands [3] = alpha_use_linkage (operands [1], cfun->decl, 1, 0);
|
operands [3] = alpha_use_linkage (operands [1], cfun->decl, 1, 0);
|
operands [4] = alpha_use_linkage (operands [1], cfun->decl, 0, 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)";
|
return "ldq $26,%4\;ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)";
|
default:
|
default:
|
gcc_unreachable ();
|
gcc_unreachable ();
|
}
|
}
|
}
|
}
|
[(set_attr "type" "jsr")
|
[(set_attr "type" "jsr")
|
(set_attr "length" "12,16")])
|
(set_attr "length" "12,16")])
|
|
|
(define_insn "*call_value_umk"
|
(define_insn "*call_value_umk"
|
[(set (match_operand 0 "" "")
|
[(set (match_operand 0 "" "")
|
(call (mem:DI (match_operand:DI 1 "call_operand" "r"))
|
(call (mem:DI (match_operand:DI 1 "call_operand" "r"))
|
(match_operand 2 "" "")))
|
(match_operand 2 "" "")))
|
(use (reg:DI 25))
|
(use (reg:DI 25))
|
(clobber (reg:DI 26))]
|
(clobber (reg:DI 26))]
|
"TARGET_ABI_UNICOSMK"
|
"TARGET_ABI_UNICOSMK"
|
"jsr $26,(%1)"
|
"jsr $26,(%1)"
|
[(set_attr "type" "jsr")])
|
[(set_attr "type" "jsr")])
|
|
|