;; Machine description for DEC Alpha for GNU C compiler
;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-;; 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+;; 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
+;; Free Software Foundation, Inc.
;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
;;
;; This file is part of GCC.
;;
;; GCC is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
+;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;;
;; GCC is distributed in the hope that it will be useful,
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
-;; along with GCC; see the file COPYING. If not, write to
-;; the Free Software Foundation, 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; along with GCC; see the file COPYING3. If not see
+;; <http://www.gnu.org/licenses/>.
;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
;; Uses of UNSPEC in this file:
-(define_constants
- [(UNSPEC_ARG_HOME 0)
- (UNSPEC_CTTZ 1)
- (UNSPEC_INSXH 2)
- (UNSPEC_MSKXH 3)
- (UNSPEC_CVTQL 4)
- (UNSPEC_NT_LDA 5)
- (UNSPEC_UMK_LAUM 6)
- (UNSPEC_UMK_LALM 7)
- (UNSPEC_UMK_LAL 8)
- (UNSPEC_UMK_LOAD_CIW 9)
- (UNSPEC_LDGP2 10)
- (UNSPEC_LITERAL 11)
- (UNSPEC_LITUSE 12)
- (UNSPEC_SIBCALL 13)
- (UNSPEC_SYMBOL 14)
-
- ;; TLS Support
- (UNSPEC_TLSGD_CALL 15)
- (UNSPEC_TLSLDM_CALL 16)
- (UNSPEC_TLSGD 17)
- (UNSPEC_TLSLDM 18)
- (UNSPEC_DTPREL 19)
- (UNSPEC_TPREL 20)
- (UNSPEC_TP 21)
-
- ;; Builtins
- (UNSPEC_CMPBGE 22)
- (UNSPEC_ZAP 23)
- (UNSPEC_AMASK 24)
- (UNSPEC_IMPLVER 25)
- (UNSPEC_PERR 26)
- (UNSPEC_CTLZ 27)
- (UNSPEC_CTPOP 28)
- ])
+(define_c_enum "unspec" [
+ UNSPEC_XFLT_COMPARE
+ UNSPEC_ARG_HOME
+ UNSPEC_LDGP1
+ UNSPEC_INSXH
+ UNSPEC_MSKXH
+ UNSPEC_CVTQL
+ UNSPEC_CVTLQ
+ UNSPEC_LDGP2
+ UNSPEC_LITERAL
+ UNSPEC_LITUSE
+ UNSPEC_SIBCALL
+ UNSPEC_SYMBOL
+
+ ;; TLS Support
+ UNSPEC_TLSGD_CALL
+ UNSPEC_TLSLDM_CALL
+ UNSPEC_TLSGD
+ UNSPEC_TLSLDM
+ UNSPEC_DTPREL
+ UNSPEC_TPREL
+ UNSPEC_TP
+
+ ;; Builtins
+ UNSPEC_CMPBGE
+ UNSPEC_ZAP
+ UNSPEC_AMASK
+ UNSPEC_IMPLVER
+ UNSPEC_PERR
+ UNSPEC_COPYSIGN
+
+ ;; Atomic operations
+ UNSPEC_MB
+ UNSPEC_ATOMIC
+ UNSPEC_CMPXCHG
+ UNSPEC_XCHG
+])
;; UNSPEC_VOLATILE:
-(define_constants
- [(UNSPECV_IMB 0)
- (UNSPECV_BLOCKAGE 1)
- (UNSPECV_SETJMPR 2) ; builtin_setjmp_receiver
- (UNSPECV_LONGJMP 3) ; builtin_longjmp
- (UNSPECV_TRAPB 4)
- (UNSPECV_PSPL 5) ; prologue_stack_probe_loop
- (UNSPECV_REALIGN 6)
- (UNSPECV_EHR 7) ; exception_receiver
- (UNSPECV_MCOUNT 8)
- (UNSPECV_FORCE_MOV 9)
- (UNSPECV_LDGP1 10)
- (UNSPECV_PLDGP2 11) ; prologue ldgp
- (UNSPECV_SET_TP 12)
- (UNSPECV_RPCC 13)
- ])
+(define_c_enum "unspecv" [
+ UNSPECV_IMB
+ UNSPECV_BLOCKAGE
+ UNSPECV_SETJMPR ; builtin_setjmp_receiver
+ UNSPECV_LONGJMP ; builtin_longjmp
+ UNSPECV_TRAPB
+ UNSPECV_PSPL ; prologue_stack_probe_loop
+ UNSPECV_REALIGN
+ UNSPECV_EHR ; exception_receiver
+ UNSPECV_MCOUNT
+ UNSPECV_FORCE_MOV
+ UNSPECV_LDGP1
+ UNSPECV_PLDGP2 ; prologue ldgp
+ UNSPECV_SET_TP
+ UNSPECV_RPCC
+ UNSPECV_SETJMPR_ER ; builtin_setjmp_receiver fragment
+ UNSPECV_LL ; load-locked
+ UNSPECV_SC ; store-conditional
+ UNSPECV_CMPXCHG
+])
+
+;; On non-BWX targets, CQImode must be handled the similarly to HImode
+;; when generating reloads.
+(define_mode_iterator RELOAD12 [QI HI CQI])
+(define_mode_attr reloadmode [(QI "qi") (HI "hi") (CQI "hi")])
+
+;; Other mode iterators
+(define_mode_iterator I12MODE [QI HI])
+(define_mode_iterator I48MODE [SI DI])
+(define_mode_attr modesuffix [(SI "l") (DI "q")])
;; Where necessary, the suffixes _le and _be are used to distinguish between
;; little-endian and big-endian patterns.
;; Processor type -- this attribute must exactly match the processor_type
;; enumeration in alpha.h.
-(define_attr "cpu" "ev4,ev5,ev6"
- (const (symbol_ref "alpha_cpu")))
+(define_attr "tune" "ev4,ev5,ev6"
+ (const (symbol_ref "((enum attr_tune) alpha_tune)")))
;; Define an insn type attribute. This is used in function unit delay
;; computations, among other purposes. For the most part, we use the names
;; separately.
(define_attr "type"
- "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,multi,none"
+ "ild,fld,ldsym,ist,fst,ibr,callpal,fbr,jsr,iadd,ilog,shift,icmov,fcmov,
+ icmp,imul,fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,mb,ld_l,st_c,
+ multi,none"
(const_string "iadd"))
;; Describe a user's asm statement.
(cond [(eq_attr "type" "ldsym,jsr")
(const_string "yes")
(eq_attr "type" "ild,fld,ist,fst")
- (symbol_ref "alpha_find_lo_sum_using_gp(insn)")
+ (symbol_ref "((enum attr_usegp) alpha_find_lo_sum_using_gp (insn))")
]
(const_string "no")))
+;; The CANNOT_COPY attribute marks instructions with relocations that
+;; cannot easily be duplicated. This includes insns with gpdisp relocs
+;; since they have to stay in 1-1 correspondence with one another. This
+;; also includes jsr insns, since they must stay in correspondence with
+;; the immediately following gpdisp instructions.
+
+(define_attr "cannot_copy" "false,true"
+ (const_string "false"))
+
+;; Used to control the "enabled" attribute on a per-instruction basis.
+;; For convenience, conflate ABI issues re loading of addresses with
+;; an "isa".
+(define_attr "isa" "base,bwx,max,fix,cix,vms,ner,er"
+ (const_string "base"))
+
+(define_attr "enabled" ""
+ (cond [(eq_attr "isa" "bwx") (symbol_ref "TARGET_BWX")
+ (eq_attr "isa" "max") (symbol_ref "TARGET_MAX")
+ (eq_attr "isa" "fix") (symbol_ref "TARGET_FIX")
+ (eq_attr "isa" "cix") (symbol_ref "TARGET_CIX")
+ (eq_attr "isa" "vms") (symbol_ref "TARGET_ABI_OPEN_VMS")
+ (eq_attr "isa" "ner") (symbol_ref "!TARGET_EXPLICIT_RELOCS")
+ (eq_attr "isa" "er") (symbol_ref "TARGET_EXPLICIT_RELOCS")
+ ]
+ (const_int 1)))
\f
;; Include scheduling descriptions.
(include "ev4.md")
(include "ev5.md")
(include "ev6.md")
+
+\f
+;; Operand and operator predicates and constraints
+
+(include "predicates.md")
+(include "constraints.md")
+
\f
;; First define the arithmetic insns. Note that the 32-bit forms also
;; sign-extend.
""
"")
-(define_insn "*extendsidi2_nofix"
- [(set (match_operand:DI 0 "register_operand" "=r,r,*f,?*f")
- (sign_extend:DI
- (match_operand:SI 1 "nonimmediate_operand" "r,m,*f,m")))]
- "! TARGET_FIX"
- "@
- addl $31,%1,%0
- ldl %0,%1
- cvtlq %1,%0
- lds %0,%1\;cvtlq %0,%0"
- [(set_attr "type" "iadd,ild,fadd,fld")
- (set_attr "length" "*,*,*,8")])
+(define_insn "*cvtlq"
+ [(set (match_operand:DI 0 "register_operand" "=f")
+ (unspec:DI [(match_operand:SF 1 "reg_or_0_operand" "fG")]
+ UNSPEC_CVTLQ))]
+ ""
+ "cvtlq %1,%0"
+ [(set_attr "type" "fadd")])
-(define_insn "*extendsidi2_fix"
- [(set (match_operand:DI 0 "register_operand" "=r,r,r,?*f,?*f")
+(define_insn "*extendsidi2_1"
+ [(set (match_operand:DI 0 "register_operand" "=r,r,!*f")
(sign_extend:DI
- (match_operand:SI 1 "nonimmediate_operand" "r,m,*f,*f,m")))]
- "TARGET_FIX"
+ (match_operand:SI 1 "nonimmediate_operand" "r,m,m")))]
+ ""
"@
addl $31,%1,%0
ldl %0,%1
- ftois %1,%0
- cvtlq %1,%0
lds %0,%1\;cvtlq %0,%0"
- [(set_attr "type" "iadd,ild,ftoi,fadd,fld")
- (set_attr "length" "*,*,*,*,8")])
+ [(set_attr "type" "iadd,ild,fld")
+ (set_attr "length" "*,*,8")])
-;; Due to issues with CLASS_CANNOT_CHANGE_SIZE, we cannot use a subreg here.
(define_split
[(set (match_operand:DI 0 "hard_fp_register_operand" "")
(sign_extend:DI (match_operand:SI 1 "memory_operand" "")))]
"reload_completed"
[(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (sign_extend:DI (match_dup 2)))]
- "operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]));")
+ (set (match_dup 0) (unspec:DI [(match_dup 2)] UNSPEC_CVTLQ))]
+{
+ operands[1] = adjust_address (operands[1], SFmode, 0);
+ operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));
+})
;; Optimize sign-extension of SImode loads. This shows up in the wake of
;; reload when converting fp->int.
(sign_extend:DI (match_dup 1)))]
"")
-(define_peephole2
- [(set (match_operand:SI 0 "hard_int_register_operand" "")
- (match_operand:SI 1 "hard_fp_register_operand" ""))
- (set (match_operand:DI 2 "hard_int_register_operand" "")
- (sign_extend:DI (match_dup 0)))]
- "TARGET_FIX
- && (true_regnum (operands[0]) == true_regnum (operands[2])
- || peep2_reg_dead_p (2, operands[0]))"
- [(set (match_dup 2)
- (sign_extend:DI (match_dup 1)))]
- "")
-
-(define_peephole2
- [(set (match_operand:DI 0 "hard_fp_register_operand" "")
- (sign_extend:DI (match_operand:SI 1 "hard_fp_register_operand" "")))
- (set (match_operand:DI 2 "hard_int_register_operand" "")
- (match_dup 0))]
- "TARGET_FIX && peep2_reg_dead_p (2, operands[0])"
- [(set (match_dup 2)
- (sign_extend:DI (match_dup 1)))]
- "")
-
-;; Don't say we have addsi3 if optimizing. This generates better code. We
-;; have the anonymous addsi3 pattern below in case combine wants to make it.
-(define_expand "addsi3"
- [(set (match_operand:SI 0 "register_operand" "")
- (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
- (match_operand:SI 2 "add_operand" "")))]
- "! optimize"
- "")
-
-(define_insn "*addsi_internal"
+(define_insn "addsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
(plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ")
(match_operand:SI 2 "add_operand" "rI,O,K,L")))]
;; and if we split before reload, we will require additional instructions.
(define_insn "*adddi_fp_hack"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (plus:DI (match_operand:DI 1 "reg_no_subreg_operand" "r")
- (match_operand:DI 2 "const_int_operand" "n")))]
+ [(set (match_operand:DI 0 "register_operand" "=r,r,r")
+ (plus:DI (match_operand:DI 1 "reg_no_subreg_operand" "r,r,r")
+ (match_operand:DI 2 "const_int_operand" "K,L,n")))]
"NONSTRICT_REG_OK_FP_BASE_P (operands[1])
&& INTVAL (operands[2]) >= 0
/* This is the largest constant an lda+ldah pair can add, minus
&& INTVAL (operands[2])
< (0x7fff8000
- FIRST_PSEUDO_REGISTER * UNITS_PER_WORD
- - ALPHA_ROUND(current_function_outgoing_args_size)
+ - ALPHA_ROUND(crtl->outgoing_args_size)
- (ALPHA_ROUND (get_frame_size ()
+ max_reg_num () * UNITS_PER_WORD
- + current_function_pretend_args_size)
- - current_function_pretend_args_size))"
- "#")
+ + crtl->args.pretend_args_size)
+ - crtl->args.pretend_args_size))"
+ "@
+ lda %0,%2(%1)
+ ldah %0,%h2(%1)
+ #")
;; Don't do this if we are adjusting SP since we don't want to do it
;; in two steps. Don't split FP sources for the reason listed above.
HOST_WIDE_INT val = INTVAL (operands[2]);
HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
HOST_WIDE_INT rest = val - low;
+ rtx rest_rtx = GEN_INT (rest);
operands[4] = GEN_INT (low);
- if (CONST_OK_FOR_LETTER_P (rest, 'L'))
- operands[3] = GEN_INT (rest);
- else if (! no_new_pseudos)
+ if (satisfies_constraint_L (rest_rtx))
+ operands[3] = rest_rtx;
+ else if (can_create_pseudo_p ())
{
operands[3] = gen_reg_rtx (DImode);
emit_move_insn (operands[3], operands[2]);
""
"subqv $31,%1,%0")
-(define_expand "subsi3"
- [(set (match_operand:SI 0 "register_operand" "")
- (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
- (match_operand:SI 2 "reg_or_8bit_operand" "")))]
- "! optimize"
- "")
-
-(define_insn "*subsi_internal"
+(define_insn "subsi3"
[(set (match_operand:SI 0 "register_operand" "=r")
(minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
(match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
""
"subqv %r1,%2,%0")
-;; The Unicos/Mk assembler doesn't support mull.
-
(define_insn "mulsi3"
[(set (match_operand:SI 0 "register_operand" "=r")
(mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
(match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
- "!TARGET_ABI_UNICOSMK"
+ ""
"mull %r1,%2,%0"
[(set_attr "type" "imul")
(set_attr "opsize" "si")])
(sign_extend:DI
(mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
(match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
- "!TARGET_ABI_UNICOSMK"
+ ""
"mull %r1,%2,%0"
[(set_attr "type" "imul")
(set_attr "opsize" "si")])
(sign_extend:DI (mult:SI (match_dup 1)
(match_dup 2))))
(const_int 0))]
- "!TARGET_ABI_UNICOSMK"
+ ""
"mullv %r1,%2,%0"
[(set_attr "type" "imul")
(set_attr "opsize" "si")])
(set_attr "opsize" "udi")])
\f
;; The divide and remainder operations take their inputs from r24 and
-;; r25, put their output in r27, and clobber r23 and r28 on all
-;; systems except Unicos/Mk. On Unicos, the standard library provides
-;; subroutines which use the standard calling convention and work on
-;; DImode operands.
-
+;; r25, put their output in r27, and clobber r23 and r28 on all systems.
+;;
;; ??? 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
;; sign-extended. But Linux, for instance, does not have this
(clobber (reg:DI 28))])
(set (match_operand:SI 0 "nonimmediate_operand" "")
(subreg:SI (match_dup 5) 0))]
- "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
+ "TARGET_ABI_OSF"
{
operands[3] = gen_reg_rtx (DImode);
operands[4] = gen_reg_rtx (DImode);
(clobber (reg:DI 28))])
(set (match_operand:SI 0 "nonimmediate_operand" "")
(subreg:SI (match_dup 5) 0))]
- "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
+ "TARGET_ABI_OSF"
{
operands[3] = gen_reg_rtx (DImode);
operands[4] = gen_reg_rtx (DImode);
(clobber (reg:DI 28))])
(set (match_operand:SI 0 "nonimmediate_operand" "")
(subreg:SI (match_dup 5) 0))]
- "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
+ "TARGET_ABI_OSF"
{
operands[3] = gen_reg_rtx (DImode);
operands[4] = gen_reg_rtx (DImode);
(clobber (reg:DI 28))])
(set (match_operand:SI 0 "nonimmediate_operand" "")
(subreg:SI (match_dup 5) 0))]
- "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
+ "TARGET_ABI_OSF"
{
operands[3] = gen_reg_rtx (DImode);
operands[4] = gen_reg_rtx (DImode);
(match_operand:DI 2 "register_operand" "")))
(clobber (reg:DI 23))
(clobber (reg:DI 28))])]
- "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
+ "TARGET_ABI_OSF"
"")
(define_expand "udivdi3"
(match_operand:DI 2 "register_operand" "")))
(clobber (reg:DI 23))
(clobber (reg:DI 28))])]
- "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
+ "TARGET_ABI_OSF"
"")
(define_expand "moddi3"
- [(use (match_operand:DI 0 "register_operand" ""))
- (use (match_operand:DI 1 "register_operand" ""))
- (use (match_operand:DI 2 "register_operand" ""))]
- "!TARGET_ABI_OPEN_VMS"
-{
- if (TARGET_ABI_UNICOSMK)
- emit_insn (gen_moddi3_umk (operands[0], operands[1], operands[2]));
- else
- emit_insn (gen_moddi3_dft (operands[0], operands[1], operands[2]));
- DONE;
-})
-
-(define_expand "moddi3_dft"
[(parallel [(set (match_operand:DI 0 "register_operand" "")
(mod:DI (match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "register_operand" "")))
(clobber (reg:DI 23))
(clobber (reg:DI 28))])]
- "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
+ "TARGET_ABI_OSF"
"")
-;; On Unicos/Mk, we do as the system's C compiler does:
-;; compute the quotient, multiply and subtract.
-
-(define_expand "moddi3_umk"
- [(use (match_operand:DI 0 "register_operand" ""))
- (use (match_operand:DI 1 "register_operand" ""))
- (use (match_operand:DI 2 "register_operand" ""))]
- "TARGET_ABI_UNICOSMK"
-{
- rtx div, mul = gen_reg_rtx (DImode);
-
- div = expand_binop (DImode, sdiv_optab, operands[1], operands[2],
- NULL_RTX, 0, OPTAB_LIB);
- div = force_reg (DImode, div);
- emit_insn (gen_muldi3 (mul, operands[2], div));
- emit_insn (gen_subdi3 (operands[0], operands[1], mul));
- DONE;
-})
-
(define_expand "umoddi3"
- [(use (match_operand:DI 0 "register_operand" ""))
- (use (match_operand:DI 1 "register_operand" ""))
- (use (match_operand:DI 2 "register_operand" ""))]
- "! TARGET_ABI_OPEN_VMS"
-{
- if (TARGET_ABI_UNICOSMK)
- emit_insn (gen_umoddi3_umk (operands[0], operands[1], operands[2]));
- else
- emit_insn (gen_umoddi3_dft (operands[0], operands[1], operands[2]));
- DONE;
-})
-
-(define_expand "umoddi3_dft"
[(parallel [(set (match_operand:DI 0 "register_operand" "")
(umod:DI (match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "register_operand" "")))
(clobber (reg:DI 23))
(clobber (reg:DI 28))])]
- "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
+ "TARGET_ABI_OSF"
"")
-(define_expand "umoddi3_umk"
- [(use (match_operand:DI 0 "register_operand" ""))
- (use (match_operand:DI 1 "register_operand" ""))
- (use (match_operand:DI 2 "register_operand" ""))]
- "TARGET_ABI_UNICOSMK"
-{
- rtx div, mul = gen_reg_rtx (DImode);
-
- div = expand_binop (DImode, udiv_optab, operands[1], operands[2],
- NULL_RTX, 1, OPTAB_LIB);
- div = force_reg (DImode, div);
- emit_insn (gen_muldi3 (mul, operands[2], div));
- emit_insn (gen_subdi3 (operands[0], operands[1], mul));
- DONE;
-})
-
;; Lengths of 8 for ldq $t12,__divq($gp); jsr $t9,($t12),__divq as
;; expanded by the assembler.
(match_operand:DI 2 "register_operand" "b")])))
(clobber (reg:DI 23))
(clobber (reg:DI 28))]
- "TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
- "ldq $27,__%E3($29)\t\t!literal!%#\;jsr $23,($27),__%E3\t\t!lituse_jsr!%#"
+ "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
+ "#"
"&& reload_completed"
[(parallel [(set (match_dup 0)
(sign_extend:DI (match_dup 3)))
str = "__remlu";
break;
default:
- abort ();
+ gcc_unreachable ();
}
operands[4] = GEN_INT (alpha_next_sequence_number++);
emit_insn (gen_movdi_er_high_g (operands[0], pic_offset_table_rtx,
(use (match_operand 5 "const_int_operand" ""))
(clobber (reg:DI 23))
(clobber (reg:DI 28))]
- "TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
- "jsr $23,($27),__%E3%J5"
+ "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
+ "jsr $23,($27),__%E3%j5"
[(set_attr "type" "jsr")
(set_attr "length" "4")])
(match_operand:DI 2 "register_operand" "b")])))
(clobber (reg:DI 23))
(clobber (reg:DI 28))]
- "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
+ "TARGET_ABI_OSF"
"%E3 %1,%2,%0"
[(set_attr "type" "jsr")
(set_attr "length" "8")])
(match_operand:DI 2 "register_operand" "b")]))
(clobber (reg:DI 23))
(clobber (reg:DI 28))]
- "TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
- "ldq $27,__%E3($29)\t\t!literal!%#\;jsr $23,($27),__%E3\t\t!lituse_jsr!%#"
+ "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
+ "#"
"&& reload_completed"
[(parallel [(set (match_dup 0) (match_dup 3))
(use (match_dup 0))
str = "__remqu";
break;
default:
- abort ();
+ gcc_unreachable ();
}
operands[4] = GEN_INT (alpha_next_sequence_number++);
emit_insn (gen_movdi_er_high_g (operands[0], pic_offset_table_rtx,
(use (match_operand 5 "const_int_operand" ""))
(clobber (reg:DI 23))
(clobber (reg:DI 28))]
- "TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
- "jsr $23,($27),__%E3%J5"
+ "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
+ "jsr $23,($27),__%E3%j5"
[(set_attr "type" "jsr")
(set_attr "length" "4")])
(match_operand:DI 2 "register_operand" "b")]))
(clobber (reg:DI 23))
(clobber (reg:DI 28))]
- "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
+ "TARGET_ABI_OSF"
"%E3 %1,%2,%0"
[(set_attr "type" "jsr")
(set_attr "length" "8")])
\f
-;; Next are the basic logical operations. These only exist in DImode.
+;; Next are the basic logical operations. We only expose the DImode operations
+;; to the rtl expanders, but SImode versions exist for combine as well as for
+;; the atomic operation splitters.
+
+(define_insn "*andsi_internal"
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r")
+ (and:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ")
+ (match_operand:SI 2 "and_operand" "rI,N,MH")))]
+ ""
+ "@
+ and %r1,%2,%0
+ bic %r1,%N2,%0
+ zapnot %r1,%m2,%0"
+ [(set_attr "type" "ilog,ilog,shift")])
(define_insn "anddi3"
[(set (match_operand:DI 0 "register_operand" "=r,r,r")
operands[4] = GEN_INT (mask2);
})
-(define_expand "zero_extendqihi2"
- [(set (match_operand:HI 0 "register_operand" "")
- (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
- ""
-{
- if (! TARGET_BWX)
- operands[1] = force_reg (QImode, operands[1]);
-})
-
-(define_insn "*zero_extendqihi2_bwx"
+(define_insn "zero_extendqihi2"
[(set (match_operand:HI 0 "register_operand" "=r,r")
- (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
- "TARGET_BWX"
+ (zero_extend:HI
+ (match_operand:QI 1 "reg_or_bwx_memory_operand" "r,m")))]
+ ""
"@
and %1,0xff,%0
ldbu %0,%1"
- [(set_attr "type" "ilog,ild")])
-
-(define_insn "*zero_extendqihi2_nobwx"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))]
- "! TARGET_BWX"
- "and %1,0xff,%0"
- [(set_attr "type" "ilog")])
-
-(define_expand "zero_extendqisi2"
- [(set (match_operand:SI 0 "register_operand" "")
- (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
- ""
-{
- if (! TARGET_BWX)
- operands[1] = force_reg (QImode, operands[1]);
-})
+ [(set_attr "type" "ilog,ild")
+ (set_attr "isa" "*,bwx")])
-(define_insn "*zero_extendqisi2_bwx"
+(define_insn "zero_extendqisi2"
[(set (match_operand:SI 0 "register_operand" "=r,r")
- (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
- "TARGET_BWX"
+ (zero_extend:SI
+ (match_operand:QI 1 "reg_or_bwx_memory_operand" "r,m")))]
+ ""
"@
and %1,0xff,%0
ldbu %0,%1"
- [(set_attr "type" "ilog,ild")])
-
-(define_insn "*zero_extendqisi2_nobwx"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))]
- "! TARGET_BWX"
- "and %1,0xff,%0"
- [(set_attr "type" "ilog")])
-
-(define_expand "zero_extendqidi2"
- [(set (match_operand:DI 0 "register_operand" "")
- (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
- ""
-{
- if (! TARGET_BWX)
- operands[1] = force_reg (QImode, operands[1]);
-})
+ [(set_attr "type" "ilog,ild")
+ (set_attr "isa" "*,bwx")])
-(define_insn "*zero_extendqidi2_bwx"
+(define_insn "zero_extendqidi2"
[(set (match_operand:DI 0 "register_operand" "=r,r")
- (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
- "TARGET_BWX"
+ (zero_extend:DI
+ (match_operand:QI 1 "reg_or_bwx_memory_operand" "r,m")))]
+ ""
"@
and %1,0xff,%0
ldbu %0,%1"
- [(set_attr "type" "ilog,ild")])
-
-(define_insn "*zero_extendqidi2_nobwx"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
- "! TARGET_BWX"
- "and %1,0xff,%0"
- [(set_attr "type" "ilog")])
-
-(define_expand "zero_extendhisi2"
- [(set (match_operand:SI 0 "register_operand" "")
- (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
- ""
-{
- if (! TARGET_BWX)
- operands[1] = force_reg (HImode, operands[1]);
-})
+ [(set_attr "type" "ilog,ild")
+ (set_attr "isa" "*,bwx")])
-(define_insn "*zero_extendhisi2_bwx"
+(define_insn "zero_extendhisi2"
[(set (match_operand:SI 0 "register_operand" "=r,r")
- (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
- "TARGET_BWX"
+ (zero_extend:SI
+ (match_operand:HI 1 "reg_or_bwx_memory_operand" "r,m")))]
+ ""
"@
zapnot %1,3,%0
ldwu %0,%1"
- [(set_attr "type" "shift,ild")])
-
-(define_insn "*zero_extendhisi2_nobwx"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (zero_extend:SI (match_operand:HI 1 "register_operand" "r")))]
- "! TARGET_BWX"
- "zapnot %1,3,%0"
- [(set_attr "type" "shift")])
-
-(define_expand "zero_extendhidi2"
- [(set (match_operand:DI 0 "register_operand" "")
- (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
- ""
-{
- if (! TARGET_BWX)
- operands[1] = force_reg (HImode, operands[1]);
-})
+ [(set_attr "type" "shift,ild")
+ (set_attr "isa" "*,bwx")])
-(define_insn "*zero_extendhidi2_bwx"
+(define_insn "zero_extendhidi2"
[(set (match_operand:DI 0 "register_operand" "=r,r")
- (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
- "TARGET_BWX"
+ (zero_extend:DI
+ (match_operand:HI 1 "reg_or_bwx_memory_operand" "r,m")))]
+ ""
"@
zapnot %1,3,%0
ldwu %0,%1"
- [(set_attr "type" "shift,ild")])
-
-(define_insn "*zero_extendhidi2_nobwx"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
- ""
- "zapnot %1,3,%0"
- [(set_attr "type" "shift")])
+ [(set_attr "type" "shift,ild")
+ (set_attr "isa" "*,bwx")])
(define_insn "zero_extendsidi2"
[(set (match_operand:DI 0 "register_operand" "=r")
"zapnot %1,15,%0"
[(set_attr "type" "shift")])
+(define_insn "*andnotsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (and:SI (not:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI"))
+ (match_operand:SI 2 "reg_or_0_operand" "rJ")))]
+ ""
+ "bic %r2,%1,%0"
+ [(set_attr "type" "ilog")])
+
(define_insn "andnotdi3"
[(set (match_operand:DI 0 "register_operand" "=r")
(and:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
"bic %r2,%1,%0"
[(set_attr "type" "ilog")])
+(define_insn "*iorsi_internal"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (ior:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
+ (match_operand:SI 2 "or_operand" "rI,N")))]
+ ""
+ "@
+ bis %r1,%2,%0
+ ornot %r1,%N2,%0"
+ [(set_attr "type" "ilog")])
+
(define_insn "iordi3"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(ior:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
ornot %r1,%N2,%0"
[(set_attr "type" "ilog")])
+(define_insn "*one_cmplsi_internal"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (not:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")))]
+ ""
+ "ornot $31,%1,%0"
+ [(set_attr "type" "ilog")])
+
(define_insn "one_cmpldi2"
[(set (match_operand:DI 0 "register_operand" "=r")
(not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
"ornot $31,%1,%0"
[(set_attr "type" "ilog")])
-(define_insn "*iornot"
+(define_insn "*iornotsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI (not:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI"))
+ (match_operand:SI 2 "reg_or_0_operand" "rJ")))]
+ ""
+ "ornot %r2,%1,%0"
+ [(set_attr "type" "ilog")])
+
+(define_insn "*iornotdi3"
[(set (match_operand:DI 0 "register_operand" "=r")
(ior:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
(match_operand:DI 2 "reg_or_0_operand" "rJ")))]
"ornot %r2,%1,%0"
[(set_attr "type" "ilog")])
+(define_insn "*xorsi_internal"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
+ (match_operand:SI 2 "or_operand" "rI,N")))]
+ ""
+ "@
+ xor %r1,%2,%0
+ eqv %r1,%N2,%0"
+ [(set_attr "type" "ilog")])
+
(define_insn "xordi3"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
eqv %r1,%N2,%0"
[(set_attr "type" "ilog")])
-(define_insn "*xornot"
+(define_insn "*xornotsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (not:SI (xor:SI (match_operand:SI 1 "register_operand" "%rJ")
+ (match_operand:SI 2 "register_operand" "rI"))))]
+ ""
+ "eqv %r1,%2,%0"
+ [(set_attr "type" "ilog")])
+
+(define_insn "*xornotdi3"
[(set (match_operand:DI 0 "register_operand" "=r")
(not:DI (xor:DI (match_operand:DI 1 "register_operand" "%rJ")
(match_operand:DI 2 "register_operand" "rI"))))]
(define_expand "ffsdi2"
[(set (match_dup 2)
- (unspec:DI [(match_operand:DI 1 "register_operand" "")] UNSPEC_CTTZ))
+ (ctz:DI (match_operand:DI 1 "register_operand" "")))
(set (match_dup 3)
(plus:DI (match_dup 2) (const_int 1)))
(set (match_operand:DI 0 "register_operand" "")
operands[3] = gen_reg_rtx (DImode);
})
-(define_insn "*cttz"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_CTTZ))]
- "TARGET_CIX"
- "cttz %1,%0"
- ; EV6 calls all mvi and cttz/ctlz/popc class imisc, so just
- ; reuse the existing type name.
- [(set_attr "type" "mvi")])
-
(define_insn "clzdi2"
[(set (match_operand:DI 0 "register_operand" "=r")
(clz:DI (match_operand:DI 1 "register_operand" "r")))]
"TARGET_CIX"
"ctpop %1,%0"
[(set_attr "type" "mvi")])
+
+(define_expand "bswapsi2"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (bswap:SI (match_operand:SI 1 "register_operand" "")))]
+ "!optimize_size"
+{
+ rtx t0, t1;
+
+ t0 = gen_reg_rtx (DImode);
+ t1 = gen_reg_rtx (DImode);
+
+ emit_insn (gen_inslh (t0, gen_lowpart (DImode, operands[1]), GEN_INT (7)));
+ emit_insn (gen_inswl_const (t1, gen_lowpart (HImode, operands[1]),
+ GEN_INT (24)));
+ emit_insn (gen_iordi3 (t1, t0, t1));
+ emit_insn (gen_lshrdi3 (t0, t1, GEN_INT (16)));
+ emit_insn (gen_anddi3 (t1, t1, alpha_expand_zap_mask (0x5)));
+ emit_insn (gen_anddi3 (t0, t0, alpha_expand_zap_mask (0xa)));
+ emit_insn (gen_addsi3 (operands[0], gen_lowpart (SImode, t0),
+ gen_lowpart (SImode, t1)));
+ DONE;
+})
+
+(define_expand "bswapdi2"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (bswap:DI (match_operand:DI 1 "register_operand" "")))]
+ "!optimize_size"
+{
+ rtx t0, t1;
+
+ t0 = gen_reg_rtx (DImode);
+ t1 = gen_reg_rtx (DImode);
+
+ /* This method of shifting and masking is not specific to Alpha, but
+ is only profitable on Alpha because of our handy byte zap insn. */
+
+ emit_insn (gen_lshrdi3 (t0, operands[1], GEN_INT (32)));
+ emit_insn (gen_ashldi3 (t1, operands[1], GEN_INT (32)));
+ emit_insn (gen_iordi3 (t1, t0, t1));
+
+ emit_insn (gen_lshrdi3 (t0, t1, GEN_INT (16)));
+ emit_insn (gen_ashldi3 (t1, t1, GEN_INT (16)));
+ emit_insn (gen_anddi3 (t0, t0, alpha_expand_zap_mask (0xcc)));
+ emit_insn (gen_anddi3 (t1, t1, alpha_expand_zap_mask (0x33)));
+ emit_insn (gen_iordi3 (t1, t0, t1));
+
+ emit_insn (gen_lshrdi3 (t0, t1, GEN_INT (8)));
+ emit_insn (gen_ashldi3 (t1, t1, GEN_INT (8)));
+ emit_insn (gen_anddi3 (t0, t0, alpha_expand_zap_mask (0xaa)));
+ emit_insn (gen_anddi3 (t1, t1, alpha_expand_zap_mask (0x55)));
+ emit_insn (gen_iordi3 (operands[0], t0, t1));
+ DONE;
+})
\f
;; Next come the shifts and the various extract and insert operations.
case 1:
return "sll %r1,%2,%0";
default:
- abort();
+ gcc_unreachable ();
}
}
[(set_attr "type" "iadd,shift")])
"sra %r1,%2,%0"
[(set_attr "type" "shift")])
-(define_expand "extendqihi2"
- [(set (match_dup 2)
- (ashift:DI (match_operand:QI 1 "some_operand" "")
- (const_int 56)))
- (set (match_operand:HI 0 "register_operand" "")
- (ashiftrt:DI (match_dup 2)
- (const_int 56)))]
+(define_insn "extendqihi2"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
+ "TARGET_BWX"
+ "sextb %1,%0"
+ [(set_attr "type" "shift")])
+
+(define_insn "extendqisi2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
+ "TARGET_BWX"
+ "sextb %1,%0"
+ [(set_attr "type" "shift")])
+
+(define_expand "extendqidi2"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (sign_extend:DI (match_operand:QI 1 "some_operand" "")))]
""
{
if (TARGET_BWX)
+ operands[1] = force_reg (QImode, operands[1]);
+ else
{
- emit_insn (gen_extendqihi2x (operands[0],
- force_reg (QImode, operands[1])));
- DONE;
- }
+ rtx x, t1, t2, i56;
- /* If we have an unaligned MEM, extend to DImode (which we do
- specially) and then copy to the result. */
- if (unaligned_memory_operand (operands[1], HImode))
- {
- rtx temp = gen_reg_rtx (DImode);
+ if (unaligned_memory_operand (operands[1], QImode))
+ {
+ x = gen_unaligned_extendqidi (operands[0], XEXP (operands[1], 0));
+ alpha_set_memflags (x, operands[1]);
+ emit_insn (x);
+ DONE;
+ }
+
+ t1 = gen_reg_rtx (DImode);
+ t2 = gen_reg_rtx (DImode);
+ i56 = GEN_INT (56);
- emit_insn (gen_extendqidi2 (temp, operands[1]));
- emit_move_insn (operands[0], gen_lowpart (HImode, temp));
+ x = gen_lowpart (DImode, force_reg (QImode, operands[1]));
+ emit_move_insn (t1, x);
+ emit_insn (gen_ashldi3 (t2, t1, i56));
+ emit_insn (gen_ashrdi3 (operands[0], t2, i56));
DONE;
}
-
- operands[0] = gen_lowpart (DImode, operands[0]);
- operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
- operands[2] = gen_reg_rtx (DImode);
})
-(define_insn "extendqidi2x"
+(define_insn "*extendqidi2_bwx"
[(set (match_operand:DI 0 "register_operand" "=r")
(sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
"TARGET_BWX"
"sextb %1,%0"
[(set_attr "type" "shift")])
-(define_insn "extendhidi2x"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
- "TARGET_BWX"
- "sextw %1,%0"
- [(set_attr "type" "shift")])
-
-(define_insn "extendqisi2x"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
- "TARGET_BWX"
- "sextb %1,%0"
- [(set_attr "type" "shift")])
-
-(define_insn "extendhisi2x"
+(define_insn "extendhisi2"
[(set (match_operand:SI 0 "register_operand" "=r")
(sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
"TARGET_BWX"
"sextw %1,%0"
[(set_attr "type" "shift")])
-(define_insn "extendqihi2x"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
- "TARGET_BWX"
- "sextb %1,%0"
- [(set_attr "type" "shift")])
-
-(define_expand "extendqisi2"
- [(set (match_dup 2)
- (ashift:DI (match_operand:QI 1 "some_operand" "")
- (const_int 56)))
- (set (match_operand:SI 0 "register_operand" "")
- (ashiftrt:DI (match_dup 2)
- (const_int 56)))]
+(define_expand "extendhidi2"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (sign_extend:DI (match_operand:HI 1 "some_operand" "")))]
""
{
if (TARGET_BWX)
+ operands[1] = force_reg (HImode, operands[1]);
+ else
{
- emit_insn (gen_extendqisi2x (operands[0],
- force_reg (QImode, operands[1])));
- DONE;
- }
+ rtx x, t1, t2, i48;
- /* If we have an unaligned MEM, extend to a DImode form of
- the result (which we do specially). */
- if (unaligned_memory_operand (operands[1], QImode))
- {
- rtx temp = gen_reg_rtx (DImode);
-
- emit_insn (gen_extendqidi2 (temp, operands[1]));
- emit_move_insn (operands[0], gen_lowpart (SImode, temp));
- DONE;
- }
-
- operands[0] = gen_lowpart (DImode, operands[0]);
- operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
- operands[2] = gen_reg_rtx (DImode);
-})
-
-(define_expand "extendqidi2"
- [(set (match_dup 2)
- (ashift:DI (match_operand:QI 1 "some_operand" "")
- (const_int 56)))
- (set (match_operand:DI 0 "register_operand" "")
- (ashiftrt:DI (match_dup 2)
- (const_int 56)))]
- ""
-{
- if (TARGET_BWX)
- {
- emit_insn (gen_extendqidi2x (operands[0],
- force_reg (QImode, operands[1])));
- DONE;
- }
-
- if (unaligned_memory_operand (operands[1], QImode))
- {
- rtx seq
- = gen_unaligned_extendqidi (operands[0],
- get_unaligned_address (operands[1], 1));
-
- alpha_set_memflags (seq, operands[1]);
- emit_insn (seq);
- DONE;
- }
-
- operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
- operands[2] = gen_reg_rtx (DImode);
-})
-
-(define_expand "extendhisi2"
- [(set (match_dup 2)
- (ashift:DI (match_operand:HI 1 "some_operand" "")
- (const_int 48)))
- (set (match_operand:SI 0 "register_operand" "")
- (ashiftrt:DI (match_dup 2)
- (const_int 48)))]
- ""
-{
- if (TARGET_BWX)
- {
- emit_insn (gen_extendhisi2x (operands[0],
- force_reg (HImode, operands[1])));
- DONE;
- }
+ if (unaligned_memory_operand (operands[1], HImode))
+ {
+ x = gen_unaligned_extendhidi (operands[0], XEXP (operands[1], 0));
+ alpha_set_memflags (x, operands[1]);
+ emit_insn (x);
+ DONE;
+ }
- /* If we have an unaligned MEM, extend to a DImode form of
- the result (which we do specially). */
- if (unaligned_memory_operand (operands[1], HImode))
- {
- rtx temp = gen_reg_rtx (DImode);
+ t1 = gen_reg_rtx (DImode);
+ t2 = gen_reg_rtx (DImode);
+ i48 = GEN_INT (48);
- emit_insn (gen_extendhidi2 (temp, operands[1]));
- emit_move_insn (operands[0], gen_lowpart (SImode, temp));
+ x = gen_lowpart (DImode, force_reg (HImode, operands[1]));
+ emit_move_insn (t1, x);
+ emit_insn (gen_ashldi3 (t2, t1, i48));
+ emit_insn (gen_ashrdi3 (operands[0], t2, i48));
DONE;
}
-
- operands[0] = gen_lowpart (DImode, operands[0]);
- operands[1] = gen_lowpart (DImode, force_reg (HImode, operands[1]));
- operands[2] = gen_reg_rtx (DImode);
})
-(define_expand "extendhidi2"
- [(set (match_dup 2)
- (ashift:DI (match_operand:HI 1 "some_operand" "")
- (const_int 48)))
- (set (match_operand:DI 0 "register_operand" "")
- (ashiftrt:DI (match_dup 2)
- (const_int 48)))]
- ""
-{
- if (TARGET_BWX)
- {
- emit_insn (gen_extendhidi2x (operands[0],
- force_reg (HImode, operands[1])));
- DONE;
- }
-
- if (unaligned_memory_operand (operands[1], HImode))
- {
- rtx seq
- = gen_unaligned_extendhidi (operands[0],
- get_unaligned_address (operands[1], 2));
-
- alpha_set_memflags (seq, operands[1]);
- emit_insn (seq);
- DONE;
- }
-
- operands[1] = gen_lowpart (DImode, force_reg (HImode, operands[1]));
- operands[2] = gen_reg_rtx (DImode);
-})
+(define_insn "*extendhidi2_bwx"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
+ "TARGET_BWX"
+ "sextw %1,%0"
+ [(set_attr "type" "shift")])
;; 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
;; the unaligned loads (see below).
;;
-;; Operand 1 is the address + 1 (+2 for HI), operand 0 is the result.
-(define_expand "unaligned_extendqidi"
- [(use (match_operand:QI 0 "register_operand" ""))
- (use (match_operand:DI 1 "address_operand" ""))]
- ""
-{
- if (WORDS_BIG_ENDIAN)
- emit_insn (gen_unaligned_extendqidi_be (operands[0], operands[1]));
- else
- emit_insn (gen_unaligned_extendqidi_le (operands[0], operands[1]));
- DONE;
-})
+;; Operand 1 is the address, operand 0 is the result.
-(define_expand "unaligned_extendqidi_le"
- [(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
- (set (match_dup 3)
- (mem:DI (and:DI (plus:DI (match_dup 2) (const_int -1))
- (const_int -8))))
+(define_expand "unaligned_extendqidi"
+ [(set (match_dup 3)
+ (mem:DI (and:DI (match_operand:DI 1 "address_operand" "") (const_int -8))))
(set (match_dup 4)
(ashift:DI (match_dup 3)
(minus:DI (const_int 64)
(ashift:DI
(and:DI (match_dup 2) (const_int 7))
(const_int 3)))))
- (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
+ (set (match_operand:QI 0 "register_operand" "")
(ashiftrt:DI (match_dup 4) (const_int 56)))]
- "! WORDS_BIG_ENDIAN"
-{
- operands[2] = gen_reg_rtx (DImode);
- operands[3] = gen_reg_rtx (DImode);
- operands[4] = gen_reg_rtx (DImode);
-})
-
-(define_expand "unaligned_extendqidi_be"
- [(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
- (set (match_dup 3) (plus:DI (match_dup 2) (const_int -1)))
- (set (match_dup 4)
- (mem:DI (and:DI (match_dup 3)
- (const_int -8))))
- (set (match_dup 5) (plus:DI (match_dup 2) (const_int -2)))
- (set (match_dup 6)
- (ashift:DI (match_dup 4)
- (ashift:DI
- (and:DI
- (plus:DI (match_dup 5) (const_int 1))
- (const_int 7))
- (const_int 3))))
- (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
- (ashiftrt:DI (match_dup 6) (const_int 56)))]
- "WORDS_BIG_ENDIAN"
+ ""
{
- operands[2] = gen_reg_rtx (DImode);
+ operands[0] = gen_lowpart (DImode, operands[0]);
+ operands[2] = get_unaligned_offset (operands[1], 1);
operands[3] = gen_reg_rtx (DImode);
operands[4] = gen_reg_rtx (DImode);
- operands[5] = gen_reg_rtx (DImode);
- operands[6] = gen_reg_rtx (DImode);
})
(define_expand "unaligned_extendhidi"
- [(use (match_operand:QI 0 "register_operand" ""))
- (use (match_operand:DI 1 "address_operand" ""))]
- ""
-{
- operands[0] = gen_lowpart (DImode, operands[0]);
- emit_insn ((WORDS_BIG_ENDIAN
- ? gen_unaligned_extendhidi_be
- : gen_unaligned_extendhidi_le) (operands[0], operands[1]));
- DONE;
-})
-
-(define_expand "unaligned_extendhidi_le"
- [(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
- (set (match_dup 3)
- (mem:DI (and:DI (plus:DI (match_dup 2) (const_int -2))
- (const_int -8))))
+ [(set (match_dup 3)
+ (mem:DI (and:DI (match_operand:DI 1 "address_operand" "") (const_int -8))))
(set (match_dup 4)
(ashift:DI (match_dup 3)
(minus:DI (const_int 64)
(ashift:DI
(and:DI (match_dup 2) (const_int 7))
(const_int 3)))))
- (set (match_operand:DI 0 "register_operand" "")
+ (set (match_operand:HI 0 "register_operand" "")
(ashiftrt:DI (match_dup 4) (const_int 48)))]
- "! WORDS_BIG_ENDIAN"
-{
- operands[2] = gen_reg_rtx (DImode);
- operands[3] = gen_reg_rtx (DImode);
- operands[4] = gen_reg_rtx (DImode);
-})
-
-(define_expand "unaligned_extendhidi_be"
- [(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
- (set (match_dup 3) (plus:DI (match_dup 2) (const_int -2)))
- (set (match_dup 4)
- (mem:DI (and:DI (match_dup 3)
- (const_int -8))))
- (set (match_dup 5) (plus:DI (match_dup 2) (const_int -3)))
- (set (match_dup 6)
- (ashift:DI (match_dup 4)
- (ashift:DI
- (and:DI
- (plus:DI (match_dup 5) (const_int 1))
- (const_int 7))
- (const_int 3))))
- (set (match_operand:DI 0 "register_operand" "")
- (ashiftrt:DI (match_dup 6) (const_int 48)))]
- "WORDS_BIG_ENDIAN"
+ ""
{
- operands[2] = gen_reg_rtx (DImode);
+ operands[0] = gen_lowpart (DImode, operands[0]);
+ operands[2] = get_unaligned_offset (operands[1], 2);
operands[3] = gen_reg_rtx (DImode);
operands[4] = gen_reg_rtx (DImode);
- operands[5] = gen_reg_rtx (DImode);
- operands[6] = gen_reg_rtx (DImode);
})
(define_insn "*extxl_const"
"ext%M2l %r1,%s3,%0"
[(set_attr "type" "shift")])
-(define_insn "extxl_le"
+(define_insn "extxl"
[(set (match_operand:DI 0 "register_operand" "=r")
(zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
(match_operand:DI 2 "mode_width_operand" "n")
(ashift:DI (match_operand:DI 3 "reg_or_8bit_operand" "rI")
(const_int 3))))]
- "! WORDS_BIG_ENDIAN"
- "ext%M2l %r1,%3,%0"
- [(set_attr "type" "shift")])
-
-(define_insn "extxl_be"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
- (match_operand:DI 2 "mode_width_operand" "n")
- (minus:DI
- (const_int 56)
- (ashift:DI
- (match_operand:DI 3 "reg_or_8bit_operand" "rI")
- (const_int 3)))))]
- "WORDS_BIG_ENDIAN"
+ ""
"ext%M2l %r1,%3,%0"
[(set_attr "type" "shift")])
;; in shifts larger than a word size. So capture these patterns that it
;; should have turned into zero_extracts.
-(define_insn "*extxl_1_le"
+(define_insn "*extxl_1"
[(set (match_operand:DI 0 "register_operand" "=r")
(and:DI (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 3)))
(match_operand:DI 3 "mode_mask_operand" "n")))]
- "! WORDS_BIG_ENDIAN"
- "ext%U3l %1,%2,%0"
- [(set_attr "type" "shift")])
-
-(define_insn "*extxl_1_be"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (and:DI (lshiftrt:DI
- (match_operand:DI 1 "reg_or_0_operand" "rJ")
- (minus:DI (const_int 56)
- (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
- (const_int 3))))
- (match_operand:DI 3 "mode_mask_operand" "n")))]
- "WORDS_BIG_ENDIAN"
+ ""
"ext%U3l %1,%2,%0"
[(set_attr "type" "shift")])
-(define_insn "*extql_2_le"
+(define_insn "*extql_2"
[(set (match_operand:DI 0 "register_operand" "=r")
(lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 3))))]
- "! WORDS_BIG_ENDIAN"
- "extql %1,%2,%0"
- [(set_attr "type" "shift")])
-
-(define_insn "*extql_2_be"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (lshiftrt:DI
- (match_operand:DI 1 "reg_or_0_operand" "rJ")
- (minus:DI (const_int 56)
- (ashift:DI
- (match_operand:DI 2 "reg_or_8bit_operand" "rI")
- (const_int 3)))))]
- "WORDS_BIG_ENDIAN"
+ ""
"extql %1,%2,%0"
[(set_attr "type" "shift")])
-(define_insn "extqh_le"
+(define_insn "extqh"
[(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI
(match_operand:DI 1 "reg_or_0_operand" "rJ")
(match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 7))
(const_int 3)))))]
- "! WORDS_BIG_ENDIAN"
- "extqh %r1,%2,%0"
- [(set_attr "type" "shift")])
-
-(define_insn "extqh_be"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (ashift:DI
- (match_operand:DI 1 "reg_or_0_operand" "rJ")
- (ashift:DI
- (and:DI
- (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
- (const_int 1))
- (const_int 7))
- (const_int 3))))]
- "WORDS_BIG_ENDIAN"
+ ""
"extqh %r1,%2,%0"
[(set_attr "type" "shift")])
-(define_insn "extlh_le"
+(define_insn "extlh"
[(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI
(and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
(match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 7))
(const_int 3)))))]
- "! WORDS_BIG_ENDIAN"
- "extlh %r1,%2,%0"
- [(set_attr "type" "shift")])
-
-(define_insn "extlh_be"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (and:DI
- (ashift:DI
- (match_operand:DI 1 "reg_or_0_operand" "rJ")
- (ashift:DI
- (and:DI
- (plus:DI
- (match_operand:DI 2 "reg_or_8bit_operand" "rI")
- (const_int 1))
- (const_int 7))
- (const_int 3)))
- (const_int 2147483647)))]
- "WORDS_BIG_ENDIAN"
+ ""
"extlh %r1,%2,%0"
[(set_attr "type" "shift")])
-(define_insn "extwh_le"
+(define_insn "extwh"
[(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI
(and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
(match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 7))
(const_int 3)))))]
- "! WORDS_BIG_ENDIAN"
- "extwh %r1,%2,%0"
- [(set_attr "type" "shift")])
-
-(define_insn "extwh_be"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (and:DI
- (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
- (ashift:DI
- (and:DI
- (plus:DI
- (match_operand:DI 2 "reg_or_8bit_operand" "rI")
- (const_int 1))
- (const_int 7))
- (const_int 3)))
- (const_int 65535)))]
- "WORDS_BIG_ENDIAN"
+ ""
"extwh %r1,%2,%0"
[(set_attr "type" "shift")])
"insbl %1,%s2,%0"
[(set_attr "type" "shift")])
-(define_insn "*inswl_const"
+(define_insn "inswl_const"
[(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
(match_operand:DI 2 "mul8_operand" "I")))]
"insll %1,%s2,%0"
[(set_attr "type" "shift")])
-(define_insn "insbl_le"
+(define_insn "insbl"
[(set (match_operand:DI 0 "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")
(const_int 3))))]
- "! WORDS_BIG_ENDIAN"
- "insbl %1,%2,%0"
- [(set_attr "type" "shift")])
-
-(define_insn "insbl_be"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
- (minus:DI (const_int 56)
- (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
- (const_int 3)))))]
- "WORDS_BIG_ENDIAN"
+ ""
"insbl %1,%2,%0"
[(set_attr "type" "shift")])
-(define_insn "inswl_le"
+(define_insn "inswl"
[(set (match_operand:DI 0 "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")
(const_int 3))))]
- "! WORDS_BIG_ENDIAN"
- "inswl %1,%2,%0"
- [(set_attr "type" "shift")])
-
-(define_insn "inswl_be"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
- (minus:DI (const_int 56)
- (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
- (const_int 3)))))]
- "WORDS_BIG_ENDIAN"
+ ""
"inswl %1,%2,%0"
[(set_attr "type" "shift")])
-(define_insn "insll_le"
+(define_insn "insll"
[(set (match_operand:DI 0 "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")
(const_int 3))))]
- "! WORDS_BIG_ENDIAN"
- "insll %1,%2,%0"
- [(set_attr "type" "shift")])
-
-(define_insn "insll_be"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
- (minus:DI (const_int 56)
- (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
- (const_int 3)))))]
- "WORDS_BIG_ENDIAN"
+ ""
"insll %1,%2,%0"
[(set_attr "type" "shift")])
-(define_insn "insql_le"
+(define_insn "insql"
[(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI (match_operand:DI 1 "register_operand" "r")
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 3))))]
- "! WORDS_BIG_ENDIAN"
- "insql %1,%2,%0"
- [(set_attr "type" "shift")])
-
-(define_insn "insql_be"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (ashift:DI (match_operand:DI 1 "register_operand" "r")
- (minus:DI (const_int 56)
- (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
- (const_int 3)))))]
- "WORDS_BIG_ENDIAN"
+ ""
"insql %1,%2,%0"
[(set_attr "type" "shift")])
(match_operand:DI 2 "mul8_operand" "I"))
(match_operand:DI 3 "immediate_operand" "i")))]
"HOST_BITS_PER_WIDE_INT == 64
- && GET_CODE (operands[3]) == CONST_INT
+ && CONST_INT_P (operands[3])
&& (((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2])
== (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
|| ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2])
== (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
return "insll %1,%s2,%0";
#endif
- abort();
+ gcc_unreachable ();
}
[(set_attr "type" "shift")])
"ins%M2h %1,%3,%0"
[(set_attr "type" "shift")])
-(define_insn "mskxl_le"
+(define_insn "mskxl"
[(set (match_operand:DI 0 "register_operand" "=r")
(and:DI (not:DI (ashift:DI
(match_operand:DI 2 "mode_mask_operand" "n")
(match_operand:DI 3 "reg_or_8bit_operand" "rI")
(const_int 3))))
(match_operand:DI 1 "reg_or_0_operand" "rJ")))]
- "! WORDS_BIG_ENDIAN"
- "msk%U2l %r1,%3,%0"
- [(set_attr "type" "shift")])
-
-(define_insn "mskxl_be"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (and:DI (not:DI (ashift:DI
- (match_operand:DI 2 "mode_mask_operand" "n")
- (minus:DI (const_int 56)
- (ashift:DI
- (match_operand:DI 3 "reg_or_8bit_operand" "rI")
- (const_int 3)))))
- (match_operand:DI 1 "reg_or_0_operand" "rJ")))]
- "WORDS_BIG_ENDIAN"
+ ""
"msk%U2l %r1,%3,%0"
[(set_attr "type" "shift")])
[(const_int 0)]
"alpha_split_tfmode_frobsign (operands, gen_xordi3); DONE;")
+(define_insn "copysignsf3"
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (unspec:SF [(match_operand:SF 1 "reg_or_0_operand" "fG")
+ (match_operand:SF 2 "reg_or_0_operand" "fG")]
+ UNSPEC_COPYSIGN))]
+ "TARGET_FP"
+ "cpys %R2,%R1,%0"
+ [(set_attr "type" "fadd")])
+
+(define_insn "*ncopysignsf3"
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (neg:SF (unspec:SF [(match_operand:SF 1 "reg_or_0_operand" "fG")
+ (match_operand:SF 2 "reg_or_0_operand" "fG")]
+ UNSPEC_COPYSIGN)))]
+ "TARGET_FP"
+ "cpysn %R2,%R1,%0"
+ [(set_attr "type" "fadd")])
+
+(define_insn "copysigndf3"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (unspec:DF [(match_operand:DF 1 "reg_or_0_operand" "fG")
+ (match_operand:DF 2 "reg_or_0_operand" "fG")]
+ UNSPEC_COPYSIGN))]
+ "TARGET_FP"
+ "cpys %R2,%R1,%0"
+ [(set_attr "type" "fadd")])
+
+(define_insn "*ncopysigndf3"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (neg:DF (unspec:DF [(match_operand:DF 1 "reg_or_0_operand" "fG")
+ (match_operand:DF 2 "reg_or_0_operand" "fG")]
+ UNSPEC_COPYSIGN)))]
+ "TARGET_FP"
+ "cpysn %R2,%R1,%0"
+ [(set_attr "type" "fadd")])
+
(define_insn "*addsf_ieee"
[(set (match_operand:SF 0 "register_operand" "=&f")
(plus:SF (match_operand:SF 1 "reg_or_0_operand" "%fG")
(set_attr "trap_suffix" "u_su_sui")])
(define_expand "addtf3"
- [(use (match_operand 0 "register_operand" ""))
- (use (match_operand 1 "general_operand" ""))
- (use (match_operand 2 "general_operand" ""))]
+ [(use (match_operand:TF 0 "register_operand" ""))
+ (use (match_operand:TF 1 "general_operand" ""))
+ (use (match_operand:TF 2 "general_operand" ""))]
"TARGET_HAS_XFLOATING_LIBS"
"alpha_emit_xfloating_arith (PLUS, operands); DONE;")
;; processing, it is cheaper to do the truncation in the int regs.
(define_insn "*cvtql"
- [(set (match_operand:SI 0 "register_operand" "=f")
- (unspec:SI [(match_operand:DI 1 "reg_or_0_operand" "fG")]
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (unspec:SF [(match_operand:DI 1 "reg_or_0_operand" "fG")]
UNSPEC_CVTQL))]
"TARGET_FP"
"cvtql%/ %R1,%0"
(define_insn_and_split "*fix_truncdfsi_ieee"
[(set (match_operand:SI 0 "memory_operand" "=m")
- (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_0_operand" "fG")) 0))
+ (subreg:SI
+ (match_operator:DI 4 "fix_operator"
+ [(match_operand:DF 1 "reg_or_0_operand" "fG")]) 0))
(clobber (match_scratch:DI 2 "=&f"))
- (clobber (match_scratch:SI 3 "=&f"))]
+ (clobber (match_scratch:SF 3 "=&f"))]
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
"#"
"&& reload_completed"
- [(set (match_dup 2) (fix:DI (match_dup 1)))
- (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
- (set (match_dup 0) (match_dup 3))]
- ""
+ [(set (match_dup 2) (match_op_dup 4 [(match_dup 1)]))
+ (set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
+ (set (match_dup 5) (match_dup 3))]
+{
+ operands[5] = adjust_address (operands[0], SFmode, 0);
+}
[(set_attr "type" "fadd")
(set_attr "trap" "yes")])
(define_insn_and_split "*fix_truncdfsi_internal"
[(set (match_operand:SI 0 "memory_operand" "=m")
- (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_0_operand" "fG")) 0))
+ (subreg:SI
+ (match_operator:DI 3 "fix_operator"
+ [(match_operand:DF 1 "reg_or_0_operand" "fG")]) 0))
(clobber (match_scratch:DI 2 "=f"))]
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
"#"
"&& reload_completed"
- [(set (match_dup 2) (fix:DI (match_dup 1)))
- (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
- (set (match_dup 0) (match_dup 3))]
- ;; Due to REG_CANNOT_CHANGE_SIZE issues, we cannot simply use SUBREG.
- "operands[3] = gen_rtx_REG (SImode, REGNO (operands[2]));"
+ [(set (match_dup 2) (match_op_dup 3 [(match_dup 1)]))
+ (set (match_dup 4) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
+ (set (match_dup 5) (match_dup 4))]
+{
+ operands[4] = gen_rtx_REG (SFmode, REGNO (operands[2]));
+ operands[5] = adjust_address (operands[0], SFmode, 0);
+}
[(set_attr "type" "fadd")
(set_attr "trap" "yes")])
(define_insn "*fix_truncdfdi_ieee"
[(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
- (fix:DI (match_operand:DF 1 "reg_or_0_operand" "fG")))]
+ (match_operator:DI 2 "fix_operator"
+ [(match_operand:DF 1 "reg_or_0_operand" "fG")]))]
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
"cvt%-q%/ %R1,%0"
[(set_attr "type" "fadd")
(set_attr "round_suffix" "c")
(set_attr "trap_suffix" "v_sv_svi")])
-(define_insn "fix_truncdfdi2"
+(define_insn "*fix_truncdfdi2"
[(set (match_operand:DI 0 "reg_no_subreg_operand" "=f")
- (fix:DI (match_operand:DF 1 "reg_or_0_operand" "fG")))]
+ (match_operator:DI 2 "fix_operator"
+ [(match_operand:DF 1 "reg_or_0_operand" "fG")]))]
"TARGET_FP"
"cvt%-q%/ %R1,%0"
[(set_attr "type" "fadd")
(set_attr "round_suffix" "c")
(set_attr "trap_suffix" "v_sv_svi")])
+(define_expand "fix_truncdfdi2"
+ [(set (match_operand:DI 0 "reg_no_subreg_operand" "")
+ (fix:DI (match_operand:DF 1 "reg_or_0_operand" "")))]
+ "TARGET_FP"
+ "")
+
+(define_expand "fixuns_truncdfdi2"
+ [(set (match_operand:DI 0 "reg_no_subreg_operand" "")
+ (unsigned_fix:DI (match_operand:DF 1 "reg_or_0_operand" "")))]
+ "TARGET_FP"
+ "")
+
;; Likewise between SFmode and SImode.
(define_insn_and_split "*fix_truncsfsi_ieee"
[(set (match_operand:SI 0 "memory_operand" "=m")
- (subreg:SI (fix:DI (float_extend:DF
- (match_operand:SF 1 "reg_or_0_operand" "fG"))) 0))
+ (subreg:SI
+ (match_operator:DI 4 "fix_operator"
+ [(float_extend:DF
+ (match_operand:SF 1 "reg_or_0_operand" "fG"))]) 0))
(clobber (match_scratch:DI 2 "=&f"))
- (clobber (match_scratch:SI 3 "=&f"))]
+ (clobber (match_scratch:SF 3 "=&f"))]
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
"#"
"&& reload_completed"
- [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1))))
- (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
- (set (match_dup 0) (match_dup 3))]
- ""
+ [(set (match_dup 2) (match_op_dup 4 [(float_extend:DF (match_dup 1))]))
+ (set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
+ (set (match_dup 5) (match_dup 3))]
+{
+ operands[5] = adjust_address (operands[0], SFmode, 0);
+}
[(set_attr "type" "fadd")
(set_attr "trap" "yes")])
(define_insn_and_split "*fix_truncsfsi_internal"
[(set (match_operand:SI 0 "memory_operand" "=m")
- (subreg:SI (fix:DI (float_extend:DF
- (match_operand:SF 1 "reg_or_0_operand" "fG"))) 0))
+ (subreg:SI
+ (match_operator:DI 3 "fix_operator"
+ [(float_extend:DF
+ (match_operand:SF 1 "reg_or_0_operand" "fG"))]) 0))
(clobber (match_scratch:DI 2 "=f"))]
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
"#"
"&& reload_completed"
- [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1))))
- (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
- (set (match_dup 0) (match_dup 3))]
- ;; Due to REG_CANNOT_CHANGE_SIZE issues, we cannot simply use SUBREG.
- "operands[3] = gen_rtx_REG (SImode, REGNO (operands[2]));"
+ [(set (match_dup 2) (match_op_dup 3 [(float_extend:DF (match_dup 1))]))
+ (set (match_dup 4) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
+ (set (match_dup 5) (match_dup 4))]
+{
+ operands[4] = gen_rtx_REG (SFmode, REGNO (operands[2]));
+ operands[5] = adjust_address (operands[0], SFmode, 0);
+}
[(set_attr "type" "fadd")
(set_attr "trap" "yes")])
(define_insn "*fix_truncsfdi_ieee"
[(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
- (fix:DI (float_extend:DF
- (match_operand:SF 1 "reg_or_0_operand" "fG"))))]
+ (match_operator:DI 2 "fix_operator"
+ [(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))]))]
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
"cvt%-q%/ %R1,%0"
[(set_attr "type" "fadd")
(set_attr "round_suffix" "c")
(set_attr "trap_suffix" "v_sv_svi")])
-(define_insn "fix_truncsfdi2"
+(define_insn "*fix_truncsfdi2"
[(set (match_operand:DI 0 "reg_no_subreg_operand" "=f")
- (fix:DI (float_extend:DF
- (match_operand:SF 1 "reg_or_0_operand" "fG"))))]
+ (match_operator:DI 2 "fix_operator"
+ [(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))]))]
"TARGET_FP"
"cvt%-q%/ %R1,%0"
[(set_attr "type" "fadd")
(set_attr "round_suffix" "c")
(set_attr "trap_suffix" "v_sv_svi")])
+(define_expand "fix_truncsfdi2"
+ [(set (match_operand:DI 0 "reg_no_subreg_operand" "")
+ (fix:DI (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))))]
+ "TARGET_FP"
+ "")
+
+(define_expand "fixuns_truncsfdi2"
+ [(set (match_operand:DI 0 "reg_no_subreg_operand" "")
+ (unsigned_fix:DI
+ (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))))]
+ "TARGET_FP"
+ "")
+
(define_expand "fix_trunctfdi2"
[(use (match_operand:DI 0 "register_operand" ""))
(use (match_operand:TF 1 "general_operand" ""))]
"TARGET_HAS_XFLOATING_LIBS"
"alpha_emit_xfloating_cvt (FIX, operands); DONE;")
+(define_expand "fixuns_trunctfdi2"
+ [(use (match_operand:DI 0 "register_operand" ""))
+ (use (match_operand:TF 1 "general_operand" ""))]
+ "TARGET_HAS_XFLOATING_LIBS"
+ "alpha_emit_xfloating_cvt (UNSIGNED_FIX, operands); DONE;")
+
(define_insn "*floatdisf_ieee"
[(set (match_operand:SF 0 "register_operand" "=&f")
(float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
(set_attr "round_suffix" "normal")
(set_attr "trap_suffix" "sui")])
+(define_insn_and_split "*floatsisf2_ieee"
+ [(set (match_operand:SF 0 "register_operand" "=&f")
+ (float:SF (match_operand:SI 1 "memory_operand" "m")))
+ (clobber (match_scratch:DI 2 "=&f"))
+ (clobber (match_scratch:SF 3 "=&f"))]
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 3) (match_dup 1))
+ (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
+ (set (match_dup 0) (float:SF (match_dup 2)))]
+{
+ operands[1] = adjust_address (operands[1], SFmode, 0);
+})
+
+(define_insn_and_split "*floatsisf2"
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (float:SF (match_operand:SI 1 "memory_operand" "m")))]
+ "TARGET_FP"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 0) (match_dup 1))
+ (set (match_dup 2) (unspec:DI [(match_dup 0)] UNSPEC_CVTLQ))
+ (set (match_dup 0) (float:SF (match_dup 2)))]
+{
+ operands[1] = adjust_address (operands[1], SFmode, 0);
+ operands[2] = gen_rtx_REG (DImode, REGNO (operands[0]));
+})
+
(define_insn "*floatdidf_ieee"
[(set (match_operand:DF 0 "register_operand" "=&f")
(float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
(set_attr "round_suffix" "normal")
(set_attr "trap_suffix" "sui")])
+(define_insn_and_split "*floatsidf2_ieee"
+ [(set (match_operand:DF 0 "register_operand" "=&f")
+ (float:DF (match_operand:SI 1 "memory_operand" "m")))
+ (clobber (match_scratch:DI 2 "=&f"))
+ (clobber (match_scratch:SF 3 "=&f"))]
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 3) (match_dup 1))
+ (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
+ (set (match_dup 0) (float:DF (match_dup 2)))]
+{
+ operands[1] = adjust_address (operands[1], SFmode, 0);
+})
+
+(define_insn_and_split "*floatsidf2"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (float:DF (match_operand:SI 1 "memory_operand" "m")))]
+ "TARGET_FP"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 3) (match_dup 1))
+ (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
+ (set (match_dup 0) (float:DF (match_dup 2)))]
+{
+ operands[1] = adjust_address (operands[1], SFmode, 0);
+ operands[2] = gen_rtx_REG (DImode, REGNO (operands[0]));
+ operands[3] = gen_rtx_REG (SFmode, REGNO (operands[0]));
+})
+
(define_expand "floatditf2"
[(use (match_operand:TF 0 "register_operand" ""))
(use (match_operand:DI 1 "general_operand" ""))]
st%- %1,%0"
[(set_attr "type" "fcpys,fld,fst")])
+;; Use register_operand for operand 1 to prevent compress_float_constant
+;; from doing something silly. When optimizing we'll put things back
+;; together anyway.
(define_expand "extendsftf2"
[(use (match_operand:TF 0 "register_operand" ""))
- (use (match_operand:SF 1 "general_operand" ""))]
+ (use (match_operand:SF 1 "register_operand" ""))]
"TARGET_HAS_XFLOATING_LIBS"
{
rtx tmp = gen_reg_rtx (DFmode);
(define_expand "extenddftf2"
[(use (match_operand:TF 0 "register_operand" ""))
- (use (match_operand:DF 1 "general_operand" ""))]
+ (use (match_operand:DF 1 "register_operand" ""))]
"TARGET_HAS_XFLOATING_LIBS"
"alpha_emit_xfloating_cvt (FLOAT_EXTEND, operands); DONE;")
(set_attr "trap_suffix" "u_su_sui")])
(define_expand "divtf3"
- [(use (match_operand 0 "register_operand" ""))
- (use (match_operand 1 "general_operand" ""))
- (use (match_operand 2 "general_operand" ""))]
+ [(use (match_operand:TF 0 "register_operand" ""))
+ (use (match_operand:TF 1 "general_operand" ""))
+ (use (match_operand:TF 2 "general_operand" ""))]
"TARGET_HAS_XFLOATING_LIBS"
"alpha_emit_xfloating_arith (DIV, operands); DONE;")
(set_attr "trap_suffix" "u_su_sui")])
(define_expand "multf3"
- [(use (match_operand 0 "register_operand" ""))
- (use (match_operand 1 "general_operand" ""))
- (use (match_operand 2 "general_operand" ""))]
+ [(use (match_operand:TF 0 "register_operand" ""))
+ (use (match_operand:TF 1 "general_operand" ""))
+ (use (match_operand:TF 2 "general_operand" ""))]
"TARGET_HAS_XFLOATING_LIBS"
"alpha_emit_xfloating_arith (MULT, operands); DONE;")
(set_attr "trap_suffix" "u_su_sui")])
(define_expand "subtf3"
- [(use (match_operand 0 "register_operand" ""))
- (use (match_operand 1 "general_operand" ""))
- (use (match_operand 2 "general_operand" ""))]
+ [(use (match_operand:TF 0 "register_operand" ""))
+ (use (match_operand:TF 1 "general_operand" ""))
+ (use (match_operand:TF 2 "general_operand" ""))]
"TARGET_HAS_XFLOATING_LIBS"
"alpha_emit_xfloating_arith (MINUS, operands); DONE;")
(match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
(match_operand:QI 1 "add_operand" "rI,0,rI,0")
(match_operand:QI 5 "add_operand" "0,rI,0,rI")))]
- "(operands[3] == const0_rtx || operands[4] == const0_rtx)"
+ "(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)"
"@
cmov%C2 %r3,%1,%0
cmov%D2 %r3,%5,%0
(match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
(match_operand:HI 1 "add_operand" "rI,0,rI,0")
(match_operand:HI 5 "add_operand" "0,rI,0,rI")))]
- "(operands[3] == const0_rtx || operands[4] == const0_rtx)"
+ "(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)"
"@
cmov%C2 %r3,%1,%0
cmov%D2 %r3,%5,%0
(match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
(match_operand:SI 1 "add_operand" "rI,0,rI,0")
(match_operand:SI 5 "add_operand" "0,rI,0,rI")))]
- "(operands[3] == const0_rtx || operands[4] == const0_rtx)"
+ "(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)"
"@
cmov%C2 %r3,%1,%0
cmov%D2 %r3,%5,%0
(match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
(match_operand:DI 1 "add_operand" "rI,0,rI,0")
(match_operand:DI 5 "add_operand" "0,rI,0,rI")))]
- "(operands[3] == const0_rtx || operands[4] == const0_rtx)"
+ "(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)"
"@
cmov%C2 %r3,%1,%0
cmov%D2 %r3,%5,%0
(match_operator:DF 1 "alpha_fp_comparison_operator"
[(match_operand:DF 2 "reg_or_0_operand" "fG")
(match_operand:DF 3 "reg_or_0_operand" "fG")]))]
- "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
- "cmp%-%C1%/ %R2,%R3,%0"
- [(set_attr "type" "fadd")
- (set_attr "trap" "yes")
- (set_attr "trap_suffix" "su")])
-
-(define_insn "*cmpdf_ieee_ext1"
- [(set (match_operand:DF 0 "register_operand" "=&f")
- (match_operator:DF 1 "alpha_fp_comparison_operator"
- [(float_extend:DF
- (match_operand:SF 2 "reg_or_0_operand" "fG"))
- (match_operand:DF 3 "reg_or_0_operand" "fG")]))]
- "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+ "TARGET_FP"
"cmp%-%C1%/ %R2,%R3,%0"
[(set_attr "type" "fadd")
(set_attr "trap" "yes")
(set_attr "trap" "yes")
(set_attr "trap_suffix" "su")])
-(define_insn "*cmpdf_ieee_ext2"
- [(set (match_operand:DF 0 "register_operand" "=&f")
- (match_operator:DF 1 "alpha_fp_comparison_operator"
- [(match_operand:DF 2 "reg_or_0_operand" "fG")
- (float_extend:DF
- (match_operand:SF 3 "reg_or_0_operand" "fG"))]))]
- "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
- "cmp%-%C1%/ %R2,%R3,%0"
- [(set_attr "type" "fadd")
- (set_attr "trap" "yes")
- (set_attr "trap_suffix" "su")])
-
(define_insn "*cmpdf_ext2"
[(set (match_operand:DF 0 "register_operand" "=f")
(match_operator:DF 1 "alpha_fp_comparison_operator"
(set_attr "trap" "yes")
(set_attr "trap_suffix" "su")])
-(define_insn "*cmpdf_ieee_ext3"
- [(set (match_operand:DF 0 "register_operand" "=&f")
- (match_operator:DF 1 "alpha_fp_comparison_operator"
- [(float_extend:DF
- (match_operand:SF 2 "reg_or_0_operand" "fG"))
- (float_extend:DF
- (match_operand:SF 3 "reg_or_0_operand" "fG"))]))]
- "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
- "cmp%-%C1%/ %R2,%R3,%0"
- [(set_attr "type" "fadd")
- (set_attr "trap" "yes")
- (set_attr "trap_suffix" "su")])
-
(define_insn "*cmpdf_ext3"
[(set (match_operand:DF 0 "register_operand" "=f")
(match_operator:DF 1 "alpha_fp_comparison_operator"
(match_operand:DF 2 "const0_operand" "G,G")])
(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG,0"))
(match_operand:DF 5 "reg_or_0_operand" "0,fG")))]
- "TARGET_FP"
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
"@
fcmov%C3 %R4,%R1,%0
fcmov%D3 %R4,%R5,%0"
(match_operand:DF 2 "const0_operand" "G,G")])
(match_operand:DF 1 "reg_or_0_operand" "fG,0")
(match_operand:DF 5 "reg_or_0_operand" "0,fG")))]
- "TARGET_FP"
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
"@
fcmov%C3 %R4,%R1,%0
fcmov%D3 %R4,%R5,%0"
(match_operand:DF 2 "const0_operand" "G,G")])
(match_operand:SF 1 "reg_or_0_operand" "fG,0")
(match_operand:SF 5 "reg_or_0_operand" "0,fG")))]
- "TARGET_FP"
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
"@
fcmov%C3 %R4,%R1,%0
fcmov%D3 %R4,%R5,%0"
(match_operand:DF 2 "const0_operand" "G,G")])
(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG,0"))
(match_operand:DF 5 "reg_or_0_operand" "0,fG")))]
- "TARGET_FP"
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
"@
fcmov%C3 %R4,%R1,%0
fcmov%D3 %R4,%R5,%0"
[(set_attr "type" "fcmov")])
-(define_expand "maxdf3"
+(define_expand "smaxdf3"
[(set (match_dup 3)
(le:DF (match_operand:DF 1 "reg_or_0_operand" "")
(match_operand:DF 2 "reg_or_0_operand" "")))
operands[4] = CONST0_RTX (DFmode);
})
-(define_expand "mindf3"
+(define_expand "smindf3"
[(set (match_dup 3)
(lt:DF (match_operand:DF 1 "reg_or_0_operand" "")
(match_operand:DF 2 "reg_or_0_operand" "")))
operands[4] = CONST0_RTX (DFmode);
})
-(define_expand "maxsf3"
+(define_expand "smaxsf3"
[(set (match_dup 3)
(le:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))
(float_extend:DF (match_operand:SF 2 "reg_or_0_operand" ""))))
(set (match_operand:SF 0 "register_operand" "")
(if_then_else:SF (eq (match_dup 3) (match_dup 4))
(match_dup 1) (match_dup 2)))]
- "TARGET_FP"
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
{
operands[3] = gen_reg_rtx (DFmode);
operands[4] = CONST0_RTX (DFmode);
})
-(define_expand "minsf3"
+(define_expand "sminsf3"
[(set (match_dup 3)
(lt:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))
(float_extend:DF (match_operand:SF 2 "reg_or_0_operand" ""))))
(set (match_operand:SF 0 "register_operand" "")
(if_then_else:SF (ne (match_dup 3) (match_dup 4))
(match_dup 1) (match_dup 2)))]
- "TARGET_FP"
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
{
operands[3] = gen_reg_rtx (DFmode);
operands[4] = CONST0_RTX (DFmode);
;; These are the main define_expand's used to make conditional branches
;; and compares.
-(define_expand "cmpdf"
- [(set (cc0) (compare (match_operand:DF 0 "reg_or_0_operand" "")
- (match_operand:DF 1 "reg_or_0_operand" "")))]
+(define_expand "cbranchdf4"
+ [(use (match_operator 0 "alpha_cbranch_operator"
+ [(match_operand:DF 1 "reg_or_0_operand" "")
+ (match_operand:DF 2 "reg_or_0_operand" "")]))
+ (use (match_operand 3 ""))]
"TARGET_FP"
-{
- alpha_compare.op0 = operands[0];
- alpha_compare.op1 = operands[1];
- alpha_compare.fp_p = 1;
- DONE;
-})
+ { alpha_emit_conditional_branch (operands, DFmode); DONE; })
-(define_expand "cmptf"
- [(set (cc0) (compare (match_operand:TF 0 "general_operand" "")
- (match_operand:TF 1 "general_operand" "")))]
+(define_expand "cbranchtf4"
+ [(use (match_operator 0 "alpha_cbranch_operator"
+ [(match_operand:TF 1 "general_operand")
+ (match_operand:TF 2 "general_operand")]))
+ (use (match_operand 3 ""))]
"TARGET_HAS_XFLOATING_LIBS"
-{
- alpha_compare.op0 = operands[0];
- alpha_compare.op1 = operands[1];
- alpha_compare.fp_p = 1;
- DONE;
-})
-
-(define_expand "cmpdi"
- [(set (cc0) (compare (match_operand:DI 0 "general_operand" "")
- (match_operand:DI 1 "general_operand" "")))]
- ""
-{
- alpha_compare.op0 = operands[0];
- alpha_compare.op1 = operands[1];
- alpha_compare.fp_p = 0;
- DONE;
-})
-
-(define_expand "beq"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{ operands[1] = alpha_emit_conditional_branch (EQ); }")
-
-(define_expand "bne"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{ operands[1] = alpha_emit_conditional_branch (NE); }")
-
-(define_expand "blt"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{ operands[1] = alpha_emit_conditional_branch (LT); }")
-
-(define_expand "ble"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{ operands[1] = alpha_emit_conditional_branch (LE); }")
-
-(define_expand "bgt"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{ operands[1] = alpha_emit_conditional_branch (GT); }")
-
-(define_expand "bge"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{ operands[1] = alpha_emit_conditional_branch (GE); }")
-
-(define_expand "bltu"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{ operands[1] = alpha_emit_conditional_branch (LTU); }")
-
-(define_expand "bleu"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{ operands[1] = alpha_emit_conditional_branch (LEU); }")
-
-(define_expand "bgtu"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{ operands[1] = alpha_emit_conditional_branch (GTU); }")
-
-(define_expand "bgeu"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{ operands[1] = alpha_emit_conditional_branch (GEU); }")
-
-(define_expand "bunordered"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{ operands[1] = alpha_emit_conditional_branch (UNORDERED); }")
-
-(define_expand "bordered"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{ operands[1] = alpha_emit_conditional_branch (ORDERED); }")
-
-(define_expand "seq"
- [(set (match_operand:DI 0 "register_operand" "")
- (match_dup 1))]
- ""
- "{ if ((operands[1] = alpha_emit_setcc (EQ)) == NULL_RTX) FAIL; }")
-
-(define_expand "sne"
- [(set (match_operand:DI 0 "register_operand" "")
- (match_dup 1))]
- ""
- "{ if ((operands[1] = alpha_emit_setcc (NE)) == NULL_RTX) FAIL; }")
-
-(define_expand "slt"
- [(set (match_operand:DI 0 "register_operand" "")
- (match_dup 1))]
- ""
- "{ if ((operands[1] = alpha_emit_setcc (LT)) == NULL_RTX) FAIL; }")
-
-(define_expand "sle"
- [(set (match_operand:DI 0 "register_operand" "")
- (match_dup 1))]
- ""
- "{ if ((operands[1] = alpha_emit_setcc (LE)) == NULL_RTX) FAIL; }")
-
-(define_expand "sgt"
- [(set (match_operand:DI 0 "register_operand" "")
- (match_dup 1))]
- ""
- "{ if ((operands[1] = alpha_emit_setcc (GT)) == NULL_RTX) FAIL; }")
-
-(define_expand "sge"
- [(set (match_operand:DI 0 "register_operand" "")
- (match_dup 1))]
- ""
- "{ if ((operands[1] = alpha_emit_setcc (GE)) == NULL_RTX) FAIL; }")
+ { alpha_emit_conditional_branch (operands, TFmode); DONE; })
-(define_expand "sltu"
- [(set (match_operand:DI 0 "register_operand" "")
- (match_dup 1))]
- ""
- "{ if ((operands[1] = alpha_emit_setcc (LTU)) == NULL_RTX) FAIL; }")
-
-(define_expand "sleu"
- [(set (match_operand:DI 0 "register_operand" "")
- (match_dup 1))]
+(define_expand "cbranchdi4"
+ [(use (match_operator 0 "alpha_cbranch_operator"
+ [(match_operand:DI 1 "some_operand")
+ (match_operand:DI 2 "some_operand")]))
+ (use (match_operand 3 ""))]
""
- "{ if ((operands[1] = alpha_emit_setcc (LEU)) == NULL_RTX) FAIL; }")
+ { alpha_emit_conditional_branch (operands, DImode); DONE; })
-(define_expand "sgtu"
- [(set (match_operand:DI 0 "register_operand" "")
- (match_dup 1))]
- ""
- "{ if ((operands[1] = alpha_emit_setcc (GTU)) == NULL_RTX) FAIL; }")
-
-(define_expand "sgeu"
- [(set (match_operand:DI 0 "register_operand" "")
- (match_dup 1))]
- ""
- "{ if ((operands[1] = alpha_emit_setcc (GEU)) == NULL_RTX) FAIL; }")
+(define_expand "cstoredf4"
+ [(use (match_operator:DI 1 "alpha_cbranch_operator"
+ [(match_operand:DF 2 "reg_or_0_operand")
+ (match_operand:DF 3 "reg_or_0_operand")]))
+ (clobber (match_operand:DI 0 "register_operand"))]
+ "TARGET_FP"
+ { if (!alpha_emit_setcc (operands, DFmode)) FAIL; else DONE; })
-(define_expand "sunordered"
- [(set (match_operand:DI 0 "register_operand" "")
- (match_dup 1))]
- ""
- "{ if ((operands[1] = alpha_emit_setcc (UNORDERED)) == NULL_RTX) FAIL; }")
+(define_expand "cstoretf4"
+ [(use (match_operator:DI 1 "alpha_cbranch_operator"
+ [(match_operand:TF 2 "general_operand")
+ (match_operand:TF 3 "general_operand")]))
+ (clobber (match_operand:DI 0 "register_operand"))]
+ "TARGET_HAS_XFLOATING_LIBS"
+ { if (!alpha_emit_setcc (operands, TFmode)) FAIL; else DONE; })
-(define_expand "sordered"
- [(set (match_operand:DI 0 "register_operand" "")
- (match_dup 1))]
+(define_expand "cstoredi4"
+ [(use (match_operator:DI 1 "alpha_cbranch_operator"
+ [(match_operand:DI 2 "some_operand")
+ (match_operand:DI 3 "some_operand")]))
+ (clobber (match_operand:DI 0 "register_operand"))]
""
- "{ if ((operands[1] = alpha_emit_setcc (ORDERED)) == NULL_RTX) FAIL; }")
+ { if (!alpha_emit_setcc (operands, DImode)) FAIL; else DONE; })
\f
;; These are the main define_expand's used to make conditional moves.
register since that is more likely to match (and to produce better code
if both would). */
- if (code == EQ && GET_CODE (operands[3]) == CONST_INT
+ if (code == EQ && CONST_INT_P (operands[3])
&& rtx_equal_p (operands[4], operands[3]))
operands[4] = operands[2];
- else if (code == NE && GET_CODE (operands[3]) == CONST_INT
+ else if (code == NE && CONST_INT_P (operands[3])
&& rtx_equal_p (operands[5], operands[3]))
operands[5] = operands[2];
|| (extended_count (operands[2], DImode, unsignedp) >= 1
&& extended_count (operands[3], DImode, unsignedp) >= 1))
{
- if (GET_CODE (operands[3]) == CONST_INT)
+ if (CONST_INT_P (operands[3]))
operands[7] = gen_rtx_PLUS (DImode, operands[2],
GEN_INT (- INTVAL (operands[3])));
else
&& extended_count (operands[3], DImode, unsignedp) >= 1)))
FAIL;
- if (GET_CODE (operands[3]) == CONST_INT)
+ if (CONST_INT_P (operands[3]))
tem = gen_rtx_PLUS (SImode, operands[2],
GEN_INT (- INTVAL (operands[3])));
else
operands[6], const0_rtx);
})
-(define_split
- [(set (pc)
- (if_then_else
- (match_operator 1 "comparison_operator"
- [(match_operand:DI 2 "reg_or_0_operand" "")
- (match_operand:DI 3 "reg_or_cint_operand" "")])
- (label_ref (match_operand 0 "" ""))
- (pc)))
- (clobber (match_operand:DI 4 "register_operand" ""))]
- "operands[3] != const0_rtx"
- [(set (match_dup 4) (match_dup 5))
- (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
-{
- enum rtx_code code = GET_CODE (operands[1]);
- int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
-
- if (code == NE || code == EQ
- || (extended_count (operands[2], DImode, unsignedp) >= 1
- && extended_count (operands[3], DImode, unsignedp) >= 1))
- {
- if (GET_CODE (operands[3]) == CONST_INT)
- operands[5] = gen_rtx_PLUS (DImode, operands[2],
- GEN_INT (- INTVAL (operands[3])));
- else
- operands[5] = gen_rtx_MINUS (DImode, operands[2], operands[3]);
-
- operands[6] = gen_rtx_fmt_ee (code, VOIDmode, operands[4], const0_rtx);
- }
-
- else if (code == EQ || code == LE || code == LT
- || code == LEU || code == LTU)
- {
- operands[5] = gen_rtx_fmt_ee (code, DImode, operands[2], operands[3]);
- operands[6] = gen_rtx_NE (VOIDmode, operands[4], const0_rtx);
- }
- else
- {
- operands[5] = gen_rtx_fmt_ee (reverse_condition (code), DImode,
- operands[2], operands[3]);
- operands[6] = gen_rtx_EQ (VOIDmode, operands[4], const0_rtx);
- }
-})
-
-(define_split
- [(set (pc)
- (if_then_else
- (match_operator 1 "comparison_operator"
- [(match_operand:SI 2 "reg_or_0_operand" "")
- (match_operand:SI 3 "const_int_operand" "")])
- (label_ref (match_operand 0 "" ""))
- (pc)))
- (clobber (match_operand:DI 4 "register_operand" ""))]
- "operands[3] != const0_rtx
- && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
- [(set (match_dup 4) (match_dup 5))
- (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
-{
- rtx tem;
-
- if (GET_CODE (operands[3]) == CONST_INT)
- tem = gen_rtx_PLUS (SImode, operands[2],
- GEN_INT (- INTVAL (operands[3])));
- else
- tem = gen_rtx_MINUS (SImode, operands[2], operands[3]);
-
- operands[5] = gen_rtx_SIGN_EXTEND (DImode, tem);
- operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
- operands[4], const0_rtx);
-})
-
-;; We can convert such things as "a > 0xffff" to "t = a & ~ 0xffff; t != 0".
-;; This eliminates one, and sometimes two, insns when the AND can be done
-;; with a ZAP.
-(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (match_operator:DI 1 "comparison_operator"
- [(match_operand:DI 2 "register_operand" "")
- (match_operand:DI 3 "const_int_operand" "")]))
- (clobber (match_operand:DI 4 "register_operand" ""))]
- "exact_log2 (INTVAL (operands[3]) + 1) >= 0
- && (GET_CODE (operands[1]) == GTU
- || GET_CODE (operands[1]) == LEU
- || ((GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == LE)
- && extended_count (operands[2], DImode, 1) > 0))"
- [(set (match_dup 4) (and:DI (match_dup 2) (match_dup 5)))
- (set (match_dup 0) (match_dup 6))]
-{
- operands[5] = GEN_INT (~ INTVAL (operands[3]));
- operands[6] = gen_rtx_fmt_ee (((GET_CODE (operands[1]) == GTU
- || GET_CODE (operands[1]) == GT)
- ? NE : EQ),
- DImode, operands[4], const0_rtx);
-})
-
;; Prefer to use cmp and arithmetic when possible instead of a cmove.
(define_split
(clobber (match_scratch:DI 5 "=r"))]
""
"#"
- "! no_new_pseudos || reload_completed"
+ ""
[(set (match_dup 5)
(match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
(set (match_dup 0)
(plus:DI (mult:DI (match_dup 5) (match_dup 3))
(match_dup 4)))]
{
- if (! no_new_pseudos)
+ if (can_create_pseudo_p ())
operands[5] = gen_reg_rtx (DImode);
else if (reg_overlap_mentioned_p (operands[5], operands[4]))
operands[5] = operands[0];
(match_operand:SI 3 "const48_operand" "I")
(const_int 0))
(match_operand:SI 4 "sext_add_operand" "rIO")))
- (clobber (match_scratch:SI 5 "=r"))]
+ (clobber (match_scratch:DI 5 "=r"))]
""
"#"
- "! no_new_pseudos || reload_completed"
+ ""
[(set (match_dup 5)
- (match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
+ (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
(set (match_dup 0)
- (plus:SI (mult:SI (match_dup 5) (match_dup 3))
+ (plus:SI (mult:SI (match_dup 6) (match_dup 3))
(match_dup 4)))]
{
- if (! no_new_pseudos)
+ if (can_create_pseudo_p ())
operands[5] = gen_reg_rtx (DImode);
else if (reg_overlap_mentioned_p (operands[5], operands[4]))
- operands[5] = operands[0];
+ operands[5] = gen_lowpart (DImode, operands[0]);
+
+ operands[6] = gen_lowpart (SImode, operands[5]);
})
(define_insn_and_split "*cmp_sadd_sidi"
(match_operand:SI 3 "const48_operand" "I")
(const_int 0))
(match_operand:SI 4 "sext_add_operand" "rIO"))))
- (clobber (match_scratch:SI 5 "=r"))]
+ (clobber (match_scratch:DI 5 "=r"))]
""
"#"
- "! no_new_pseudos || reload_completed"
+ ""
[(set (match_dup 5)
- (match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
+ (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
(set (match_dup 0)
- (sign_extend:DI (plus:SI (mult:SI (match_dup 5) (match_dup 3))
+ (sign_extend:DI (plus:SI (mult:SI (match_dup 6) (match_dup 3))
(match_dup 4))))]
{
- if (! no_new_pseudos)
+ if (can_create_pseudo_p ())
operands[5] = gen_reg_rtx (DImode);
else if (reg_overlap_mentioned_p (operands[5], operands[4]))
operands[5] = operands[0];
+
+ operands[6] = gen_lowpart (SImode, operands[5]);
})
(define_insn_and_split "*cmp_ssub_di"
(clobber (match_scratch:DI 5 "=r"))]
""
"#"
- "! no_new_pseudos || reload_completed"
+ ""
[(set (match_dup 5)
(match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
(set (match_dup 0)
(minus:DI (mult:DI (match_dup 5) (match_dup 3))
(match_dup 4)))]
{
- if (! no_new_pseudos)
+ if (can_create_pseudo_p ())
operands[5] = gen_reg_rtx (DImode);
else if (reg_overlap_mentioned_p (operands[5], operands[4]))
operands[5] = operands[0];
(match_operand:SI 3 "const48_operand" "I")
(const_int 0))
(match_operand:SI 4 "reg_or_8bit_operand" "rI")))
- (clobber (match_scratch:SI 5 "=r"))]
+ (clobber (match_scratch:DI 5 "=r"))]
""
"#"
- "! no_new_pseudos || reload_completed"
+ ""
[(set (match_dup 5)
- (match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
+ (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
(set (match_dup 0)
- (minus:SI (mult:SI (match_dup 5) (match_dup 3))
+ (minus:SI (mult:SI (match_dup 6) (match_dup 3))
(match_dup 4)))]
{
- if (! no_new_pseudos)
+ if (can_create_pseudo_p ())
operands[5] = gen_reg_rtx (DImode);
else if (reg_overlap_mentioned_p (operands[5], operands[4]))
- operands[5] = operands[0];
+ operands[5] = gen_lowpart (DImode, operands[0]);
+
+ operands[6] = gen_lowpart (SImode, operands[5]);
})
(define_insn_and_split "*cmp_ssub_sidi"
(match_operand:SI 3 "const48_operand" "I")
(const_int 0))
(match_operand:SI 4 "reg_or_8bit_operand" "rI"))))
- (clobber (match_scratch:SI 5 "=r"))]
+ (clobber (match_scratch:DI 5 "=r"))]
""
"#"
- "! no_new_pseudos || reload_completed"
+ ""
[(set (match_dup 5)
- (match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
+ (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
(set (match_dup 0)
- (sign_extend:DI (minus:SI (mult:SI (match_dup 5) (match_dup 3))
+ (sign_extend:DI (minus:SI (mult:SI (match_dup 6) (match_dup 3))
(match_dup 4))))]
{
- if (! no_new_pseudos)
+ if (can_create_pseudo_p ())
operands[5] = gen_reg_rtx (DImode);
else if (reg_overlap_mentioned_p (operands[5], operands[4]))
operands[5] = operands[0];
+
+ operands[6] = gen_lowpart (SImode, operands[5]);
})
\f
;; Here are the CALL and unconditional branch insns. Calls on NT and OSF
;; work differently, so we have different patterns 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
-;; 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
-;; 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
-;; 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
-;; $25 is generated.
-
(define_expand "call"
[(use (match_operand:DI 0 "" ""))
(use (match_operand 1 "" ""))
(use (match_operand 3 "" ""))]
""
{
- if (TARGET_ABI_WINDOWS_NT)
- emit_call_insn (gen_call_nt (operands[0], operands[1]));
- else if (TARGET_ABI_OPEN_VMS)
+ if (TARGET_ABI_OPEN_VMS)
emit_call_insn (gen_call_vms (operands[0], operands[2]));
- else if (TARGET_ABI_UNICOSMK)
- emit_call_insn (gen_call_umk (operands[0], operands[2]));
else
emit_call_insn (gen_call_osf (operands[0], operands[1]));
DONE;
(unspec [(reg:DI 29)] UNSPEC_SIBCALL)])]
"TARGET_ABI_OSF"
{
- if (GET_CODE (operands[0]) != MEM)
- abort ();
+ gcc_assert (MEM_P (operands[0]));
operands[0] = XEXP (operands[0], 0);
})
(clobber (reg:DI 26))])]
""
{
- if (GET_CODE (operands[0]) != MEM)
- abort ();
+ gcc_assert (MEM_P (operands[0]));
operands[0] = XEXP (operands[0], 0);
if (! call_operand (operands[0], Pmode))
operands[0] = copy_to_mode_reg (Pmode, operands[0]);
})
-(define_expand "call_nt"
- [(parallel [(call (mem:DI (match_operand 0 "" ""))
- (match_operand 1 "" ""))
- (clobber (reg:DI 26))])]
- ""
-{
- if (GET_CODE (operands[0]) != MEM)
- abort ();
-
- operands[0] = XEXP (operands[0], 0);
- if (GET_CODE (operands[0]) != SYMBOL_REF && GET_CODE (operands[0]) != REG)
- operands[0] = force_reg (DImode, operands[0]);
-})
-
-;; Calls on Unicos/Mk are always indirect.
-;; op 0: symbol ref for called function
-;; op 1: CIW for $25 represented by an unspec
-
-(define_expand "call_umk"
- [(parallel [(call (mem:DI (match_operand 0 "" ""))
- (match_operand 1 "" ""))
- (use (reg:DI 25))
- (clobber (reg:DI 26))])]
- ""
-{
- if (GET_CODE (operands[0]) != MEM)
- abort ();
-
- /* Always load the address of the called function into a register;
- load the CIW in $25. */
-
- operands[0] = XEXP (operands[0], 0);
- if (GET_CODE (operands[0]) != REG)
- operands[0] = force_reg (DImode, operands[0]);
-
- emit_move_insn (gen_rtx_REG (DImode, 25), operands[1]);
-})
-
;;
;; call openvms/alpha
;; op 0: symbol ref for called function
(clobber (reg:DI 27))])]
""
{
- if (GET_CODE (operands[0]) != MEM)
- abort ();
+ gcc_assert (MEM_P (operands[0]));
operands[0] = XEXP (operands[0], 0);
emit_move_insn (gen_rtx_REG (DImode, 25), operands[1]);
if (GET_CODE (operands[0]) == SYMBOL_REF)
{
- alpha_need_linkage (XSTR (operands[0], 0), 0);
-
operands[2] = const0_rtx;
}
else
(use (match_operand 4 "" ""))]
""
{
- if (TARGET_ABI_WINDOWS_NT)
- emit_call_insn (gen_call_value_nt (operands[0], operands[1], operands[2]));
- else if (TARGET_ABI_OPEN_VMS)
+ if (TARGET_ABI_OPEN_VMS)
emit_call_insn (gen_call_value_vms (operands[0], operands[1],
operands[3]));
- else if (TARGET_ABI_UNICOSMK)
- emit_call_insn (gen_call_value_umk (operands[0], operands[1],
- operands[3]));
else
emit_call_insn (gen_call_value_osf (operands[0], operands[1],
operands[2]));
(unspec [(reg:DI 29)] UNSPEC_SIBCALL)])]
"TARGET_ABI_OSF"
{
- if (GET_CODE (operands[1]) != MEM)
- abort ();
+ gcc_assert (MEM_P (operands[1]));
operands[1] = XEXP (operands[1], 0);
})
(clobber (reg:DI 26))])]
""
{
- if (GET_CODE (operands[1]) != MEM)
- abort ();
+ gcc_assert (MEM_P (operands[1]));
operands[1] = XEXP (operands[1], 0);
if (! call_operand (operands[1], Pmode))
operands[1] = copy_to_mode_reg (Pmode, operands[1]);
})
-(define_expand "call_value_nt"
- [(parallel [(set (match_operand 0 "" "")
- (call (mem:DI (match_operand 1 "" ""))
- (match_operand 2 "" "")))
- (clobber (reg:DI 26))])]
- ""
-{
- if (GET_CODE (operands[1]) != MEM)
- abort ();
-
- operands[1] = XEXP (operands[1], 0);
- if (GET_CODE (operands[1]) != SYMBOL_REF && GET_CODE (operands[1]) != REG)
- operands[1] = force_reg (DImode, operands[1]);
-})
-
(define_expand "call_value_vms"
[(parallel [(set (match_operand 0 "" "")
(call (mem:DI (match_operand:DI 1 "" ""))
(clobber (reg:DI 27))])]
""
{
- if (GET_CODE (operands[1]) != MEM)
- abort ();
+ gcc_assert (MEM_P (operands[1]));
operands[1] = XEXP (operands[1], 0);
emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]);
if (GET_CODE (operands[1]) == SYMBOL_REF)
{
- alpha_need_linkage (XSTR (operands[1], 0), 0);
-
operands[3] = const0_rtx;
}
else
}
})
-(define_expand "call_value_umk"
- [(parallel [(set (match_operand 0 "" "")
- (call (mem:DI (match_operand 1 "" ""))
- (match_operand 2 "" "")))
- (use (reg:DI 25))
- (clobber (reg:DI 26))])]
- ""
-{
- if (GET_CODE (operands[1]) != MEM)
- abort ();
-
- operands[1] = XEXP (operands[1], 0);
- if (GET_CODE (operands[1]) != REG)
- operands[1] = force_reg (DImode, operands[1]);
-
- emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]);
-})
+(define_insn "*call_osf_1_er_noreturn"
+ [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
+ (match_operand 1 "" ""))
+ (use (reg:DI 29))
+ (clobber (reg:DI 26))]
+ "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
+ && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
+ "@
+ jsr $26,($27),0
+ bsr $26,%0\t\t!samegp
+ ldq $27,%0($29)\t\t!literal!%#\;jsr $26,($27),%0\t\t!lituse_jsr!%#"
+ [(set_attr "type" "jsr")
+ (set_attr "length" "*,*,8")])
(define_insn "*call_osf_1_er"
[(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
(clobber (reg:DI 26))])]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
&& ! 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))"
[(parallel [(call (mem:DI (match_dup 2))
(match_dup 1))
- (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
- (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
+ (use (reg:DI 29))
(use (match_dup 0))
- (use (match_dup 3))])]
+ (use (match_dup 3))
+ (clobber (reg:DI 26))])]
{
if (CONSTANT_P (operands[0]))
{
(clobber (reg:DI 26))])]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
&& ! 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))"
[(parallel [(call (mem:DI (match_dup 2))
(match_dup 1))
- (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
- (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
+ (set (match_dup 5)
+ (unspec:DI [(match_dup 5) (match_dup 3)] UNSPEC_LDGP1))
(use (match_dup 0))
- (use (match_dup 4))])
- (set (reg:DI 29)
- (unspec_volatile:DI [(reg:DI 26) (match_dup 3)] UNSPECV_LDGP1))
- (set (reg:DI 29)
- (unspec:DI [(reg:DI 29) (match_dup 3)] UNSPEC_LDGP2))]
+ (use (match_dup 4))
+ (clobber (reg:DI 26))])
+ (set (match_dup 5)
+ (unspec:DI [(match_dup 5) (match_dup 3)] UNSPEC_LDGP2))]
{
if (CONSTANT_P (operands[0]))
{
operands[4] = const0_rtx;
}
operands[3] = GEN_INT (alpha_next_sequence_number++);
+ operands[5] = pic_offset_table_rtx;
})
-;; We add a blockage unspec_volatile to prevent insns from moving down
-;; from above the call to in between the call and the ldah gpdisp.
-
-(define_insn "*call_osf_2_er"
+(define_insn "*call_osf_2_er_nogp"
[(call (mem:DI (match_operand:DI 0 "register_operand" "c"))
(match_operand 1 "" ""))
- (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
- (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
+ (use (reg:DI 29))
(use (match_operand 2 "" ""))
- (use (match_operand 3 "const_int_operand" ""))]
+ (use (match_operand 3 "const_int_operand" ""))
+ (clobber (reg:DI 26))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"jsr $26,(%0),%2%J3"
[(set_attr "type" "jsr")])
-;; We output a nop after noreturn calls at the very end of the function to
-;; ensure that the return address always remains in the caller's code range,
-;; as not doing so might confuse unwinding engines.
-;;
-;; The potential change in insn length is not reflected in the length
-;; attributes at this stage. Since the extra space is only actually added at
-;; the very end of the compilation process (via final/print_operand), it
-;; really seems harmless and not worth the trouble of some extra computation
-;; cost and complexity.
+(define_insn "*call_osf_2_er"
+ [(call (mem:DI (match_operand:DI 0 "register_operand" "c"))
+ (match_operand 1 "" ""))
+ (set (reg:DI 29)
+ (unspec:DI [(reg:DI 29) (match_operand 4 "const_int_operand" "")]
+ UNSPEC_LDGP1))
+ (use (match_operand 2 "" ""))
+ (use (match_operand 3 "const_int_operand" ""))
+ (clobber (reg:DI 26))]
+ "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
+ "jsr $26,(%0),%2%J3\;ldah $29,0($26)\t\t!gpdisp!%4"
+ [(set_attr "type" "jsr")
+ (set_attr "cannot_copy" "true")
+ (set_attr "length" "8")])
(define_insn "*call_osf_1_noreturn"
[(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
"! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
"@
- jsr $26,($27),0%+
- bsr $26,$%0..ng%+
- jsr $26,%0%+"
+ jsr $26,($27),0
+ bsr $26,$%0..ng
+ jsr $26,%0"
[(set_attr "type" "jsr")
(set_attr "length" "*,*,8")])
[(set_attr "type" "jsr")
(set_attr "length" "12,*,16")])
-;; Note that the DEC assembler expands "jmp foo" with $at, which
-;; doesn't do what we want.
(define_insn "*sibcall_osf_1_er"
[(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s"))
(match_operand 1 "" ""))
[(set_attr "type" "jsr")
(set_attr "length" "*,8")])
+;; Note that the DEC assembler expands "jmp foo" with $at, which
+;; doesn't do what we want.
(define_insn "*sibcall_osf_1"
[(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s"))
(match_operand 1 "" ""))
[(set_attr "type" "jsr")
(set_attr "length" "*,8")])
-(define_insn "*call_nt_1"
- [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,s"))
- (match_operand 1 "" ""))
- (clobber (reg:DI 26))]
- "TARGET_ABI_WINDOWS_NT"
- "@
- jsr $26,(%0)
- bsr $26,%0
- jsr $26,%0"
- [(set_attr "type" "jsr")
- (set_attr "length" "*,*,12")])
-
; GAS relies on the order and position of instructions output below in order
; to generate relocs for VMS link to potentially optimize the call.
; Please do not molest.
case 0:
return "mov %2,$27\;jsr $26,0\;ldq $27,0($29)";
case 1:
- operands [2] = alpha_use_linkage (operands [0], cfun->decl, 1, 0);
- operands [3] = alpha_use_linkage (operands [0], cfun->decl, 0, 0);
+ operands [2] = alpha_use_linkage (operands [0], true, false);
+ operands [3] = alpha_use_linkage (operands [0], false, false);
return "ldq $26,%3\;ldq $27,%2\;jsr $26,%0\;ldq $27,0($29)";
default:
- abort();
+ gcc_unreachable ();
}
}
[(set_attr "type" "jsr")
(set_attr "length" "12,16")])
-(define_insn "*call_umk_1"
- [(call (mem:DI (match_operand:DI 0 "call_operand" "r"))
- (match_operand 1 "" ""))
- (use (reg:DI 25))
- (clobber (reg:DI 26))]
- "TARGET_ABI_UNICOSMK"
- "jsr $26,(%0)"
- [(set_attr "type" "jsr")])
-
;; Call subroutine returning any type.
(define_expand "untyped_call"
(use (label_ref:DI (match_operand 1 "" "")))])]
""
{
- if (TARGET_ABI_WINDOWS_NT)
- {
- rtx dest = gen_reg_rtx (DImode);
- emit_insn (gen_extendsidi2 (dest, operands[0]));
- operands[0] = dest;
- }
- else if (TARGET_ABI_OSF)
+ if (TARGET_ABI_OSF)
{
rtx dest = gen_reg_rtx (DImode);
emit_insn (gen_extendsidi2 (dest, operands[0]));
}
})
-(define_insn "*tablejump_osf_nt_internal"
- [(set (pc)
- (match_operand:DI 0 "register_operand" "r"))
- (use (label_ref:DI (match_operand 1 "" "")))]
- "(TARGET_ABI_OSF || TARGET_ABI_WINDOWS_NT)
- && alpha_tablejump_addr_vec (insn)"
-{
- operands[2] = alpha_tablejump_best_label (insn);
- return "jmp $31,(%0),%2";
-}
- [(set_attr "type" "ibr")])
-
(define_insn "*tablejump_internal"
[(set (pc)
(match_operand:DI 0 "register_operand" "r"))
"jmp $31,(%0),0"
[(set_attr "type" "ibr")])
-;; Cache flush. Used by INITIALIZE_TRAMPOLINE. 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.
-;;
-;; Technically the type for call_pal is jsr, but we use that for determining
-;; if we need a GP. Use ibr instead since it has the same EV5 scheduling
-;; characteristics.
(define_insn "imb"
[(unspec_volatile [(const_int 0)] UNSPECV_IMB)]
""
[(set_attr "type" "callpal")])
;; BUGCHK is documented common to OSF/1 and VMS PALcode.
-;; NT does not document anything at 0x81 -- presumably it would generate
-;; the equivalent of SIGILL, but this isn't that important.
-;; ??? Presuming unicosmk uses either OSF/1 or VMS PALcode.
(define_insn "trap"
[(trap_if (const_int 1) (const_int 0))]
- "!TARGET_ABI_WINDOWS_NT"
+ ""
"call_pal 0x81"
[(set_attr "type" "callpal")])
return "call_pal 0x9f";
}
[(set_attr "type" "callpal")])
+
+;; Special builtins for establishing and reverting VMS condition handlers.
+
+(define_expand "builtin_establish_vms_condition_handler"
+ [(set (reg:DI 0) (match_operand:DI 0 "register_operand" ""))
+ (use (match_operand:DI 1 "address_operand" ""))]
+ "TARGET_ABI_OPEN_VMS"
+{
+ alpha_expand_builtin_establish_vms_condition_handler (operands[0],
+ operands[1]);
+})
+
+(define_expand "builtin_revert_vms_condition_handler"
+ [(set (reg:DI 0) (match_operand:DI 0 "register_operand" ""))]
+ "TARGET_ABI_OPEN_VMS"
+{
+ alpha_expand_builtin_revert_vms_condition_handler (operands[0]);
+})
\f
;; 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
;; they are simpler.
-(define_insn "*movsf_nofix"
- [(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"))]
- "TARGET_FPREGS && ! TARGET_FIX
- && (register_operand (operands[0], SFmode)
- || reg_or_0_operand (operands[1], SFmode))"
- "@
- cpys %R1,%R1,%0
- ld%, %0,%1
- bis $31,%r1,%0
- ldl %0,%1
- st%, %R1,%0
- stl %r1,%0"
- [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")])
+(define_expand "movsf"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "")
+ (match_operand:SF 1 "general_operand" ""))]
+ ""
+{
+ if (MEM_P (operands[0])
+ && ! reg_or_0_operand (operands[1], SFmode))
+ operands[1] = force_reg (SFmode, operands[1]);
+})
-(define_insn "*movsf_fix"
+(define_insn "*movsf"
[(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"))]
- "TARGET_FPREGS && TARGET_FIX
- && (register_operand (operands[0], SFmode)
- || reg_or_0_operand (operands[1], SFmode))"
+ "register_operand (operands[0], SFmode)
+ || reg_or_0_operand (operands[1], SFmode)"
"@
cpys %R1,%R1,%0
ld%, %0,%1
stl %r1,%0
itofs %1,%0
ftois %1,%0"
- [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")])
-
-(define_insn "*movsf_nofp"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
- (match_operand:SF 1 "input_operand" "rG,m,r"))]
- "! TARGET_FPREGS
- && (register_operand (operands[0], SFmode)
- || reg_or_0_operand (operands[1], SFmode))"
- "@
- bis $31,%r1,%0
- ldl %0,%1
- stl %r1,%0"
- [(set_attr "type" "ilog,ild,ist")])
-
-(define_insn "*movdf_nofix"
- [(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"))]
- "TARGET_FPREGS && ! TARGET_FIX
- && (register_operand (operands[0], DFmode)
- || reg_or_0_operand (operands[1], DFmode))"
- "@
- cpys %R1,%R1,%0
- ld%- %0,%1
- bis $31,%r1,%0
- ldq %0,%1
- st%- %R1,%0
- stq %r1,%0"
- [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")])
+ [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")
+ (set_attr "isa" "*,*,*,*,*,*,fix,fix")])
+
+(define_expand "movdf"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "")
+ (match_operand:DF 1 "general_operand" ""))]
+ ""
+{
+ if (MEM_P (operands[0])
+ && ! reg_or_0_operand (operands[1], DFmode))
+ operands[1] = force_reg (DFmode, operands[1]);
+})
-(define_insn "*movdf_fix"
+(define_insn "*movdf"
[(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"))]
- "TARGET_FPREGS && TARGET_FIX
- && (register_operand (operands[0], DFmode)
- || reg_or_0_operand (operands[1], DFmode))"
+ "register_operand (operands[0], DFmode)
+ || reg_or_0_operand (operands[1], DFmode)"
"@
cpys %R1,%R1,%0
ld%- %0,%1
stq %r1,%0
itoft %1,%0
ftoit %1,%0"
- [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")])
-
-(define_insn "*movdf_nofp"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
- (match_operand:DF 1 "input_operand" "rG,m,r"))]
- "! TARGET_FPREGS
- && (register_operand (operands[0], DFmode)
- || reg_or_0_operand (operands[1], DFmode))"
- "@
- bis $31,%r1,%0
- ldq %0,%1
- stq %r1,%0"
- [(set_attr "type" "ilog,ild,ist")])
+ [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")
+ (set_attr "isa" "*,*,*,*,*,*,fix,fix")])
;; Subregs suck for register allocation. Pretend we can move TFmode
;; data between general registers until after reload.
+;; ??? Is this still true now that we have the lower-subreg pass?
+
+(define_expand "movtf"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "")
+ (match_operand:TF 1 "general_operand" ""))]
+ ""
+{
+ if (MEM_P (operands[0])
+ && ! reg_or_0_operand (operands[1], TFmode))
+ operands[1] = force_reg (TFmode, operands[1]);
+})
-(define_insn_and_split "*movtf_internal"
+(define_insn_and_split "*movtf"
[(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
(match_operand:TF 1 "input_operand" "roG,rG"))]
"register_operand (operands[0], TFmode)
[(set (match_dup 0) (match_dup 2))
(set (match_dup 1) (match_dup 3))]
{
- alpha_split_tfmode_pair (operands);
- if (reg_overlap_mentioned_p (operands[0], operands[3]))
- {
- rtx tmp;
- tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
- tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
- }
-})
-
-(define_expand "movsf"
- [(set (match_operand:SF 0 "nonimmediate_operand" "")
- (match_operand:SF 1 "general_operand" ""))]
- ""
-{
- if (GET_CODE (operands[0]) == MEM
- && ! reg_or_0_operand (operands[1], SFmode))
- operands[1] = force_reg (SFmode, operands[1]);
-})
-
-(define_expand "movdf"
- [(set (match_operand:DF 0 "nonimmediate_operand" "")
- (match_operand:DF 1 "general_operand" ""))]
- ""
-{
- if (GET_CODE (operands[0]) == MEM
- && ! reg_or_0_operand (operands[1], DFmode))
- operands[1] = force_reg (DFmode, operands[1]);
-})
-
-(define_expand "movtf"
- [(set (match_operand:TF 0 "nonimmediate_operand" "")
- (match_operand:TF 1 "general_operand" ""))]
- ""
-{
- if (GET_CODE (operands[0]) == MEM
- && ! reg_or_0_operand (operands[1], TFmode))
- operands[1] = force_reg (TFmode, operands[1]);
+ alpha_split_tmode_pair (operands, TFmode, true);
})
-(define_insn "*movsi_nofix"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*f,*f,m")
- (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f"))]
- "(TARGET_ABI_OSF || TARGET_ABI_UNICOSMK) && ! TARGET_FIX
- && (register_operand (operands[0], SImode)
- || reg_or_0_operand (operands[1], SImode))"
- "@
- bis $31,%r1,%0
- lda %0,%1($31)
- ldah %0,%h1($31)
- ldl %0,%1
- stl %r1,%0
- cpys %R1,%R1,%0
- ld%, %0,%1
- st%, %R1,%0"
- [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst")])
-
-(define_insn "*movsi_fix"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*f,*f,m,r,*f")
- (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f,*f,r"))]
- "TARGET_ABI_OSF && TARGET_FIX
- && (register_operand (operands[0], SImode)
- || reg_or_0_operand (operands[1], SImode))"
- "@
- bis $31,%r1,%0
- lda %0,%1($31)
- ldah %0,%h1($31)
- ldl %0,%1
- stl %r1,%0
- cpys %R1,%R1,%0
- ld%, %0,%1
- st%, %R1,%0
- ftois %1,%0
- itofs %1,%0"
- [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst,ftoi,itof")])
-
-(define_insn "*movsi_nt_vms_nofix"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,m")
- (match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,m,*f"))]
- "(TARGET_ABI_WINDOWS_NT || TARGET_ABI_OPEN_VMS)
- && !TARGET_FIX
- && (register_operand (operands[0], SImode)
- || reg_or_0_operand (operands[1], SImode))"
- "@
- bis $31,%1,%0
- lda %0,%1
- ldah %0,%h1
- lda %0,%1
- ldl %0,%1
- stl %r1,%0
- cpys %R1,%R1,%0
- ld%, %0,%1
- st%, %R1,%0"
- [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
-
-(define_insn "*movsi_nt_vms_fix"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,m,r,*f")
- (match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,m,*f,*f,r"))]
- "(TARGET_ABI_WINDOWS_NT || TARGET_ABI_OPEN_VMS)
- && TARGET_FIX
- && (register_operand (operands[0], SImode)
- || reg_or_0_operand (operands[1], SImode))"
- "@
- bis $31,%1,%0
- lda %0,%1
- ldah %0,%h1
- lda %0,%1
- ldl %0,%1
- stl %r1,%0
- cpys %R1,%R1,%0
- ld%, %0,%1
- st%, %R1,%0
- ftois %1,%0
- itofs %1,%0"
- [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")])
-
-(define_insn "*movhi_nobwx"
- [(set (match_operand:HI 0 "register_operand" "=r,r")
- (match_operand:HI 1 "input_operand" "rJ,n"))]
- "! TARGET_BWX
- && (register_operand (operands[0], HImode)
- || register_operand (operands[1], HImode))"
- "@
- bis $31,%r1,%0
- lda %0,%L1($31)"
- [(set_attr "type" "ilog,iadd")])
-
-(define_insn "*movhi_bwx"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
- (match_operand:HI 1 "input_operand" "rJ,n,m,rJ"))]
- "TARGET_BWX
- && (register_operand (operands[0], HImode)
- || reg_or_0_operand (operands[1], HImode))"
- "@
- bis $31,%r1,%0
- lda %0,%L1($31)
- ldwu %0,%1
- stw %r1,%0"
- [(set_attr "type" "ilog,iadd,ild,ist")])
-
-(define_insn "*movqi_nobwx"
- [(set (match_operand:QI 0 "register_operand" "=r,r")
- (match_operand:QI 1 "input_operand" "rJ,n"))]
- "! TARGET_BWX
- && (register_operand (operands[0], QImode)
- || register_operand (operands[1], QImode))"
- "@
- bis $31,%r1,%0
- lda %0,%L1($31)"
- [(set_attr "type" "ilog,iadd")])
-
-(define_insn "*movqi_bwx"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m")
- (match_operand:QI 1 "input_operand" "rJ,n,m,rJ"))]
- "TARGET_BWX
- && (register_operand (operands[0], QImode)
- || reg_or_0_operand (operands[1], QImode))"
- "@
- bis $31,%r1,%0
- lda %0,%L1($31)
- ldbu %0,%1
- stb %r1,%0"
- [(set_attr "type" "ilog,iadd,ild,ist")])
-
;; We do two major things here: handle mem->mem and construct long
;; constants.
DONE;
})
+(define_insn "*movsi"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,r")
+ (match_operand:SI 1 "input_operand" "rJ,K,L,n,m,rJ,s"))]
+ "register_operand (operands[0], SImode)
+ || reg_or_0_operand (operands[1], SImode)"
+ "@
+ bis $31,%r1,%0
+ lda %0,%1($31)
+ ldah %0,%h1($31)
+ #
+ ldl %0,%1
+ stl %r1,%0
+ lda %0,%1"
+ [(set_attr "type" "ilog,iadd,iadd,multi,ild,ist,ldsym")
+ (set_attr "isa" "*,*,*,*,*,*,vms")])
+
;; Split a load of a large constant into the appropriate two-insn
;; sequence.
(define_split
[(set (match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "const_int_operand" ""))]
- "! add_operand (operands[1], SImode)"
- [(set (match_dup 0) (match_dup 2))
- (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
+ (match_operand:SI 1 "non_add_const_operand" ""))]
+ ""
+ [(const_int 0)]
{
- rtx tem
- = alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 2);
-
- if (tem == operands[0])
+ if (alpha_split_const_mov (SImode, operands))
DONE;
else
FAIL;
})
-;; 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
-;; optimizations. If the symbolic operand is a label_ref, generate REG_LABEL
-;; notes and update LABEL_NUSES because this is not done automatically.
-;; Labels may be incorrectly deleted if we don't do this.
-;;
-;; Describing what the individual instructions do correctly is too complicated
-;; so use UNSPECs for each of the three parts of an address.
-
-(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "symbolic_operand" ""))]
- "TARGET_ABI_UNICOSMK && reload_completed"
- [(const_int 0)]
-{
- rtx insn1, insn2, insn3;
-
- insn1 = emit_insn (gen_umk_laum (operands[0], operands[1]));
- emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
- insn2 = emit_insn (gen_umk_lalm (operands[0], operands[0], operands[1]));
- insn3 = emit_insn (gen_umk_lal (operands[0], operands[0], operands[1]));
- REG_NOTES (insn3) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
- REG_NOTES (insn3));
- if (GET_CODE (operands[1]) == LABEL_REF)
- {
- rtx label;
-
- label = XEXP (operands[1], 0);
- REG_NOTES (insn1) = gen_rtx_EXPR_LIST (REG_LABEL, label,
- REG_NOTES (insn1));
- REG_NOTES (insn2) = gen_rtx_EXPR_LIST (REG_LABEL, label,
- REG_NOTES (insn2));
- REG_NOTES (insn3) = gen_rtx_EXPR_LIST (REG_LABEL, label,
- REG_NOTES (insn3));
- LABEL_NUSES (label) += 3;
- }
- DONE;
-})
-
-;; Instructions for loading the three parts of an address on Unicos/Mk.
-
-(define_insn "umk_laum"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
- UNSPEC_UMK_LAUM))]
- "TARGET_ABI_UNICOSMK"
- "laum %r0,%t1($31)"
- [(set_attr "type" "iadd")])
-
-(define_insn "umk_lalm"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (plus:DI (match_operand:DI 1 "register_operand" "r")
- (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
- UNSPEC_UMK_LALM)))]
- "TARGET_ABI_UNICOSMK"
- "lalm %r0,%t2(%r1)"
- [(set_attr "type" "iadd")])
-
-(define_insn "umk_lal"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (plus:DI (match_operand:DI 1 "register_operand" "r")
- (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
- UNSPEC_UMK_LAL)))]
- "TARGET_ABI_UNICOSMK"
- "lal %r0,%t2(%r1)"
- [(set_attr "type" "iadd")])
-
-;; 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
-;; associated with the correct function even in the presence of inlining.
-
-(define_insn "*umk_load_ciw"
- [(set (reg:DI 25)
- (unspec:DI [(match_operand 0 "" "")] UNSPEC_UMK_LOAD_CIW))]
- "TARGET_ABI_UNICOSMK"
-{
- operands[0] = unicosmk_add_call_info_word (operands[0]);
- return "lda $25,%0";
-}
- [(set_attr "type" "iadd")])
-
(define_insn "*movdi_er_low_l"
[(set (match_operand:DI 0 "register_operand" "=r")
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
(define_split
[(match_operand 0 "some_small_symbolic_operand" "")]
- "TARGET_EXPLICIT_RELOCS && reload_completed"
+ ""
[(match_dup 0)]
"operands[0] = split_small_symbolic_operand (operands[0]);")
(const_int 0)] UNSPEC_LITERAL))]
"operands[2] = pic_offset_table_rtx;")
-;; With RTL inlining, at -O3, rtl is generated, stored, then actually
-;; compiled at the end of compilation. In the meantime, someone can
-;; re-encode-section-info on some symbol changing it e.g. from global
-;; to local-not-small. If this happens, we'd have emitted a plain
-;; load rather than a high+losum load and not recognize the insn.
-;;
-;; So if rtl inlining is in effect, we delay the global/not-global
-;; decision until rest_of_compilation by wrapping it in an UNSPEC_SYMBOL.
-
-(define_insn_and_split "movdi_er_maybe_g"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
- UNSPEC_SYMBOL))]
- "TARGET_EXPLICIT_RELOCS && flag_inline_functions"
- "#"
- ""
- [(set (match_dup 0) (match_dup 1))]
-{
- if (local_symbolic_operand (operands[1], Pmode)
- && !small_symbolic_operand (operands[1], Pmode))
- {
- rtx subtarget = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
- rtx tmp;
-
- tmp = gen_rtx_HIGH (Pmode, operands[1]);
- if (reload_completed)
- tmp = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, tmp);
- emit_insn (gen_rtx_SET (VOIDmode, subtarget, tmp));
-
- tmp = gen_rtx_LO_SUM (Pmode, subtarget, operands[1]);
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], tmp));
- DONE;
- }
-})
-
-(define_insn "movdi_er_tlsgd"
+(define_insn "movdi_er_tlsgd"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
(match_operand:DI 2 "symbolic_operand" "")
operands[2] = pic_offset_table_rtx;
})
-(define_insn "*movdi_er_nofix"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,*f,*f,Q")
- (match_operand:DI 1 "input_operand" "rJ,K,L,T,s,m,rJ,*fJ,Q,*f"))]
- "TARGET_EXPLICIT_RELOCS && ! TARGET_FIX
- && (register_operand (operands[0], DImode)
- || reg_or_0_operand (operands[1], DImode))"
- "@
- mov %r1,%0
- lda %0,%1($31)
- ldah %0,%h1($31)
- #
- #
- ldq%A1 %0,%1
- stq%A0 %r1,%0
- fmov %R1,%0
- ldt %0,%1
- stt %R1,%0"
- [(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")
- (set_attr "usegp" "*,*,*,yes,*,*,*,*,*,*")])
-
-;; The 'U' constraint matches symbolic operands on Unicos/Mk. Those should
-;; have been split up by the rules above but we shouldn't reject the
-;; possibility of them getting through.
-
-(define_insn "*movdi_nofix"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,*f,*f,Q")
- (match_operand:DI 1 "input_operand" "rJ,K,L,U,s,m,rJ,*fJ,Q,*f"))]
- "! TARGET_FIX
- && (register_operand (operands[0], DImode)
- || reg_or_0_operand (operands[1], DImode))"
- "@
- bis $31,%r1,%0
- lda %0,%1($31)
- ldah %0,%h1($31)
- laum %0,%t1($31)\;sll %0,32,%0\;lalm %0,%t1(%0)\;lal %0,%t1(%0)
- lda %0,%1
- ldq%A1 %0,%1
- stq%A0 %r1,%0
- cpys %R1,%R1,%0
- ldt %0,%1
- stt %R1,%0"
- [(set_attr "type" "ilog,iadd,iadd,ldsym,ldsym,ild,ist,fcpys,fld,fst")
- (set_attr "length" "*,*,*,16,*,*,*,*,*,*")])
-
-(define_insn "*movdi_er_fix"
+(define_insn "*movdi"
[(set (match_operand:DI 0 "nonimmediate_operand"
- "=r,r,r,r,r,r, m, *f,*f, Q, r,*f")
+ "=r,r,r,r,r,r,r,r, m, *f,*f, Q, r,*f")
(match_operand:DI 1 "input_operand"
- "rJ,K,L,T,s,m,rJ,*fJ, Q,*f,*f, r"))]
- "TARGET_EXPLICIT_RELOCS && TARGET_FIX
- && (register_operand (operands[0], DImode)
- || reg_or_0_operand (operands[1], DImode))"
+ "rJ,K,L,T,s,n,s,m,rJ,*fJ, Q,*f,*f, r"))]
+ "register_operand (operands[0], DImode)
+ || reg_or_0_operand (operands[1], DImode)"
"@
mov %r1,%0
lda %0,%1($31)
ldah %0,%h1($31)
#
#
- ldq%A1 %0,%1
- stq%A0 %r1,%0
- fmov %R1,%0
- ldt %0,%1
- stt %R1,%0
- ftoit %1,%0
- itoft %1,%0"
- [(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")
- (set_attr "usegp" "*,*,*,yes,*,*,*,*,*,*,*,*")])
-
-(define_insn "*movdi_fix"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,Q,r,*f")
- (match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,Q,*f,*f,r"))]
- "! TARGET_EXPLICIT_RELOCS && TARGET_FIX
- && (register_operand (operands[0], DImode)
- || reg_or_0_operand (operands[1], DImode))"
- "@
- bis $31,%r1,%0
- lda %0,%1($31)
- ldah %0,%h1($31)
+ #
lda %0,%1
ldq%A1 %0,%1
stq%A0 %r1,%0
- cpys %R1,%R1,%0
+ fmov %R1,%0
ldt %0,%1
stt %R1,%0
ftoit %1,%0
itoft %1,%0"
- [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")])
+ [(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,multi,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")
+ (set_attr "isa" "*,*,*,er,er,*,ner,*,*,*,*,*,fix,fix")
+ (set_attr "usegp" "*,*,*,yes,*,*,*,*,*,*,*,*,*,*")])
;; VMS needs to set up "vms_base_regno" for unwinding. This move
;; often appears dead to the life analysis code, at which point we
-;; abort for emitting dead prologue instructions. Force this live.
+;; die for emitting dead prologue instructions. Force this live.
(define_insn "force_movdi"
[(set (match_operand:DI 0 "register_operand" "=r")
(define_split
[(set (match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "const_int_operand" ""))]
- "! add_operand (operands[1], DImode)"
- [(set (match_dup 0) (match_dup 2))
- (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
+ (match_operand:DI 1 "non_add_const_operand" ""))]
+ ""
+ [(const_int 0)]
{
- rtx tem
- = alpha_emit_set_const (operands[0], DImode, INTVAL (operands[1]), 2);
-
- if (tem == operands[0])
+ if (alpha_split_const_mov (DImode, operands))
DONE;
else
FAIL;
})
+;; We need to prevent reload from splitting TImode moves, because it
+;; might decide to overwrite a pointer with the value it points to.
+;; In that case we have to do the loads in the appropriate order so
+;; that the pointer is not destroyed too early.
+
+(define_insn_and_split "*movti_internal"
+ [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
+ (match_operand:TI 1 "input_operand" "roJ,rJ"))]
+ "(register_operand (operands[0], TImode)
+ /* Prevent rematerialization of constants. */
+ && ! CONSTANT_P (operands[1]))
+ || reg_or_0_operand (operands[1], TImode)"
+ "#"
+ "reload_completed"
+ [(set (match_dup 0) (match_dup 2))
+ (set (match_dup 1) (match_dup 3))]
+{
+ alpha_split_tmode_pair (operands, TImode, true);
+})
+
+(define_expand "movti"
+ [(set (match_operand:TI 0 "nonimmediate_operand" "")
+ (match_operand:TI 1 "general_operand" ""))]
+ ""
+{
+ if (MEM_P (operands[0])
+ && ! reg_or_0_operand (operands[1], TImode))
+ operands[1] = force_reg (TImode, operands[1]);
+
+ if (operands[1] == const0_rtx)
+ ;
+ /* We must put 64-bit constants in memory. We could keep the
+ 32-bit constants in TImode and rely on the splitter, but
+ this doesn't seem to be worth the pain. */
+ else if (CONST_INT_P (operands[1])
+ || GET_CODE (operands[1]) == CONST_DOUBLE)
+ {
+ rtx in[2], out[2], target;
+
+ gcc_assert (can_create_pseudo_p ());
+
+ split_double (operands[1], &in[0], &in[1]);
+
+ if (in[0] == const0_rtx)
+ out[0] = const0_rtx;
+ else
+ {
+ out[0] = gen_reg_rtx (DImode);
+ emit_insn (gen_movdi (out[0], in[0]));
+ }
+
+ if (in[1] == const0_rtx)
+ out[1] = const0_rtx;
+ else
+ {
+ out[1] = gen_reg_rtx (DImode);
+ emit_insn (gen_movdi (out[1], in[1]));
+ }
+
+ if (!REG_P (operands[0]))
+ target = gen_reg_rtx (TImode);
+ else
+ target = operands[0];
+
+ emit_insn (gen_movdi (operand_subword (target, 0, 0, TImode), out[0]));
+ emit_insn (gen_movdi (operand_subword (target, 1, 0, TImode), out[1]));
+
+ if (target != operands[0])
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], target));
+
+ DONE;
+ }
+})
+
;; These are the partial-word cases.
;;
;; First we have the code to load an aligned word. Operand 0 is the register
(define_expand "aligned_loadqi"
[(set (match_operand:SI 3 "register_operand" "")
(match_operand:SI 1 "memory_operand" ""))
- (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
+ (set (match_operand:DI 0 "register_operand" "")
(zero_extract:DI (subreg:DI (match_dup 3) 0)
(const_int 8)
(match_operand:DI 2 "const_int_operand" "")))]
(define_expand "aligned_loadhi"
[(set (match_operand:SI 3 "register_operand" "")
(match_operand:SI 1 "memory_operand" ""))
- (set (subreg:DI (match_operand:HI 0 "register_operand" "") 0)
+ (set (match_operand:DI 0 "register_operand" "")
(zero_extract:DI (subreg:DI (match_dup 3) 0)
(const_int 16)
(match_operand:DI 2 "const_int_operand" "")))]
;; operand 3 can overlap the input and output registers.
(define_expand "unaligned_loadqi"
- [(use (match_operand:QI 0 "register_operand" ""))
- (use (match_operand:DI 1 "address_operand" ""))
- (use (match_operand:DI 2 "register_operand" ""))
- (use (match_operand:DI 3 "register_operand" ""))]
- ""
-{
- if (WORDS_BIG_ENDIAN)
- emit_insn (gen_unaligned_loadqi_be (operands[0], operands[1],
- operands[2], operands[3]));
- else
- emit_insn (gen_unaligned_loadqi_le (operands[0], operands[1],
- operands[2], operands[3]));
- DONE;
-})
-
-(define_expand "unaligned_loadqi_le"
[(set (match_operand:DI 2 "register_operand" "")
(mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
(const_int -8))))
(set (match_operand:DI 3 "register_operand" "")
(match_dup 1))
- (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
+ (set (match_operand:DI 0 "register_operand" "")
(zero_extract:DI (match_dup 2)
(const_int 8)
(ashift:DI (match_dup 3) (const_int 3))))]
- "! WORDS_BIG_ENDIAN"
- "")
-
-(define_expand "unaligned_loadqi_be"
- [(set (match_operand:DI 2 "register_operand" "")
- (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
- (const_int -8))))
- (set (match_operand:DI 3 "register_operand" "")
- (match_dup 1))
- (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
- (zero_extract:DI (match_dup 2)
- (const_int 8)
- (minus:DI
- (const_int 56)
- (ashift:DI (match_dup 3) (const_int 3)))))]
- "WORDS_BIG_ENDIAN"
+ ""
"")
(define_expand "unaligned_loadhi"
- [(use (match_operand:QI 0 "register_operand" ""))
- (use (match_operand:DI 1 "address_operand" ""))
- (use (match_operand:DI 2 "register_operand" ""))
- (use (match_operand:DI 3 "register_operand" ""))]
- ""
-{
- if (WORDS_BIG_ENDIAN)
- emit_insn (gen_unaligned_loadhi_be (operands[0], operands[1],
- operands[2], operands[3]));
- else
- emit_insn (gen_unaligned_loadhi_le (operands[0], operands[1],
- operands[2], operands[3]));
- DONE;
-})
-
-(define_expand "unaligned_loadhi_le"
[(set (match_operand:DI 2 "register_operand" "")
(mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
(const_int -8))))
(set (match_operand:DI 3 "register_operand" "")
(match_dup 1))
- (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
+ (set (match_operand:DI 0 "register_operand" "")
(zero_extract:DI (match_dup 2)
(const_int 16)
(ashift:DI (match_dup 3) (const_int 3))))]
- "! WORDS_BIG_ENDIAN"
- "")
-
-(define_expand "unaligned_loadhi_be"
- [(set (match_operand:DI 2 "register_operand" "")
- (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
- (const_int -8))))
- (set (match_operand:DI 3 "register_operand" "")
- (plus:DI (match_dup 1) (const_int 1)))
- (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
- (zero_extract:DI (match_dup 2)
- (const_int 16)
- (minus:DI
- (const_int 56)
- (ashift:DI (match_dup 3) (const_int 3)))))]
- "WORDS_BIG_ENDIAN"
+ ""
"")
;; Storing an aligned byte or word requires two temporaries. Operand 0 is the
;; operand 2 can be that register.
(define_expand "unaligned_storeqi"
- [(use (match_operand:DI 0 "address_operand" ""))
- (use (match_operand:QI 1 "register_operand" ""))
- (use (match_operand:DI 2 "register_operand" ""))
- (use (match_operand:DI 3 "register_operand" ""))
- (use (match_operand:DI 4 "register_operand" ""))]
- ""
-{
- if (WORDS_BIG_ENDIAN)
- emit_insn (gen_unaligned_storeqi_be (operands[0], operands[1],
- operands[2], operands[3],
- operands[4]));
- else
- emit_insn (gen_unaligned_storeqi_le (operands[0], operands[1],
- operands[2], operands[3],
- operands[4]));
- DONE;
-})
-
-(define_expand "unaligned_storeqi_le"
[(set (match_operand:DI 3 "register_operand" "")
(mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
(const_int -8))))
(set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
(set (mem:DI (and:DI (match_dup 0) (const_int -8)))
(match_dup 4))]
- "! WORDS_BIG_ENDIAN"
- "")
-
-(define_expand "unaligned_storeqi_be"
- [(set (match_operand:DI 3 "register_operand" "")
- (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
- (const_int -8))))
- (set (match_operand:DI 2 "register_operand" "")
- (match_dup 0))
- (set (match_dup 3)
- (and:DI (not:DI (ashift:DI (const_int 255)
- (minus:DI (const_int 56)
- (ashift:DI (match_dup 2) (const_int 3)))))
- (match_dup 3)))
- (set (match_operand:DI 4 "register_operand" "")
- (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" ""))
- (minus:DI (const_int 56)
- (ashift:DI (match_dup 2) (const_int 3)))))
- (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
- (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
- (match_dup 4))]
- "WORDS_BIG_ENDIAN"
+ ""
"")
(define_expand "unaligned_storehi"
- [(use (match_operand:DI 0 "address_operand" ""))
- (use (match_operand:HI 1 "register_operand" ""))
- (use (match_operand:DI 2 "register_operand" ""))
- (use (match_operand:DI 3 "register_operand" ""))
- (use (match_operand:DI 4 "register_operand" ""))]
- ""
-{
- if (WORDS_BIG_ENDIAN)
- emit_insn (gen_unaligned_storehi_be (operands[0], operands[1],
- operands[2], operands[3],
- operands[4]));
- else
- emit_insn (gen_unaligned_storehi_le (operands[0], operands[1],
- operands[2], operands[3],
- operands[4]));
- DONE;
-})
-
-(define_expand "unaligned_storehi_le"
[(set (match_operand:DI 3 "register_operand" "")
(mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
(const_int -8))))
(set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
(set (mem:DI (and:DI (match_dup 0) (const_int -8)))
(match_dup 4))]
- "! WORDS_BIG_ENDIAN"
+ ""
"")
-(define_expand "unaligned_storehi_be"
- [(set (match_operand:DI 3 "register_operand" "")
- (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
- (const_int -8))))
- (set (match_operand:DI 2 "register_operand" "")
- (plus:DI (match_dup 0) (const_int 1)))
- (set (match_dup 3)
- (and:DI (not:DI (ashift:DI
- (const_int 65535)
- (minus:DI (const_int 56)
- (ashift:DI (match_dup 2) (const_int 3)))))
- (match_dup 3)))
- (set (match_operand:DI 4 "register_operand" "")
- (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" ""))
- (minus:DI (const_int 56)
- (ashift:DI (match_dup 2) (const_int 3)))))
- (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
- (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
- (match_dup 4))]
- "WORDS_BIG_ENDIAN"
- "")
-\f
;; 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
;; registers for reload.
DONE;
})
+(define_insn "*movqi"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m")
+ (match_operand:QI 1 "input_operand" "rJ,n,m,rJ"))]
+ "register_operand (operands[0], QImode)
+ || reg_or_0_operand (operands[1], QImode)"
+ "@
+ bis $31,%r1,%0
+ lda %0,%L1($31)
+ ldbu %0,%1
+ stb %r1,%0"
+ [(set_attr "type" "ilog,iadd,ild,ist")
+ (set_attr "isa" "*,*,bwx,bwx")])
+
(define_expand "movhi"
[(set (match_operand:HI 0 "nonimmediate_operand" "")
(match_operand:HI 1 "general_operand" ""))]
DONE;
})
-;; Here are the versions for reload. Note that in the unaligned cases
-;; we know that the operand must not be a pseudo-register because stack
-;; slots are always aligned references.
-
-(define_expand "reload_inqi"
- [(parallel [(match_operand:QI 0 "register_operand" "=r")
- (match_operand:QI 1 "any_memory_operand" "m")
- (match_operand:TI 2 "register_operand" "=&r")])]
- "! TARGET_BWX"
-{
- rtx scratch, seq;
-
- if (GET_CODE (operands[1]) != MEM)
- abort ();
-
- if (aligned_memory_operand (operands[1], QImode))
+(define_insn "*movhi"
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
+ (match_operand:HI 1 "input_operand" "rJ,n,m,rJ"))]
+ "register_operand (operands[0], HImode)
+ || reg_or_0_operand (operands[1], HImode)"
+ "@
+ bis $31,%r1,%0
+ lda %0,%L1($31)
+ ldwu %0,%1
+ stw %r1,%0"
+ [(set_attr "type" "ilog,iadd,ild,ist")
+ (set_attr "isa" "*,*,bwx,bwx")])
+
+;; We need to hook into the extra support that we have for HImode
+;; reloads when BWX insns are not available.
+(define_expand "movcqi"
+ [(set (match_operand:CQI 0 "nonimmediate_operand" "")
+ (match_operand:CQI 1 "general_operand" ""))]
+ "!TARGET_BWX"
+{
+ if (GET_CODE (operands[0]) == CONCAT || GET_CODE (operands[1]) == CONCAT)
+ ;
+ else if (!any_memory_operand (operands[0], CQImode))
{
- seq = gen_reload_inqi_help (operands[0], operands[1],
- gen_rtx_REG (SImode, REGNO (operands[2])));
+ if (!any_memory_operand (operands[1], CQImode))
+ {
+ emit_move_insn (gen_lowpart (HImode, operands[0]),
+ gen_lowpart (HImode, operands[1]));
+ DONE;
+ }
+ if (aligned_memory_operand (operands[1], CQImode))
+ {
+ bool done;
+ do_aligned1:
+ operands[1] = gen_lowpart (HImode, operands[1]);
+ do_aligned2:
+ operands[0] = gen_lowpart (HImode, operands[0]);
+ done = alpha_expand_mov_nobwx (HImode, operands);
+ gcc_assert (done);
+ DONE;
+ }
}
- else
+ else if (aligned_memory_operand (operands[0], CQImode))
{
- rtx addr;
-
- /* It is possible that one of the registers we got for operands[2]
- might coincide with that of operands[0] (which is why we made
- it TImode). Pick the other one to use as our scratch. */
- if (REGNO (operands[0]) == REGNO (operands[2]))
- scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
- else
- scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
-
- addr = get_unaligned_address (operands[1], 0);
- seq = gen_unaligned_loadqi (operands[0], addr, scratch,
- gen_rtx_REG (DImode, REGNO (operands[0])));
- alpha_set_memflags (seq, operands[1]);
+ if (MEM_P (operands[1]))
+ {
+ rtx x = gen_reg_rtx (HImode);
+ emit_move_insn (gen_lowpart (CQImode, x), operands[1]);
+ operands[1] = x;
+ goto do_aligned2;
+ }
+ goto do_aligned1;
}
- emit_insn (seq);
+
+ gcc_assert (!reload_in_progress);
+ emit_move_complex_parts (operands[0], operands[1]);
DONE;
})
-(define_expand "reload_inhi"
- [(parallel [(match_operand:HI 0 "register_operand" "=r")
- (match_operand:HI 1 "any_memory_operand" "m")
+;; Here are the versions for reload.
+;;
+;; The aligned input case is recognized early in alpha_secondary_reload
+;; in order to avoid allocating an unnecessary scratch register.
+;;
+;; Note that in the unaligned cases we know that the operand must not be
+;; a pseudo-register because stack slots are always aligned references.
+
+(define_expand "reload_in<mode>"
+ [(parallel [(match_operand:RELOAD12 0 "register_operand" "=r")
+ (match_operand:RELOAD12 1 "any_memory_operand" "m")
(match_operand:TI 2 "register_operand" "=&r")])]
- "! TARGET_BWX"
+ "!TARGET_BWX"
{
- rtx scratch, seq;
-
- if (GET_CODE (operands[1]) != MEM)
- abort ();
+ rtx scratch, seq, addr;
+ unsigned regno = REGNO (operands[2]);
- if (aligned_memory_operand (operands[1], HImode))
- {
- seq = gen_reload_inhi_help (operands[0], operands[1],
- gen_rtx_REG (SImode, REGNO (operands[2])));
- }
- else
- {
- rtx addr;
+ /* It is possible that one of the registers we got for operands[2]
+ might coincide with that of operands[0] (which is why we made
+ it TImode). Pick the other one to use as our scratch. */
+ if (regno == REGNO (operands[0]))
+ regno++;
+ scratch = gen_rtx_REG (DImode, regno);
- /* It is possible that one of the registers we got for operands[2]
- might coincide with that of operands[0] (which is why we made
- it TImode). Pick the other one to use as our scratch. */
- if (REGNO (operands[0]) == REGNO (operands[2]))
- scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
- else
- scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
+ addr = get_unaligned_address (operands[1]);
+ operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
+ seq = gen_unaligned_load<reloadmode> (operands[0], addr,
+ scratch, operands[0]);
+ alpha_set_memflags (seq, operands[1]);
- addr = get_unaligned_address (operands[1], 0);
- seq = gen_unaligned_loadhi (operands[0], addr, scratch,
- gen_rtx_REG (DImode, REGNO (operands[0])));
- alpha_set_memflags (seq, operands[1]);
- }
emit_insn (seq);
DONE;
})
-(define_expand "reload_outqi"
- [(parallel [(match_operand:QI 0 "any_memory_operand" "=m")
- (match_operand:QI 1 "register_operand" "r")
+(define_expand "reload_out<mode>"
+ [(parallel [(match_operand:RELOAD12 0 "any_memory_operand" "=m")
+ (match_operand:RELOAD12 1 "register_operand" "r")
(match_operand:TI 2 "register_operand" "=&r")])]
- "! TARGET_BWX"
+ "!TARGET_BWX"
{
- if (GET_CODE (operands[0]) != MEM)
- abort ();
+ unsigned regno = REGNO (operands[2]);
- if (aligned_memory_operand (operands[0], QImode))
+ if (<MODE>mode == CQImode)
{
- emit_insn (gen_reload_outqi_help
- (operands[0], operands[1],
- gen_rtx_REG (SImode, REGNO (operands[2])),
- gen_rtx_REG (SImode, REGNO (operands[2]) + 1)));
+ operands[0] = gen_lowpart (HImode, operands[0]);
+ operands[1] = gen_lowpart (HImode, operands[1]);
}
- else
- {
- rtx addr = get_unaligned_address (operands[0], 0);
- rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2]));
- rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
- rtx scratch3 = scratch1;
- rtx seq;
- if (GET_CODE (addr) == REG)
- scratch1 = addr;
-
- seq = gen_unaligned_storeqi (addr, operands[1], scratch1,
- scratch2, scratch3);
- alpha_set_memflags (seq, operands[0]);
- emit_insn (seq);
- }
- DONE;
-})
-
-(define_expand "reload_outhi"
- [(parallel [(match_operand:HI 0 "any_memory_operand" "=m")
- (match_operand:HI 1 "register_operand" "r")
- (match_operand:TI 2 "register_operand" "=&r")])]
- "! TARGET_BWX"
-{
- if (GET_CODE (operands[0]) != MEM)
- abort ();
-
- if (aligned_memory_operand (operands[0], HImode))
+ if (aligned_memory_operand (operands[0], <MODE>mode))
{
- emit_insn (gen_reload_outhi_help
+ emit_insn (gen_reload_out<reloadmode>_aligned
(operands[0], operands[1],
- gen_rtx_REG (SImode, REGNO (operands[2])),
- gen_rtx_REG (SImode, REGNO (operands[2]) + 1)));
+ gen_rtx_REG (SImode, regno),
+ gen_rtx_REG (SImode, regno + 1)));
}
else
{
- rtx addr = get_unaligned_address (operands[0], 0);
- rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2]));
- rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
+ rtx addr = get_unaligned_address (operands[0]);
+ rtx scratch1 = gen_rtx_REG (DImode, regno);
+ rtx scratch2 = gen_rtx_REG (DImode, regno + 1);
rtx scratch3 = scratch1;
rtx seq;
- if (GET_CODE (addr) == REG)
+ if (REG_P (addr))
scratch1 = addr;
- seq = gen_unaligned_storehi (addr, operands[1], scratch1,
- scratch2, scratch3);
+ seq = gen_unaligned_store<reloadmode> (addr, operands[1], scratch1,
+ scratch2, scratch3);
alpha_set_memflags (seq, operands[0]);
emit_insn (seq);
}
;; always get a proper address for a stack slot during reload_foo
;; expansion, so we must delay our address manipulations until after.
-(define_insn "reload_inqi_help"
- [(set (match_operand:QI 0 "register_operand" "=r")
- (match_operand:QI 1 "memory_operand" "m"))
- (clobber (match_operand:SI 2 "register_operand" "=r"))]
- "! TARGET_BWX && (reload_in_progress || reload_completed)"
- "#")
-
-(define_insn "reload_inhi_help"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (match_operand:HI 1 "memory_operand" "m"))
- (clobber (match_operand:SI 2 "register_operand" "=r"))]
- "! TARGET_BWX && (reload_in_progress || reload_completed)"
- "#")
-
-(define_insn "reload_outqi_help"
- [(set (match_operand:QI 0 "memory_operand" "=m")
- (match_operand:QI 1 "register_operand" "r"))
- (clobber (match_operand:SI 2 "register_operand" "=r"))
- (clobber (match_operand:SI 3 "register_operand" "=r"))]
- "! TARGET_BWX && (reload_in_progress || reload_completed)"
- "#")
-
-(define_insn "reload_outhi_help"
- [(set (match_operand:HI 0 "memory_operand" "=m")
- (match_operand:HI 1 "register_operand" "r"))
- (clobber (match_operand:SI 2 "register_operand" "=r"))
- (clobber (match_operand:SI 3 "register_operand" "=r"))]
- "! TARGET_BWX && (reload_in_progress || reload_completed)"
- "#")
-
-(define_split
- [(set (match_operand:QI 0 "register_operand" "")
- (match_operand:QI 1 "memory_operand" ""))
- (clobber (match_operand:SI 2 "register_operand" ""))]
- "! TARGET_BWX && reload_completed"
- [(const_int 0)]
-{
- rtx aligned_mem, bitnum;
- get_aligned_mem (operands[1], &aligned_mem, &bitnum);
-
- emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
- operands[2]));
- DONE;
-})
-
-(define_split
- [(set (match_operand:HI 0 "register_operand" "")
- (match_operand:HI 1 "memory_operand" ""))
- (clobber (match_operand:SI 2 "register_operand" ""))]
- "! TARGET_BWX && reload_completed"
+(define_insn_and_split "reload_in<mode>_aligned"
+ [(set (match_operand:I12MODE 0 "register_operand" "=r")
+ (match_operand:I12MODE 1 "memory_operand" "m"))]
+ "!TARGET_BWX && (reload_in_progress || reload_completed)"
+ "#"
+ "!TARGET_BWX && reload_completed"
[(const_int 0)]
{
rtx aligned_mem, bitnum;
get_aligned_mem (operands[1], &aligned_mem, &bitnum);
-
- emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
- operands[2]));
- DONE;
-})
-
-(define_split
- [(set (match_operand:QI 0 "memory_operand" "")
- (match_operand:QI 1 "register_operand" ""))
- (clobber (match_operand:SI 2 "register_operand" ""))
- (clobber (match_operand:SI 3 "register_operand" ""))]
- "! TARGET_BWX && reload_completed"
- [(const_int 0)]
-{
- rtx aligned_mem, bitnum;
- get_aligned_mem (operands[0], &aligned_mem, &bitnum);
- emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
- operands[2], operands[3]));
+ emit_insn (gen_aligned_load<reloadmode>
+ (gen_lowpart (DImode, operands[0]), aligned_mem, bitnum,
+ gen_rtx_REG (SImode, REGNO (operands[0]))));
DONE;
})
-(define_split
- [(set (match_operand:HI 0 "memory_operand" "")
- (match_operand:HI 1 "register_operand" ""))
- (clobber (match_operand:SI 2 "register_operand" ""))
- (clobber (match_operand:SI 3 "register_operand" ""))]
- "! TARGET_BWX && reload_completed"
+(define_insn_and_split "reload_out<mode>_aligned"
+ [(set (match_operand:I12MODE 0 "memory_operand" "=m")
+ (match_operand:I12MODE 1 "register_operand" "r"))
+ (clobber (match_operand:SI 2 "register_operand" "=r"))
+ (clobber (match_operand:SI 3 "register_operand" "=r"))]
+ "!TARGET_BWX && (reload_in_progress || reload_completed)"
+ "#"
+ "!TARGET_BWX && reload_completed"
[(const_int 0)]
{
rtx aligned_mem, bitnum;
\f
;; Vector operations
-(define_expand "movv8qi"
- [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
- (match_operand:V8QI 1 "general_operand" ""))]
+(define_mode_iterator VEC [V8QI V4HI V2SI])
+
+(define_expand "mov<mode>"
+ [(set (match_operand:VEC 0 "nonimmediate_operand" "")
+ (match_operand:VEC 1 "general_operand" ""))]
""
{
- if (alpha_expand_mov (V8QImode, operands))
+ if (alpha_expand_mov (<MODE>mode, operands))
DONE;
})
-(define_insn "*movv8qi_fix"
- [(set (match_operand:V8QI 0 "nonimmediate_operand" "=r,r,m,*f,*f,m,r,*f")
- (match_operand:V8QI 1 "input_operand" "rW,m,rW,*fW,m,*f,*f,r"))]
- "TARGET_FIX
- && (register_operand (operands[0], V8QImode)
- || reg_or_0_operand (operands[1], V8QImode))"
- "@
- bis $31,%r1,%0
- ldq %0,%1
- stq %r1,%0
- cpys %R1,%R1,%0
- ldt %0,%1
- stt %R1,%0
- ftoit %1,%0
- itoft %1,%0"
- [(set_attr "type" "ilog,ild,ist,fcpys,fld,fst,ftoi,itof")])
-
-(define_insn "*movv8qi_nofix"
- [(set (match_operand:V8QI 0 "nonimmediate_operand" "=r,r,m,*f,*f,m")
- (match_operand:V8QI 1 "input_operand" "rW,m,rW,*fW,m,*f"))]
- "! TARGET_FIX
- && (register_operand (operands[0], V8QImode)
- || reg_or_0_operand (operands[1], V8QImode))"
- "@
- bis $31,%r1,%0
- ldq %0,%1
- stq %r1,%0
- cpys %R1,%R1,%0
- ldt %0,%1
- stt %R1,%0"
- [(set_attr "type" "ilog,ild,ist,fcpys,fld,fst")])
-
-(define_expand "movv4hi"
- [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
- (match_operand:V4HI 1 "general_operand" ""))]
+(define_split
+ [(set (match_operand:VEC 0 "register_operand" "")
+ (match_operand:VEC 1 "non_zero_const_operand" ""))]
""
+ [(const_int 0)]
{
- if (alpha_expand_mov (V4HImode, operands))
+ if (alpha_split_const_mov (<MODE>mode, operands))
DONE;
+ else
+ FAIL;
})
-(define_insn "*movv4hi_fix"
- [(set (match_operand:V4HI 0 "nonimmediate_operand" "=r,r,m,*f,*f,m,r,*f")
- (match_operand:V4HI 1 "input_operand" "rW,m,rW,*fW,m,*f,*f,r"))]
- "TARGET_FIX
- && (register_operand (operands[0], V4HImode)
- || reg_or_0_operand (operands[1], V4HImode))"
- "@
- bis $31,%r1,%0
- ldq %0,%1
- stq %r1,%0
- cpys %R1,%R1,%0
- ldt %0,%1
- stt %R1,%0
- ftoit %1,%0
- itoft %1,%0"
- [(set_attr "type" "ilog,ild,ist,fcpys,fld,fst,ftoi,itof")])
-
-(define_insn "*movv4hi_nofix"
- [(set (match_operand:V4HI 0 "nonimmediate_operand" "=r,r,m,*f,*f,m")
- (match_operand:V4HI 1 "input_operand" "rW,m,rW,*fW,m,*f"))]
- "! TARGET_FIX
- && (register_operand (operands[0], V4HImode)
- || reg_or_0_operand (operands[1], V4HImode))"
- "@
- bis $31,%r1,%0
- ldq %0,%1
- stq %r1,%0
- cpys %R1,%R1,%0
- ldt %0,%1
- stt %R1,%0"
- [(set_attr "type" "ilog,ild,ist,fcpys,fld,fst")])
-(define_expand "movv2si"
- [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
- (match_operand:V2SI 1 "general_operand" ""))]
+(define_expand "movmisalign<mode>"
+ [(set (match_operand:VEC 0 "nonimmediate_operand" "")
+ (match_operand:VEC 1 "general_operand" ""))]
""
{
- if (alpha_expand_mov (V2SImode, operands))
- DONE;
+ alpha_expand_movmisalign (<MODE>mode, operands);
+ DONE;
})
-(define_insn "*movv2si_fix"
- [(set (match_operand:V2SI 0 "nonimmediate_operand" "=r,r,m,*f,*f,m,r,*f")
- (match_operand:V2SI 1 "input_operand" "rW,m,rW,*fW,m,*f,*f,r"))]
- "TARGET_FIX
- && (register_operand (operands[0], V2SImode)
- || reg_or_0_operand (operands[1], V2SImode))"
+(define_insn "*mov<mode>_fix"
+ [(set (match_operand:VEC 0 "nonimmediate_operand" "=r,r,r,m,*f,*f,m,r,*f")
+ (match_operand:VEC 1 "input_operand" "rW,i,m,rW,*fW,m,*f,*f,r"))]
+ "register_operand (operands[0], <MODE>mode)
+ || reg_or_0_operand (operands[1], <MODE>mode)"
"@
bis $31,%r1,%0
+ #
ldq %0,%1
stq %r1,%0
cpys %R1,%R1,%0
stt %R1,%0
ftoit %1,%0
itoft %1,%0"
- [(set_attr "type" "ilog,ild,ist,fcpys,fld,fst,ftoi,itof")])
-
-(define_insn "*movv2si_nofix"
- [(set (match_operand:V2SI 0 "nonimmediate_operand" "=r,r,m,*f,*f,m")
- (match_operand:V2SI 1 "input_operand" "rW,m,rW,*fW,m,*f"))]
- "! TARGET_FIX
- && (register_operand (operands[0], V2SImode)
- || reg_or_0_operand (operands[1], V2SImode))"
- "@
- bis $31,%r1,%0
- ldq %0,%1
- stq %r1,%0
- cpys %R1,%R1,%0
- ldt %0,%1
- stt %R1,%0"
- [(set_attr "type" "ilog,ild,ist,fcpys,fld,fst")])
+ [(set_attr "type" "ilog,multi,ild,ist,fcpys,fld,fst,ftoi,itof")
+ (set_attr "isa" "*,*,*,*,*,*,*,fix,fix")])
(define_insn "uminv8qi3"
[(set (match_operand:V8QI 0 "register_operand" "=r")
"TARGET_MAX"
"maxsw4 %r1,%r2,%0"
[(set_attr "type" "mvi")])
+
+(define_insn "one_cmpl<mode>2"
+ [(set (match_operand:VEC 0 "register_operand" "=r")
+ (not:VEC (match_operand:VEC 1 "register_operand" "r")))]
+ ""
+ "ornot $31,%1,%0"
+ [(set_attr "type" "ilog")])
+
+(define_insn "and<mode>3"
+ [(set (match_operand:VEC 0 "register_operand" "=r")
+ (and:VEC (match_operand:VEC 1 "register_operand" "r")
+ (match_operand:VEC 2 "register_operand" "r")))]
+ ""
+ "and %1,%2,%0"
+ [(set_attr "type" "ilog")])
+
+(define_insn "*andnot<mode>3"
+ [(set (match_operand:VEC 0 "register_operand" "=r")
+ (and:VEC (not:VEC (match_operand:VEC 1 "register_operand" "r"))
+ (match_operand:VEC 2 "register_operand" "r")))]
+ ""
+ "bic %2,%1,%0"
+ [(set_attr "type" "ilog")])
+
+(define_insn "ior<mode>3"
+ [(set (match_operand:VEC 0 "register_operand" "=r")
+ (ior:VEC (match_operand:VEC 1 "register_operand" "r")
+ (match_operand:VEC 2 "register_operand" "r")))]
+ ""
+ "bis %1,%2,%0"
+ [(set_attr "type" "ilog")])
+
+(define_insn "*iornot<mode>3"
+ [(set (match_operand:VEC 0 "register_operand" "=r")
+ (ior:VEC (not:DI (match_operand:VEC 1 "register_operand" "r"))
+ (match_operand:VEC 2 "register_operand" "r")))]
+ ""
+ "ornot %2,%1,%0"
+ [(set_attr "type" "ilog")])
+
+(define_insn "xor<mode>3"
+ [(set (match_operand:VEC 0 "register_operand" "=r")
+ (xor:VEC (match_operand:VEC 1 "register_operand" "r")
+ (match_operand:VEC 2 "register_operand" "r")))]
+ ""
+ "xor %1,%2,%0"
+ [(set_attr "type" "ilog")])
+
+(define_insn "*xornot<mode>3"
+ [(set (match_operand:VEC 0 "register_operand" "=r")
+ (not:VEC (xor:VEC (match_operand:VEC 1 "register_operand" "r")
+ (match_operand:VEC 2 "register_operand" "r"))))]
+ ""
+ "eqv %1,%2,%0"
+ [(set_attr "type" "ilog")])
+
+(define_expand "vec_shl_<mode>"
+ [(set (match_operand:VEC 0 "register_operand" "")
+ (ashift:DI (match_operand:VEC 1 "register_operand" "")
+ (match_operand:DI 2 "reg_or_6bit_operand" "")))]
+ ""
+{
+ operands[0] = gen_lowpart (DImode, operands[0]);
+ operands[1] = gen_lowpart (DImode, operands[1]);
+})
+
+(define_expand "vec_shr_<mode>"
+ [(set (match_operand:VEC 0 "register_operand" "")
+ (lshiftrt:DI (match_operand:VEC 1 "register_operand" "")
+ (match_operand:DI 2 "reg_or_6bit_operand" "")))]
+ ""
+{
+ operands[0] = gen_lowpart (DImode, operands[0]);
+ operands[1] = gen_lowpart (DImode, operands[1]);
+})
\f
;; Bit field extract patterns which use ext[wlq][lh]
/* From mips.md: extract_bit_field doesn't verify that our source
matches the predicate, so we force it to be a MEM here. */
- if (GET_CODE (operands[1]) != MEM)
+ if (!MEM_P (operands[1]))
FAIL;
- /* 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
- that the bit number is negative in big-endian mode in this case.
- We have to convert that to the offset. */
- if (WORDS_BIG_ENDIAN)
- ofs = GET_MODE_BITSIZE (GET_MODE (operands[1]))
- - INTVAL (operands[2]) - INTVAL (operands[3]);
- else
- ofs = INTVAL (operands[3]);
-
+ ofs = INTVAL (operands[3]);
ofs = ofs / 8;
alpha_expand_unaligned_load (operands[0], operands[1],
&& INTVAL (operands[2]) != 64))
FAIL;
- if (GET_CODE (operands[1]) == MEM)
+ if (MEM_P (operands[1]))
{
int ofs;
- /* Fail 8 bit fields, falling back on a simple byte load. */
+ /* Fail 8-bit fields, falling back on a simple byte load. */
if (INTVAL (operands[2]) == 8)
FAIL;
- /* 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
- that the bit number is negative in big-endian mode in this case.
- We have to convert that to the offset. */
- if (WORDS_BIG_ENDIAN)
- ofs = GET_MODE_BITSIZE (GET_MODE (operands[1]))
- - INTVAL (operands[2]) - INTVAL (operands[3]);
- else
- ofs = INTVAL (operands[3]);
-
+ ofs = INTVAL (operands[3]);
ofs = ofs / 8;
alpha_expand_unaligned_load (operands[0], operands[1],
/* From mips.md: store_bit_field doesn't verify that our source
matches the predicate, so we force it to be a MEM here. */
- if (GET_CODE (operands[0]) != MEM)
+ if (!MEM_P (operands[0]))
FAIL;
- /* 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
- that the bit number is negative in big-endian mode in this case.
- We have to convert that to the offset. */
- if (WORDS_BIG_ENDIAN)
- ofs = GET_MODE_BITSIZE (GET_MODE (operands[0]))
- - INTVAL (operands[1]) - INTVAL (operands[2]);
- else
- ofs = INTVAL (operands[2]);
-
+ ofs = INTVAL (operands[2]);
ofs = ofs / 8;
alpha_expand_unaligned_store (operands[0], operands[3],
;; Argument 2 is the length
;; Argument 3 is the alignment
-(define_expand "movstrqi"
+(define_expand "movmemqi"
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
(match_operand:BLK 1 "memory_operand" ""))
(use (match_operand:DI 2 "immediate_operand" ""))
FAIL;
})
-(define_expand "movstrdi"
+(define_expand "movmemdi"
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
(match_operand:BLK 1 "memory_operand" ""))
(use (match_operand:DI 2 "immediate_operand" ""))
"TARGET_ABI_OPEN_VMS"
{
operands[4] = gen_rtx_SYMBOL_REF (Pmode, "OTS$MOVE");
- alpha_need_linkage (XSTR (operands[4], 0), 0);
})
-(define_insn "*movstrdi_1"
+(define_insn "*movmemdi_1"
[(set (match_operand:BLK 0 "memory_operand" "=m,=m")
(match_operand:BLK 1 "memory_operand" "m,m"))
(use (match_operand:DI 2 "nonmemory_operand" "r,i"))
(clobber (reg:DI 27))]
"TARGET_ABI_OPEN_VMS"
{
- operands [5] = alpha_use_linkage (operands [4], cfun->decl, 0, 1);
+ operands [5] = alpha_use_linkage (operands [4], false, true);
switch (which_alternative)
{
case 0:
case 1:
return "lda $16,%0\;lda $17,%2($31)\;lda $18,%1\;ldq $26,%5\;lda $25,3($31)\;jsr $26,%4\;ldq $27,0($29)";
default:
- abort();
+ gcc_unreachable ();
}
}
[(set_attr "type" "multi")
(set_attr "length" "28")])
-(define_expand "clrstrqi"
+(define_expand "setmemqi"
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
- (const_int 0))
+ (match_operand 2 "const_int_operand" ""))
(use (match_operand:DI 1 "immediate_operand" ""))
- (use (match_operand:DI 2 "immediate_operand" ""))])]
+ (use (match_operand:DI 3 "immediate_operand" ""))])]
""
{
+ /* If value to set is not zero, use the library routine. */
+ if (operands[2] != const0_rtx)
+ FAIL;
+
if (alpha_expand_block_clear (operands))
DONE;
else
FAIL;
})
-(define_expand "clrstrdi"
+(define_expand "setmemdi"
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
- (const_int 0))
+ (match_operand 2 "const_int_operand" ""))
(use (match_operand:DI 1 "immediate_operand" ""))
- (use (match_operand:DI 2 "immediate_operand" ""))
- (use (match_dup 3))
+ (use (match_operand:DI 3 "immediate_operand" ""))
+ (use (match_dup 4))
(clobber (reg:DI 25))
(clobber (reg:DI 16))
(clobber (reg:DI 17))
(clobber (reg:DI 27))])]
"TARGET_ABI_OPEN_VMS"
{
- operands[3] = gen_rtx_SYMBOL_REF (Pmode, "OTS$ZERO");
- alpha_need_linkage (XSTR (operands[3], 0), 0);
+ /* If value to set is not zero, use the library routine. */
+ if (operands[2] != const0_rtx)
+ FAIL;
+
+ operands[4] = gen_rtx_SYMBOL_REF (Pmode, "OTS$ZERO");
})
-(define_insn "*clrstrdi_1"
+(define_insn "*clrmemdi_1"
[(set (match_operand:BLK 0 "memory_operand" "=m,=m")
(const_int 0))
(use (match_operand:DI 1 "nonmemory_operand" "r,i"))
(clobber (reg:DI 27))]
"TARGET_ABI_OPEN_VMS"
{
- operands [4] = alpha_use_linkage (operands [3], cfun->decl, 0, 1);
+ operands [4] = alpha_use_linkage (operands [3], false, true);
switch (which_alternative)
{
case 0:
case 1:
return "lda $16,%0\;lda $17,%1($31)\;ldq $26,%4\;lda $25,2($31)\;jsr $26,%3\;ldq $27,0($29)";
default:
- abort();
+ gcc_unreachable ();
}
}
[(set_attr "type" "multi")
(match_dup 2))]
""
{
- if (GET_CODE (operands[1]) == CONST_INT
+ if (CONST_INT_P (operands[1])
&& INTVAL (operands[1]) < 32768)
{
if (INTVAL (operands[1]) >= 4096)
rtx loop_label = gen_label_rtx ();
rtx want = gen_reg_rtx (Pmode);
rtx tmp = gen_reg_rtx (Pmode);
- rtx memref;
+ rtx memref, test;
emit_insn (gen_subdi3 (want, stack_pointer_rtx,
force_reg (Pmode, operands[1])));
- emit_insn (gen_adddi3 (tmp, stack_pointer_rtx, GEN_INT (-4096)));
- if (GET_CODE (operands[1]) != CONST_INT)
+ if (!CONST_INT_P (operands[1]))
{
+ rtx limit = GEN_INT (4096);
out_label = gen_label_rtx ();
- emit_insn (gen_cmpdi (want, tmp));
- emit_jump_insn (gen_bgeu (out_label));
+ test = gen_rtx_LTU (VOIDmode, operands[1], limit);
+ emit_jump_insn
+ (gen_cbranchdi4 (test, operands[1], limit, out_label));
}
+ emit_insn (gen_adddi3 (tmp, stack_pointer_rtx, GEN_INT (-4096)));
emit_label (loop_label);
memref = gen_rtx_MEM (DImode, tmp);
MEM_VOLATILE_P (memref) = 1;
emit_move_insn (memref, const0_rtx);
emit_insn (gen_adddi3 (tmp, tmp, GEN_INT(-8192)));
- emit_insn (gen_cmpdi (tmp, want));
- emit_jump_insn (gen_bgtu (loop_label));
+ test = gen_rtx_GTU (VOIDmode, tmp, want);
+ emit_jump_insn (gen_cbranchdi4 (test, tmp, want, loop_label));
memref = gen_rtx_MEM (DImode, want);
MEM_VOLATILE_P (memref) = 1;
(match_operand 2 "const_int_operand" "")]
UNSPECV_LDGP1))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
- "ldah %0,0(%1)\t\t!gpdisp!%2")
+ "ldah %0,0(%1)\t\t!gpdisp!%2"
+ [(set_attr "cannot_copy" "true")])
(define_insn "*ldgp_er_2"
[(set (match_operand:DI 0 "register_operand" "=r")
(match_operand 2 "const_int_operand" "")]
UNSPEC_LDGP2))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
- "lda %0,0(%1)\t\t!gpdisp!%2")
+ "lda %0,0(%1)\t\t!gpdisp!%2"
+ [(set_attr "cannot_copy" "true")])
(define_insn "*prologue_ldgp_er_2"
[(set (match_operand:DI 0 "register_operand" "=r")
(match_operand 2 "const_int_operand" "")]
UNSPECV_PLDGP2))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
- "lda %0,0(%1)\t\t!gpdisp!%2\n$%~..ng:")
+ "lda %0,0(%1)\t\t!gpdisp!%2\n$%~..ng:"
+ [(set_attr "cannot_copy" "true")])
(define_insn "*prologue_ldgp_1"
[(set (match_operand:DI 0 "register_operand" "=r")
(match_operand 2 "const_int_operand" "")]
UNSPECV_LDGP1))]
""
- "ldgp %0,0(%1)\n$%~..ng:")
+ "ldgp %0,0(%1)\n$%~..ng:"
+ [(set_attr "cannot_copy" "true")])
(define_insn "*prologue_ldgp_2"
[(set (match_operand:DI 0 "register_operand" "=r")
DONE;
})
-;; In creating a large stack frame, NT _must_ use ldah+lda to load
-;; the frame size into a register. We use this pattern to ensure
-;; we get lda instead of addq.
-(define_insn "nt_lda"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (unspec:DI [(match_dup 0)
- (match_operand:DI 1 "const_int_operand" "n")]
- UNSPEC_NT_LDA))]
- ""
- "lda %0,%1(%0)")
-
(define_expand "builtin_longjmp"
[(use (match_operand:DI 0 "register_operand" "r"))]
"TARGET_ABI_OSF"
/* This bit is the same as expand_builtin_longjmp. */
emit_move_insn (hard_frame_pointer_rtx, fp);
emit_move_insn (pv, lab);
- emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
- emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
- emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
+ emit_stack_restore (SAVE_NONLOCAL, stack);
+ emit_use (hard_frame_pointer_rtx);
+ emit_use (stack_pointer_rtx);
/* Load the label we are jumping through into $27 so that we know
where to look for it when we get back to setjmp's function for
"jmp $31,(%0),0"
[(set_attr "type" "ibr")])
-(define_insn "*builtin_setjmp_receiver_er_sl_1"
- [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
- "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && TARGET_AS_CAN_SUBTRACT_LABELS"
- "lda $27,$LSJ%=-%l0($27)\n$LSJ%=:")
-
-(define_insn "*builtin_setjmp_receiver_er_1"
- [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
- "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
- "br $27,$LSJ%=\n$LSJ%=:"
- [(set_attr "type" "ibr")])
-
-(define_split
- [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
- "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
- && prev_nonnote_insn (insn) == operands[0]"
- [(const_int 0)]
- "
-{
- emit_note (NOTE_INSN_DELETED);
- DONE;
-}")
-
-(define_insn "*builtin_setjmp_receiver_1"
+(define_expand "builtin_setjmp_receiver"
[(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
"TARGET_ABI_OSF"
- "br $27,$LSJ%=\n$LSJ%=:\;ldgp $29,0($27)"
- [(set_attr "length" "12")
- (set_attr "type" "multi")])
+ "")
-(define_expand "builtin_setjmp_receiver_er"
- [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)
- (set (match_dup 1)
+(define_insn_and_split "*builtin_setjmp_receiver_1"
+ [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR)]
+ "TARGET_ABI_OSF"
+{
+ if (TARGET_EXPLICIT_RELOCS)
+ return "#";
+ else
+ return "br $27,$LSJ%=\n$LSJ%=:\;ldgp $29,0($27)";
+}
+ "&& TARGET_EXPLICIT_RELOCS && reload_completed"
+ [(set (match_dup 1)
(unspec_volatile:DI [(match_dup 2) (match_dup 3)] UNSPECV_LDGP1))
(set (match_dup 1)
(unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_LDGP2))]
- ""
{
+ if (prev_nonnote_insn (curr_insn) != XEXP (operands[0], 0))
+ emit_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, operands[0]),
+ UNSPECV_SETJMPR_ER));
operands[1] = pic_offset_table_rtx;
operands[2] = gen_rtx_REG (Pmode, 27);
operands[3] = GEN_INT (alpha_next_sequence_number++);
-})
+}
+ [(set_attr "length" "12")
+ (set_attr "type" "multi")])
-(define_expand "builtin_setjmp_receiver"
- [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
- "TARGET_ABI_OSF"
-{
- if (TARGET_EXPLICIT_RELOCS)
- {
- emit_insn (gen_builtin_setjmp_receiver_er (operands[0]));
- DONE;
- }
-})
+(define_insn "*builtin_setjmp_receiver_er_sl_1"
+ [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR_ER)]
+ "TARGET_ABI_OSF && TARGET_EXPLICIT_RELOCS && TARGET_AS_CAN_SUBTRACT_LABELS"
+ "lda $27,$LSJ%=-%l0($27)\n$LSJ%=:")
+
+(define_insn "*builtin_setjmp_receiver_er_1"
+ [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR_ER)]
+ "TARGET_ABI_OSF && TARGET_EXPLICIT_RELOCS"
+ "br $27,$LSJ%=\n$LSJ%=:"
+ [(set_attr "type" "ibr")])
-(define_expand "exception_receiver_er"
- [(set (match_dup 0)
- (unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1))
- (set (match_dup 0)
- (unspec:DI [(match_dup 0) (match_dup 2)] UNSPEC_LDGP2))]
- ""
-{
- operands[0] = pic_offset_table_rtx;
- operands[1] = gen_rtx_REG (Pmode, 26);
- operands[2] = GEN_INT (alpha_next_sequence_number++);
-})
+;; When flag_reorder_blocks_and_partition is in effect, compiler puts
+;; 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
+;; original landing pad. Since landing pad is moved, RA-relative GP
+;; 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.
(define_expand "exception_receiver"
[(unspec_volatile [(match_dup 0)] UNSPECV_EHR)]
"TARGET_ABI_OSF"
{
- if (TARGET_LD_BUGGY_LDGP)
+ if (TARGET_LD_BUGGY_LDGP || flag_reorder_blocks_and_partition)
operands[0] = alpha_gp_save_rtx ();
- else if (TARGET_EXPLICIT_RELOCS)
- {
- emit_insn (gen_exception_receiver_er ());
- DONE;
- }
else
operands[0] = const0_rtx;
})
-(define_insn "*exception_receiver_1"
- [(unspec_volatile [(const_int 0)] UNSPECV_EHR)]
- "! TARGET_LD_BUGGY_LDGP"
- "ldgp $29,0($26)"
- [(set_attr "length" "8")
- (set_attr "type" "multi")])
-
(define_insn "*exception_receiver_2"
[(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_EHR)]
- "TARGET_LD_BUGGY_LDGP"
+ "TARGET_ABI_OSF
+ && (TARGET_LD_BUGGY_LDGP || flag_reorder_blocks_and_partition)"
"ldq $29,%0"
[(set_attr "type" "ild")])
+(define_insn_and_split "*exception_receiver_1"
+ [(unspec_volatile [(const_int 0)] UNSPECV_EHR)]
+ "TARGET_ABI_OSF"
+{
+ if (TARGET_EXPLICIT_RELOCS)
+ return "ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*";
+ else
+ return "ldgp $29,0($26)";
+}
+ "&& TARGET_EXPLICIT_RELOCS && reload_completed"
+ [(set (match_dup 0)
+ (unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1))
+ (set (match_dup 0)
+ (unspec:DI [(match_dup 0) (match_dup 2)] UNSPEC_LDGP2))]
+{
+ operands[0] = pic_offset_table_rtx;
+ operands[1] = gen_rtx_REG (Pmode, 26);
+ operands[2] = GEN_INT (alpha_next_sequence_number++);
+}
+ [(set_attr "length" "8")
+ (set_attr "type" "multi")])
+
(define_expand "nonlocal_goto_receiver"
[(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
(set (reg:DI 27) (mem:DI (reg:DI 29)))
[(set_attr "length" "16")
(set_attr "type" "multi")])
-;; Load the CIW into r2 for calling __T3E_MISMATCH
-
-(define_expand "umk_mismatch_args"
- [(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 (reg:DI 1) (match_operand:DI 0 "const_int_operand" ""))
- (set:DI (match_dup 3) (plus:DI (mult:DI (reg:DI 25)
- (const_int 8))
- (match_dup 2)))
- (set:DI (reg:DI 2) (mem:DI (match_dup 3)))]
- "TARGET_ABI_UNICOSMK"
-{
- operands[1] = gen_reg_rtx (DImode);
- operands[2] = gen_reg_rtx (DImode);
- operands[3] = gen_reg_rtx (DImode);
-})
-
-(define_insn "arg_home_umk"
- [(unspec [(const_int 0)] UNSPEC_ARG_HOME)
- (use (reg:DI 1))
- (use (reg:DI 2))
- (use (reg:DI 16))
- (use (reg:DI 17))
- (use (reg:DI 18))
- (use (reg:DI 19))
- (use (reg:DI 20))
- (use (reg:DI 21))
- (use (reg:DI 48))
- (use (reg:DI 49))
- (use (reg:DI 50))
- (use (reg:DI 51))
- (use (reg:DI 52))
- (use (reg:DI 53))
- (clobber (mem:BLK (const_int 0)))
- (parallel [
- (clobber (reg:DI 22))
- (clobber (reg:DI 23))
- (clobber (reg:DI 24))
- (clobber (reg:DI 0))
- (clobber (reg:DI 1))
- (clobber (reg:DI 2))
- (clobber (reg:DI 3))
- (clobber (reg:DI 4))
- (clobber (reg:DI 5))
- (clobber (reg:DI 6))
- (clobber (reg:DI 7))
- (clobber (reg:DI 8))])]
- "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)"
- [(set_attr "length" "16")
- (set_attr "type" "multi")])
-
;; Prefetch data.
;;
;; On EV4, these instructions are nops -- no load occurs.
[(prefetch (match_operand:DI 0 "address_operand" "p")
(match_operand:DI 1 "const_int_operand" "n")
(match_operand:DI 2 "const_int_operand" "n"))]
- "TARGET_FIXUP_EV5_PREFETCH || TARGET_CPU_EV6"
+ "TARGET_FIXUP_EV5_PREFETCH || alpha_cpu == PROCESSOR_EV6"
{
/* Interpret "no temporal locality" as this data should be evicted once
it is used. The "evict next" alternatives load the data into the cache
""
"ldq_u $31,0($30)")
-;; On Unicos/Mk we use a macro for aligning code.
-
(define_insn "realign"
[(unspec_volatile [(match_operand 0 "immediate_operand" "i")]
UNSPECV_REALIGN)]
""
-{
- if (TARGET_ABI_UNICOSMK)
- return "gcc@code@align %0";
- else
- return ".align %0 #realign";
-})
+ ".align %0 #realign")
\f
;; Instructions to be emitted from __builtins.
;; actually differentiate between ILOG and ICMP in the schedule.
[(set_attr "type" "icmp")])
-(define_expand "builtin_extbl"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
- ""
-{
- rtx (*gen) (rtx, rtx, rtx, rtx);
- if (WORDS_BIG_ENDIAN)
- gen = gen_extxl_be;
- else
- gen = gen_extxl_le;
- emit_insn ((*gen) (operands[0], operands[1], GEN_INT (8), operands[2]));
- DONE;
-})
-
-(define_expand "builtin_extwl"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
- ""
-{
- rtx (*gen) (rtx, rtx, rtx, rtx);
- if (WORDS_BIG_ENDIAN)
- gen = gen_extxl_be;
- else
- gen = gen_extxl_le;
- emit_insn ((*gen) (operands[0], operands[1], GEN_INT (16), operands[2]));
- DONE;
-})
-
-(define_expand "builtin_extll"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
- ""
-{
- rtx (*gen) (rtx, rtx, rtx, rtx);
- if (WORDS_BIG_ENDIAN)
- gen = gen_extxl_be;
- else
- gen = gen_extxl_le;
- emit_insn ((*gen) (operands[0], operands[1], GEN_INT (32), operands[2]));
- DONE;
-})
-
-(define_expand "builtin_extql"
+(define_expand "extbl"
[(match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "reg_or_0_operand" "")
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) (rtx, rtx, rtx, rtx);
- if (WORDS_BIG_ENDIAN)
- gen = gen_extxl_be;
- else
- gen = gen_extxl_le;
- emit_insn ((*gen) (operands[0], operands[1], GEN_INT (64), operands[2]));
+ emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (8), operands[2]));
DONE;
})
-(define_expand "builtin_extwh"
+(define_expand "extwl"
[(match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "reg_or_0_operand" "")
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) (rtx, rtx, rtx);
- if (WORDS_BIG_ENDIAN)
- gen = gen_extwh_be;
- else
- gen = gen_extwh_le;
- emit_insn ((*gen) (operands[0], operands[1], operands[2]));
+ emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (16), operands[2]));
DONE;
})
-(define_expand "builtin_extlh"
+(define_expand "extll"
[(match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "reg_or_0_operand" "")
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) (rtx, rtx, rtx);
- if (WORDS_BIG_ENDIAN)
- gen = gen_extlh_be;
- else
- gen = gen_extlh_le;
- emit_insn ((*gen) (operands[0], operands[1], operands[2]));
+ emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (32), operands[2]));
DONE;
})
-(define_expand "builtin_extqh"
+(define_expand "extql"
[(match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "reg_or_0_operand" "")
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) (rtx, rtx, rtx);
- if (WORDS_BIG_ENDIAN)
- gen = gen_extqh_be;
- else
- gen = gen_extqh_le;
- emit_insn ((*gen) (operands[0], operands[1], operands[2]));
+ emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (64), operands[2]));
DONE;
})
(define_expand "builtin_insbl"
[(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
+ (match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) (rtx, rtx, rtx);
- if (WORDS_BIG_ENDIAN)
- gen = gen_insbl_be;
- else
- gen = gen_insbl_le;
operands[1] = gen_lowpart (QImode, operands[1]);
- emit_insn ((*gen) (operands[0], operands[1], operands[2]));
+ emit_insn (gen_insbl (operands[0], operands[1], operands[2]));
DONE;
})
(define_expand "builtin_inswl"
[(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
+ (match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) (rtx, rtx, rtx);
- if (WORDS_BIG_ENDIAN)
- gen = gen_inswl_be;
- else
- gen = gen_inswl_le;
operands[1] = gen_lowpart (HImode, operands[1]);
- emit_insn ((*gen) (operands[0], operands[1], operands[2]));
+ emit_insn (gen_inswl (operands[0], operands[1], operands[2]));
DONE;
})
(define_expand "builtin_insll"
[(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
+ (match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) (rtx, rtx, rtx);
- if (WORDS_BIG_ENDIAN)
- gen = gen_insll_be;
- else
- gen = gen_insll_le;
operands[1] = gen_lowpart (SImode, operands[1]);
- emit_insn ((*gen) (operands[0], operands[1], operands[2]));
- emit_insn ((*gen) (operands[0], operands[1], operands[2]));
- DONE;
-})
-
-(define_expand "builtin_insql"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
- ""
-{
- rtx (*gen) (rtx, rtx, rtx);
- if (WORDS_BIG_ENDIAN)
- gen = gen_insql_be;
- else
- gen = gen_insql_le;
- emit_insn ((*gen) (operands[0], operands[1], operands[2]));
+ emit_insn (gen_insll (operands[0], operands[1], operands[2]));
DONE;
})
-(define_expand "builtin_inswh"
+(define_expand "inswh"
[(match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "reg_or_8bit_operand" "")]
DONE;
})
-(define_expand "builtin_inslh"
+(define_expand "inslh"
[(match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "reg_or_8bit_operand" "")]
DONE;
})
-(define_expand "builtin_insqh"
+(define_expand "insqh"
[(match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "reg_or_8bit_operand" "")]
DONE;
})
-(define_expand "builtin_mskbl"
+(define_expand "mskbl"
[(match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "reg_or_0_operand" "")
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) (rtx, rtx, rtx, rtx);
- rtx mask;
- if (WORDS_BIG_ENDIAN)
- gen = gen_mskxl_be;
- else
- gen = gen_mskxl_le;
- mask = GEN_INT (0xff);
- emit_insn ((*gen) (operands[0], operands[1], mask, operands[2]));
+ rtx mask = GEN_INT (0xff);
+ emit_insn (gen_mskxl (operands[0], operands[1], mask, operands[2]));
DONE;
})
-(define_expand "builtin_mskwl"
+(define_expand "mskwl"
[(match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "reg_or_0_operand" "")
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) (rtx, rtx, rtx, rtx);
- rtx mask;
- if (WORDS_BIG_ENDIAN)
- gen = gen_mskxl_be;
- else
- gen = gen_mskxl_le;
- mask = GEN_INT (0xffff);
- emit_insn ((*gen) (operands[0], operands[1], mask, operands[2]));
+ rtx mask = GEN_INT (0xffff);
+ emit_insn (gen_mskxl (operands[0], operands[1], mask, operands[2]));
DONE;
})
-(define_expand "builtin_mskll"
+(define_expand "mskll"
[(match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "reg_or_0_operand" "")
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) (rtx, rtx, rtx, rtx);
- rtx mask;
- if (WORDS_BIG_ENDIAN)
- gen = gen_mskxl_be;
- else
- gen = gen_mskxl_le;
- mask = immed_double_const (0xffffffff, 0, DImode);
- emit_insn ((*gen) (operands[0], operands[1], mask, operands[2]));
+ rtx mask = immed_double_const (0xffffffff, 0, DImode);
+ emit_insn (gen_mskxl (operands[0], operands[1], mask, operands[2]));
DONE;
})
-(define_expand "builtin_mskql"
+(define_expand "mskql"
[(match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "reg_or_0_operand" "")
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) (rtx, rtx, rtx, rtx);
- rtx mask;
- if (WORDS_BIG_ENDIAN)
- gen = gen_mskxl_be;
- else
- gen = gen_mskxl_le;
- mask = constm1_rtx;
- emit_insn ((*gen) (operands[0], operands[1], mask, operands[2]));
+ rtx mask = constm1_rtx;
+ emit_insn (gen_mskxl (operands[0], operands[1], mask, operands[2]));
DONE;
})
-(define_expand "builtin_mskwh"
+(define_expand "mskwh"
[(match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "reg_or_8bit_operand" "")]
DONE;
})
-(define_expand "builtin_msklh"
+(define_expand "msklh"
[(match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "reg_or_8bit_operand" "")]
DONE;
})
-(define_expand "builtin_mskqh"
+(define_expand "mskqh"
[(match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "reg_or_8bit_operand" "")]
(define_expand "builtin_zap"
[(set (match_operand:DI 0 "register_operand" "")
(and:DI (unspec:DI
- [(match_operand:DI 2 "reg_or_const_int_operand" "")]
+ [(match_operand:DI 2 "reg_or_cint_operand" "")]
UNSPEC_ZAP)
- (match_operand:DI 1 "reg_or_const_int_operand" "")))]
+ (match_operand:DI 1 "reg_or_cint_operand" "")))]
""
{
- if (GET_CODE (operands[2]) == CONST_INT)
+ if (CONST_INT_P (operands[2]))
{
rtx mask = alpha_expand_zap_mask (INTVAL (operands[2]));
(define_insn "*builtin_zap_1"
[(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
(and:DI (unspec:DI
- [(match_operand:QI 2 "reg_or_const_int_operand" "n,n,r,r")]
+ [(match_operand:QI 2 "reg_or_cint_operand" "n,n,r,r")]
UNSPEC_ZAP)
- (match_operand:DI 1 "reg_or_const_int_operand" "n,r,J,r")))]
+ (match_operand:DI 1 "reg_or_cint_operand" "n,r,J,r")))]
""
"@
#
[(const_int 0)]
{
rtx mask = alpha_expand_zap_mask (INTVAL (operands[2]));
- if (HOST_BITS_PER_WIDE_INT >= 64 || GET_CODE (mask) == CONST_INT)
+ if (HOST_BITS_PER_WIDE_INT >= 64 || CONST_INT_P (mask))
operands[1] = gen_int_mode (INTVAL (operands[1]) & INTVAL (mask), DImode);
else
{
(define_expand "builtin_zapnot"
[(set (match_operand:DI 0 "register_operand" "")
(and:DI (unspec:DI
- [(not:QI (match_operand:DI 2 "reg_or_const_int_operand" ""))]
+ [(not:QI (match_operand:DI 2 "reg_or_cint_operand" ""))]
UNSPEC_ZAP)
- (match_operand:DI 1 "reg_or_const_int_operand" "")))]
+ (match_operand:DI 1 "reg_or_cint_operand" "")))]
""
{
- if (GET_CODE (operands[2]) == CONST_INT)
+ if (CONST_INT_P (operands[2]))
{
rtx mask = alpha_expand_zap_mask (~ INTVAL (operands[2]));
"TARGET_MAX"
"unpkbw %r1,%0"
[(set_attr "type" "mvi")])
-
-(define_expand "builtin_cttz"
- [(set (match_operand:DI 0 "register_operand" "")
- (unspec:DI [(match_operand:DI 1 "register_operand" "")]
- UNSPEC_CTTZ))]
- "TARGET_CIX"
- "")
-
-(define_insn "builtin_ctlz"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (unspec:DI [(match_operand:DI 1 "register_operand" "r")]
- UNSPEC_CTLZ))]
- "TARGET_CIX"
- "ctlz %1,%0"
- [(set_attr "type" "mvi")])
-
-(define_insn "builtin_ctpop"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (unspec:DI [(match_operand:DI 1 "register_operand" "r")]
- UNSPEC_CTPOP))]
- "TARGET_CIX"
- "ctpop %1,%0"
- [(set_attr "type" "mvi")])
+\f
+(include "sync.md")
\f
;; The call patterns are at the end of the file because their
;; wildcard operand0 interferes with nice recognition.
+(define_insn "*call_value_osf_1_er_noreturn"
+ [(set (match_operand 0 "" "")
+ (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
+ (match_operand 2 "" "")))
+ (use (reg:DI 29))
+ (clobber (reg:DI 26))]
+ "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
+ && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
+ "@
+ jsr $26,($27),0
+ bsr $26,%1\t\t!samegp
+ ldq $27,%1($29)\t\t!literal!%#\;jsr $26,($27),%1\t\t!lituse_jsr!%#"
+ [(set_attr "type" "jsr")
+ (set_attr "length" "*,*,8")])
+
(define_insn "*call_value_osf_1_er"
[(set (match_operand 0 "" "")
(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
(clobber (reg:DI 26))])]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
&& ! 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))"
[(parallel [(set (match_dup 0)
(call (mem:DI (match_dup 3))
(match_dup 2)))
- (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
- (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
+ (use (reg:DI 29))
(use (match_dup 1))
- (use (match_dup 4))])]
+ (use (match_dup 4))
+ (clobber (reg:DI 26))])]
{
if (CONSTANT_P (operands[1]))
{
(clobber (reg:DI 26))])]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
&& ! 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))"
[(parallel [(set (match_dup 0)
(call (mem:DI (match_dup 3))
(match_dup 2)))
- (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
- (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
+ (set (match_dup 6)
+ (unspec:DI [(match_dup 6) (match_dup 4)] UNSPEC_LDGP1))
(use (match_dup 1))
- (use (match_dup 5))])
- (set (reg:DI 29)
- (unspec_volatile:DI [(reg:DI 26) (match_dup 4)] UNSPECV_LDGP1))
- (set (reg:DI 29)
- (unspec:DI [(reg:DI 29) (match_dup 4)] UNSPEC_LDGP2))]
+ (use (match_dup 5))
+ (clobber (reg:DI 26))])
+ (set (match_dup 6)
+ (unspec:DI [(match_dup 6) (match_dup 4)] UNSPEC_LDGP2))]
{
if (CONSTANT_P (operands[1]))
{
operands[5] = const0_rtx;
}
operands[4] = GEN_INT (alpha_next_sequence_number++);
+ operands[6] = pic_offset_table_rtx;
})
-;; We add a blockage unspec_volatile to prevent insns from moving down
-;; from above the call to in between the call and the ldah gpdisp.
-(define_insn "*call_value_osf_2_er"
+(define_insn "*call_value_osf_2_er_nogp"
[(set (match_operand 0 "" "")
(call (mem:DI (match_operand:DI 1 "register_operand" "c"))
(match_operand 2 "" "")))
- (set (reg:DI 26)
- (plus:DI (pc) (const_int 4)))
- (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
+ (use (reg:DI 29))
(use (match_operand 3 "" ""))
- (use (match_operand 4 "" ""))]
+ (use (match_operand 4 "" ""))
+ (clobber (reg:DI 26))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"jsr $26,(%1),%3%J4"
[(set_attr "type" "jsr")])
+(define_insn "*call_value_osf_2_er"
+ [(set (match_operand 0 "" "")
+ (call (mem:DI (match_operand:DI 1 "register_operand" "c"))
+ (match_operand 2 "" "")))
+ (set (reg:DI 29)
+ (unspec:DI [(reg:DI 29) (match_operand 5 "const_int_operand" "")]
+ UNSPEC_LDGP1))
+ (use (match_operand 3 "" ""))
+ (use (match_operand 4 "" ""))
+ (clobber (reg:DI 26))]
+ "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
+ "jsr $26,(%1),%3%J4\;ldah $29,0($26)\t\t!gpdisp!%5"
+ [(set_attr "type" "jsr")
+ (set_attr "cannot_copy" "true")
+ (set_attr "length" "8")])
+
(define_insn "*call_value_osf_1_noreturn"
[(set (match_operand 0 "" "")
(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
"! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
"@
- jsr $26,($27),0%+
- bsr $26,$%1..ng%+
- jsr $26,%1%+"
+ jsr $26,($27),0
+ bsr $26,$%1..ng
+ jsr $26,%1"
[(set_attr "type" "jsr")
(set_attr "length" "*,*,8")])
(parallel [(set (match_dup 0)
(call (mem:DI (match_dup 3))
(const_int 0)))
- (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
- (unspec_volatile [(match_dup 5)] UNSPECV_BLOCKAGE)
+ (set (match_dup 5)
+ (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP1))
(use (match_dup 1))
- (use (unspec [(match_dup 2)] UNSPEC_TLSGD_CALL))])
- (set (match_dup 5)
- (unspec_volatile:DI [(reg:DI 26) (match_dup 4)] UNSPECV_LDGP1))
+ (use (unspec [(match_dup 2)] UNSPEC_TLSGD_CALL))
+ (clobber (reg:DI 26))])
(set (match_dup 5)
(unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP2))]
{
(parallel [(set (match_dup 0)
(call (mem:DI (match_dup 3))
(const_int 0)))
- (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
- (unspec_volatile [(match_dup 5)] UNSPECV_BLOCKAGE)
+ (set (match_dup 5)
+ (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP1))
(use (match_dup 1))
- (use (unspec [(match_dup 2)] UNSPEC_TLSLDM_CALL))])
- (set (reg:DI 29)
- (unspec_volatile:DI [(reg:DI 26) (match_dup 4)] UNSPECV_LDGP1))
- (set (reg:DI 29)
- (unspec:DI [(reg:DI 29) (match_dup 4)] UNSPEC_LDGP2))]
+ (use (unspec [(match_dup 2)] UNSPEC_TLSLDM_CALL))
+ (clobber (reg:DI 26))])
+ (set (match_dup 5)
+ (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP2))]
{
operands[3] = gen_rtx_REG (Pmode, 27);
operands[4] = GEN_INT (alpha_next_sequence_number++);
[(set_attr "type" "jsr")
(set_attr "length" "*,8")])
-(define_insn "*call_value_nt_1"
- [(set (match_operand 0 "" "")
- (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,s"))
- (match_operand 2 "" "")))
- (clobber (reg:DI 26))]
- "TARGET_ABI_WINDOWS_NT"
- "@
- jsr $26,(%1)
- bsr $26,%1
- jsr $26,%1"
- [(set_attr "type" "jsr")
- (set_attr "length" "*,*,12")])
-
; GAS relies on the order and position of instructions output below in order
; to generate relocs for VMS link to potentially optimize the call.
; Please do not molest.
case 0:
return "mov %3,$27\;jsr $26,0\;ldq $27,0($29)";
case 1:
- operands [3] = alpha_use_linkage (operands [1], cfun->decl, 1, 0);
- operands [4] = alpha_use_linkage (operands [1], cfun->decl, 0, 0);
+ operands [3] = alpha_use_linkage (operands [1], true, false);
+ operands [4] = alpha_use_linkage (operands [1], false, false);
return "ldq $26,%4\;ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)";
default:
- abort();
+ gcc_unreachable ();
}
}
[(set_attr "type" "jsr")
(set_attr "length" "12,16")])
-
-(define_insn "*call_value_umk"
- [(set (match_operand 0 "" "")
- (call (mem:DI (match_operand:DI 1 "call_operand" "r"))
- (match_operand 2 "" "")))
- (use (reg:DI 25))
- (clobber (reg:DI 26))]
- "TARGET_ABI_UNICOSMK"
- "jsr $26,(%1)"
- [(set_attr "type" "jsr")])