1404b540aSrobert;; Machine description for DEC Alpha for GNU C compiler 2404b540aSrobert;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 3404b540aSrobert;; 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 4404b540aSrobert;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) 5404b540aSrobert;; 6404b540aSrobert;; This file is part of GCC. 7404b540aSrobert;; 8404b540aSrobert;; GCC is free software; you can redistribute it and/or modify 9404b540aSrobert;; it under the terms of the GNU General Public License as published by 10404b540aSrobert;; the Free Software Foundation; either version 2, or (at your option) 11404b540aSrobert;; any later version. 12404b540aSrobert;; 13404b540aSrobert;; GCC is distributed in the hope that it will be useful, 14404b540aSrobert;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15404b540aSrobert;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16404b540aSrobert;; GNU General Public License for more details. 17404b540aSrobert;; 18404b540aSrobert;; You should have received a copy of the GNU General Public License 19404b540aSrobert;; along with GCC; see the file COPYING. If not, write to 20404b540aSrobert;; the Free Software Foundation, 51 Franklin Street, Fifth Floor, 21404b540aSrobert;; Boston, MA 02110-1301, USA. 22404b540aSrobert 23404b540aSrobert;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. 24404b540aSrobert 25404b540aSrobert;; Uses of UNSPEC in this file: 26404b540aSrobert 27404b540aSrobert(define_constants 28404b540aSrobert [(UNSPEC_ARG_HOME 0) 29404b540aSrobert (UNSPEC_INSXH 2) 30404b540aSrobert (UNSPEC_MSKXH 3) 31404b540aSrobert (UNSPEC_CVTQL 4) 32404b540aSrobert (UNSPEC_CVTLQ 5) 33404b540aSrobert (UNSPEC_UMK_LAUM 6) 34404b540aSrobert (UNSPEC_UMK_LALM 7) 35404b540aSrobert (UNSPEC_UMK_LAL 8) 36404b540aSrobert (UNSPEC_UMK_LOAD_CIW 9) 37404b540aSrobert (UNSPEC_LDGP2 10) 38404b540aSrobert (UNSPEC_LITERAL 11) 39404b540aSrobert (UNSPEC_LITUSE 12) 40404b540aSrobert (UNSPEC_SIBCALL 13) 41404b540aSrobert (UNSPEC_SYMBOL 14) 42404b540aSrobert 43404b540aSrobert ;; TLS Support 44404b540aSrobert (UNSPEC_TLSGD_CALL 15) 45404b540aSrobert (UNSPEC_TLSLDM_CALL 16) 46404b540aSrobert (UNSPEC_TLSGD 17) 47404b540aSrobert (UNSPEC_TLSLDM 18) 48404b540aSrobert (UNSPEC_DTPREL 19) 49404b540aSrobert (UNSPEC_TPREL 20) 50404b540aSrobert (UNSPEC_TP 21) 51404b540aSrobert 52404b540aSrobert ;; Builtins 53404b540aSrobert (UNSPEC_CMPBGE 22) 54404b540aSrobert (UNSPEC_ZAP 23) 55404b540aSrobert (UNSPEC_AMASK 24) 56404b540aSrobert (UNSPEC_IMPLVER 25) 57404b540aSrobert (UNSPEC_PERR 26) 58404b540aSrobert (UNSPEC_COPYSIGN 27) 59404b540aSrobert 60404b540aSrobert ;; Atomic operations 61404b540aSrobert (UNSPEC_MB 28) 62404b540aSrobert (UNSPEC_ATOMIC 31) 63404b540aSrobert (UNSPEC_CMPXCHG 32) 64404b540aSrobert (UNSPEC_XCHG 33) 65404b540aSrobert ]) 66404b540aSrobert 67404b540aSrobert;; UNSPEC_VOLATILE: 68404b540aSrobert 69404b540aSrobert(define_constants 70404b540aSrobert [(UNSPECV_IMB 0) 71404b540aSrobert (UNSPECV_BLOCKAGE 1) 72404b540aSrobert (UNSPECV_SETJMPR 2) ; builtin_setjmp_receiver 73404b540aSrobert (UNSPECV_LONGJMP 3) ; builtin_longjmp 74404b540aSrobert (UNSPECV_TRAPB 4) 75404b540aSrobert (UNSPECV_PSPL 5) ; prologue_stack_probe_loop 76404b540aSrobert (UNSPECV_REALIGN 6) 77404b540aSrobert (UNSPECV_EHR 7) ; exception_receiver 78404b540aSrobert (UNSPECV_MCOUNT 8) 79404b540aSrobert (UNSPECV_FORCE_MOV 9) 80404b540aSrobert (UNSPECV_LDGP1 10) 81404b540aSrobert (UNSPECV_PLDGP2 11) ; prologue ldgp 82404b540aSrobert (UNSPECV_SET_TP 12) 83404b540aSrobert (UNSPECV_RPCC 13) 84404b540aSrobert (UNSPECV_SETJMPR_ER 14) ; builtin_setjmp_receiver fragment 85404b540aSrobert (UNSPECV_LL 15) ; load-locked 86404b540aSrobert (UNSPECV_SC 16) ; store-conditional 87404b540aSrobert ]) 88404b540aSrobert 89404b540aSrobert;; Where necessary, the suffixes _le and _be are used to distinguish between 90404b540aSrobert;; little-endian and big-endian patterns. 91404b540aSrobert;; 92404b540aSrobert;; Note that the Unicos/Mk assembler does not support the following 93404b540aSrobert;; opcodes: mov, fmov, nop, fnop, unop. 94404b540aSrobert 95404b540aSrobert;; Processor type -- this attribute must exactly match the processor_type 96404b540aSrobert;; enumeration in alpha.h. 97404b540aSrobert 98404b540aSrobert(define_attr "tune" "ev4,ev5,ev6" 99404b540aSrobert (const (symbol_ref "alpha_tune"))) 100404b540aSrobert 101404b540aSrobert;; Define an insn type attribute. This is used in function unit delay 102404b540aSrobert;; computations, among other purposes. For the most part, we use the names 103404b540aSrobert;; defined in the EV4 documentation, but add a few that we have to know about 104404b540aSrobert;; separately. 105404b540aSrobert 106404b540aSrobert(define_attr "type" 107404b540aSrobert "ild,fld,ldsym,ist,fst,ibr,callpal,fbr,jsr,iadd,ilog,shift,icmov,fcmov, 108404b540aSrobert icmp,imul,fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,mb,ld_l,st_c, 109404b540aSrobert multi,none" 110404b540aSrobert (const_string "iadd")) 111404b540aSrobert 112404b540aSrobert;; Describe a user's asm statement. 113404b540aSrobert(define_asm_attributes 114404b540aSrobert [(set_attr "type" "multi")]) 115404b540aSrobert 116404b540aSrobert;; Define the operand size an insn operates on. Used primarily by mul 117404b540aSrobert;; and div operations that have size dependent timings. 118404b540aSrobert 119404b540aSrobert(define_attr "opsize" "si,di,udi" 120404b540aSrobert (const_string "di")) 121404b540aSrobert 122404b540aSrobert;; The TRAP attribute marks instructions that may generate traps 123404b540aSrobert;; (which are imprecise and may need a trapb if software completion 124404b540aSrobert;; is desired). 125404b540aSrobert 126404b540aSrobert(define_attr "trap" "no,yes" 127404b540aSrobert (const_string "no")) 128404b540aSrobert 129404b540aSrobert;; The ROUND_SUFFIX attribute marks which instructions require a 130404b540aSrobert;; rounding-mode suffix. The value NONE indicates no suffix, 131404b540aSrobert;; the value NORMAL indicates a suffix controlled by alpha_fprm. 132404b540aSrobert 133404b540aSrobert(define_attr "round_suffix" "none,normal,c" 134404b540aSrobert (const_string "none")) 135404b540aSrobert 136404b540aSrobert;; The TRAP_SUFFIX attribute marks instructions requiring a trap-mode suffix: 137404b540aSrobert;; NONE no suffix 138404b540aSrobert;; SU accepts only /su (cmpt et al) 139404b540aSrobert;; SUI accepts only /sui (cvtqt and cvtqs) 140404b540aSrobert;; V_SV accepts /v and /sv (cvtql only) 141404b540aSrobert;; V_SV_SVI accepts /v, /sv and /svi (cvttq only) 142404b540aSrobert;; U_SU_SUI accepts /u, /su and /sui (most fp instructions) 143404b540aSrobert;; 144404b540aSrobert;; The actual suffix emitted is controlled by alpha_fptm. 145404b540aSrobert 146404b540aSrobert(define_attr "trap_suffix" "none,su,sui,v_sv,v_sv_svi,u_su_sui" 147404b540aSrobert (const_string "none")) 148404b540aSrobert 149404b540aSrobert;; The length of an instruction sequence in bytes. 150404b540aSrobert 151404b540aSrobert(define_attr "length" "" 152404b540aSrobert (const_int 4)) 153404b540aSrobert 154404b540aSrobert;; The USEGP attribute marks instructions that have relocations that use 155404b540aSrobert;; the GP. 156404b540aSrobert 157404b540aSrobert(define_attr "usegp" "no,yes" 158404b540aSrobert (cond [(eq_attr "type" "ldsym,jsr") 159404b540aSrobert (const_string "yes") 160404b540aSrobert (eq_attr "type" "ild,fld,ist,fst") 161404b540aSrobert (symbol_ref "alpha_find_lo_sum_using_gp(insn)") 162404b540aSrobert ] 163404b540aSrobert (const_string "no"))) 164404b540aSrobert 165404b540aSrobert;; The CANNOT_COPY attribute marks instructions with relocations that 166404b540aSrobert;; cannot easily be duplicated. This includes insns with gpdisp relocs 167404b540aSrobert;; since they have to stay in 1-1 correspondence with one another. This 168404b540aSrobert;; also includes jsr insns, since they must stay in correspondence with 169404b540aSrobert;; the immediately following gpdisp instructions. 170404b540aSrobert 171404b540aSrobert(define_attr "cannot_copy" "false,true" 172404b540aSrobert (const_string "false")) 173404b540aSrobert 174404b540aSrobert;; Include scheduling descriptions. 175404b540aSrobert 176404b540aSrobert(include "ev4.md") 177404b540aSrobert(include "ev5.md") 178404b540aSrobert(include "ev6.md") 179404b540aSrobert 180404b540aSrobert 181404b540aSrobert;; Include predicate definitions 182404b540aSrobert 183404b540aSrobert(include "predicates.md") 184404b540aSrobert 185404b540aSrobert 186404b540aSrobert;; First define the arithmetic insns. Note that the 32-bit forms also 187404b540aSrobert;; sign-extend. 188404b540aSrobert 189404b540aSrobert;; Handle 32-64 bit extension from memory to a floating point register 190404b540aSrobert;; specially, since this occurs frequently in int->double conversions. 191404b540aSrobert;; 192404b540aSrobert;; Note that while we must retain the =f case in the insn for reload's 193404b540aSrobert;; benefit, it should be eliminated after reload, so we should never emit 194404b540aSrobert;; code for that case. But we don't reject the possibility. 195404b540aSrobert 196404b540aSrobert(define_expand "extendsidi2" 197404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 198404b540aSrobert (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))] 199404b540aSrobert "" 200404b540aSrobert "") 201404b540aSrobert 202404b540aSrobert(define_insn "*cvtlq" 203404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=f") 204404b540aSrobert (unspec:DI [(match_operand:SF 1 "reg_or_0_operand" "fG")] 205404b540aSrobert UNSPEC_CVTLQ))] 206404b540aSrobert "" 207404b540aSrobert "cvtlq %1,%0" 208404b540aSrobert [(set_attr "type" "fadd")]) 209404b540aSrobert 210404b540aSrobert(define_insn "*extendsidi2_1" 211404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r,r,!*f") 212404b540aSrobert (sign_extend:DI 213404b540aSrobert (match_operand:SI 1 "nonimmediate_operand" "r,m,m")))] 214404b540aSrobert "" 215404b540aSrobert "@ 216404b540aSrobert addl $31,%1,%0 217404b540aSrobert ldl %0,%1 218404b540aSrobert lds %0,%1\;cvtlq %0,%0" 219404b540aSrobert [(set_attr "type" "iadd,ild,fld") 220404b540aSrobert (set_attr "length" "*,*,8")]) 221404b540aSrobert 222404b540aSrobert(define_split 223404b540aSrobert [(set (match_operand:DI 0 "hard_fp_register_operand" "") 224404b540aSrobert (sign_extend:DI (match_operand:SI 1 "memory_operand" "")))] 225404b540aSrobert "reload_completed" 226404b540aSrobert [(set (match_dup 2) (match_dup 1)) 227404b540aSrobert (set (match_dup 0) (unspec:DI [(match_dup 2)] UNSPEC_CVTLQ))] 228404b540aSrobert{ 229404b540aSrobert operands[1] = adjust_address (operands[1], SFmode, 0); 230404b540aSrobert operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0])); 231404b540aSrobert}) 232404b540aSrobert 233404b540aSrobert;; Optimize sign-extension of SImode loads. This shows up in the wake of 234404b540aSrobert;; reload when converting fp->int. 235404b540aSrobert 236404b540aSrobert(define_peephole2 237404b540aSrobert [(set (match_operand:SI 0 "hard_int_register_operand" "") 238404b540aSrobert (match_operand:SI 1 "memory_operand" "")) 239404b540aSrobert (set (match_operand:DI 2 "hard_int_register_operand" "") 240404b540aSrobert (sign_extend:DI (match_dup 0)))] 241404b540aSrobert "true_regnum (operands[0]) == true_regnum (operands[2]) 242404b540aSrobert || peep2_reg_dead_p (2, operands[0])" 243404b540aSrobert [(set (match_dup 2) 244404b540aSrobert (sign_extend:DI (match_dup 1)))] 245404b540aSrobert "") 246404b540aSrobert 247404b540aSrobert;; Don't say we have addsi3 if optimizing. This generates better code. We 248404b540aSrobert;; have the anonymous addsi3 pattern below in case combine wants to make it. 249404b540aSrobert(define_expand "addsi3" 250404b540aSrobert [(set (match_operand:SI 0 "register_operand" "") 251404b540aSrobert (plus:SI (match_operand:SI 1 "reg_or_0_operand" "") 252404b540aSrobert (match_operand:SI 2 "add_operand" "")))] 253404b540aSrobert "! optimize" 254404b540aSrobert "") 255404b540aSrobert 256404b540aSrobert(define_insn "*addsi_internal" 257404b540aSrobert [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") 258404b540aSrobert (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ") 259404b540aSrobert (match_operand:SI 2 "add_operand" "rI,O,K,L")))] 260404b540aSrobert "" 261404b540aSrobert "@ 262404b540aSrobert addl %r1,%2,%0 263404b540aSrobert subl %r1,%n2,%0 264404b540aSrobert lda %0,%2(%r1) 265404b540aSrobert ldah %0,%h2(%r1)") 266404b540aSrobert 267404b540aSrobert(define_split 268404b540aSrobert [(set (match_operand:SI 0 "register_operand" "") 269404b540aSrobert (plus:SI (match_operand:SI 1 "register_operand" "") 270404b540aSrobert (match_operand:SI 2 "const_int_operand" "")))] 271404b540aSrobert "! add_operand (operands[2], SImode)" 272404b540aSrobert [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3))) 273404b540aSrobert (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))] 274404b540aSrobert{ 275404b540aSrobert HOST_WIDE_INT val = INTVAL (operands[2]); 276404b540aSrobert HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000); 277404b540aSrobert HOST_WIDE_INT rest = val - low; 278404b540aSrobert 279404b540aSrobert operands[3] = GEN_INT (rest); 280404b540aSrobert operands[4] = GEN_INT (low); 281404b540aSrobert}) 282404b540aSrobert 283404b540aSrobert(define_insn "*addsi_se" 284404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r,r") 285404b540aSrobert (sign_extend:DI 286404b540aSrobert (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ") 287404b540aSrobert (match_operand:SI 2 "sext_add_operand" "rI,O"))))] 288404b540aSrobert "" 289404b540aSrobert "@ 290404b540aSrobert addl %r1,%2,%0 291404b540aSrobert subl %r1,%n2,%0") 292404b540aSrobert 293404b540aSrobert(define_insn "*addsi_se2" 294404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r,r") 295404b540aSrobert (sign_extend:DI 296404b540aSrobert (subreg:SI (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ") 297404b540aSrobert (match_operand:DI 2 "sext_add_operand" "rI,O")) 298404b540aSrobert 0)))] 299404b540aSrobert "" 300404b540aSrobert "@ 301404b540aSrobert addl %r1,%2,%0 302404b540aSrobert subl %r1,%n2,%0") 303404b540aSrobert 304404b540aSrobert(define_split 305404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 306404b540aSrobert (sign_extend:DI 307404b540aSrobert (plus:SI (match_operand:SI 1 "reg_not_elim_operand" "") 308404b540aSrobert (match_operand:SI 2 "const_int_operand" "")))) 309404b540aSrobert (clobber (match_operand:SI 3 "reg_not_elim_operand" ""))] 310404b540aSrobert "! sext_add_operand (operands[2], SImode) && INTVAL (operands[2]) > 0 311404b540aSrobert && INTVAL (operands[2]) % 4 == 0" 312404b540aSrobert [(set (match_dup 3) (match_dup 4)) 313404b540aSrobert (set (match_dup 0) (sign_extend:DI (plus:SI (mult:SI (match_dup 3) 314404b540aSrobert (match_dup 5)) 315404b540aSrobert (match_dup 1))))] 316404b540aSrobert{ 317404b540aSrobert HOST_WIDE_INT val = INTVAL (operands[2]) / 4; 318404b540aSrobert int mult = 4; 319404b540aSrobert 320404b540aSrobert if (val % 2 == 0) 321404b540aSrobert val /= 2, mult = 8; 322404b540aSrobert 323404b540aSrobert operands[4] = GEN_INT (val); 324404b540aSrobert operands[5] = GEN_INT (mult); 325404b540aSrobert}) 326404b540aSrobert 327404b540aSrobert(define_split 328404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 329404b540aSrobert (sign_extend:DI 330404b540aSrobert (plus:SI (match_operator:SI 1 "comparison_operator" 331404b540aSrobert [(match_operand 2 "" "") 332404b540aSrobert (match_operand 3 "" "")]) 333404b540aSrobert (match_operand:SI 4 "add_operand" "")))) 334404b540aSrobert (clobber (match_operand:DI 5 "register_operand" ""))] 335404b540aSrobert "" 336404b540aSrobert [(set (match_dup 5) (match_dup 6)) 337404b540aSrobert (set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 7) (match_dup 4))))] 338404b540aSrobert{ 339404b540aSrobert operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[1]), DImode, 340404b540aSrobert operands[2], operands[3]); 341404b540aSrobert operands[7] = gen_lowpart (SImode, operands[5]); 342404b540aSrobert}) 343404b540aSrobert 344404b540aSrobert(define_insn "addvsi3" 345404b540aSrobert [(set (match_operand:SI 0 "register_operand" "=r,r") 346404b540aSrobert (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ") 347404b540aSrobert (match_operand:SI 2 "sext_add_operand" "rI,O"))) 348404b540aSrobert (trap_if (ne (plus:DI (sign_extend:DI (match_dup 1)) 349404b540aSrobert (sign_extend:DI (match_dup 2))) 350404b540aSrobert (sign_extend:DI (plus:SI (match_dup 1) 351404b540aSrobert (match_dup 2)))) 352404b540aSrobert (const_int 0))] 353404b540aSrobert "" 354404b540aSrobert "@ 355404b540aSrobert addlv %r1,%2,%0 356404b540aSrobert sublv %r1,%n2,%0") 357404b540aSrobert 358404b540aSrobert(define_expand "adddi3" 359404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 360404b540aSrobert (plus:DI (match_operand:DI 1 "register_operand" "") 361404b540aSrobert (match_operand:DI 2 "add_operand" "")))] 362404b540aSrobert "" 363404b540aSrobert "") 364404b540aSrobert 365404b540aSrobert(define_insn "*adddi_er_lo16_dtp" 366404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 367404b540aSrobert (lo_sum:DI (match_operand:DI 1 "register_operand" "r") 368404b540aSrobert (match_operand:DI 2 "dtp16_symbolic_operand" "")))] 369404b540aSrobert "HAVE_AS_TLS" 370404b540aSrobert "lda %0,%2(%1)\t\t!dtprel") 371404b540aSrobert 372404b540aSrobert(define_insn "*adddi_er_hi32_dtp" 373404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 374404b540aSrobert (plus:DI (match_operand:DI 1 "register_operand" "r") 375404b540aSrobert (high:DI (match_operand:DI 2 "dtp32_symbolic_operand" ""))))] 376404b540aSrobert "HAVE_AS_TLS" 377404b540aSrobert "ldah %0,%2(%1)\t\t!dtprelhi") 378404b540aSrobert 379404b540aSrobert(define_insn "*adddi_er_lo32_dtp" 380404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 381404b540aSrobert (lo_sum:DI (match_operand:DI 1 "register_operand" "r") 382404b540aSrobert (match_operand:DI 2 "dtp32_symbolic_operand" "")))] 383404b540aSrobert "HAVE_AS_TLS" 384404b540aSrobert "lda %0,%2(%1)\t\t!dtprello") 385404b540aSrobert 386404b540aSrobert(define_insn "*adddi_er_lo16_tp" 387404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 388404b540aSrobert (lo_sum:DI (match_operand:DI 1 "register_operand" "r") 389404b540aSrobert (match_operand:DI 2 "tp16_symbolic_operand" "")))] 390404b540aSrobert "HAVE_AS_TLS" 391404b540aSrobert "lda %0,%2(%1)\t\t!tprel") 392404b540aSrobert 393404b540aSrobert(define_insn "*adddi_er_hi32_tp" 394404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 395404b540aSrobert (plus:DI (match_operand:DI 1 "register_operand" "r") 396404b540aSrobert (high:DI (match_operand:DI 2 "tp32_symbolic_operand" ""))))] 397404b540aSrobert "HAVE_AS_TLS" 398404b540aSrobert "ldah %0,%2(%1)\t\t!tprelhi") 399404b540aSrobert 400404b540aSrobert(define_insn "*adddi_er_lo32_tp" 401404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 402404b540aSrobert (lo_sum:DI (match_operand:DI 1 "register_operand" "r") 403404b540aSrobert (match_operand:DI 2 "tp32_symbolic_operand" "")))] 404404b540aSrobert "HAVE_AS_TLS" 405404b540aSrobert "lda %0,%2(%1)\t\t!tprello") 406404b540aSrobert 407404b540aSrobert(define_insn "*adddi_er_high_l" 408404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 409404b540aSrobert (plus:DI (match_operand:DI 1 "register_operand" "r") 410404b540aSrobert (high:DI (match_operand:DI 2 "local_symbolic_operand" ""))))] 411404b540aSrobert "TARGET_EXPLICIT_RELOCS && reload_completed" 412404b540aSrobert "ldah %0,%2(%1)\t\t!gprelhigh" 413404b540aSrobert [(set_attr "usegp" "yes")]) 414404b540aSrobert 415404b540aSrobert(define_split 416404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 417404b540aSrobert (high:DI (match_operand:DI 1 "local_symbolic_operand" "")))] 418404b540aSrobert "TARGET_EXPLICIT_RELOCS && reload_completed" 419404b540aSrobert [(set (match_dup 0) 420404b540aSrobert (plus:DI (match_dup 2) (high:DI (match_dup 1))))] 421404b540aSrobert "operands[2] = pic_offset_table_rtx;") 422404b540aSrobert 423404b540aSrobert;; We used to expend quite a lot of effort choosing addq/subq/lda. 424404b540aSrobert;; With complications like 425404b540aSrobert;; 426404b540aSrobert;; The NT stack unwind code can't handle a subq to adjust the stack 427404b540aSrobert;; (that's a bug, but not one we can do anything about). As of NT4.0 SP3, 428404b540aSrobert;; the exception handling code will loop if a subq is used and an 429404b540aSrobert;; exception occurs. 430404b540aSrobert;; 431404b540aSrobert;; The 19980616 change to emit prologues as RTL also confused some 432404b540aSrobert;; versions of GDB, which also interprets prologues. This has been 433404b540aSrobert;; fixed as of GDB 4.18, but it does not harm to unconditionally 434404b540aSrobert;; use lda here. 435404b540aSrobert;; 436404b540aSrobert;; and the fact that the three insns schedule exactly the same, it's 437404b540aSrobert;; just not worth the effort. 438404b540aSrobert 439404b540aSrobert(define_insn "*adddi_internal" 440404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r,r,r") 441404b540aSrobert (plus:DI (match_operand:DI 1 "register_operand" "%r,r,r") 442404b540aSrobert (match_operand:DI 2 "add_operand" "r,K,L")))] 443404b540aSrobert "" 444404b540aSrobert "@ 445404b540aSrobert addq %1,%2,%0 446404b540aSrobert lda %0,%2(%1) 447404b540aSrobert ldah %0,%h2(%1)") 448404b540aSrobert 449404b540aSrobert;; ??? Allow large constants when basing off the frame pointer or some 450404b540aSrobert;; virtual register that may eliminate to the frame pointer. This is 451404b540aSrobert;; done because register elimination offsets will change the hi/lo split, 452404b540aSrobert;; and if we split before reload, we will require additional instructions. 453404b540aSrobert 454404b540aSrobert(define_insn "*adddi_fp_hack" 455404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r,r,r") 456404b540aSrobert (plus:DI (match_operand:DI 1 "reg_no_subreg_operand" "r,r,r") 457404b540aSrobert (match_operand:DI 2 "const_int_operand" "K,L,n")))] 458404b540aSrobert "NONSTRICT_REG_OK_FP_BASE_P (operands[1]) 459404b540aSrobert && INTVAL (operands[2]) >= 0 460404b540aSrobert /* This is the largest constant an lda+ldah pair can add, minus 461404b540aSrobert an upper bound on the displacement between SP and AP during 462404b540aSrobert register elimination. See INITIAL_ELIMINATION_OFFSET. */ 463404b540aSrobert && INTVAL (operands[2]) 464404b540aSrobert < (0x7fff8000 465404b540aSrobert - FIRST_PSEUDO_REGISTER * UNITS_PER_WORD 466404b540aSrobert - ALPHA_ROUND(current_function_outgoing_args_size) 467404b540aSrobert - (ALPHA_ROUND (get_frame_size () 468404b540aSrobert + max_reg_num () * UNITS_PER_WORD 469404b540aSrobert + current_function_pretend_args_size) 470404b540aSrobert - current_function_pretend_args_size))" 471404b540aSrobert "@ 472404b540aSrobert lda %0,%2(%1) 473404b540aSrobert ldah %0,%h2(%1) 474404b540aSrobert #") 475404b540aSrobert 476404b540aSrobert;; Don't do this if we are adjusting SP since we don't want to do it 477404b540aSrobert;; in two steps. Don't split FP sources for the reason listed above. 478404b540aSrobert(define_split 479404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 480404b540aSrobert (plus:DI (match_operand:DI 1 "register_operand" "") 481404b540aSrobert (match_operand:DI 2 "const_int_operand" "")))] 482404b540aSrobert "! add_operand (operands[2], DImode) 483404b540aSrobert && operands[0] != stack_pointer_rtx 484404b540aSrobert && operands[1] != frame_pointer_rtx 485404b540aSrobert && operands[1] != arg_pointer_rtx" 486404b540aSrobert [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3))) 487404b540aSrobert (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))] 488404b540aSrobert{ 489404b540aSrobert HOST_WIDE_INT val = INTVAL (operands[2]); 490404b540aSrobert HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000); 491404b540aSrobert HOST_WIDE_INT rest = val - low; 492404b540aSrobert 493404b540aSrobert operands[4] = GEN_INT (low); 494404b540aSrobert if (CONST_OK_FOR_LETTER_P (rest, 'L')) 495404b540aSrobert operands[3] = GEN_INT (rest); 496404b540aSrobert else if (! no_new_pseudos) 497404b540aSrobert { 498404b540aSrobert operands[3] = gen_reg_rtx (DImode); 499404b540aSrobert emit_move_insn (operands[3], operands[2]); 500404b540aSrobert emit_insn (gen_adddi3 (operands[0], operands[1], operands[3])); 501404b540aSrobert DONE; 502404b540aSrobert } 503404b540aSrobert else 504404b540aSrobert FAIL; 505404b540aSrobert}) 506404b540aSrobert 507404b540aSrobert(define_insn "*saddl" 508404b540aSrobert [(set (match_operand:SI 0 "register_operand" "=r,r") 509404b540aSrobert (plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r") 510404b540aSrobert (match_operand:SI 2 "const48_operand" "I,I")) 511404b540aSrobert (match_operand:SI 3 "sext_add_operand" "rI,O")))] 512404b540aSrobert "" 513404b540aSrobert "@ 514404b540aSrobert s%2addl %1,%3,%0 515404b540aSrobert s%2subl %1,%n3,%0") 516404b540aSrobert 517404b540aSrobert(define_insn "*saddl_se" 518404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r,r") 519404b540aSrobert (sign_extend:DI 520404b540aSrobert (plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r") 521404b540aSrobert (match_operand:SI 2 "const48_operand" "I,I")) 522404b540aSrobert (match_operand:SI 3 "sext_add_operand" "rI,O"))))] 523404b540aSrobert "" 524404b540aSrobert "@ 525404b540aSrobert s%2addl %1,%3,%0 526404b540aSrobert s%2subl %1,%n3,%0") 527404b540aSrobert 528404b540aSrobert(define_split 529404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 530404b540aSrobert (sign_extend:DI 531404b540aSrobert (plus:SI (mult:SI (match_operator:SI 1 "comparison_operator" 532404b540aSrobert [(match_operand 2 "" "") 533404b540aSrobert (match_operand 3 "" "")]) 534404b540aSrobert (match_operand:SI 4 "const48_operand" "")) 535404b540aSrobert (match_operand:SI 5 "sext_add_operand" "")))) 536404b540aSrobert (clobber (match_operand:DI 6 "reg_not_elim_operand" ""))] 537404b540aSrobert "" 538404b540aSrobert [(set (match_dup 6) (match_dup 7)) 539404b540aSrobert (set (match_dup 0) 540404b540aSrobert (sign_extend:DI (plus:SI (mult:SI (match_dup 8) (match_dup 4)) 541404b540aSrobert (match_dup 5))))] 542404b540aSrobert{ 543404b540aSrobert operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[1]), DImode, 544404b540aSrobert operands[2], operands[3]); 545404b540aSrobert operands[8] = gen_lowpart (SImode, operands[6]); 546404b540aSrobert}) 547404b540aSrobert 548404b540aSrobert(define_insn "*saddq" 549404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r,r") 550404b540aSrobert (plus:DI (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r,r") 551404b540aSrobert (match_operand:DI 2 "const48_operand" "I,I")) 552404b540aSrobert (match_operand:DI 3 "sext_add_operand" "rI,O")))] 553404b540aSrobert "" 554404b540aSrobert "@ 555404b540aSrobert s%2addq %1,%3,%0 556404b540aSrobert s%2subq %1,%n3,%0") 557404b540aSrobert 558404b540aSrobert(define_insn "addvdi3" 559404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r,r") 560404b540aSrobert (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ") 561404b540aSrobert (match_operand:DI 2 "sext_add_operand" "rI,O"))) 562404b540aSrobert (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1)) 563404b540aSrobert (sign_extend:TI (match_dup 2))) 564404b540aSrobert (sign_extend:TI (plus:DI (match_dup 1) 565404b540aSrobert (match_dup 2)))) 566404b540aSrobert (const_int 0))] 567404b540aSrobert "" 568404b540aSrobert "@ 569404b540aSrobert addqv %r1,%2,%0 570404b540aSrobert subqv %r1,%n2,%0") 571404b540aSrobert 572404b540aSrobert(define_insn "negsi2" 573404b540aSrobert [(set (match_operand:SI 0 "register_operand" "=r") 574404b540aSrobert (neg:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")))] 575404b540aSrobert "" 576404b540aSrobert "subl $31,%1,%0") 577404b540aSrobert 578404b540aSrobert(define_insn "*negsi_se" 579404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 580404b540aSrobert (sign_extend:DI (neg:SI 581404b540aSrobert (match_operand:SI 1 "reg_or_8bit_operand" "rI"))))] 582404b540aSrobert "" 583404b540aSrobert "subl $31,%1,%0") 584404b540aSrobert 585404b540aSrobert(define_insn "negvsi2" 586404b540aSrobert [(set (match_operand:SI 0 "register_operand" "=r") 587404b540aSrobert (neg:SI (match_operand:SI 1 "register_operand" "r"))) 588404b540aSrobert (trap_if (ne (neg:DI (sign_extend:DI (match_dup 1))) 589404b540aSrobert (sign_extend:DI (neg:SI (match_dup 1)))) 590404b540aSrobert (const_int 0))] 591404b540aSrobert "" 592404b540aSrobert "sublv $31,%1,%0") 593404b540aSrobert 594404b540aSrobert(define_insn "negdi2" 595404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 596404b540aSrobert (neg:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))] 597404b540aSrobert "" 598404b540aSrobert "subq $31,%1,%0") 599404b540aSrobert 600404b540aSrobert(define_insn "negvdi2" 601404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 602404b540aSrobert (neg:DI (match_operand:DI 1 "register_operand" "r"))) 603404b540aSrobert (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1))) 604404b540aSrobert (sign_extend:TI (neg:DI (match_dup 1)))) 605404b540aSrobert (const_int 0))] 606404b540aSrobert "" 607404b540aSrobert "subqv $31,%1,%0") 608404b540aSrobert 609404b540aSrobert(define_expand "subsi3" 610404b540aSrobert [(set (match_operand:SI 0 "register_operand" "") 611404b540aSrobert (minus:SI (match_operand:SI 1 "reg_or_0_operand" "") 612404b540aSrobert (match_operand:SI 2 "reg_or_8bit_operand" "")))] 613404b540aSrobert "! optimize" 614404b540aSrobert "") 615404b540aSrobert 616404b540aSrobert(define_insn "*subsi_internal" 617404b540aSrobert [(set (match_operand:SI 0 "register_operand" "=r") 618404b540aSrobert (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") 619404b540aSrobert (match_operand:SI 2 "reg_or_8bit_operand" "rI")))] 620404b540aSrobert "" 621404b540aSrobert "subl %r1,%2,%0") 622404b540aSrobert 623404b540aSrobert(define_insn "*subsi_se" 624404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 625404b540aSrobert (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") 626404b540aSrobert (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))] 627404b540aSrobert "" 628404b540aSrobert "subl %r1,%2,%0") 629404b540aSrobert 630404b540aSrobert(define_insn "*subsi_se2" 631404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 632404b540aSrobert (sign_extend:DI 633404b540aSrobert (subreg:SI (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") 634404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "rI")) 635404b540aSrobert 0)))] 636404b540aSrobert "" 637404b540aSrobert "subl %r1,%2,%0") 638404b540aSrobert 639404b540aSrobert(define_insn "subvsi3" 640404b540aSrobert [(set (match_operand:SI 0 "register_operand" "=r") 641404b540aSrobert (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") 642404b540aSrobert (match_operand:SI 2 "reg_or_8bit_operand" "rI"))) 643404b540aSrobert (trap_if (ne (minus:DI (sign_extend:DI (match_dup 1)) 644404b540aSrobert (sign_extend:DI (match_dup 2))) 645404b540aSrobert (sign_extend:DI (minus:SI (match_dup 1) 646404b540aSrobert (match_dup 2)))) 647404b540aSrobert (const_int 0))] 648404b540aSrobert "" 649404b540aSrobert "sublv %r1,%2,%0") 650404b540aSrobert 651404b540aSrobert(define_insn "subdi3" 652404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 653404b540aSrobert (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") 654404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "rI")))] 655404b540aSrobert "" 656404b540aSrobert "subq %r1,%2,%0") 657404b540aSrobert 658404b540aSrobert(define_insn "*ssubl" 659404b540aSrobert [(set (match_operand:SI 0 "register_operand" "=r") 660404b540aSrobert (minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r") 661404b540aSrobert (match_operand:SI 2 "const48_operand" "I")) 662404b540aSrobert (match_operand:SI 3 "reg_or_8bit_operand" "rI")))] 663404b540aSrobert "" 664404b540aSrobert "s%2subl %1,%3,%0") 665404b540aSrobert 666404b540aSrobert(define_insn "*ssubl_se" 667404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 668404b540aSrobert (sign_extend:DI 669404b540aSrobert (minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r") 670404b540aSrobert (match_operand:SI 2 "const48_operand" "I")) 671404b540aSrobert (match_operand:SI 3 "reg_or_8bit_operand" "rI"))))] 672404b540aSrobert "" 673404b540aSrobert "s%2subl %1,%3,%0") 674404b540aSrobert 675404b540aSrobert(define_insn "*ssubq" 676404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 677404b540aSrobert (minus:DI (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r") 678404b540aSrobert (match_operand:DI 2 "const48_operand" "I")) 679404b540aSrobert (match_operand:DI 3 "reg_or_8bit_operand" "rI")))] 680404b540aSrobert "" 681404b540aSrobert "s%2subq %1,%3,%0") 682404b540aSrobert 683404b540aSrobert(define_insn "subvdi3" 684404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 685404b540aSrobert (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") 686404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "rI"))) 687404b540aSrobert (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1)) 688404b540aSrobert (sign_extend:TI (match_dup 2))) 689404b540aSrobert (sign_extend:TI (minus:DI (match_dup 1) 690404b540aSrobert (match_dup 2)))) 691404b540aSrobert (const_int 0))] 692404b540aSrobert "" 693404b540aSrobert "subqv %r1,%2,%0") 694404b540aSrobert 695404b540aSrobert;; The Unicos/Mk assembler doesn't support mull. 696404b540aSrobert 697404b540aSrobert(define_insn "mulsi3" 698404b540aSrobert [(set (match_operand:SI 0 "register_operand" "=r") 699404b540aSrobert (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ") 700404b540aSrobert (match_operand:SI 2 "reg_or_8bit_operand" "rI")))] 701404b540aSrobert "!TARGET_ABI_UNICOSMK" 702404b540aSrobert "mull %r1,%2,%0" 703404b540aSrobert [(set_attr "type" "imul") 704404b540aSrobert (set_attr "opsize" "si")]) 705404b540aSrobert 706404b540aSrobert(define_insn "*mulsi_se" 707404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 708404b540aSrobert (sign_extend:DI 709404b540aSrobert (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ") 710404b540aSrobert (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))] 711404b540aSrobert "!TARGET_ABI_UNICOSMK" 712404b540aSrobert "mull %r1,%2,%0" 713404b540aSrobert [(set_attr "type" "imul") 714404b540aSrobert (set_attr "opsize" "si")]) 715404b540aSrobert 716404b540aSrobert(define_insn "mulvsi3" 717404b540aSrobert [(set (match_operand:SI 0 "register_operand" "=r") 718404b540aSrobert (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ") 719404b540aSrobert (match_operand:SI 2 "reg_or_8bit_operand" "rI"))) 720404b540aSrobert (trap_if (ne (mult:DI (sign_extend:DI (match_dup 1)) 721404b540aSrobert (sign_extend:DI (match_dup 2))) 722404b540aSrobert (sign_extend:DI (mult:SI (match_dup 1) 723404b540aSrobert (match_dup 2)))) 724404b540aSrobert (const_int 0))] 725404b540aSrobert "!TARGET_ABI_UNICOSMK" 726404b540aSrobert "mullv %r1,%2,%0" 727404b540aSrobert [(set_attr "type" "imul") 728404b540aSrobert (set_attr "opsize" "si")]) 729404b540aSrobert 730404b540aSrobert(define_insn "muldi3" 731404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 732404b540aSrobert (mult:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ") 733404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "rI")))] 734404b540aSrobert "" 735404b540aSrobert "mulq %r1,%2,%0" 736404b540aSrobert [(set_attr "type" "imul")]) 737404b540aSrobert 738404b540aSrobert(define_insn "mulvdi3" 739404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 740404b540aSrobert (mult:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ") 741404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "rI"))) 742404b540aSrobert (trap_if (ne (mult:TI (sign_extend:TI (match_dup 1)) 743404b540aSrobert (sign_extend:TI (match_dup 2))) 744404b540aSrobert (sign_extend:TI (mult:DI (match_dup 1) 745404b540aSrobert (match_dup 2)))) 746404b540aSrobert (const_int 0))] 747404b540aSrobert "" 748404b540aSrobert "mulqv %r1,%2,%0" 749404b540aSrobert [(set_attr "type" "imul")]) 750404b540aSrobert 751404b540aSrobert(define_expand "umuldi3_highpart" 752404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 753404b540aSrobert (truncate:DI 754404b540aSrobert (lshiftrt:TI 755404b540aSrobert (mult:TI (zero_extend:TI 756404b540aSrobert (match_operand:DI 1 "register_operand" "")) 757404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "")) 758404b540aSrobert (const_int 64))))] 759404b540aSrobert "" 760404b540aSrobert{ 761404b540aSrobert if (REG_P (operands[2])) 762404b540aSrobert operands[2] = gen_rtx_ZERO_EXTEND (TImode, operands[2]); 763404b540aSrobert}) 764404b540aSrobert 765404b540aSrobert(define_insn "*umuldi3_highpart_reg" 766404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 767404b540aSrobert (truncate:DI 768404b540aSrobert (lshiftrt:TI 769404b540aSrobert (mult:TI (zero_extend:TI 770404b540aSrobert (match_operand:DI 1 "register_operand" "r")) 771404b540aSrobert (zero_extend:TI 772404b540aSrobert (match_operand:DI 2 "register_operand" "r"))) 773404b540aSrobert (const_int 64))))] 774404b540aSrobert "" 775404b540aSrobert "umulh %1,%2,%0" 776404b540aSrobert [(set_attr "type" "imul") 777404b540aSrobert (set_attr "opsize" "udi")]) 778404b540aSrobert 779404b540aSrobert(define_insn "*umuldi3_highpart_const" 780404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 781404b540aSrobert (truncate:DI 782404b540aSrobert (lshiftrt:TI 783404b540aSrobert (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "r")) 784404b540aSrobert (match_operand:TI 2 "cint8_operand" "I")) 785404b540aSrobert (const_int 64))))] 786404b540aSrobert "" 787404b540aSrobert "umulh %1,%2,%0" 788404b540aSrobert [(set_attr "type" "imul") 789404b540aSrobert (set_attr "opsize" "udi")]) 790404b540aSrobert 791404b540aSrobert;; The divide and remainder operations take their inputs from r24 and 792404b540aSrobert;; r25, put their output in r27, and clobber r23 and r28 on all 793404b540aSrobert;; systems except Unicos/Mk. On Unicos, the standard library provides 794404b540aSrobert;; subroutines which use the standard calling convention and work on 795404b540aSrobert;; DImode operands. 796404b540aSrobert 797404b540aSrobert;; ??? Force sign-extension here because some versions of OSF/1 and 798404b540aSrobert;; Interix/NT don't do the right thing if the inputs are not properly 799404b540aSrobert;; sign-extended. But Linux, for instance, does not have this 800404b540aSrobert;; problem. Is it worth the complication here to eliminate the sign 801404b540aSrobert;; extension? 802404b540aSrobert 803404b540aSrobert(define_expand "divsi3" 804404b540aSrobert [(set (match_dup 3) 805404b540aSrobert (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" ""))) 806404b540aSrobert (set (match_dup 4) 807404b540aSrobert (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" ""))) 808404b540aSrobert (parallel [(set (match_dup 5) 809404b540aSrobert (sign_extend:DI (div:SI (match_dup 3) (match_dup 4)))) 810404b540aSrobert (clobber (reg:DI 23)) 811404b540aSrobert (clobber (reg:DI 28))]) 812404b540aSrobert (set (match_operand:SI 0 "nonimmediate_operand" "") 813404b540aSrobert (subreg:SI (match_dup 5) 0))] 814404b540aSrobert "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK" 815404b540aSrobert{ 816404b540aSrobert operands[3] = gen_reg_rtx (DImode); 817404b540aSrobert operands[4] = gen_reg_rtx (DImode); 818404b540aSrobert operands[5] = gen_reg_rtx (DImode); 819404b540aSrobert}) 820404b540aSrobert 821404b540aSrobert(define_expand "udivsi3" 822404b540aSrobert [(set (match_dup 3) 823404b540aSrobert (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" ""))) 824404b540aSrobert (set (match_dup 4) 825404b540aSrobert (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" ""))) 826404b540aSrobert (parallel [(set (match_dup 5) 827404b540aSrobert (sign_extend:DI (udiv:SI (match_dup 3) (match_dup 4)))) 828404b540aSrobert (clobber (reg:DI 23)) 829404b540aSrobert (clobber (reg:DI 28))]) 830404b540aSrobert (set (match_operand:SI 0 "nonimmediate_operand" "") 831404b540aSrobert (subreg:SI (match_dup 5) 0))] 832404b540aSrobert "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK" 833404b540aSrobert{ 834404b540aSrobert operands[3] = gen_reg_rtx (DImode); 835404b540aSrobert operands[4] = gen_reg_rtx (DImode); 836404b540aSrobert operands[5] = gen_reg_rtx (DImode); 837404b540aSrobert}) 838404b540aSrobert 839404b540aSrobert(define_expand "modsi3" 840404b540aSrobert [(set (match_dup 3) 841404b540aSrobert (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" ""))) 842404b540aSrobert (set (match_dup 4) 843404b540aSrobert (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" ""))) 844404b540aSrobert (parallel [(set (match_dup 5) 845404b540aSrobert (sign_extend:DI (mod:SI (match_dup 3) (match_dup 4)))) 846404b540aSrobert (clobber (reg:DI 23)) 847404b540aSrobert (clobber (reg:DI 28))]) 848404b540aSrobert (set (match_operand:SI 0 "nonimmediate_operand" "") 849404b540aSrobert (subreg:SI (match_dup 5) 0))] 850404b540aSrobert "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK" 851404b540aSrobert{ 852404b540aSrobert operands[3] = gen_reg_rtx (DImode); 853404b540aSrobert operands[4] = gen_reg_rtx (DImode); 854404b540aSrobert operands[5] = gen_reg_rtx (DImode); 855404b540aSrobert}) 856404b540aSrobert 857404b540aSrobert(define_expand "umodsi3" 858404b540aSrobert [(set (match_dup 3) 859404b540aSrobert (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" ""))) 860404b540aSrobert (set (match_dup 4) 861404b540aSrobert (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" ""))) 862404b540aSrobert (parallel [(set (match_dup 5) 863404b540aSrobert (sign_extend:DI (umod:SI (match_dup 3) (match_dup 4)))) 864404b540aSrobert (clobber (reg:DI 23)) 865404b540aSrobert (clobber (reg:DI 28))]) 866404b540aSrobert (set (match_operand:SI 0 "nonimmediate_operand" "") 867404b540aSrobert (subreg:SI (match_dup 5) 0))] 868404b540aSrobert "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK" 869404b540aSrobert{ 870404b540aSrobert operands[3] = gen_reg_rtx (DImode); 871404b540aSrobert operands[4] = gen_reg_rtx (DImode); 872404b540aSrobert operands[5] = gen_reg_rtx (DImode); 873404b540aSrobert}) 874404b540aSrobert 875404b540aSrobert(define_expand "divdi3" 876404b540aSrobert [(parallel [(set (match_operand:DI 0 "register_operand" "") 877404b540aSrobert (div:DI (match_operand:DI 1 "register_operand" "") 878404b540aSrobert (match_operand:DI 2 "register_operand" ""))) 879404b540aSrobert (clobber (reg:DI 23)) 880404b540aSrobert (clobber (reg:DI 28))])] 881404b540aSrobert "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK" 882404b540aSrobert "") 883404b540aSrobert 884404b540aSrobert(define_expand "udivdi3" 885404b540aSrobert [(parallel [(set (match_operand:DI 0 "register_operand" "") 886404b540aSrobert (udiv:DI (match_operand:DI 1 "register_operand" "") 887404b540aSrobert (match_operand:DI 2 "register_operand" ""))) 888404b540aSrobert (clobber (reg:DI 23)) 889404b540aSrobert (clobber (reg:DI 28))])] 890404b540aSrobert "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK" 891404b540aSrobert "") 892404b540aSrobert 893404b540aSrobert(define_expand "moddi3" 894404b540aSrobert [(use (match_operand:DI 0 "register_operand" "")) 895404b540aSrobert (use (match_operand:DI 1 "register_operand" "")) 896404b540aSrobert (use (match_operand:DI 2 "register_operand" ""))] 897404b540aSrobert "!TARGET_ABI_OPEN_VMS" 898404b540aSrobert{ 899404b540aSrobert if (TARGET_ABI_UNICOSMK) 900404b540aSrobert emit_insn (gen_moddi3_umk (operands[0], operands[1], operands[2])); 901404b540aSrobert else 902404b540aSrobert emit_insn (gen_moddi3_dft (operands[0], operands[1], operands[2])); 903404b540aSrobert DONE; 904404b540aSrobert}) 905404b540aSrobert 906404b540aSrobert(define_expand "moddi3_dft" 907404b540aSrobert [(parallel [(set (match_operand:DI 0 "register_operand" "") 908404b540aSrobert (mod:DI (match_operand:DI 1 "register_operand" "") 909404b540aSrobert (match_operand:DI 2 "register_operand" ""))) 910404b540aSrobert (clobber (reg:DI 23)) 911404b540aSrobert (clobber (reg:DI 28))])] 912404b540aSrobert "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK" 913404b540aSrobert "") 914404b540aSrobert 915404b540aSrobert;; On Unicos/Mk, we do as the system's C compiler does: 916404b540aSrobert;; compute the quotient, multiply and subtract. 917404b540aSrobert 918404b540aSrobert(define_expand "moddi3_umk" 919404b540aSrobert [(use (match_operand:DI 0 "register_operand" "")) 920404b540aSrobert (use (match_operand:DI 1 "register_operand" "")) 921404b540aSrobert (use (match_operand:DI 2 "register_operand" ""))] 922404b540aSrobert "TARGET_ABI_UNICOSMK" 923404b540aSrobert{ 924404b540aSrobert rtx div, mul = gen_reg_rtx (DImode); 925404b540aSrobert 926404b540aSrobert div = expand_binop (DImode, sdiv_optab, operands[1], operands[2], 927404b540aSrobert NULL_RTX, 0, OPTAB_LIB); 928404b540aSrobert div = force_reg (DImode, div); 929404b540aSrobert emit_insn (gen_muldi3 (mul, operands[2], div)); 930404b540aSrobert emit_insn (gen_subdi3 (operands[0], operands[1], mul)); 931404b540aSrobert DONE; 932404b540aSrobert}) 933404b540aSrobert 934404b540aSrobert(define_expand "umoddi3" 935404b540aSrobert [(use (match_operand:DI 0 "register_operand" "")) 936404b540aSrobert (use (match_operand:DI 1 "register_operand" "")) 937404b540aSrobert (use (match_operand:DI 2 "register_operand" ""))] 938404b540aSrobert "! TARGET_ABI_OPEN_VMS" 939404b540aSrobert{ 940404b540aSrobert if (TARGET_ABI_UNICOSMK) 941404b540aSrobert emit_insn (gen_umoddi3_umk (operands[0], operands[1], operands[2])); 942404b540aSrobert else 943404b540aSrobert emit_insn (gen_umoddi3_dft (operands[0], operands[1], operands[2])); 944404b540aSrobert DONE; 945404b540aSrobert}) 946404b540aSrobert 947404b540aSrobert(define_expand "umoddi3_dft" 948404b540aSrobert [(parallel [(set (match_operand:DI 0 "register_operand" "") 949404b540aSrobert (umod:DI (match_operand:DI 1 "register_operand" "") 950404b540aSrobert (match_operand:DI 2 "register_operand" ""))) 951404b540aSrobert (clobber (reg:DI 23)) 952404b540aSrobert (clobber (reg:DI 28))])] 953404b540aSrobert "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK" 954404b540aSrobert "") 955404b540aSrobert 956404b540aSrobert(define_expand "umoddi3_umk" 957404b540aSrobert [(use (match_operand:DI 0 "register_operand" "")) 958404b540aSrobert (use (match_operand:DI 1 "register_operand" "")) 959404b540aSrobert (use (match_operand:DI 2 "register_operand" ""))] 960404b540aSrobert "TARGET_ABI_UNICOSMK" 961404b540aSrobert{ 962404b540aSrobert rtx div, mul = gen_reg_rtx (DImode); 963404b540aSrobert 964404b540aSrobert div = expand_binop (DImode, udiv_optab, operands[1], operands[2], 965404b540aSrobert NULL_RTX, 1, OPTAB_LIB); 966404b540aSrobert div = force_reg (DImode, div); 967404b540aSrobert emit_insn (gen_muldi3 (mul, operands[2], div)); 968404b540aSrobert emit_insn (gen_subdi3 (operands[0], operands[1], mul)); 969404b540aSrobert DONE; 970404b540aSrobert}) 971404b540aSrobert 972404b540aSrobert;; Lengths of 8 for ldq $t12,__divq($gp); jsr $t9,($t12),__divq as 973404b540aSrobert;; expanded by the assembler. 974404b540aSrobert 975404b540aSrobert(define_insn_and_split "*divmodsi_internal_er" 976404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=c") 977404b540aSrobert (sign_extend:DI (match_operator:SI 3 "divmod_operator" 978404b540aSrobert [(match_operand:DI 1 "register_operand" "a") 979404b540aSrobert (match_operand:DI 2 "register_operand" "b")]))) 980404b540aSrobert (clobber (reg:DI 23)) 981404b540aSrobert (clobber (reg:DI 28))] 982404b540aSrobert "TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS" 983404b540aSrobert "#" 984404b540aSrobert "&& reload_completed" 985404b540aSrobert [(parallel [(set (match_dup 0) 986404b540aSrobert (sign_extend:DI (match_dup 3))) 987404b540aSrobert (use (match_dup 0)) 988404b540aSrobert (use (match_dup 4)) 989404b540aSrobert (clobber (reg:DI 23)) 990404b540aSrobert (clobber (reg:DI 28))])] 991404b540aSrobert{ 992404b540aSrobert const char *str; 993404b540aSrobert switch (GET_CODE (operands[3])) 994404b540aSrobert { 995404b540aSrobert case DIV: 996404b540aSrobert str = "__divl"; 997404b540aSrobert break; 998404b540aSrobert case UDIV: 999404b540aSrobert str = "__divlu"; 1000404b540aSrobert break; 1001404b540aSrobert case MOD: 1002404b540aSrobert str = "__reml"; 1003404b540aSrobert break; 1004404b540aSrobert case UMOD: 1005404b540aSrobert str = "__remlu"; 1006404b540aSrobert break; 1007404b540aSrobert default: 1008404b540aSrobert gcc_unreachable (); 1009404b540aSrobert } 1010404b540aSrobert operands[4] = GEN_INT (alpha_next_sequence_number++); 1011404b540aSrobert emit_insn (gen_movdi_er_high_g (operands[0], pic_offset_table_rtx, 1012404b540aSrobert gen_rtx_SYMBOL_REF (DImode, str), 1013404b540aSrobert operands[4])); 1014404b540aSrobert} 1015404b540aSrobert [(set_attr "type" "jsr") 1016404b540aSrobert (set_attr "length" "8")]) 1017404b540aSrobert 1018404b540aSrobert(define_insn "*divmodsi_internal_er_1" 1019404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=c") 1020404b540aSrobert (sign_extend:DI (match_operator:SI 3 "divmod_operator" 1021404b540aSrobert [(match_operand:DI 1 "register_operand" "a") 1022404b540aSrobert (match_operand:DI 2 "register_operand" "b")]))) 1023404b540aSrobert (use (match_operand:DI 4 "register_operand" "c")) 1024404b540aSrobert (use (match_operand 5 "const_int_operand" "")) 1025404b540aSrobert (clobber (reg:DI 23)) 1026404b540aSrobert (clobber (reg:DI 28))] 1027404b540aSrobert "TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS" 1028404b540aSrobert "jsr $23,($27),__%E3%j5" 1029404b540aSrobert [(set_attr "type" "jsr") 1030404b540aSrobert (set_attr "length" "4")]) 1031404b540aSrobert 1032404b540aSrobert(define_insn "*divmodsi_internal" 1033404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=c") 1034404b540aSrobert (sign_extend:DI (match_operator:SI 3 "divmod_operator" 1035404b540aSrobert [(match_operand:DI 1 "register_operand" "a") 1036404b540aSrobert (match_operand:DI 2 "register_operand" "b")]))) 1037404b540aSrobert (clobber (reg:DI 23)) 1038404b540aSrobert (clobber (reg:DI 28))] 1039404b540aSrobert "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK" 1040404b540aSrobert "%E3 %1,%2,%0" 1041404b540aSrobert [(set_attr "type" "jsr") 1042404b540aSrobert (set_attr "length" "8")]) 1043404b540aSrobert 1044404b540aSrobert(define_insn_and_split "*divmoddi_internal_er" 1045404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=c") 1046404b540aSrobert (match_operator:DI 3 "divmod_operator" 1047404b540aSrobert [(match_operand:DI 1 "register_operand" "a") 1048404b540aSrobert (match_operand:DI 2 "register_operand" "b")])) 1049404b540aSrobert (clobber (reg:DI 23)) 1050404b540aSrobert (clobber (reg:DI 28))] 1051404b540aSrobert "TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS" 1052404b540aSrobert "#" 1053404b540aSrobert "&& reload_completed" 1054404b540aSrobert [(parallel [(set (match_dup 0) (match_dup 3)) 1055404b540aSrobert (use (match_dup 0)) 1056404b540aSrobert (use (match_dup 4)) 1057404b540aSrobert (clobber (reg:DI 23)) 1058404b540aSrobert (clobber (reg:DI 28))])] 1059404b540aSrobert{ 1060404b540aSrobert const char *str; 1061404b540aSrobert switch (GET_CODE (operands[3])) 1062404b540aSrobert { 1063404b540aSrobert case DIV: 1064404b540aSrobert str = "__divq"; 1065404b540aSrobert break; 1066404b540aSrobert case UDIV: 1067404b540aSrobert str = "__divqu"; 1068404b540aSrobert break; 1069404b540aSrobert case MOD: 1070404b540aSrobert str = "__remq"; 1071404b540aSrobert break; 1072404b540aSrobert case UMOD: 1073404b540aSrobert str = "__remqu"; 1074404b540aSrobert break; 1075404b540aSrobert default: 1076404b540aSrobert gcc_unreachable (); 1077404b540aSrobert } 1078404b540aSrobert operands[4] = GEN_INT (alpha_next_sequence_number++); 1079404b540aSrobert emit_insn (gen_movdi_er_high_g (operands[0], pic_offset_table_rtx, 1080404b540aSrobert gen_rtx_SYMBOL_REF (DImode, str), 1081404b540aSrobert operands[4])); 1082404b540aSrobert} 1083404b540aSrobert [(set_attr "type" "jsr") 1084404b540aSrobert (set_attr "length" "8")]) 1085404b540aSrobert 1086404b540aSrobert(define_insn "*divmoddi_internal_er_1" 1087404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=c") 1088404b540aSrobert (match_operator:DI 3 "divmod_operator" 1089404b540aSrobert [(match_operand:DI 1 "register_operand" "a") 1090404b540aSrobert (match_operand:DI 2 "register_operand" "b")])) 1091404b540aSrobert (use (match_operand:DI 4 "register_operand" "c")) 1092404b540aSrobert (use (match_operand 5 "const_int_operand" "")) 1093404b540aSrobert (clobber (reg:DI 23)) 1094404b540aSrobert (clobber (reg:DI 28))] 1095404b540aSrobert "TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS" 1096404b540aSrobert "jsr $23,($27),__%E3%j5" 1097404b540aSrobert [(set_attr "type" "jsr") 1098404b540aSrobert (set_attr "length" "4")]) 1099404b540aSrobert 1100404b540aSrobert(define_insn "*divmoddi_internal" 1101404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=c") 1102404b540aSrobert (match_operator:DI 3 "divmod_operator" 1103404b540aSrobert [(match_operand:DI 1 "register_operand" "a") 1104404b540aSrobert (match_operand:DI 2 "register_operand" "b")])) 1105404b540aSrobert (clobber (reg:DI 23)) 1106404b540aSrobert (clobber (reg:DI 28))] 1107404b540aSrobert "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK" 1108404b540aSrobert "%E3 %1,%2,%0" 1109404b540aSrobert [(set_attr "type" "jsr") 1110404b540aSrobert (set_attr "length" "8")]) 1111404b540aSrobert 1112404b540aSrobert;; Next are the basic logical operations. We only expose the DImode operations 1113404b540aSrobert;; to the rtl expanders, but SImode versions exist for combine as well as for 1114404b540aSrobert;; the atomic operation splitters. 1115404b540aSrobert 1116404b540aSrobert(define_insn "*andsi_internal" 1117404b540aSrobert [(set (match_operand:SI 0 "register_operand" "=r,r,r") 1118404b540aSrobert (and:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ") 1119404b540aSrobert (match_operand:SI 2 "and_operand" "rI,N,MH")))] 1120404b540aSrobert "" 1121404b540aSrobert "@ 1122404b540aSrobert and %r1,%2,%0 1123404b540aSrobert bic %r1,%N2,%0 1124404b540aSrobert zapnot %r1,%m2,%0" 1125404b540aSrobert [(set_attr "type" "ilog,ilog,shift")]) 1126404b540aSrobert 1127404b540aSrobert(define_insn "anddi3" 1128404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r,r,r") 1129404b540aSrobert (and:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ") 1130404b540aSrobert (match_operand:DI 2 "and_operand" "rI,N,MH")))] 1131404b540aSrobert "" 1132404b540aSrobert "@ 1133404b540aSrobert and %r1,%2,%0 1134404b540aSrobert bic %r1,%N2,%0 1135404b540aSrobert zapnot %r1,%m2,%0" 1136404b540aSrobert [(set_attr "type" "ilog,ilog,shift")]) 1137404b540aSrobert 1138404b540aSrobert;; There are times when we can split an AND into two AND insns. This occurs 1139404b540aSrobert;; when we can first clear any bytes and then clear anything else. For 1140404b540aSrobert;; example "I & 0xffff07" is "(I & 0xffffff) & 0xffffffffffffff07". 1141404b540aSrobert;; Only do this when running on 64-bit host since the computations are 1142404b540aSrobert;; too messy otherwise. 1143404b540aSrobert 1144404b540aSrobert(define_split 1145404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 1146404b540aSrobert (and:DI (match_operand:DI 1 "register_operand" "") 1147404b540aSrobert (match_operand:DI 2 "const_int_operand" "")))] 1148404b540aSrobert "HOST_BITS_PER_WIDE_INT == 64 && ! and_operand (operands[2], DImode)" 1149404b540aSrobert [(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3))) 1150404b540aSrobert (set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))] 1151404b540aSrobert{ 1152404b540aSrobert unsigned HOST_WIDE_INT mask1 = INTVAL (operands[2]); 1153404b540aSrobert unsigned HOST_WIDE_INT mask2 = mask1; 1154404b540aSrobert int i; 1155404b540aSrobert 1156404b540aSrobert /* For each byte that isn't all zeros, make it all ones. */ 1157404b540aSrobert for (i = 0; i < 64; i += 8) 1158404b540aSrobert if ((mask1 & ((HOST_WIDE_INT) 0xff << i)) != 0) 1159404b540aSrobert mask1 |= (HOST_WIDE_INT) 0xff << i; 1160404b540aSrobert 1161404b540aSrobert /* Now turn on any bits we've just turned off. */ 1162404b540aSrobert mask2 |= ~ mask1; 1163404b540aSrobert 1164404b540aSrobert operands[3] = GEN_INT (mask1); 1165404b540aSrobert operands[4] = GEN_INT (mask2); 1166404b540aSrobert}) 1167404b540aSrobert 1168404b540aSrobert(define_expand "zero_extendqihi2" 1169404b540aSrobert [(set (match_operand:HI 0 "register_operand" "") 1170404b540aSrobert (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))] 1171404b540aSrobert "" 1172404b540aSrobert{ 1173404b540aSrobert if (! TARGET_BWX) 1174404b540aSrobert operands[1] = force_reg (QImode, operands[1]); 1175404b540aSrobert}) 1176404b540aSrobert 1177404b540aSrobert(define_insn "*zero_extendqihi2_bwx" 1178404b540aSrobert [(set (match_operand:HI 0 "register_operand" "=r,r") 1179404b540aSrobert (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))] 1180404b540aSrobert "TARGET_BWX" 1181404b540aSrobert "@ 1182404b540aSrobert and %1,0xff,%0 1183404b540aSrobert ldbu %0,%1" 1184404b540aSrobert [(set_attr "type" "ilog,ild")]) 1185404b540aSrobert 1186404b540aSrobert(define_insn "*zero_extendqihi2_nobwx" 1187404b540aSrobert [(set (match_operand:HI 0 "register_operand" "=r") 1188404b540aSrobert (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))] 1189404b540aSrobert "! TARGET_BWX" 1190404b540aSrobert "and %1,0xff,%0" 1191404b540aSrobert [(set_attr "type" "ilog")]) 1192404b540aSrobert 1193404b540aSrobert(define_expand "zero_extendqisi2" 1194404b540aSrobert [(set (match_operand:SI 0 "register_operand" "") 1195404b540aSrobert (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] 1196404b540aSrobert "" 1197404b540aSrobert{ 1198404b540aSrobert if (! TARGET_BWX) 1199404b540aSrobert operands[1] = force_reg (QImode, operands[1]); 1200404b540aSrobert}) 1201404b540aSrobert 1202404b540aSrobert(define_insn "*zero_extendqisi2_bwx" 1203404b540aSrobert [(set (match_operand:SI 0 "register_operand" "=r,r") 1204404b540aSrobert (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))] 1205404b540aSrobert "TARGET_BWX" 1206404b540aSrobert "@ 1207404b540aSrobert and %1,0xff,%0 1208404b540aSrobert ldbu %0,%1" 1209404b540aSrobert [(set_attr "type" "ilog,ild")]) 1210404b540aSrobert 1211404b540aSrobert(define_insn "*zero_extendqisi2_nobwx" 1212404b540aSrobert [(set (match_operand:SI 0 "register_operand" "=r") 1213404b540aSrobert (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))] 1214404b540aSrobert "! TARGET_BWX" 1215404b540aSrobert "and %1,0xff,%0" 1216404b540aSrobert [(set_attr "type" "ilog")]) 1217404b540aSrobert 1218404b540aSrobert(define_expand "zero_extendqidi2" 1219404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 1220404b540aSrobert (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))] 1221404b540aSrobert "" 1222404b540aSrobert{ 1223404b540aSrobert if (! TARGET_BWX) 1224404b540aSrobert operands[1] = force_reg (QImode, operands[1]); 1225404b540aSrobert}) 1226404b540aSrobert 1227404b540aSrobert(define_insn "*zero_extendqidi2_bwx" 1228404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r,r") 1229404b540aSrobert (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))] 1230404b540aSrobert "TARGET_BWX" 1231404b540aSrobert "@ 1232404b540aSrobert and %1,0xff,%0 1233404b540aSrobert ldbu %0,%1" 1234404b540aSrobert [(set_attr "type" "ilog,ild")]) 1235404b540aSrobert 1236404b540aSrobert(define_insn "*zero_extendqidi2_nobwx" 1237404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 1238404b540aSrobert (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))] 1239404b540aSrobert "! TARGET_BWX" 1240404b540aSrobert "and %1,0xff,%0" 1241404b540aSrobert [(set_attr "type" "ilog")]) 1242404b540aSrobert 1243404b540aSrobert(define_expand "zero_extendhisi2" 1244404b540aSrobert [(set (match_operand:SI 0 "register_operand" "") 1245404b540aSrobert (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] 1246404b540aSrobert "" 1247404b540aSrobert{ 1248404b540aSrobert if (! TARGET_BWX) 1249404b540aSrobert operands[1] = force_reg (HImode, operands[1]); 1250404b540aSrobert}) 1251404b540aSrobert 1252404b540aSrobert(define_insn "*zero_extendhisi2_bwx" 1253404b540aSrobert [(set (match_operand:SI 0 "register_operand" "=r,r") 1254404b540aSrobert (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))] 1255404b540aSrobert "TARGET_BWX" 1256404b540aSrobert "@ 1257404b540aSrobert zapnot %1,3,%0 1258404b540aSrobert ldwu %0,%1" 1259404b540aSrobert [(set_attr "type" "shift,ild")]) 1260404b540aSrobert 1261404b540aSrobert(define_insn "*zero_extendhisi2_nobwx" 1262404b540aSrobert [(set (match_operand:SI 0 "register_operand" "=r") 1263404b540aSrobert (zero_extend:SI (match_operand:HI 1 "register_operand" "r")))] 1264404b540aSrobert "! TARGET_BWX" 1265404b540aSrobert "zapnot %1,3,%0" 1266404b540aSrobert [(set_attr "type" "shift")]) 1267404b540aSrobert 1268404b540aSrobert(define_expand "zero_extendhidi2" 1269404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 1270404b540aSrobert (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))] 1271404b540aSrobert "" 1272404b540aSrobert{ 1273404b540aSrobert if (! TARGET_BWX) 1274404b540aSrobert operands[1] = force_reg (HImode, operands[1]); 1275404b540aSrobert}) 1276404b540aSrobert 1277404b540aSrobert(define_insn "*zero_extendhidi2_bwx" 1278404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r,r") 1279404b540aSrobert (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))] 1280404b540aSrobert "TARGET_BWX" 1281404b540aSrobert "@ 1282404b540aSrobert zapnot %1,3,%0 1283404b540aSrobert ldwu %0,%1" 1284404b540aSrobert [(set_attr "type" "shift,ild")]) 1285404b540aSrobert 1286404b540aSrobert(define_insn "*zero_extendhidi2_nobwx" 1287404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 1288404b540aSrobert (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))] 1289404b540aSrobert "" 1290404b540aSrobert "zapnot %1,3,%0" 1291404b540aSrobert [(set_attr "type" "shift")]) 1292404b540aSrobert 1293404b540aSrobert(define_insn "zero_extendsidi2" 1294404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 1295404b540aSrobert (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))] 1296404b540aSrobert "" 1297404b540aSrobert "zapnot %1,15,%0" 1298404b540aSrobert [(set_attr "type" "shift")]) 1299404b540aSrobert 1300404b540aSrobert(define_insn "*andnotsi3" 1301404b540aSrobert [(set (match_operand:SI 0 "register_operand" "=r") 1302404b540aSrobert (and:SI (not:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")) 1303404b540aSrobert (match_operand:SI 2 "reg_or_0_operand" "rJ")))] 1304404b540aSrobert "" 1305404b540aSrobert "bic %r2,%1,%0" 1306404b540aSrobert [(set_attr "type" "ilog")]) 1307404b540aSrobert 1308404b540aSrobert(define_insn "andnotdi3" 1309404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 1310404b540aSrobert (and:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")) 1311404b540aSrobert (match_operand:DI 2 "reg_or_0_operand" "rJ")))] 1312404b540aSrobert "" 1313404b540aSrobert "bic %r2,%1,%0" 1314404b540aSrobert [(set_attr "type" "ilog")]) 1315404b540aSrobert 1316404b540aSrobert(define_insn "*iorsi_internal" 1317404b540aSrobert [(set (match_operand:SI 0 "register_operand" "=r,r") 1318404b540aSrobert (ior:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ") 1319404b540aSrobert (match_operand:SI 2 "or_operand" "rI,N")))] 1320404b540aSrobert "" 1321404b540aSrobert "@ 1322404b540aSrobert bis %r1,%2,%0 1323404b540aSrobert ornot %r1,%N2,%0" 1324404b540aSrobert [(set_attr "type" "ilog")]) 1325404b540aSrobert 1326404b540aSrobert(define_insn "iordi3" 1327404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r,r") 1328404b540aSrobert (ior:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ") 1329404b540aSrobert (match_operand:DI 2 "or_operand" "rI,N")))] 1330404b540aSrobert "" 1331404b540aSrobert "@ 1332404b540aSrobert bis %r1,%2,%0 1333404b540aSrobert ornot %r1,%N2,%0" 1334404b540aSrobert [(set_attr "type" "ilog")]) 1335404b540aSrobert 1336404b540aSrobert(define_insn "*one_cmplsi_internal" 1337404b540aSrobert [(set (match_operand:SI 0 "register_operand" "=r") 1338404b540aSrobert (not:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")))] 1339404b540aSrobert "" 1340404b540aSrobert "ornot $31,%1,%0" 1341404b540aSrobert [(set_attr "type" "ilog")]) 1342404b540aSrobert 1343404b540aSrobert(define_insn "one_cmpldi2" 1344404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 1345404b540aSrobert (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))] 1346404b540aSrobert "" 1347404b540aSrobert "ornot $31,%1,%0" 1348404b540aSrobert [(set_attr "type" "ilog")]) 1349404b540aSrobert 1350404b540aSrobert(define_insn "*iornotsi3" 1351404b540aSrobert [(set (match_operand:SI 0 "register_operand" "=r") 1352404b540aSrobert (ior:SI (not:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")) 1353404b540aSrobert (match_operand:SI 2 "reg_or_0_operand" "rJ")))] 1354404b540aSrobert "" 1355404b540aSrobert "ornot %r2,%1,%0" 1356404b540aSrobert [(set_attr "type" "ilog")]) 1357404b540aSrobert 1358404b540aSrobert(define_insn "*iornotdi3" 1359404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 1360404b540aSrobert (ior:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")) 1361404b540aSrobert (match_operand:DI 2 "reg_or_0_operand" "rJ")))] 1362404b540aSrobert "" 1363404b540aSrobert "ornot %r2,%1,%0" 1364404b540aSrobert [(set_attr "type" "ilog")]) 1365404b540aSrobert 1366404b540aSrobert(define_insn "*xorsi_internal" 1367404b540aSrobert [(set (match_operand:SI 0 "register_operand" "=r,r") 1368404b540aSrobert (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ") 1369404b540aSrobert (match_operand:SI 2 "or_operand" "rI,N")))] 1370404b540aSrobert "" 1371404b540aSrobert "@ 1372404b540aSrobert xor %r1,%2,%0 1373404b540aSrobert eqv %r1,%N2,%0" 1374404b540aSrobert [(set_attr "type" "ilog")]) 1375404b540aSrobert 1376404b540aSrobert(define_insn "xordi3" 1377404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r,r") 1378404b540aSrobert (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ") 1379404b540aSrobert (match_operand:DI 2 "or_operand" "rI,N")))] 1380404b540aSrobert "" 1381404b540aSrobert "@ 1382404b540aSrobert xor %r1,%2,%0 1383404b540aSrobert eqv %r1,%N2,%0" 1384404b540aSrobert [(set_attr "type" "ilog")]) 1385404b540aSrobert 1386404b540aSrobert(define_insn "*xornotsi3" 1387404b540aSrobert [(set (match_operand:SI 0 "register_operand" "=r") 1388404b540aSrobert (not:SI (xor:SI (match_operand:SI 1 "register_operand" "%rJ") 1389404b540aSrobert (match_operand:SI 2 "register_operand" "rI"))))] 1390404b540aSrobert "" 1391404b540aSrobert "eqv %r1,%2,%0" 1392404b540aSrobert [(set_attr "type" "ilog")]) 1393404b540aSrobert 1394404b540aSrobert(define_insn "*xornotdi3" 1395404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 1396404b540aSrobert (not:DI (xor:DI (match_operand:DI 1 "register_operand" "%rJ") 1397404b540aSrobert (match_operand:DI 2 "register_operand" "rI"))))] 1398404b540aSrobert "" 1399404b540aSrobert "eqv %r1,%2,%0" 1400404b540aSrobert [(set_attr "type" "ilog")]) 1401404b540aSrobert 1402404b540aSrobert;; Handle FFS and related insns iff we support CIX. 1403404b540aSrobert 1404404b540aSrobert(define_expand "ffsdi2" 1405404b540aSrobert [(set (match_dup 2) 1406404b540aSrobert (ctz:DI (match_operand:DI 1 "register_operand" ""))) 1407404b540aSrobert (set (match_dup 3) 1408404b540aSrobert (plus:DI (match_dup 2) (const_int 1))) 1409404b540aSrobert (set (match_operand:DI 0 "register_operand" "") 1410404b540aSrobert (if_then_else:DI (eq (match_dup 1) (const_int 0)) 1411404b540aSrobert (const_int 0) (match_dup 3)))] 1412404b540aSrobert "TARGET_CIX" 1413404b540aSrobert{ 1414404b540aSrobert operands[2] = gen_reg_rtx (DImode); 1415404b540aSrobert operands[3] = gen_reg_rtx (DImode); 1416404b540aSrobert}) 1417404b540aSrobert 1418404b540aSrobert(define_insn "clzdi2" 1419404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 1420404b540aSrobert (clz:DI (match_operand:DI 1 "register_operand" "r")))] 1421404b540aSrobert "TARGET_CIX" 1422404b540aSrobert "ctlz %1,%0" 1423404b540aSrobert [(set_attr "type" "mvi")]) 1424404b540aSrobert 1425404b540aSrobert(define_insn "ctzdi2" 1426404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 1427404b540aSrobert (ctz:DI (match_operand:DI 1 "register_operand" "r")))] 1428404b540aSrobert "TARGET_CIX" 1429404b540aSrobert "cttz %1,%0" 1430404b540aSrobert [(set_attr "type" "mvi")]) 1431404b540aSrobert 1432404b540aSrobert(define_insn "popcountdi2" 1433404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 1434404b540aSrobert (popcount:DI (match_operand:DI 1 "register_operand" "r")))] 1435404b540aSrobert "TARGET_CIX" 1436404b540aSrobert "ctpop %1,%0" 1437404b540aSrobert [(set_attr "type" "mvi")]) 1438404b540aSrobert 1439404b540aSrobert;; Next come the shifts and the various extract and insert operations. 1440404b540aSrobert 1441404b540aSrobert(define_insn "ashldi3" 1442404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r,r") 1443404b540aSrobert (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ") 1444404b540aSrobert (match_operand:DI 2 "reg_or_6bit_operand" "P,rS")))] 1445404b540aSrobert "" 1446404b540aSrobert{ 1447404b540aSrobert switch (which_alternative) 1448404b540aSrobert { 1449404b540aSrobert case 0: 1450404b540aSrobert if (operands[2] == const1_rtx) 1451404b540aSrobert return "addq %r1,%r1,%0"; 1452404b540aSrobert else 1453404b540aSrobert return "s%P2addq %r1,0,%0"; 1454404b540aSrobert case 1: 1455404b540aSrobert return "sll %r1,%2,%0"; 1456404b540aSrobert default: 1457404b540aSrobert gcc_unreachable (); 1458404b540aSrobert } 1459404b540aSrobert} 1460404b540aSrobert [(set_attr "type" "iadd,shift")]) 1461404b540aSrobert 1462404b540aSrobert(define_insn "*ashldi_se" 1463404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 1464404b540aSrobert (sign_extend:DI 1465404b540aSrobert (subreg:SI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") 1466404b540aSrobert (match_operand:DI 2 "const_int_operand" "P")) 1467404b540aSrobert 0)))] 1468404b540aSrobert "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3" 1469404b540aSrobert{ 1470404b540aSrobert if (operands[2] == const1_rtx) 1471404b540aSrobert return "addl %r1,%r1,%0"; 1472404b540aSrobert else 1473404b540aSrobert return "s%P2addl %r1,0,%0"; 1474404b540aSrobert} 1475404b540aSrobert [(set_attr "type" "iadd")]) 1476404b540aSrobert 1477404b540aSrobert(define_insn "lshrdi3" 1478404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 1479404b540aSrobert (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") 1480404b540aSrobert (match_operand:DI 2 "reg_or_6bit_operand" "rS")))] 1481404b540aSrobert "" 1482404b540aSrobert "srl %r1,%2,%0" 1483404b540aSrobert [(set_attr "type" "shift")]) 1484404b540aSrobert 1485404b540aSrobert(define_insn "ashrdi3" 1486404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 1487404b540aSrobert (ashiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") 1488404b540aSrobert (match_operand:DI 2 "reg_or_6bit_operand" "rS")))] 1489404b540aSrobert "" 1490404b540aSrobert "sra %r1,%2,%0" 1491404b540aSrobert [(set_attr "type" "shift")]) 1492404b540aSrobert 1493404b540aSrobert(define_expand "extendqihi2" 1494404b540aSrobert [(set (match_dup 2) 1495404b540aSrobert (ashift:DI (match_operand:QI 1 "some_operand" "") 1496404b540aSrobert (const_int 56))) 1497404b540aSrobert (set (match_operand:HI 0 "register_operand" "") 1498404b540aSrobert (ashiftrt:DI (match_dup 2) 1499404b540aSrobert (const_int 56)))] 1500404b540aSrobert "" 1501404b540aSrobert{ 1502404b540aSrobert if (TARGET_BWX) 1503404b540aSrobert { 1504404b540aSrobert emit_insn (gen_extendqihi2x (operands[0], 1505404b540aSrobert force_reg (QImode, operands[1]))); 1506404b540aSrobert DONE; 1507404b540aSrobert } 1508404b540aSrobert 1509404b540aSrobert /* If we have an unaligned MEM, extend to DImode (which we do 1510404b540aSrobert specially) and then copy to the result. */ 1511404b540aSrobert if (unaligned_memory_operand (operands[1], HImode)) 1512404b540aSrobert { 1513404b540aSrobert rtx temp = gen_reg_rtx (DImode); 1514404b540aSrobert 1515404b540aSrobert emit_insn (gen_extendqidi2 (temp, operands[1])); 1516404b540aSrobert emit_move_insn (operands[0], gen_lowpart (HImode, temp)); 1517404b540aSrobert DONE; 1518404b540aSrobert } 1519404b540aSrobert 1520404b540aSrobert operands[0] = gen_lowpart (DImode, operands[0]); 1521404b540aSrobert operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1])); 1522404b540aSrobert operands[2] = gen_reg_rtx (DImode); 1523404b540aSrobert}) 1524404b540aSrobert 1525404b540aSrobert(define_insn "extendqidi2x" 1526404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 1527404b540aSrobert (sign_extend:DI (match_operand:QI 1 "register_operand" "r")))] 1528404b540aSrobert "TARGET_BWX" 1529404b540aSrobert "sextb %1,%0" 1530404b540aSrobert [(set_attr "type" "shift")]) 1531404b540aSrobert 1532404b540aSrobert(define_insn "extendhidi2x" 1533404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 1534404b540aSrobert (sign_extend:DI (match_operand:HI 1 "register_operand" "r")))] 1535404b540aSrobert "TARGET_BWX" 1536404b540aSrobert "sextw %1,%0" 1537404b540aSrobert [(set_attr "type" "shift")]) 1538404b540aSrobert 1539404b540aSrobert(define_insn "extendqisi2x" 1540404b540aSrobert [(set (match_operand:SI 0 "register_operand" "=r") 1541404b540aSrobert (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))] 1542404b540aSrobert "TARGET_BWX" 1543404b540aSrobert "sextb %1,%0" 1544404b540aSrobert [(set_attr "type" "shift")]) 1545404b540aSrobert 1546404b540aSrobert(define_insn "extendhisi2x" 1547404b540aSrobert [(set (match_operand:SI 0 "register_operand" "=r") 1548404b540aSrobert (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))] 1549404b540aSrobert "TARGET_BWX" 1550404b540aSrobert "sextw %1,%0" 1551404b540aSrobert [(set_attr "type" "shift")]) 1552404b540aSrobert 1553404b540aSrobert(define_insn "extendqihi2x" 1554404b540aSrobert [(set (match_operand:HI 0 "register_operand" "=r") 1555404b540aSrobert (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))] 1556404b540aSrobert "TARGET_BWX" 1557404b540aSrobert "sextb %1,%0" 1558404b540aSrobert [(set_attr "type" "shift")]) 1559404b540aSrobert 1560404b540aSrobert(define_expand "extendqisi2" 1561404b540aSrobert [(set (match_dup 2) 1562404b540aSrobert (ashift:DI (match_operand:QI 1 "some_operand" "") 1563404b540aSrobert (const_int 56))) 1564404b540aSrobert (set (match_operand:SI 0 "register_operand" "") 1565404b540aSrobert (ashiftrt:DI (match_dup 2) 1566404b540aSrobert (const_int 56)))] 1567404b540aSrobert "" 1568404b540aSrobert{ 1569404b540aSrobert if (TARGET_BWX) 1570404b540aSrobert { 1571404b540aSrobert emit_insn (gen_extendqisi2x (operands[0], 1572404b540aSrobert force_reg (QImode, operands[1]))); 1573404b540aSrobert DONE; 1574404b540aSrobert } 1575404b540aSrobert 1576404b540aSrobert /* If we have an unaligned MEM, extend to a DImode form of 1577404b540aSrobert the result (which we do specially). */ 1578404b540aSrobert if (unaligned_memory_operand (operands[1], QImode)) 1579404b540aSrobert { 1580404b540aSrobert rtx temp = gen_reg_rtx (DImode); 1581404b540aSrobert 1582404b540aSrobert emit_insn (gen_extendqidi2 (temp, operands[1])); 1583404b540aSrobert emit_move_insn (operands[0], gen_lowpart (SImode, temp)); 1584404b540aSrobert DONE; 1585404b540aSrobert } 1586404b540aSrobert 1587404b540aSrobert operands[0] = gen_lowpart (DImode, operands[0]); 1588404b540aSrobert operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1])); 1589404b540aSrobert operands[2] = gen_reg_rtx (DImode); 1590404b540aSrobert}) 1591404b540aSrobert 1592404b540aSrobert(define_expand "extendqidi2" 1593404b540aSrobert [(set (match_dup 2) 1594404b540aSrobert (ashift:DI (match_operand:QI 1 "some_operand" "") 1595404b540aSrobert (const_int 56))) 1596404b540aSrobert (set (match_operand:DI 0 "register_operand" "") 1597404b540aSrobert (ashiftrt:DI (match_dup 2) 1598404b540aSrobert (const_int 56)))] 1599404b540aSrobert "" 1600404b540aSrobert{ 1601404b540aSrobert if (TARGET_BWX) 1602404b540aSrobert { 1603404b540aSrobert emit_insn (gen_extendqidi2x (operands[0], 1604404b540aSrobert force_reg (QImode, operands[1]))); 1605404b540aSrobert DONE; 1606404b540aSrobert } 1607404b540aSrobert 1608404b540aSrobert if (unaligned_memory_operand (operands[1], QImode)) 1609404b540aSrobert { 1610404b540aSrobert rtx seq = gen_unaligned_extendqidi (operands[0], XEXP (operands[1], 0)); 1611404b540aSrobert alpha_set_memflags (seq, operands[1]); 1612404b540aSrobert emit_insn (seq); 1613404b540aSrobert DONE; 1614404b540aSrobert } 1615404b540aSrobert 1616404b540aSrobert operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1])); 1617404b540aSrobert operands[2] = gen_reg_rtx (DImode); 1618404b540aSrobert}) 1619404b540aSrobert 1620404b540aSrobert(define_expand "extendhisi2" 1621404b540aSrobert [(set (match_dup 2) 1622404b540aSrobert (ashift:DI (match_operand:HI 1 "some_operand" "") 1623404b540aSrobert (const_int 48))) 1624404b540aSrobert (set (match_operand:SI 0 "register_operand" "") 1625404b540aSrobert (ashiftrt:DI (match_dup 2) 1626404b540aSrobert (const_int 48)))] 1627404b540aSrobert "" 1628404b540aSrobert{ 1629404b540aSrobert if (TARGET_BWX) 1630404b540aSrobert { 1631404b540aSrobert emit_insn (gen_extendhisi2x (operands[0], 1632404b540aSrobert force_reg (HImode, operands[1]))); 1633404b540aSrobert DONE; 1634404b540aSrobert } 1635404b540aSrobert 1636404b540aSrobert /* If we have an unaligned MEM, extend to a DImode form of 1637404b540aSrobert the result (which we do specially). */ 1638404b540aSrobert if (unaligned_memory_operand (operands[1], HImode)) 1639404b540aSrobert { 1640404b540aSrobert rtx temp = gen_reg_rtx (DImode); 1641404b540aSrobert 1642404b540aSrobert emit_insn (gen_extendhidi2 (temp, operands[1])); 1643404b540aSrobert emit_move_insn (operands[0], gen_lowpart (SImode, temp)); 1644404b540aSrobert DONE; 1645404b540aSrobert } 1646404b540aSrobert 1647404b540aSrobert operands[0] = gen_lowpart (DImode, operands[0]); 1648404b540aSrobert operands[1] = gen_lowpart (DImode, force_reg (HImode, operands[1])); 1649404b540aSrobert operands[2] = gen_reg_rtx (DImode); 1650404b540aSrobert}) 1651404b540aSrobert 1652404b540aSrobert(define_expand "extendhidi2" 1653404b540aSrobert [(set (match_dup 2) 1654404b540aSrobert (ashift:DI (match_operand:HI 1 "some_operand" "") 1655404b540aSrobert (const_int 48))) 1656404b540aSrobert (set (match_operand:DI 0 "register_operand" "") 1657404b540aSrobert (ashiftrt:DI (match_dup 2) 1658404b540aSrobert (const_int 48)))] 1659404b540aSrobert "" 1660404b540aSrobert{ 1661404b540aSrobert if (TARGET_BWX) 1662404b540aSrobert { 1663404b540aSrobert emit_insn (gen_extendhidi2x (operands[0], 1664404b540aSrobert force_reg (HImode, operands[1]))); 1665404b540aSrobert DONE; 1666404b540aSrobert } 1667404b540aSrobert 1668404b540aSrobert if (unaligned_memory_operand (operands[1], HImode)) 1669404b540aSrobert { 1670404b540aSrobert rtx seq = gen_unaligned_extendhidi (operands[0], XEXP (operands[1], 0)); 1671404b540aSrobert 1672404b540aSrobert alpha_set_memflags (seq, operands[1]); 1673404b540aSrobert emit_insn (seq); 1674404b540aSrobert DONE; 1675404b540aSrobert } 1676404b540aSrobert 1677404b540aSrobert operands[1] = gen_lowpart (DImode, force_reg (HImode, operands[1])); 1678404b540aSrobert operands[2] = gen_reg_rtx (DImode); 1679404b540aSrobert}) 1680404b540aSrobert 1681404b540aSrobert;; Here's how we sign extend an unaligned byte and halfword. Doing this 1682404b540aSrobert;; as a pattern saves one instruction. The code is similar to that for 1683404b540aSrobert;; the unaligned loads (see below). 1684404b540aSrobert;; 1685404b540aSrobert;; Operand 1 is the address, operand 0 is the result. 1686404b540aSrobert(define_expand "unaligned_extendqidi" 1687404b540aSrobert [(use (match_operand:QI 0 "register_operand" "")) 1688404b540aSrobert (use (match_operand:DI 1 "address_operand" ""))] 1689404b540aSrobert "" 1690404b540aSrobert{ 1691404b540aSrobert operands[0] = gen_lowpart (DImode, operands[0]); 1692404b540aSrobert if (WORDS_BIG_ENDIAN) 1693404b540aSrobert emit_insn (gen_unaligned_extendqidi_be (operands[0], operands[1])); 1694404b540aSrobert else 1695404b540aSrobert emit_insn (gen_unaligned_extendqidi_le (operands[0], operands[1])); 1696404b540aSrobert DONE; 1697404b540aSrobert}) 1698404b540aSrobert 1699404b540aSrobert(define_expand "unaligned_extendqidi_le" 1700404b540aSrobert [(set (match_dup 3) 1701404b540aSrobert (mem:DI (and:DI (match_operand:DI 1 "" "") (const_int -8)))) 1702404b540aSrobert (set (match_dup 4) 1703404b540aSrobert (ashift:DI (match_dup 3) 1704*7014c930Smartynas (minus:DI (const_int 56) 1705404b540aSrobert (ashift:DI 1706*7014c930Smartynas (and:DI (plus:DI (match_dup 2) (const_int -1)) 1707*7014c930Smartynas (const_int 7)) 1708404b540aSrobert (const_int 3))))) 1709404b540aSrobert (set (match_operand:DI 0 "register_operand" "") 1710404b540aSrobert (ashiftrt:DI (match_dup 4) (const_int 56)))] 1711404b540aSrobert "! WORDS_BIG_ENDIAN" 1712404b540aSrobert{ 1713404b540aSrobert operands[2] = get_unaligned_offset (operands[1], 1); 1714404b540aSrobert operands[3] = gen_reg_rtx (DImode); 1715404b540aSrobert operands[4] = gen_reg_rtx (DImode); 1716404b540aSrobert}) 1717404b540aSrobert 1718404b540aSrobert(define_expand "unaligned_extendqidi_be" 1719404b540aSrobert [(set (match_dup 3) 1720404b540aSrobert (mem:DI (and:DI (match_operand:DI 1 "" "") (const_int -8)))) 1721404b540aSrobert (set (match_dup 4) 1722404b540aSrobert (ashift:DI (match_dup 3) 1723404b540aSrobert (ashift:DI 1724404b540aSrobert (and:DI 1725404b540aSrobert (plus:DI (match_dup 2) (const_int 1)) 1726404b540aSrobert (const_int 7)) 1727404b540aSrobert (const_int 3)))) 1728404b540aSrobert (set (match_operand:DI 0 "register_operand" "") 1729404b540aSrobert (ashiftrt:DI (match_dup 4) (const_int 56)))] 1730404b540aSrobert "WORDS_BIG_ENDIAN" 1731404b540aSrobert{ 1732404b540aSrobert operands[2] = get_unaligned_offset (operands[1], -1); 1733404b540aSrobert operands[3] = gen_reg_rtx (DImode); 1734404b540aSrobert operands[4] = gen_reg_rtx (DImode); 1735404b540aSrobert}) 1736404b540aSrobert 1737404b540aSrobert(define_expand "unaligned_extendhidi" 1738404b540aSrobert [(use (match_operand:QI 0 "register_operand" "")) 1739404b540aSrobert (use (match_operand:DI 1 "address_operand" ""))] 1740404b540aSrobert "" 1741404b540aSrobert{ 1742404b540aSrobert operands[0] = gen_lowpart (DImode, operands[0]); 1743404b540aSrobert if (WORDS_BIG_ENDIAN) 1744404b540aSrobert emit_insn (gen_unaligned_extendhidi_be (operands[0], operands[1])); 1745404b540aSrobert else 1746404b540aSrobert emit_insn (gen_unaligned_extendhidi_le (operands[0], operands[1])); 1747404b540aSrobert DONE; 1748404b540aSrobert}) 1749404b540aSrobert 1750404b540aSrobert(define_expand "unaligned_extendhidi_le" 1751404b540aSrobert [(set (match_dup 3) 1752404b540aSrobert (mem:DI (and:DI (match_operand:DI 1 "" "") (const_int -8)))) 1753404b540aSrobert (set (match_dup 4) 1754404b540aSrobert (ashift:DI (match_dup 3) 1755*7014c930Smartynas (minus:DI (const_int 56) 1756404b540aSrobert (ashift:DI 1757*7014c930Smartynas (and:DI (plus:DI (match_dup 2) (const_int -1)) 1758*7014c930Smartynas (const_int 7)) 1759404b540aSrobert (const_int 3))))) 1760404b540aSrobert (set (match_operand:DI 0 "register_operand" "") 1761404b540aSrobert (ashiftrt:DI (match_dup 4) (const_int 48)))] 1762404b540aSrobert "! WORDS_BIG_ENDIAN" 1763404b540aSrobert{ 1764404b540aSrobert operands[2] = get_unaligned_offset (operands[1], 2); 1765404b540aSrobert operands[3] = gen_reg_rtx (DImode); 1766404b540aSrobert operands[4] = gen_reg_rtx (DImode); 1767404b540aSrobert}) 1768404b540aSrobert 1769404b540aSrobert(define_expand "unaligned_extendhidi_be" 1770404b540aSrobert [(set (match_dup 3) 1771404b540aSrobert (mem:DI (and:DI (match_operand:DI 1 "" "") (const_int -8)))) 1772404b540aSrobert (set (match_dup 4) 1773404b540aSrobert (ashift:DI (match_dup 3) 1774404b540aSrobert (ashift:DI 1775404b540aSrobert (and:DI 1776404b540aSrobert (plus:DI (match_dup 2) (const_int 1)) 1777404b540aSrobert (const_int 7)) 1778404b540aSrobert (const_int 3)))) 1779404b540aSrobert (set (match_operand:DI 0 "register_operand" "") 1780404b540aSrobert (ashiftrt:DI (match_dup 4) (const_int 48)))] 1781404b540aSrobert "WORDS_BIG_ENDIAN" 1782404b540aSrobert{ 1783404b540aSrobert operands[2] = get_unaligned_offset (operands[1], -1); 1784404b540aSrobert operands[3] = gen_reg_rtx (DImode); 1785404b540aSrobert operands[4] = gen_reg_rtx (DImode); 1786404b540aSrobert}) 1787404b540aSrobert 1788404b540aSrobert(define_insn "*extxl_const" 1789404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 1790404b540aSrobert (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") 1791404b540aSrobert (match_operand:DI 2 "mode_width_operand" "n") 1792404b540aSrobert (match_operand:DI 3 "mul8_operand" "I")))] 1793404b540aSrobert "" 1794404b540aSrobert "ext%M2l %r1,%s3,%0" 1795404b540aSrobert [(set_attr "type" "shift")]) 1796404b540aSrobert 1797404b540aSrobert(define_insn "extxl_le" 1798404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 1799404b540aSrobert (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") 1800404b540aSrobert (match_operand:DI 2 "mode_width_operand" "n") 1801404b540aSrobert (ashift:DI (match_operand:DI 3 "reg_or_8bit_operand" "rI") 1802404b540aSrobert (const_int 3))))] 1803404b540aSrobert "! WORDS_BIG_ENDIAN" 1804404b540aSrobert "ext%M2l %r1,%3,%0" 1805404b540aSrobert [(set_attr "type" "shift")]) 1806404b540aSrobert 1807404b540aSrobert(define_insn "extxl_be" 1808404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 1809404b540aSrobert (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") 1810404b540aSrobert (match_operand:DI 2 "mode_width_operand" "n") 1811404b540aSrobert (minus:DI 1812404b540aSrobert (const_int 56) 1813404b540aSrobert (ashift:DI 1814404b540aSrobert (match_operand:DI 3 "reg_or_8bit_operand" "rI") 1815404b540aSrobert (const_int 3)))))] 1816404b540aSrobert "WORDS_BIG_ENDIAN" 1817404b540aSrobert "ext%M2l %r1,%3,%0" 1818404b540aSrobert [(set_attr "type" "shift")]) 1819404b540aSrobert 1820404b540aSrobert;; Combine has some strange notion of preserving existing undefined behavior 1821404b540aSrobert;; in shifts larger than a word size. So capture these patterns that it 1822404b540aSrobert;; should have turned into zero_extracts. 1823404b540aSrobert 1824404b540aSrobert(define_insn "*extxl_1_le" 1825404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 1826404b540aSrobert (and:DI (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") 1827404b540aSrobert (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") 1828404b540aSrobert (const_int 3))) 1829404b540aSrobert (match_operand:DI 3 "mode_mask_operand" "n")))] 1830404b540aSrobert "! WORDS_BIG_ENDIAN" 1831404b540aSrobert "ext%U3l %1,%2,%0" 1832404b540aSrobert [(set_attr "type" "shift")]) 1833404b540aSrobert 1834404b540aSrobert(define_insn "*extxl_1_be" 1835404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 1836404b540aSrobert (and:DI (lshiftrt:DI 1837404b540aSrobert (match_operand:DI 1 "reg_or_0_operand" "rJ") 1838404b540aSrobert (minus:DI (const_int 56) 1839404b540aSrobert (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") 1840404b540aSrobert (const_int 3)))) 1841404b540aSrobert (match_operand:DI 3 "mode_mask_operand" "n")))] 1842404b540aSrobert "WORDS_BIG_ENDIAN" 1843404b540aSrobert "ext%U3l %1,%2,%0" 1844404b540aSrobert [(set_attr "type" "shift")]) 1845404b540aSrobert 1846404b540aSrobert(define_insn "*extql_2_le" 1847404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 1848404b540aSrobert (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") 1849404b540aSrobert (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") 1850404b540aSrobert (const_int 3))))] 1851404b540aSrobert "! WORDS_BIG_ENDIAN" 1852404b540aSrobert "extql %1,%2,%0" 1853404b540aSrobert [(set_attr "type" "shift")]) 1854404b540aSrobert 1855404b540aSrobert(define_insn "*extql_2_be" 1856404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 1857404b540aSrobert (lshiftrt:DI 1858404b540aSrobert (match_operand:DI 1 "reg_or_0_operand" "rJ") 1859404b540aSrobert (minus:DI (const_int 56) 1860404b540aSrobert (ashift:DI 1861404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "rI") 1862404b540aSrobert (const_int 3)))))] 1863404b540aSrobert "WORDS_BIG_ENDIAN" 1864404b540aSrobert "extql %1,%2,%0" 1865404b540aSrobert [(set_attr "type" "shift")]) 1866404b540aSrobert 1867404b540aSrobert(define_insn "extqh_le" 1868404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 1869404b540aSrobert (ashift:DI 1870404b540aSrobert (match_operand:DI 1 "reg_or_0_operand" "rJ") 1871*7014c930Smartynas (minus:DI (const_int 56) 1872404b540aSrobert (ashift:DI 1873404b540aSrobert (and:DI 1874*7014c930Smartynas (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") 1875*7014c930Smartynas (const_int -1)) 1876404b540aSrobert (const_int 7)) 1877404b540aSrobert (const_int 3)))))] 1878404b540aSrobert "! WORDS_BIG_ENDIAN" 1879404b540aSrobert "extqh %r1,%2,%0" 1880404b540aSrobert [(set_attr "type" "shift")]) 1881404b540aSrobert 1882404b540aSrobert(define_insn "extqh_be" 1883404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 1884404b540aSrobert (ashift:DI 1885404b540aSrobert (match_operand:DI 1 "reg_or_0_operand" "rJ") 1886404b540aSrobert (ashift:DI 1887404b540aSrobert (and:DI 1888404b540aSrobert (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") 1889404b540aSrobert (const_int 1)) 1890404b540aSrobert (const_int 7)) 1891404b540aSrobert (const_int 3))))] 1892404b540aSrobert "WORDS_BIG_ENDIAN" 1893404b540aSrobert "extqh %r1,%2,%0" 1894404b540aSrobert [(set_attr "type" "shift")]) 1895404b540aSrobert 1896404b540aSrobert(define_insn "extlh_le" 1897404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 1898404b540aSrobert (ashift:DI 1899404b540aSrobert (and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") 1900404b540aSrobert (const_int 2147483647)) 1901*7014c930Smartynas (minus:DI (const_int 56) 1902404b540aSrobert (ashift:DI 1903404b540aSrobert (and:DI 1904*7014c930Smartynas (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") 1905*7014c930Smartynas (const_int -1)) 1906404b540aSrobert (const_int 7)) 1907404b540aSrobert (const_int 3)))))] 1908404b540aSrobert "! WORDS_BIG_ENDIAN" 1909404b540aSrobert "extlh %r1,%2,%0" 1910404b540aSrobert [(set_attr "type" "shift")]) 1911404b540aSrobert 1912404b540aSrobert(define_insn "extlh_be" 1913404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 1914404b540aSrobert (and:DI 1915404b540aSrobert (ashift:DI 1916404b540aSrobert (match_operand:DI 1 "reg_or_0_operand" "rJ") 1917404b540aSrobert (ashift:DI 1918404b540aSrobert (and:DI 1919404b540aSrobert (plus:DI 1920404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "rI") 1921404b540aSrobert (const_int 1)) 1922404b540aSrobert (const_int 7)) 1923404b540aSrobert (const_int 3))) 1924404b540aSrobert (const_int 2147483647)))] 1925404b540aSrobert "WORDS_BIG_ENDIAN" 1926404b540aSrobert "extlh %r1,%2,%0" 1927404b540aSrobert [(set_attr "type" "shift")]) 1928404b540aSrobert 1929404b540aSrobert(define_insn "extwh_le" 1930404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 1931404b540aSrobert (ashift:DI 1932404b540aSrobert (and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") 1933404b540aSrobert (const_int 65535)) 1934*7014c930Smartynas (minus:DI (const_int 56) 1935404b540aSrobert (ashift:DI 1936404b540aSrobert (and:DI 1937*7014c930Smartynas (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") 1938*7014c930Smartynas (const_int -1)) 1939404b540aSrobert (const_int 7)) 1940404b540aSrobert (const_int 3)))))] 1941404b540aSrobert "! WORDS_BIG_ENDIAN" 1942404b540aSrobert "extwh %r1,%2,%0" 1943404b540aSrobert [(set_attr "type" "shift")]) 1944404b540aSrobert 1945404b540aSrobert(define_insn "extwh_be" 1946404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 1947404b540aSrobert (and:DI 1948404b540aSrobert (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") 1949404b540aSrobert (ashift:DI 1950404b540aSrobert (and:DI 1951404b540aSrobert (plus:DI 1952404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "rI") 1953404b540aSrobert (const_int 1)) 1954404b540aSrobert (const_int 7)) 1955404b540aSrobert (const_int 3))) 1956404b540aSrobert (const_int 65535)))] 1957404b540aSrobert "WORDS_BIG_ENDIAN" 1958404b540aSrobert "extwh %r1,%2,%0" 1959404b540aSrobert [(set_attr "type" "shift")]) 1960404b540aSrobert 1961404b540aSrobert;; This converts an extXl into an extXh with an appropriate adjustment 1962404b540aSrobert;; to the address calculation. 1963404b540aSrobert 1964404b540aSrobert;;(define_split 1965404b540aSrobert;; [(set (match_operand:DI 0 "register_operand" "") 1966404b540aSrobert;; (ashift:DI (zero_extract:DI (match_operand:DI 1 "register_operand" "") 1967404b540aSrobert;; (match_operand:DI 2 "mode_width_operand" "") 1968404b540aSrobert;; (ashift:DI (match_operand:DI 3 "" "") 1969404b540aSrobert;; (const_int 3))) 1970404b540aSrobert;; (match_operand:DI 4 "const_int_operand" ""))) 1971404b540aSrobert;; (clobber (match_operand:DI 5 "register_operand" ""))] 1972404b540aSrobert;; "INTVAL (operands[4]) == 64 - INTVAL (operands[2])" 1973404b540aSrobert;; [(set (match_dup 5) (match_dup 6)) 1974404b540aSrobert;; (set (match_dup 0) 1975404b540aSrobert;; (ashift:DI (zero_extract:DI (match_dup 1) (match_dup 2) 1976404b540aSrobert;; (ashift:DI (plus:DI (match_dup 5) 1977404b540aSrobert;; (match_dup 7)) 1978404b540aSrobert;; (const_int 3))) 1979404b540aSrobert;; (match_dup 4)))] 1980404b540aSrobert;; " 1981404b540aSrobert;;{ 1982404b540aSrobert;; operands[6] = plus_constant (operands[3], 1983404b540aSrobert;; INTVAL (operands[2]) / BITS_PER_UNIT); 1984404b540aSrobert;; operands[7] = GEN_INT (- INTVAL (operands[2]) / BITS_PER_UNIT); 1985404b540aSrobert;;}") 1986404b540aSrobert 1987404b540aSrobert(define_insn "*insbl_const" 1988404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 1989404b540aSrobert (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r")) 1990404b540aSrobert (match_operand:DI 2 "mul8_operand" "I")))] 1991404b540aSrobert "" 1992404b540aSrobert "insbl %1,%s2,%0" 1993404b540aSrobert [(set_attr "type" "shift")]) 1994404b540aSrobert 1995404b540aSrobert(define_insn "*inswl_const" 1996404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 1997404b540aSrobert (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r")) 1998404b540aSrobert (match_operand:DI 2 "mul8_operand" "I")))] 1999404b540aSrobert "" 2000404b540aSrobert "inswl %1,%s2,%0" 2001404b540aSrobert [(set_attr "type" "shift")]) 2002404b540aSrobert 2003404b540aSrobert(define_insn "*insll_const" 2004404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 2005404b540aSrobert (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) 2006404b540aSrobert (match_operand:DI 2 "mul8_operand" "I")))] 2007404b540aSrobert "" 2008404b540aSrobert "insll %1,%s2,%0" 2009404b540aSrobert [(set_attr "type" "shift")]) 2010404b540aSrobert 2011404b540aSrobert(define_insn "insbl_le" 2012404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 2013404b540aSrobert (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r")) 2014404b540aSrobert (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") 2015404b540aSrobert (const_int 3))))] 2016404b540aSrobert "! WORDS_BIG_ENDIAN" 2017404b540aSrobert "insbl %1,%2,%0" 2018404b540aSrobert [(set_attr "type" "shift")]) 2019404b540aSrobert 2020404b540aSrobert(define_insn "insbl_be" 2021404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 2022404b540aSrobert (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r")) 2023404b540aSrobert (minus:DI (const_int 56) 2024404b540aSrobert (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") 2025404b540aSrobert (const_int 3)))))] 2026404b540aSrobert "WORDS_BIG_ENDIAN" 2027404b540aSrobert "insbl %1,%2,%0" 2028404b540aSrobert [(set_attr "type" "shift")]) 2029404b540aSrobert 2030404b540aSrobert(define_insn "inswl_le" 2031404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 2032404b540aSrobert (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r")) 2033404b540aSrobert (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") 2034404b540aSrobert (const_int 3))))] 2035404b540aSrobert "! WORDS_BIG_ENDIAN" 2036404b540aSrobert "inswl %1,%2,%0" 2037404b540aSrobert [(set_attr "type" "shift")]) 2038404b540aSrobert 2039404b540aSrobert(define_insn "inswl_be" 2040404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 2041404b540aSrobert (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r")) 2042404b540aSrobert (minus:DI (const_int 56) 2043404b540aSrobert (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") 2044404b540aSrobert (const_int 3)))))] 2045404b540aSrobert "WORDS_BIG_ENDIAN" 2046404b540aSrobert "inswl %1,%2,%0" 2047404b540aSrobert [(set_attr "type" "shift")]) 2048404b540aSrobert 2049404b540aSrobert(define_insn "insll_le" 2050404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 2051404b540aSrobert (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) 2052404b540aSrobert (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") 2053404b540aSrobert (const_int 3))))] 2054404b540aSrobert "! WORDS_BIG_ENDIAN" 2055404b540aSrobert "insll %1,%2,%0" 2056404b540aSrobert [(set_attr "type" "shift")]) 2057404b540aSrobert 2058404b540aSrobert(define_insn "insll_be" 2059404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 2060404b540aSrobert (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) 2061404b540aSrobert (minus:DI (const_int 56) 2062404b540aSrobert (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") 2063404b540aSrobert (const_int 3)))))] 2064404b540aSrobert "WORDS_BIG_ENDIAN" 2065404b540aSrobert "insll %1,%2,%0" 2066404b540aSrobert [(set_attr "type" "shift")]) 2067404b540aSrobert 2068404b540aSrobert(define_insn "insql_le" 2069404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 2070404b540aSrobert (ashift:DI (match_operand:DI 1 "register_operand" "r") 2071404b540aSrobert (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") 2072404b540aSrobert (const_int 3))))] 2073404b540aSrobert "! WORDS_BIG_ENDIAN" 2074404b540aSrobert "insql %1,%2,%0" 2075404b540aSrobert [(set_attr "type" "shift")]) 2076404b540aSrobert 2077404b540aSrobert(define_insn "insql_be" 2078404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 2079404b540aSrobert (ashift:DI (match_operand:DI 1 "register_operand" "r") 2080404b540aSrobert (minus:DI (const_int 56) 2081404b540aSrobert (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") 2082404b540aSrobert (const_int 3)))))] 2083404b540aSrobert "WORDS_BIG_ENDIAN" 2084404b540aSrobert "insql %1,%2,%0" 2085404b540aSrobert [(set_attr "type" "shift")]) 2086404b540aSrobert 2087404b540aSrobert;; Combine has this sometimes habit of moving the and outside of the 2088404b540aSrobert;; shift, making life more interesting. 2089404b540aSrobert 2090404b540aSrobert(define_insn "*insxl" 2091404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 2092404b540aSrobert (and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r") 2093404b540aSrobert (match_operand:DI 2 "mul8_operand" "I")) 2094404b540aSrobert (match_operand:DI 3 "immediate_operand" "i")))] 2095404b540aSrobert "HOST_BITS_PER_WIDE_INT == 64 2096404b540aSrobert && GET_CODE (operands[3]) == CONST_INT 2097404b540aSrobert && (((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2]) 2098404b540aSrobert == (unsigned HOST_WIDE_INT) INTVAL (operands[3])) 2099404b540aSrobert || ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2]) 2100404b540aSrobert == (unsigned HOST_WIDE_INT) INTVAL (operands[3])) 2101404b540aSrobert || ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2]) 2102404b540aSrobert == (unsigned HOST_WIDE_INT) INTVAL (operands[3])))" 2103404b540aSrobert{ 2104404b540aSrobert#if HOST_BITS_PER_WIDE_INT == 64 2105404b540aSrobert if ((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2]) 2106404b540aSrobert == (unsigned HOST_WIDE_INT) INTVAL (operands[3])) 2107404b540aSrobert return "insbl %1,%s2,%0"; 2108404b540aSrobert if ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2]) 2109404b540aSrobert == (unsigned HOST_WIDE_INT) INTVAL (operands[3])) 2110404b540aSrobert return "inswl %1,%s2,%0"; 2111404b540aSrobert if ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2]) 2112404b540aSrobert == (unsigned HOST_WIDE_INT) INTVAL (operands[3])) 2113404b540aSrobert return "insll %1,%s2,%0"; 2114404b540aSrobert#endif 2115404b540aSrobert gcc_unreachable (); 2116404b540aSrobert} 2117404b540aSrobert [(set_attr "type" "shift")]) 2118404b540aSrobert 2119404b540aSrobert;; We do not include the insXh insns because they are complex to express 2120404b540aSrobert;; and it does not appear that we would ever want to generate them. 2121404b540aSrobert;; 2122404b540aSrobert;; Since we need them for block moves, though, cop out and use unspec. 2123404b540aSrobert 2124404b540aSrobert(define_insn "insxh" 2125404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 2126404b540aSrobert (unspec:DI [(match_operand:DI 1 "register_operand" "r") 2127404b540aSrobert (match_operand:DI 2 "mode_width_operand" "n") 2128404b540aSrobert (match_operand:DI 3 "reg_or_8bit_operand" "rI")] 2129404b540aSrobert UNSPEC_INSXH))] 2130404b540aSrobert "" 2131404b540aSrobert "ins%M2h %1,%3,%0" 2132404b540aSrobert [(set_attr "type" "shift")]) 2133404b540aSrobert 2134404b540aSrobert(define_insn "mskxl_le" 2135404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 2136404b540aSrobert (and:DI (not:DI (ashift:DI 2137404b540aSrobert (match_operand:DI 2 "mode_mask_operand" "n") 2138404b540aSrobert (ashift:DI 2139404b540aSrobert (match_operand:DI 3 "reg_or_8bit_operand" "rI") 2140404b540aSrobert (const_int 3)))) 2141404b540aSrobert (match_operand:DI 1 "reg_or_0_operand" "rJ")))] 2142404b540aSrobert "! WORDS_BIG_ENDIAN" 2143404b540aSrobert "msk%U2l %r1,%3,%0" 2144404b540aSrobert [(set_attr "type" "shift")]) 2145404b540aSrobert 2146404b540aSrobert(define_insn "mskxl_be" 2147404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 2148404b540aSrobert (and:DI (not:DI (ashift:DI 2149404b540aSrobert (match_operand:DI 2 "mode_mask_operand" "n") 2150404b540aSrobert (minus:DI (const_int 56) 2151404b540aSrobert (ashift:DI 2152404b540aSrobert (match_operand:DI 3 "reg_or_8bit_operand" "rI") 2153404b540aSrobert (const_int 3))))) 2154404b540aSrobert (match_operand:DI 1 "reg_or_0_operand" "rJ")))] 2155404b540aSrobert "WORDS_BIG_ENDIAN" 2156404b540aSrobert "msk%U2l %r1,%3,%0" 2157404b540aSrobert [(set_attr "type" "shift")]) 2158404b540aSrobert 2159404b540aSrobert;; We do not include the mskXh insns because it does not appear we would 2160404b540aSrobert;; ever generate one. 2161404b540aSrobert;; 2162404b540aSrobert;; Again, we do for block moves and we use unspec again. 2163404b540aSrobert 2164404b540aSrobert(define_insn "mskxh" 2165404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 2166404b540aSrobert (unspec:DI [(match_operand:DI 1 "register_operand" "r") 2167404b540aSrobert (match_operand:DI 2 "mode_width_operand" "n") 2168404b540aSrobert (match_operand:DI 3 "reg_or_8bit_operand" "rI")] 2169404b540aSrobert UNSPEC_MSKXH))] 2170404b540aSrobert "" 2171404b540aSrobert "msk%M2h %1,%3,%0" 2172404b540aSrobert [(set_attr "type" "shift")]) 2173404b540aSrobert 2174404b540aSrobert;; Prefer AND + NE over LSHIFTRT + AND. 2175404b540aSrobert 2176404b540aSrobert(define_insn_and_split "*ze_and_ne" 2177404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 2178404b540aSrobert (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") 2179404b540aSrobert (const_int 1) 2180404b540aSrobert (match_operand 2 "const_int_operand" "I")))] 2181404b540aSrobert "(unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 8" 2182404b540aSrobert "#" 2183404b540aSrobert "(unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 8" 2184404b540aSrobert [(set (match_dup 0) 2185404b540aSrobert (and:DI (match_dup 1) (match_dup 3))) 2186404b540aSrobert (set (match_dup 0) 2187404b540aSrobert (ne:DI (match_dup 0) (const_int 0)))] 2188404b540aSrobert "operands[3] = GEN_INT (1 << INTVAL (operands[2]));") 2189404b540aSrobert 2190404b540aSrobert;; Floating-point operations. All the double-precision insns can extend 2191404b540aSrobert;; from single, so indicate that. The exception are the ones that simply 2192404b540aSrobert;; play with the sign bits; it's not clear what to do there. 2193404b540aSrobert 2194404b540aSrobert(define_insn "abssf2" 2195404b540aSrobert [(set (match_operand:SF 0 "register_operand" "=f") 2196404b540aSrobert (abs:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))] 2197404b540aSrobert "TARGET_FP" 2198404b540aSrobert "cpys $f31,%R1,%0" 2199404b540aSrobert [(set_attr "type" "fcpys")]) 2200404b540aSrobert 2201404b540aSrobert(define_insn "*nabssf2" 2202404b540aSrobert [(set (match_operand:SF 0 "register_operand" "=f") 2203404b540aSrobert (neg:SF (abs:SF (match_operand:SF 1 "reg_or_0_operand" "fG"))))] 2204404b540aSrobert "TARGET_FP" 2205404b540aSrobert "cpysn $f31,%R1,%0" 2206404b540aSrobert [(set_attr "type" "fadd")]) 2207404b540aSrobert 2208404b540aSrobert(define_insn "absdf2" 2209404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f") 2210404b540aSrobert (abs:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))] 2211404b540aSrobert "TARGET_FP" 2212404b540aSrobert "cpys $f31,%R1,%0" 2213404b540aSrobert [(set_attr "type" "fcpys")]) 2214404b540aSrobert 2215404b540aSrobert(define_insn "*nabsdf2" 2216404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f") 2217404b540aSrobert (neg:DF (abs:DF (match_operand:DF 1 "reg_or_0_operand" "fG"))))] 2218404b540aSrobert "TARGET_FP" 2219404b540aSrobert "cpysn $f31,%R1,%0" 2220404b540aSrobert [(set_attr "type" "fadd")]) 2221404b540aSrobert 2222404b540aSrobert(define_expand "abstf2" 2223404b540aSrobert [(parallel [(set (match_operand:TF 0 "register_operand" "") 2224404b540aSrobert (abs:TF (match_operand:TF 1 "reg_or_0_operand" ""))) 2225404b540aSrobert (use (match_dup 2))])] 2226404b540aSrobert "TARGET_HAS_XFLOATING_LIBS" 2227404b540aSrobert{ 2228404b540aSrobert#if HOST_BITS_PER_WIDE_INT >= 64 2229404b540aSrobert operands[2] = force_reg (DImode, GEN_INT ((HOST_WIDE_INT) 1 << 63)); 2230404b540aSrobert#else 2231404b540aSrobert operands[2] = force_reg (DImode, immed_double_const (0, 0x80000000, DImode)); 2232404b540aSrobert#endif 2233404b540aSrobert}) 2234404b540aSrobert 2235404b540aSrobert(define_insn_and_split "*abstf_internal" 2236404b540aSrobert [(set (match_operand:TF 0 "register_operand" "=r") 2237404b540aSrobert (abs:TF (match_operand:TF 1 "reg_or_0_operand" "rG"))) 2238404b540aSrobert (use (match_operand:DI 2 "register_operand" "r"))] 2239404b540aSrobert "TARGET_HAS_XFLOATING_LIBS" 2240404b540aSrobert "#" 2241404b540aSrobert "&& reload_completed" 2242404b540aSrobert [(const_int 0)] 2243404b540aSrobert "alpha_split_tfmode_frobsign (operands, gen_andnotdi3); DONE;") 2244404b540aSrobert 2245404b540aSrobert(define_insn "negsf2" 2246404b540aSrobert [(set (match_operand:SF 0 "register_operand" "=f") 2247404b540aSrobert (neg:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))] 2248404b540aSrobert "TARGET_FP" 2249404b540aSrobert "cpysn %R1,%R1,%0" 2250404b540aSrobert [(set_attr "type" "fadd")]) 2251404b540aSrobert 2252404b540aSrobert(define_insn "negdf2" 2253404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f") 2254404b540aSrobert (neg:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))] 2255404b540aSrobert "TARGET_FP" 2256404b540aSrobert "cpysn %R1,%R1,%0" 2257404b540aSrobert [(set_attr "type" "fadd")]) 2258404b540aSrobert 2259404b540aSrobert(define_expand "negtf2" 2260404b540aSrobert [(parallel [(set (match_operand:TF 0 "register_operand" "") 2261404b540aSrobert (neg:TF (match_operand:TF 1 "reg_or_0_operand" ""))) 2262404b540aSrobert (use (match_dup 2))])] 2263404b540aSrobert "TARGET_HAS_XFLOATING_LIBS" 2264404b540aSrobert{ 2265404b540aSrobert#if HOST_BITS_PER_WIDE_INT >= 64 2266404b540aSrobert operands[2] = force_reg (DImode, GEN_INT ((HOST_WIDE_INT) 1 << 63)); 2267404b540aSrobert#else 2268404b540aSrobert operands[2] = force_reg (DImode, immed_double_const (0, 0x80000000, DImode)); 2269404b540aSrobert#endif 2270404b540aSrobert}) 2271404b540aSrobert 2272404b540aSrobert(define_insn_and_split "*negtf_internal" 2273404b540aSrobert [(set (match_operand:TF 0 "register_operand" "=r") 2274404b540aSrobert (neg:TF (match_operand:TF 1 "reg_or_0_operand" "rG"))) 2275404b540aSrobert (use (match_operand:DI 2 "register_operand" "r"))] 2276404b540aSrobert "TARGET_HAS_XFLOATING_LIBS" 2277404b540aSrobert "#" 2278404b540aSrobert "&& reload_completed" 2279404b540aSrobert [(const_int 0)] 2280404b540aSrobert "alpha_split_tfmode_frobsign (operands, gen_xordi3); DONE;") 2281404b540aSrobert 2282404b540aSrobert(define_insn "copysignsf3" 2283404b540aSrobert [(set (match_operand:SF 0 "register_operand" "=f") 2284404b540aSrobert (unspec:SF [(match_operand:SF 1 "reg_or_0_operand" "fG") 2285404b540aSrobert (match_operand:SF 2 "reg_or_0_operand" "fG")] 2286404b540aSrobert UNSPEC_COPYSIGN))] 2287404b540aSrobert "TARGET_FP" 2288404b540aSrobert "cpys %R2,%R1,%0" 2289404b540aSrobert [(set_attr "type" "fadd")]) 2290404b540aSrobert 2291404b540aSrobert(define_insn "*ncopysignsf3" 2292404b540aSrobert [(set (match_operand:SF 0 "register_operand" "=f") 2293404b540aSrobert (neg:SF (unspec:SF [(match_operand:SF 1 "reg_or_0_operand" "fG") 2294404b540aSrobert (match_operand:SF 2 "reg_or_0_operand" "fG")] 2295404b540aSrobert UNSPEC_COPYSIGN)))] 2296404b540aSrobert "TARGET_FP" 2297404b540aSrobert "cpysn %R2,%R1,%0" 2298404b540aSrobert [(set_attr "type" "fadd")]) 2299404b540aSrobert 2300404b540aSrobert(define_insn "copysigndf3" 2301404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f") 2302404b540aSrobert (unspec:DF [(match_operand:DF 1 "reg_or_0_operand" "fG") 2303404b540aSrobert (match_operand:DF 2 "reg_or_0_operand" "fG")] 2304404b540aSrobert UNSPEC_COPYSIGN))] 2305404b540aSrobert "TARGET_FP" 2306404b540aSrobert "cpys %R2,%R1,%0" 2307404b540aSrobert [(set_attr "type" "fadd")]) 2308404b540aSrobert 2309404b540aSrobert(define_insn "*ncopysigndf3" 2310404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f") 2311404b540aSrobert (neg:DF (unspec:DF [(match_operand:DF 1 "reg_or_0_operand" "fG") 2312404b540aSrobert (match_operand:DF 2 "reg_or_0_operand" "fG")] 2313404b540aSrobert UNSPEC_COPYSIGN)))] 2314404b540aSrobert "TARGET_FP" 2315404b540aSrobert "cpysn %R2,%R1,%0" 2316404b540aSrobert [(set_attr "type" "fadd")]) 2317404b540aSrobert 2318404b540aSrobert(define_insn "*addsf_ieee" 2319404b540aSrobert [(set (match_operand:SF 0 "register_operand" "=&f") 2320404b540aSrobert (plus:SF (match_operand:SF 1 "reg_or_0_operand" "%fG") 2321404b540aSrobert (match_operand:SF 2 "reg_or_0_operand" "fG")))] 2322404b540aSrobert "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" 2323404b540aSrobert "add%,%/ %R1,%R2,%0" 2324404b540aSrobert [(set_attr "type" "fadd") 2325404b540aSrobert (set_attr "trap" "yes") 2326404b540aSrobert (set_attr "round_suffix" "normal") 2327404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 2328404b540aSrobert 2329404b540aSrobert(define_insn "addsf3" 2330404b540aSrobert [(set (match_operand:SF 0 "register_operand" "=f") 2331404b540aSrobert (plus:SF (match_operand:SF 1 "reg_or_0_operand" "%fG") 2332404b540aSrobert (match_operand:SF 2 "reg_or_0_operand" "fG")))] 2333404b540aSrobert "TARGET_FP" 2334404b540aSrobert "add%,%/ %R1,%R2,%0" 2335404b540aSrobert [(set_attr "type" "fadd") 2336404b540aSrobert (set_attr "trap" "yes") 2337404b540aSrobert (set_attr "round_suffix" "normal") 2338404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 2339404b540aSrobert 2340404b540aSrobert(define_insn "*adddf_ieee" 2341404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=&f") 2342404b540aSrobert (plus:DF (match_operand:DF 1 "reg_or_0_operand" "%fG") 2343404b540aSrobert (match_operand:DF 2 "reg_or_0_operand" "fG")))] 2344404b540aSrobert "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" 2345404b540aSrobert "add%-%/ %R1,%R2,%0" 2346404b540aSrobert [(set_attr "type" "fadd") 2347404b540aSrobert (set_attr "trap" "yes") 2348404b540aSrobert (set_attr "round_suffix" "normal") 2349404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 2350404b540aSrobert 2351404b540aSrobert(define_insn "adddf3" 2352404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f") 2353404b540aSrobert (plus:DF (match_operand:DF 1 "reg_or_0_operand" "%fG") 2354404b540aSrobert (match_operand:DF 2 "reg_or_0_operand" "fG")))] 2355404b540aSrobert "TARGET_FP" 2356404b540aSrobert "add%-%/ %R1,%R2,%0" 2357404b540aSrobert [(set_attr "type" "fadd") 2358404b540aSrobert (set_attr "trap" "yes") 2359404b540aSrobert (set_attr "round_suffix" "normal") 2360404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 2361404b540aSrobert 2362404b540aSrobert(define_insn "*adddf_ext1" 2363404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f") 2364404b540aSrobert (plus:DF (float_extend:DF 2365404b540aSrobert (match_operand:SF 1 "reg_or_0_operand" "fG")) 2366404b540aSrobert (match_operand:DF 2 "reg_or_0_operand" "fG")))] 2367404b540aSrobert "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" 2368404b540aSrobert "add%-%/ %R1,%R2,%0" 2369404b540aSrobert [(set_attr "type" "fadd") 2370404b540aSrobert (set_attr "trap" "yes") 2371404b540aSrobert (set_attr "round_suffix" "normal") 2372404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 2373404b540aSrobert 2374404b540aSrobert(define_insn "*adddf_ext2" 2375404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f") 2376404b540aSrobert (plus:DF (float_extend:DF 2377404b540aSrobert (match_operand:SF 1 "reg_or_0_operand" "%fG")) 2378404b540aSrobert (float_extend:DF 2379404b540aSrobert (match_operand:SF 2 "reg_or_0_operand" "fG"))))] 2380404b540aSrobert "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" 2381404b540aSrobert "add%-%/ %R1,%R2,%0" 2382404b540aSrobert [(set_attr "type" "fadd") 2383404b540aSrobert (set_attr "trap" "yes") 2384404b540aSrobert (set_attr "round_suffix" "normal") 2385404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 2386404b540aSrobert 2387404b540aSrobert(define_expand "addtf3" 2388404b540aSrobert [(use (match_operand 0 "register_operand" "")) 2389404b540aSrobert (use (match_operand 1 "general_operand" "")) 2390404b540aSrobert (use (match_operand 2 "general_operand" ""))] 2391404b540aSrobert "TARGET_HAS_XFLOATING_LIBS" 2392404b540aSrobert "alpha_emit_xfloating_arith (PLUS, operands); DONE;") 2393404b540aSrobert 2394404b540aSrobert;; Define conversion operators between DFmode and SImode, using the cvtql 2395404b540aSrobert;; instruction. To allow combine et al to do useful things, we keep the 2396404b540aSrobert;; operation as a unit until after reload, at which point we split the 2397404b540aSrobert;; instructions. 2398404b540aSrobert;; 2399404b540aSrobert;; Note that we (attempt to) only consider this optimization when the 2400404b540aSrobert;; ultimate destination is memory. If we will be doing further integer 2401404b540aSrobert;; processing, it is cheaper to do the truncation in the int regs. 2402404b540aSrobert 2403404b540aSrobert(define_insn "*cvtql" 2404404b540aSrobert [(set (match_operand:SF 0 "register_operand" "=f") 2405404b540aSrobert (unspec:SF [(match_operand:DI 1 "reg_or_0_operand" "fG")] 2406404b540aSrobert UNSPEC_CVTQL))] 2407404b540aSrobert "TARGET_FP" 2408404b540aSrobert "cvtql%/ %R1,%0" 2409404b540aSrobert [(set_attr "type" "fadd") 2410404b540aSrobert (set_attr "trap" "yes") 2411404b540aSrobert (set_attr "trap_suffix" "v_sv")]) 2412404b540aSrobert 2413404b540aSrobert(define_insn_and_split "*fix_truncdfsi_ieee" 2414404b540aSrobert [(set (match_operand:SI 0 "memory_operand" "=m") 2415404b540aSrobert (subreg:SI 2416404b540aSrobert (match_operator:DI 4 "fix_operator" 2417404b540aSrobert [(match_operand:DF 1 "reg_or_0_operand" "fG")]) 0)) 2418404b540aSrobert (clobber (match_scratch:DI 2 "=&f")) 2419404b540aSrobert (clobber (match_scratch:SF 3 "=&f"))] 2420404b540aSrobert "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" 2421404b540aSrobert "#" 2422404b540aSrobert "&& reload_completed" 2423404b540aSrobert [(set (match_dup 2) (match_op_dup 4 [(match_dup 1)])) 2424404b540aSrobert (set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL)) 2425404b540aSrobert (set (match_dup 5) (match_dup 3))] 2426404b540aSrobert{ 2427404b540aSrobert operands[5] = adjust_address (operands[0], SFmode, 0); 2428404b540aSrobert} 2429404b540aSrobert [(set_attr "type" "fadd") 2430404b540aSrobert (set_attr "trap" "yes")]) 2431404b540aSrobert 2432404b540aSrobert(define_insn_and_split "*fix_truncdfsi_internal" 2433404b540aSrobert [(set (match_operand:SI 0 "memory_operand" "=m") 2434404b540aSrobert (subreg:SI 2435404b540aSrobert (match_operator:DI 3 "fix_operator" 2436404b540aSrobert [(match_operand:DF 1 "reg_or_0_operand" "fG")]) 0)) 2437404b540aSrobert (clobber (match_scratch:DI 2 "=f"))] 2438404b540aSrobert "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" 2439404b540aSrobert "#" 2440404b540aSrobert "&& reload_completed" 2441404b540aSrobert [(set (match_dup 2) (match_op_dup 3 [(match_dup 1)])) 2442404b540aSrobert (set (match_dup 4) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL)) 2443404b540aSrobert (set (match_dup 5) (match_dup 4))] 2444404b540aSrobert{ 2445404b540aSrobert operands[4] = gen_rtx_REG (SFmode, REGNO (operands[2])); 2446404b540aSrobert operands[5] = adjust_address (operands[0], SFmode, 0); 2447404b540aSrobert} 2448404b540aSrobert [(set_attr "type" "fadd") 2449404b540aSrobert (set_attr "trap" "yes")]) 2450404b540aSrobert 2451404b540aSrobert(define_insn "*fix_truncdfdi_ieee" 2452404b540aSrobert [(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f") 2453404b540aSrobert (match_operator:DI 2 "fix_operator" 2454404b540aSrobert [(match_operand:DF 1 "reg_or_0_operand" "fG")]))] 2455404b540aSrobert "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" 2456404b540aSrobert "cvt%-q%/ %R1,%0" 2457404b540aSrobert [(set_attr "type" "fadd") 2458404b540aSrobert (set_attr "trap" "yes") 2459404b540aSrobert (set_attr "round_suffix" "c") 2460404b540aSrobert (set_attr "trap_suffix" "v_sv_svi")]) 2461404b540aSrobert 2462404b540aSrobert(define_insn "*fix_truncdfdi2" 2463404b540aSrobert [(set (match_operand:DI 0 "reg_no_subreg_operand" "=f") 2464404b540aSrobert (match_operator:DI 2 "fix_operator" 2465404b540aSrobert [(match_operand:DF 1 "reg_or_0_operand" "fG")]))] 2466404b540aSrobert "TARGET_FP" 2467404b540aSrobert "cvt%-q%/ %R1,%0" 2468404b540aSrobert [(set_attr "type" "fadd") 2469404b540aSrobert (set_attr "trap" "yes") 2470404b540aSrobert (set_attr "round_suffix" "c") 2471404b540aSrobert (set_attr "trap_suffix" "v_sv_svi")]) 2472404b540aSrobert 2473404b540aSrobert(define_expand "fix_truncdfdi2" 2474404b540aSrobert [(set (match_operand:DI 0 "reg_no_subreg_operand" "") 2475404b540aSrobert (fix:DI (match_operand:DF 1 "reg_or_0_operand" "")))] 2476404b540aSrobert "TARGET_FP" 2477404b540aSrobert "") 2478404b540aSrobert 2479404b540aSrobert(define_expand "fixuns_truncdfdi2" 2480404b540aSrobert [(set (match_operand:DI 0 "reg_no_subreg_operand" "") 2481404b540aSrobert (unsigned_fix:DI (match_operand:DF 1 "reg_or_0_operand" "")))] 2482404b540aSrobert "TARGET_FP" 2483404b540aSrobert "") 2484404b540aSrobert 2485404b540aSrobert;; Likewise between SFmode and SImode. 2486404b540aSrobert 2487404b540aSrobert(define_insn_and_split "*fix_truncsfsi_ieee" 2488404b540aSrobert [(set (match_operand:SI 0 "memory_operand" "=m") 2489404b540aSrobert (subreg:SI 2490404b540aSrobert (match_operator:DI 4 "fix_operator" 2491404b540aSrobert [(float_extend:DF 2492404b540aSrobert (match_operand:SF 1 "reg_or_0_operand" "fG"))]) 0)) 2493404b540aSrobert (clobber (match_scratch:DI 2 "=&f")) 2494404b540aSrobert (clobber (match_scratch:SF 3 "=&f"))] 2495404b540aSrobert "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" 2496404b540aSrobert "#" 2497404b540aSrobert "&& reload_completed" 2498404b540aSrobert [(set (match_dup 2) (match_op_dup 4 [(float_extend:DF (match_dup 1))])) 2499404b540aSrobert (set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL)) 2500404b540aSrobert (set (match_dup 5) (match_dup 3))] 2501404b540aSrobert{ 2502404b540aSrobert operands[5] = adjust_address (operands[0], SFmode, 0); 2503404b540aSrobert} 2504404b540aSrobert [(set_attr "type" "fadd") 2505404b540aSrobert (set_attr "trap" "yes")]) 2506404b540aSrobert 2507404b540aSrobert(define_insn_and_split "*fix_truncsfsi_internal" 2508404b540aSrobert [(set (match_operand:SI 0 "memory_operand" "=m") 2509404b540aSrobert (subreg:SI 2510404b540aSrobert (match_operator:DI 3 "fix_operator" 2511404b540aSrobert [(float_extend:DF 2512404b540aSrobert (match_operand:SF 1 "reg_or_0_operand" "fG"))]) 0)) 2513404b540aSrobert (clobber (match_scratch:DI 2 "=f"))] 2514404b540aSrobert "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" 2515404b540aSrobert "#" 2516404b540aSrobert "&& reload_completed" 2517404b540aSrobert [(set (match_dup 2) (match_op_dup 3 [(float_extend:DF (match_dup 1))])) 2518404b540aSrobert (set (match_dup 4) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL)) 2519404b540aSrobert (set (match_dup 5) (match_dup 4))] 2520404b540aSrobert{ 2521404b540aSrobert operands[4] = gen_rtx_REG (SFmode, REGNO (operands[2])); 2522404b540aSrobert operands[5] = adjust_address (operands[0], SFmode, 0); 2523404b540aSrobert} 2524404b540aSrobert [(set_attr "type" "fadd") 2525404b540aSrobert (set_attr "trap" "yes")]) 2526404b540aSrobert 2527404b540aSrobert(define_insn "*fix_truncsfdi_ieee" 2528404b540aSrobert [(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f") 2529404b540aSrobert (match_operator:DI 2 "fix_operator" 2530404b540aSrobert [(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))]))] 2531404b540aSrobert "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" 2532404b540aSrobert "cvt%-q%/ %R1,%0" 2533404b540aSrobert [(set_attr "type" "fadd") 2534404b540aSrobert (set_attr "trap" "yes") 2535404b540aSrobert (set_attr "round_suffix" "c") 2536404b540aSrobert (set_attr "trap_suffix" "v_sv_svi")]) 2537404b540aSrobert 2538404b540aSrobert(define_insn "*fix_truncsfdi2" 2539404b540aSrobert [(set (match_operand:DI 0 "reg_no_subreg_operand" "=f") 2540404b540aSrobert (match_operator:DI 2 "fix_operator" 2541404b540aSrobert [(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))]))] 2542404b540aSrobert "TARGET_FP" 2543404b540aSrobert "cvt%-q%/ %R1,%0" 2544404b540aSrobert [(set_attr "type" "fadd") 2545404b540aSrobert (set_attr "trap" "yes") 2546404b540aSrobert (set_attr "round_suffix" "c") 2547404b540aSrobert (set_attr "trap_suffix" "v_sv_svi")]) 2548404b540aSrobert 2549404b540aSrobert(define_expand "fix_truncsfdi2" 2550404b540aSrobert [(set (match_operand:DI 0 "reg_no_subreg_operand" "") 2551404b540aSrobert (fix:DI (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))))] 2552404b540aSrobert "TARGET_FP" 2553404b540aSrobert "") 2554404b540aSrobert 2555404b540aSrobert(define_expand "fixuns_truncsfdi2" 2556404b540aSrobert [(set (match_operand:DI 0 "reg_no_subreg_operand" "") 2557404b540aSrobert (unsigned_fix:DI 2558404b540aSrobert (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))))] 2559404b540aSrobert "TARGET_FP" 2560404b540aSrobert "") 2561404b540aSrobert 2562404b540aSrobert(define_expand "fix_trunctfdi2" 2563404b540aSrobert [(use (match_operand:DI 0 "register_operand" "")) 2564404b540aSrobert (use (match_operand:TF 1 "general_operand" ""))] 2565404b540aSrobert "TARGET_HAS_XFLOATING_LIBS" 2566404b540aSrobert "alpha_emit_xfloating_cvt (FIX, operands); DONE;") 2567404b540aSrobert 2568404b540aSrobert(define_expand "fixuns_trunctfdi2" 2569404b540aSrobert [(use (match_operand:DI 0 "register_operand" "")) 2570404b540aSrobert (use (match_operand:TF 1 "general_operand" ""))] 2571404b540aSrobert "TARGET_HAS_XFLOATING_LIBS" 2572404b540aSrobert "alpha_emit_xfloating_cvt (UNSIGNED_FIX, operands); DONE;") 2573404b540aSrobert 2574404b540aSrobert(define_insn "*floatdisf_ieee" 2575404b540aSrobert [(set (match_operand:SF 0 "register_operand" "=&f") 2576404b540aSrobert (float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))] 2577404b540aSrobert "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" 2578404b540aSrobert "cvtq%,%/ %1,%0" 2579404b540aSrobert [(set_attr "type" "fadd") 2580404b540aSrobert (set_attr "trap" "yes") 2581404b540aSrobert (set_attr "round_suffix" "normal") 2582404b540aSrobert (set_attr "trap_suffix" "sui")]) 2583404b540aSrobert 2584404b540aSrobert(define_insn "floatdisf2" 2585404b540aSrobert [(set (match_operand:SF 0 "register_operand" "=f") 2586404b540aSrobert (float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))] 2587404b540aSrobert "TARGET_FP" 2588404b540aSrobert "cvtq%,%/ %1,%0" 2589404b540aSrobert [(set_attr "type" "fadd") 2590404b540aSrobert (set_attr "trap" "yes") 2591404b540aSrobert (set_attr "round_suffix" "normal") 2592404b540aSrobert (set_attr "trap_suffix" "sui")]) 2593404b540aSrobert 2594404b540aSrobert(define_insn_and_split "*floatsisf2_ieee" 2595404b540aSrobert [(set (match_operand:SF 0 "register_operand" "=&f") 2596404b540aSrobert (float:SF (match_operand:SI 1 "memory_operand" "m"))) 2597404b540aSrobert (clobber (match_scratch:DI 2 "=&f")) 2598404b540aSrobert (clobber (match_scratch:SF 3 "=&f"))] 2599404b540aSrobert "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" 2600404b540aSrobert "#" 2601404b540aSrobert "&& reload_completed" 2602404b540aSrobert [(set (match_dup 3) (match_dup 1)) 2603404b540aSrobert (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ)) 2604404b540aSrobert (set (match_dup 0) (float:SF (match_dup 2)))] 2605404b540aSrobert{ 2606404b540aSrobert operands[1] = adjust_address (operands[1], SFmode, 0); 2607404b540aSrobert}) 2608404b540aSrobert 2609404b540aSrobert(define_insn_and_split "*floatsisf2" 2610404b540aSrobert [(set (match_operand:SF 0 "register_operand" "=f") 2611404b540aSrobert (float:SF (match_operand:SI 1 "memory_operand" "m")))] 2612404b540aSrobert "TARGET_FP" 2613404b540aSrobert "#" 2614404b540aSrobert "&& reload_completed" 2615404b540aSrobert [(set (match_dup 0) (match_dup 1)) 2616404b540aSrobert (set (match_dup 2) (unspec:DI [(match_dup 0)] UNSPEC_CVTLQ)) 2617404b540aSrobert (set (match_dup 0) (float:SF (match_dup 2)))] 2618404b540aSrobert{ 2619404b540aSrobert operands[1] = adjust_address (operands[1], SFmode, 0); 2620404b540aSrobert operands[2] = gen_rtx_REG (DImode, REGNO (operands[0])); 2621404b540aSrobert}) 2622404b540aSrobert 2623404b540aSrobert(define_insn "*floatdidf_ieee" 2624404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=&f") 2625404b540aSrobert (float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))] 2626404b540aSrobert "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" 2627404b540aSrobert "cvtq%-%/ %1,%0" 2628404b540aSrobert [(set_attr "type" "fadd") 2629404b540aSrobert (set_attr "trap" "yes") 2630404b540aSrobert (set_attr "round_suffix" "normal") 2631404b540aSrobert (set_attr "trap_suffix" "sui")]) 2632404b540aSrobert 2633404b540aSrobert(define_insn "floatdidf2" 2634404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f") 2635404b540aSrobert (float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))] 2636404b540aSrobert "TARGET_FP" 2637404b540aSrobert "cvtq%-%/ %1,%0" 2638404b540aSrobert [(set_attr "type" "fadd") 2639404b540aSrobert (set_attr "trap" "yes") 2640404b540aSrobert (set_attr "round_suffix" "normal") 2641404b540aSrobert (set_attr "trap_suffix" "sui")]) 2642404b540aSrobert 2643404b540aSrobert(define_insn_and_split "*floatsidf2_ieee" 2644404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=&f") 2645404b540aSrobert (float:DF (match_operand:SI 1 "memory_operand" "m"))) 2646404b540aSrobert (clobber (match_scratch:DI 2 "=&f")) 2647404b540aSrobert (clobber (match_scratch:SF 3 "=&f"))] 2648404b540aSrobert "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" 2649404b540aSrobert "#" 2650404b540aSrobert "&& reload_completed" 2651404b540aSrobert [(set (match_dup 3) (match_dup 1)) 2652404b540aSrobert (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ)) 2653404b540aSrobert (set (match_dup 0) (float:DF (match_dup 2)))] 2654404b540aSrobert{ 2655404b540aSrobert operands[1] = adjust_address (operands[1], SFmode, 0); 2656404b540aSrobert}) 2657404b540aSrobert 2658404b540aSrobert(define_insn_and_split "*floatsidf2" 2659404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f") 2660404b540aSrobert (float:DF (match_operand:SI 1 "memory_operand" "m")))] 2661404b540aSrobert "TARGET_FP" 2662404b540aSrobert "#" 2663404b540aSrobert "&& reload_completed" 2664404b540aSrobert [(set (match_dup 3) (match_dup 1)) 2665404b540aSrobert (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ)) 2666404b540aSrobert (set (match_dup 0) (float:DF (match_dup 2)))] 2667404b540aSrobert{ 2668404b540aSrobert operands[1] = adjust_address (operands[1], SFmode, 0); 2669404b540aSrobert operands[2] = gen_rtx_REG (DImode, REGNO (operands[0])); 2670404b540aSrobert operands[3] = gen_rtx_REG (SFmode, REGNO (operands[0])); 2671404b540aSrobert}) 2672404b540aSrobert 2673404b540aSrobert(define_expand "floatditf2" 2674404b540aSrobert [(use (match_operand:TF 0 "register_operand" "")) 2675404b540aSrobert (use (match_operand:DI 1 "general_operand" ""))] 2676404b540aSrobert "TARGET_HAS_XFLOATING_LIBS" 2677404b540aSrobert "alpha_emit_xfloating_cvt (FLOAT, operands); DONE;") 2678404b540aSrobert 2679404b540aSrobert(define_expand "floatunsdisf2" 2680404b540aSrobert [(use (match_operand:SF 0 "register_operand" "")) 2681404b540aSrobert (use (match_operand:DI 1 "register_operand" ""))] 2682404b540aSrobert "TARGET_FP" 2683404b540aSrobert "alpha_emit_floatuns (operands); DONE;") 2684404b540aSrobert 2685404b540aSrobert(define_expand "floatunsdidf2" 2686404b540aSrobert [(use (match_operand:DF 0 "register_operand" "")) 2687404b540aSrobert (use (match_operand:DI 1 "register_operand" ""))] 2688404b540aSrobert "TARGET_FP" 2689404b540aSrobert "alpha_emit_floatuns (operands); DONE;") 2690404b540aSrobert 2691404b540aSrobert(define_expand "floatunsditf2" 2692404b540aSrobert [(use (match_operand:TF 0 "register_operand" "")) 2693404b540aSrobert (use (match_operand:DI 1 "general_operand" ""))] 2694404b540aSrobert "TARGET_HAS_XFLOATING_LIBS" 2695404b540aSrobert "alpha_emit_xfloating_cvt (UNSIGNED_FLOAT, operands); DONE;") 2696404b540aSrobert 2697404b540aSrobert(define_expand "extendsfdf2" 2698404b540aSrobert [(set (match_operand:DF 0 "register_operand" "") 2699404b540aSrobert (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))] 2700404b540aSrobert "TARGET_FP" 2701404b540aSrobert{ 2702404b540aSrobert if (alpha_fptm >= ALPHA_FPTM_SU) 2703404b540aSrobert operands[1] = force_reg (SFmode, operands[1]); 2704404b540aSrobert}) 2705404b540aSrobert 2706404b540aSrobert;; The Unicos/Mk assembler doesn't support cvtst, but we've already 2707404b540aSrobert;; asserted that alpha_fptm == ALPHA_FPTM_N. 2708404b540aSrobert 2709404b540aSrobert(define_insn "*extendsfdf2_ieee" 2710404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=&f") 2711404b540aSrobert (float_extend:DF (match_operand:SF 1 "register_operand" "f")))] 2712404b540aSrobert "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" 2713404b540aSrobert "cvtsts %1,%0" 2714404b540aSrobert [(set_attr "type" "fadd") 2715404b540aSrobert (set_attr "trap" "yes")]) 2716404b540aSrobert 2717404b540aSrobert(define_insn "*extendsfdf2_internal" 2718404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f,f,m") 2719404b540aSrobert (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m,f")))] 2720404b540aSrobert "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" 2721404b540aSrobert "@ 2722404b540aSrobert cpys %1,%1,%0 2723404b540aSrobert ld%, %0,%1 2724404b540aSrobert st%- %1,%0" 2725404b540aSrobert [(set_attr "type" "fcpys,fld,fst")]) 2726404b540aSrobert 2727404b540aSrobert;; Use register_operand for operand 1 to prevent compress_float_constant 2728404b540aSrobert;; from doing something silly. When optimizing we'll put things back 2729404b540aSrobert;; together anyway. 2730404b540aSrobert(define_expand "extendsftf2" 2731404b540aSrobert [(use (match_operand:TF 0 "register_operand" "")) 2732404b540aSrobert (use (match_operand:SF 1 "register_operand" ""))] 2733404b540aSrobert "TARGET_HAS_XFLOATING_LIBS" 2734404b540aSrobert{ 2735404b540aSrobert rtx tmp = gen_reg_rtx (DFmode); 2736404b540aSrobert emit_insn (gen_extendsfdf2 (tmp, operands[1])); 2737404b540aSrobert emit_insn (gen_extenddftf2 (operands[0], tmp)); 2738404b540aSrobert DONE; 2739404b540aSrobert}) 2740404b540aSrobert 2741404b540aSrobert(define_expand "extenddftf2" 2742404b540aSrobert [(use (match_operand:TF 0 "register_operand" "")) 2743404b540aSrobert (use (match_operand:DF 1 "register_operand" ""))] 2744404b540aSrobert "TARGET_HAS_XFLOATING_LIBS" 2745404b540aSrobert "alpha_emit_xfloating_cvt (FLOAT_EXTEND, operands); DONE;") 2746404b540aSrobert 2747404b540aSrobert(define_insn "*truncdfsf2_ieee" 2748404b540aSrobert [(set (match_operand:SF 0 "register_operand" "=&f") 2749404b540aSrobert (float_truncate:SF (match_operand:DF 1 "reg_or_0_operand" "fG")))] 2750404b540aSrobert "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" 2751404b540aSrobert "cvt%-%,%/ %R1,%0" 2752404b540aSrobert [(set_attr "type" "fadd") 2753404b540aSrobert (set_attr "trap" "yes") 2754404b540aSrobert (set_attr "round_suffix" "normal") 2755404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 2756404b540aSrobert 2757404b540aSrobert(define_insn "truncdfsf2" 2758404b540aSrobert [(set (match_operand:SF 0 "register_operand" "=f") 2759404b540aSrobert (float_truncate:SF (match_operand:DF 1 "reg_or_0_operand" "fG")))] 2760404b540aSrobert "TARGET_FP" 2761404b540aSrobert "cvt%-%,%/ %R1,%0" 2762404b540aSrobert [(set_attr "type" "fadd") 2763404b540aSrobert (set_attr "trap" "yes") 2764404b540aSrobert (set_attr "round_suffix" "normal") 2765404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 2766404b540aSrobert 2767404b540aSrobert(define_expand "trunctfdf2" 2768404b540aSrobert [(use (match_operand:DF 0 "register_operand" "")) 2769404b540aSrobert (use (match_operand:TF 1 "general_operand" ""))] 2770404b540aSrobert "TARGET_HAS_XFLOATING_LIBS" 2771404b540aSrobert "alpha_emit_xfloating_cvt (FLOAT_TRUNCATE, operands); DONE;") 2772404b540aSrobert 2773404b540aSrobert(define_expand "trunctfsf2" 2774404b540aSrobert [(use (match_operand:SF 0 "register_operand" "")) 2775404b540aSrobert (use (match_operand:TF 1 "general_operand" ""))] 2776404b540aSrobert "TARGET_FP && TARGET_HAS_XFLOATING_LIBS" 2777404b540aSrobert{ 2778404b540aSrobert rtx tmpf, sticky, arg, lo, hi; 2779404b540aSrobert 2780404b540aSrobert tmpf = gen_reg_rtx (DFmode); 2781404b540aSrobert sticky = gen_reg_rtx (DImode); 2782404b540aSrobert arg = copy_to_mode_reg (TFmode, operands[1]); 2783404b540aSrobert lo = gen_lowpart (DImode, arg); 2784404b540aSrobert hi = gen_highpart (DImode, arg); 2785404b540aSrobert 2786404b540aSrobert /* Convert the low word of the TFmode value into a sticky rounding bit, 2787404b540aSrobert then or it into the low bit of the high word. This leaves the sticky 2788404b540aSrobert bit at bit 48 of the fraction, which is representable in DFmode, 2789404b540aSrobert which prevents rounding error in the final conversion to SFmode. */ 2790404b540aSrobert 2791404b540aSrobert emit_insn (gen_rtx_SET (VOIDmode, sticky, 2792404b540aSrobert gen_rtx_NE (DImode, lo, const0_rtx))); 2793404b540aSrobert emit_insn (gen_iordi3 (hi, hi, sticky)); 2794404b540aSrobert emit_insn (gen_trunctfdf2 (tmpf, arg)); 2795404b540aSrobert emit_insn (gen_truncdfsf2 (operands[0], tmpf)); 2796404b540aSrobert DONE; 2797404b540aSrobert}) 2798404b540aSrobert 2799404b540aSrobert(define_insn "*divsf3_ieee" 2800404b540aSrobert [(set (match_operand:SF 0 "register_operand" "=&f") 2801404b540aSrobert (div:SF (match_operand:SF 1 "reg_or_0_operand" "fG") 2802404b540aSrobert (match_operand:SF 2 "reg_or_0_operand" "fG")))] 2803404b540aSrobert "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" 2804404b540aSrobert "div%,%/ %R1,%R2,%0" 2805404b540aSrobert [(set_attr "type" "fdiv") 2806404b540aSrobert (set_attr "opsize" "si") 2807404b540aSrobert (set_attr "trap" "yes") 2808404b540aSrobert (set_attr "round_suffix" "normal") 2809404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 2810404b540aSrobert 2811404b540aSrobert(define_insn "divsf3" 2812404b540aSrobert [(set (match_operand:SF 0 "register_operand" "=f") 2813404b540aSrobert (div:SF (match_operand:SF 1 "reg_or_0_operand" "fG") 2814404b540aSrobert (match_operand:SF 2 "reg_or_0_operand" "fG")))] 2815404b540aSrobert "TARGET_FP" 2816404b540aSrobert "div%,%/ %R1,%R2,%0" 2817404b540aSrobert [(set_attr "type" "fdiv") 2818404b540aSrobert (set_attr "opsize" "si") 2819404b540aSrobert (set_attr "trap" "yes") 2820404b540aSrobert (set_attr "round_suffix" "normal") 2821404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 2822404b540aSrobert 2823404b540aSrobert(define_insn "*divdf3_ieee" 2824404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=&f") 2825404b540aSrobert (div:DF (match_operand:DF 1 "reg_or_0_operand" "fG") 2826404b540aSrobert (match_operand:DF 2 "reg_or_0_operand" "fG")))] 2827404b540aSrobert "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" 2828404b540aSrobert "div%-%/ %R1,%R2,%0" 2829404b540aSrobert [(set_attr "type" "fdiv") 2830404b540aSrobert (set_attr "trap" "yes") 2831404b540aSrobert (set_attr "round_suffix" "normal") 2832404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 2833404b540aSrobert 2834404b540aSrobert(define_insn "divdf3" 2835404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f") 2836404b540aSrobert (div:DF (match_operand:DF 1 "reg_or_0_operand" "fG") 2837404b540aSrobert (match_operand:DF 2 "reg_or_0_operand" "fG")))] 2838404b540aSrobert "TARGET_FP" 2839404b540aSrobert "div%-%/ %R1,%R2,%0" 2840404b540aSrobert [(set_attr "type" "fdiv") 2841404b540aSrobert (set_attr "trap" "yes") 2842404b540aSrobert (set_attr "round_suffix" "normal") 2843404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 2844404b540aSrobert 2845404b540aSrobert(define_insn "*divdf_ext1" 2846404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f") 2847404b540aSrobert (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG")) 2848404b540aSrobert (match_operand:DF 2 "reg_or_0_operand" "fG")))] 2849404b540aSrobert "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" 2850404b540aSrobert "div%-%/ %R1,%R2,%0" 2851404b540aSrobert [(set_attr "type" "fdiv") 2852404b540aSrobert (set_attr "trap" "yes") 2853404b540aSrobert (set_attr "round_suffix" "normal") 2854404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 2855404b540aSrobert 2856404b540aSrobert(define_insn "*divdf_ext2" 2857404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f") 2858404b540aSrobert (div:DF (match_operand:DF 1 "reg_or_0_operand" "fG") 2859404b540aSrobert (float_extend:DF 2860404b540aSrobert (match_operand:SF 2 "reg_or_0_operand" "fG"))))] 2861404b540aSrobert "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" 2862404b540aSrobert "div%-%/ %R1,%R2,%0" 2863404b540aSrobert [(set_attr "type" "fdiv") 2864404b540aSrobert (set_attr "trap" "yes") 2865404b540aSrobert (set_attr "round_suffix" "normal") 2866404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 2867404b540aSrobert 2868404b540aSrobert(define_insn "*divdf_ext3" 2869404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f") 2870404b540aSrobert (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG")) 2871404b540aSrobert (float_extend:DF (match_operand:SF 2 "reg_or_0_operand" "fG"))))] 2872404b540aSrobert "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" 2873404b540aSrobert "div%-%/ %R1,%R2,%0" 2874404b540aSrobert [(set_attr "type" "fdiv") 2875404b540aSrobert (set_attr "trap" "yes") 2876404b540aSrobert (set_attr "round_suffix" "normal") 2877404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 2878404b540aSrobert 2879404b540aSrobert(define_expand "divtf3" 2880404b540aSrobert [(use (match_operand 0 "register_operand" "")) 2881404b540aSrobert (use (match_operand 1 "general_operand" "")) 2882404b540aSrobert (use (match_operand 2 "general_operand" ""))] 2883404b540aSrobert "TARGET_HAS_XFLOATING_LIBS" 2884404b540aSrobert "alpha_emit_xfloating_arith (DIV, operands); DONE;") 2885404b540aSrobert 2886404b540aSrobert(define_insn "*mulsf3_ieee" 2887404b540aSrobert [(set (match_operand:SF 0 "register_operand" "=&f") 2888404b540aSrobert (mult:SF (match_operand:SF 1 "reg_or_0_operand" "%fG") 2889404b540aSrobert (match_operand:SF 2 "reg_or_0_operand" "fG")))] 2890404b540aSrobert "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" 2891404b540aSrobert "mul%,%/ %R1,%R2,%0" 2892404b540aSrobert [(set_attr "type" "fmul") 2893404b540aSrobert (set_attr "trap" "yes") 2894404b540aSrobert (set_attr "round_suffix" "normal") 2895404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 2896404b540aSrobert 2897404b540aSrobert(define_insn "mulsf3" 2898404b540aSrobert [(set (match_operand:SF 0 "register_operand" "=f") 2899404b540aSrobert (mult:SF (match_operand:SF 1 "reg_or_0_operand" "%fG") 2900404b540aSrobert (match_operand:SF 2 "reg_or_0_operand" "fG")))] 2901404b540aSrobert "TARGET_FP" 2902404b540aSrobert "mul%,%/ %R1,%R2,%0" 2903404b540aSrobert [(set_attr "type" "fmul") 2904404b540aSrobert (set_attr "trap" "yes") 2905404b540aSrobert (set_attr "round_suffix" "normal") 2906404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 2907404b540aSrobert 2908404b540aSrobert(define_insn "*muldf3_ieee" 2909404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=&f") 2910404b540aSrobert (mult:DF (match_operand:DF 1 "reg_or_0_operand" "%fG") 2911404b540aSrobert (match_operand:DF 2 "reg_or_0_operand" "fG")))] 2912404b540aSrobert "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" 2913404b540aSrobert "mul%-%/ %R1,%R2,%0" 2914404b540aSrobert [(set_attr "type" "fmul") 2915404b540aSrobert (set_attr "trap" "yes") 2916404b540aSrobert (set_attr "round_suffix" "normal") 2917404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 2918404b540aSrobert 2919404b540aSrobert(define_insn "muldf3" 2920404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f") 2921404b540aSrobert (mult:DF (match_operand:DF 1 "reg_or_0_operand" "%fG") 2922404b540aSrobert (match_operand:DF 2 "reg_or_0_operand" "fG")))] 2923404b540aSrobert "TARGET_FP" 2924404b540aSrobert "mul%-%/ %R1,%R2,%0" 2925404b540aSrobert [(set_attr "type" "fmul") 2926404b540aSrobert (set_attr "trap" "yes") 2927404b540aSrobert (set_attr "round_suffix" "normal") 2928404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 2929404b540aSrobert 2930404b540aSrobert(define_insn "*muldf_ext1" 2931404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f") 2932404b540aSrobert (mult:DF (float_extend:DF 2933404b540aSrobert (match_operand:SF 1 "reg_or_0_operand" "fG")) 2934404b540aSrobert (match_operand:DF 2 "reg_or_0_operand" "fG")))] 2935404b540aSrobert "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" 2936404b540aSrobert "mul%-%/ %R1,%R2,%0" 2937404b540aSrobert [(set_attr "type" "fmul") 2938404b540aSrobert (set_attr "trap" "yes") 2939404b540aSrobert (set_attr "round_suffix" "normal") 2940404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 2941404b540aSrobert 2942404b540aSrobert(define_insn "*muldf_ext2" 2943404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f") 2944404b540aSrobert (mult:DF (float_extend:DF 2945404b540aSrobert (match_operand:SF 1 "reg_or_0_operand" "%fG")) 2946404b540aSrobert (float_extend:DF 2947404b540aSrobert (match_operand:SF 2 "reg_or_0_operand" "fG"))))] 2948404b540aSrobert "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" 2949404b540aSrobert "mul%-%/ %R1,%R2,%0" 2950404b540aSrobert [(set_attr "type" "fmul") 2951404b540aSrobert (set_attr "trap" "yes") 2952404b540aSrobert (set_attr "round_suffix" "normal") 2953404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 2954404b540aSrobert 2955404b540aSrobert(define_expand "multf3" 2956404b540aSrobert [(use (match_operand 0 "register_operand" "")) 2957404b540aSrobert (use (match_operand 1 "general_operand" "")) 2958404b540aSrobert (use (match_operand 2 "general_operand" ""))] 2959404b540aSrobert "TARGET_HAS_XFLOATING_LIBS" 2960404b540aSrobert "alpha_emit_xfloating_arith (MULT, operands); DONE;") 2961404b540aSrobert 2962404b540aSrobert(define_insn "*subsf3_ieee" 2963404b540aSrobert [(set (match_operand:SF 0 "register_operand" "=&f") 2964404b540aSrobert (minus:SF (match_operand:SF 1 "reg_or_0_operand" "fG") 2965404b540aSrobert (match_operand:SF 2 "reg_or_0_operand" "fG")))] 2966404b540aSrobert "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" 2967404b540aSrobert "sub%,%/ %R1,%R2,%0" 2968404b540aSrobert [(set_attr "type" "fadd") 2969404b540aSrobert (set_attr "trap" "yes") 2970404b540aSrobert (set_attr "round_suffix" "normal") 2971404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 2972404b540aSrobert 2973404b540aSrobert(define_insn "subsf3" 2974404b540aSrobert [(set (match_operand:SF 0 "register_operand" "=f") 2975404b540aSrobert (minus:SF (match_operand:SF 1 "reg_or_0_operand" "fG") 2976404b540aSrobert (match_operand:SF 2 "reg_or_0_operand" "fG")))] 2977404b540aSrobert "TARGET_FP" 2978404b540aSrobert "sub%,%/ %R1,%R2,%0" 2979404b540aSrobert [(set_attr "type" "fadd") 2980404b540aSrobert (set_attr "trap" "yes") 2981404b540aSrobert (set_attr "round_suffix" "normal") 2982404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 2983404b540aSrobert 2984404b540aSrobert(define_insn "*subdf3_ieee" 2985404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=&f") 2986404b540aSrobert (minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG") 2987404b540aSrobert (match_operand:DF 2 "reg_or_0_operand" "fG")))] 2988404b540aSrobert "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" 2989404b540aSrobert "sub%-%/ %R1,%R2,%0" 2990404b540aSrobert [(set_attr "type" "fadd") 2991404b540aSrobert (set_attr "trap" "yes") 2992404b540aSrobert (set_attr "round_suffix" "normal") 2993404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 2994404b540aSrobert 2995404b540aSrobert(define_insn "subdf3" 2996404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f") 2997404b540aSrobert (minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG") 2998404b540aSrobert (match_operand:DF 2 "reg_or_0_operand" "fG")))] 2999404b540aSrobert "TARGET_FP" 3000404b540aSrobert "sub%-%/ %R1,%R2,%0" 3001404b540aSrobert [(set_attr "type" "fadd") 3002404b540aSrobert (set_attr "trap" "yes") 3003404b540aSrobert (set_attr "round_suffix" "normal") 3004404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 3005404b540aSrobert 3006404b540aSrobert(define_insn "*subdf_ext1" 3007404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f") 3008404b540aSrobert (minus:DF (float_extend:DF 3009404b540aSrobert (match_operand:SF 1 "reg_or_0_operand" "fG")) 3010404b540aSrobert (match_operand:DF 2 "reg_or_0_operand" "fG")))] 3011404b540aSrobert "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" 3012404b540aSrobert "sub%-%/ %R1,%R2,%0" 3013404b540aSrobert [(set_attr "type" "fadd") 3014404b540aSrobert (set_attr "trap" "yes") 3015404b540aSrobert (set_attr "round_suffix" "normal") 3016404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 3017404b540aSrobert 3018404b540aSrobert(define_insn "*subdf_ext2" 3019404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f") 3020404b540aSrobert (minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG") 3021404b540aSrobert (float_extend:DF 3022404b540aSrobert (match_operand:SF 2 "reg_or_0_operand" "fG"))))] 3023404b540aSrobert "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" 3024404b540aSrobert "sub%-%/ %R1,%R2,%0" 3025404b540aSrobert [(set_attr "type" "fadd") 3026404b540aSrobert (set_attr "trap" "yes") 3027404b540aSrobert (set_attr "round_suffix" "normal") 3028404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 3029404b540aSrobert 3030404b540aSrobert(define_insn "*subdf_ext3" 3031404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f") 3032404b540aSrobert (minus:DF (float_extend:DF 3033404b540aSrobert (match_operand:SF 1 "reg_or_0_operand" "fG")) 3034404b540aSrobert (float_extend:DF 3035404b540aSrobert (match_operand:SF 2 "reg_or_0_operand" "fG"))))] 3036404b540aSrobert "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" 3037404b540aSrobert "sub%-%/ %R1,%R2,%0" 3038404b540aSrobert [(set_attr "type" "fadd") 3039404b540aSrobert (set_attr "trap" "yes") 3040404b540aSrobert (set_attr "round_suffix" "normal") 3041404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 3042404b540aSrobert 3043404b540aSrobert(define_expand "subtf3" 3044404b540aSrobert [(use (match_operand 0 "register_operand" "")) 3045404b540aSrobert (use (match_operand 1 "general_operand" "")) 3046404b540aSrobert (use (match_operand 2 "general_operand" ""))] 3047404b540aSrobert "TARGET_HAS_XFLOATING_LIBS" 3048404b540aSrobert "alpha_emit_xfloating_arith (MINUS, operands); DONE;") 3049404b540aSrobert 3050404b540aSrobert(define_insn "*sqrtsf2_ieee" 3051404b540aSrobert [(set (match_operand:SF 0 "register_operand" "=&f") 3052404b540aSrobert (sqrt:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))] 3053404b540aSrobert "TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU" 3054404b540aSrobert "sqrt%,%/ %R1,%0" 3055404b540aSrobert [(set_attr "type" "fsqrt") 3056404b540aSrobert (set_attr "opsize" "si") 3057404b540aSrobert (set_attr "trap" "yes") 3058404b540aSrobert (set_attr "round_suffix" "normal") 3059404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 3060404b540aSrobert 3061404b540aSrobert(define_insn "sqrtsf2" 3062404b540aSrobert [(set (match_operand:SF 0 "register_operand" "=f") 3063404b540aSrobert (sqrt:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))] 3064404b540aSrobert "TARGET_FP && TARGET_FIX" 3065404b540aSrobert "sqrt%,%/ %R1,%0" 3066404b540aSrobert [(set_attr "type" "fsqrt") 3067404b540aSrobert (set_attr "opsize" "si") 3068404b540aSrobert (set_attr "trap" "yes") 3069404b540aSrobert (set_attr "round_suffix" "normal") 3070404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 3071404b540aSrobert 3072404b540aSrobert(define_insn "*sqrtdf2_ieee" 3073404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=&f") 3074404b540aSrobert (sqrt:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))] 3075404b540aSrobert "TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU" 3076404b540aSrobert "sqrt%-%/ %R1,%0" 3077404b540aSrobert [(set_attr "type" "fsqrt") 3078404b540aSrobert (set_attr "trap" "yes") 3079404b540aSrobert (set_attr "round_suffix" "normal") 3080404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 3081404b540aSrobert 3082404b540aSrobert(define_insn "sqrtdf2" 3083404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f") 3084404b540aSrobert (sqrt:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))] 3085404b540aSrobert "TARGET_FP && TARGET_FIX" 3086404b540aSrobert "sqrt%-%/ %R1,%0" 3087404b540aSrobert [(set_attr "type" "fsqrt") 3088404b540aSrobert (set_attr "trap" "yes") 3089404b540aSrobert (set_attr "round_suffix" "normal") 3090404b540aSrobert (set_attr "trap_suffix" "u_su_sui")]) 3091404b540aSrobert 3092404b540aSrobert;; Next are all the integer comparisons, and conditional moves and branches 3093404b540aSrobert;; and some of the related define_expand's and define_split's. 3094404b540aSrobert 3095404b540aSrobert(define_insn "*setcc_internal" 3096404b540aSrobert [(set (match_operand 0 "register_operand" "=r") 3097404b540aSrobert (match_operator 1 "alpha_comparison_operator" 3098404b540aSrobert [(match_operand:DI 2 "register_operand" "r") 3099404b540aSrobert (match_operand:DI 3 "reg_or_8bit_operand" "rI")]))] 3100404b540aSrobert "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT 3101404b540aSrobert && GET_MODE_SIZE (GET_MODE (operands[0])) <= 8 3102404b540aSrobert && GET_MODE (operands[0]) == GET_MODE (operands[1])" 3103404b540aSrobert "cmp%C1 %2,%3,%0" 3104404b540aSrobert [(set_attr "type" "icmp")]) 3105404b540aSrobert 3106404b540aSrobert;; Yes, we can technically support reg_or_8bit_operand in operand 2, 3107404b540aSrobert;; but that's non-canonical rtl and allowing that causes inefficiencies 3108404b540aSrobert;; from cse on. 3109404b540aSrobert(define_insn "*setcc_swapped_internal" 3110404b540aSrobert [(set (match_operand 0 "register_operand" "=r") 3111404b540aSrobert (match_operator 1 "alpha_swapped_comparison_operator" 3112404b540aSrobert [(match_operand:DI 2 "register_operand" "r") 3113404b540aSrobert (match_operand:DI 3 "reg_or_0_operand" "rJ")]))] 3114404b540aSrobert "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT 3115404b540aSrobert && GET_MODE_SIZE (GET_MODE (operands[0])) <= 8 3116404b540aSrobert && GET_MODE (operands[0]) == GET_MODE (operands[1])" 3117404b540aSrobert "cmp%c1 %r3,%2,%0" 3118404b540aSrobert [(set_attr "type" "icmp")]) 3119404b540aSrobert 3120404b540aSrobert;; Use match_operator rather than ne directly so that we can match 3121404b540aSrobert;; multiple integer modes. 3122404b540aSrobert(define_insn "*setne_internal" 3123404b540aSrobert [(set (match_operand 0 "register_operand" "=r") 3124404b540aSrobert (match_operator 1 "signed_comparison_operator" 3125404b540aSrobert [(match_operand:DI 2 "register_operand" "r") 3126404b540aSrobert (const_int 0)]))] 3127404b540aSrobert "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT 3128404b540aSrobert && GET_MODE_SIZE (GET_MODE (operands[0])) <= 8 3129404b540aSrobert && GET_CODE (operands[1]) == NE 3130404b540aSrobert && GET_MODE (operands[0]) == GET_MODE (operands[1])" 3131404b540aSrobert "cmpult $31,%2,%0" 3132404b540aSrobert [(set_attr "type" "icmp")]) 3133404b540aSrobert 3134404b540aSrobert;; The mode folding trick can't be used with const_int operands, since 3135404b540aSrobert;; reload needs to know the proper mode. 3136404b540aSrobert;; 3137404b540aSrobert;; Use add_operand instead of the more seemingly natural reg_or_8bit_operand 3138404b540aSrobert;; in order to create more pairs of constants. As long as we're allowing 3139404b540aSrobert;; two constants at the same time, and will have to reload one of them... 3140404b540aSrobert 3141404b540aSrobert(define_insn "*movqicc_internal" 3142404b540aSrobert [(set (match_operand:QI 0 "register_operand" "=r,r,r,r") 3143404b540aSrobert (if_then_else:QI 3144404b540aSrobert (match_operator 2 "signed_comparison_operator" 3145404b540aSrobert [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J") 3146404b540aSrobert (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")]) 3147404b540aSrobert (match_operand:QI 1 "add_operand" "rI,0,rI,0") 3148404b540aSrobert (match_operand:QI 5 "add_operand" "0,rI,0,rI")))] 3149404b540aSrobert "(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)" 3150404b540aSrobert "@ 3151404b540aSrobert cmov%C2 %r3,%1,%0 3152404b540aSrobert cmov%D2 %r3,%5,%0 3153404b540aSrobert cmov%c2 %r4,%1,%0 3154404b540aSrobert cmov%d2 %r4,%5,%0" 3155404b540aSrobert [(set_attr "type" "icmov")]) 3156404b540aSrobert 3157404b540aSrobert(define_insn "*movhicc_internal" 3158404b540aSrobert [(set (match_operand:HI 0 "register_operand" "=r,r,r,r") 3159404b540aSrobert (if_then_else:HI 3160404b540aSrobert (match_operator 2 "signed_comparison_operator" 3161404b540aSrobert [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J") 3162404b540aSrobert (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")]) 3163404b540aSrobert (match_operand:HI 1 "add_operand" "rI,0,rI,0") 3164404b540aSrobert (match_operand:HI 5 "add_operand" "0,rI,0,rI")))] 3165404b540aSrobert "(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)" 3166404b540aSrobert "@ 3167404b540aSrobert cmov%C2 %r3,%1,%0 3168404b540aSrobert cmov%D2 %r3,%5,%0 3169404b540aSrobert cmov%c2 %r4,%1,%0 3170404b540aSrobert cmov%d2 %r4,%5,%0" 3171404b540aSrobert [(set_attr "type" "icmov")]) 3172404b540aSrobert 3173404b540aSrobert(define_insn "*movsicc_internal" 3174404b540aSrobert [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") 3175404b540aSrobert (if_then_else:SI 3176404b540aSrobert (match_operator 2 "signed_comparison_operator" 3177404b540aSrobert [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J") 3178404b540aSrobert (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")]) 3179404b540aSrobert (match_operand:SI 1 "add_operand" "rI,0,rI,0") 3180404b540aSrobert (match_operand:SI 5 "add_operand" "0,rI,0,rI")))] 3181404b540aSrobert "(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)" 3182404b540aSrobert "@ 3183404b540aSrobert cmov%C2 %r3,%1,%0 3184404b540aSrobert cmov%D2 %r3,%5,%0 3185404b540aSrobert cmov%c2 %r4,%1,%0 3186404b540aSrobert cmov%d2 %r4,%5,%0" 3187404b540aSrobert [(set_attr "type" "icmov")]) 3188404b540aSrobert 3189404b540aSrobert(define_insn "*movdicc_internal" 3190404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r,r,r,r") 3191404b540aSrobert (if_then_else:DI 3192404b540aSrobert (match_operator 2 "signed_comparison_operator" 3193404b540aSrobert [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J") 3194404b540aSrobert (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")]) 3195404b540aSrobert (match_operand:DI 1 "add_operand" "rI,0,rI,0") 3196404b540aSrobert (match_operand:DI 5 "add_operand" "0,rI,0,rI")))] 3197404b540aSrobert "(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)" 3198404b540aSrobert "@ 3199404b540aSrobert cmov%C2 %r3,%1,%0 3200404b540aSrobert cmov%D2 %r3,%5,%0 3201404b540aSrobert cmov%c2 %r4,%1,%0 3202404b540aSrobert cmov%d2 %r4,%5,%0" 3203404b540aSrobert [(set_attr "type" "icmov")]) 3204404b540aSrobert 3205404b540aSrobert(define_insn "*movqicc_lbc" 3206404b540aSrobert [(set (match_operand:QI 0 "register_operand" "=r,r") 3207404b540aSrobert (if_then_else:QI 3208404b540aSrobert (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ") 3209404b540aSrobert (const_int 1) 3210404b540aSrobert (const_int 0)) 3211404b540aSrobert (const_int 0)) 3212404b540aSrobert (match_operand:QI 1 "reg_or_8bit_operand" "rI,0") 3213404b540aSrobert (match_operand:QI 3 "reg_or_8bit_operand" "0,rI")))] 3214404b540aSrobert "" 3215404b540aSrobert "@ 3216404b540aSrobert cmovlbc %r2,%1,%0 3217404b540aSrobert cmovlbs %r2,%3,%0" 3218404b540aSrobert [(set_attr "type" "icmov")]) 3219404b540aSrobert 3220404b540aSrobert(define_insn "*movhicc_lbc" 3221404b540aSrobert [(set (match_operand:HI 0 "register_operand" "=r,r") 3222404b540aSrobert (if_then_else:HI 3223404b540aSrobert (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ") 3224404b540aSrobert (const_int 1) 3225404b540aSrobert (const_int 0)) 3226404b540aSrobert (const_int 0)) 3227404b540aSrobert (match_operand:HI 1 "reg_or_8bit_operand" "rI,0") 3228404b540aSrobert (match_operand:HI 3 "reg_or_8bit_operand" "0,rI")))] 3229404b540aSrobert "" 3230404b540aSrobert "@ 3231404b540aSrobert cmovlbc %r2,%1,%0 3232404b540aSrobert cmovlbs %r2,%3,%0" 3233404b540aSrobert [(set_attr "type" "icmov")]) 3234404b540aSrobert 3235404b540aSrobert(define_insn "*movsicc_lbc" 3236404b540aSrobert [(set (match_operand:SI 0 "register_operand" "=r,r") 3237404b540aSrobert (if_then_else:SI 3238404b540aSrobert (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ") 3239404b540aSrobert (const_int 1) 3240404b540aSrobert (const_int 0)) 3241404b540aSrobert (const_int 0)) 3242404b540aSrobert (match_operand:SI 1 "reg_or_8bit_operand" "rI,0") 3243404b540aSrobert (match_operand:SI 3 "reg_or_8bit_operand" "0,rI")))] 3244404b540aSrobert "" 3245404b540aSrobert "@ 3246404b540aSrobert cmovlbc %r2,%1,%0 3247404b540aSrobert cmovlbs %r2,%3,%0" 3248404b540aSrobert [(set_attr "type" "icmov")]) 3249404b540aSrobert 3250404b540aSrobert(define_insn "*movdicc_lbc" 3251404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r,r") 3252404b540aSrobert (if_then_else:DI 3253404b540aSrobert (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ") 3254404b540aSrobert (const_int 1) 3255404b540aSrobert (const_int 0)) 3256404b540aSrobert (const_int 0)) 3257404b540aSrobert (match_operand:DI 1 "reg_or_8bit_operand" "rI,0") 3258404b540aSrobert (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))] 3259404b540aSrobert "" 3260404b540aSrobert "@ 3261404b540aSrobert cmovlbc %r2,%1,%0 3262404b540aSrobert cmovlbs %r2,%3,%0" 3263404b540aSrobert [(set_attr "type" "icmov")]) 3264404b540aSrobert 3265404b540aSrobert(define_insn "*movqicc_lbs" 3266404b540aSrobert [(set (match_operand:QI 0 "register_operand" "=r,r") 3267404b540aSrobert (if_then_else:QI 3268404b540aSrobert (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ") 3269404b540aSrobert (const_int 1) 3270404b540aSrobert (const_int 0)) 3271404b540aSrobert (const_int 0)) 3272404b540aSrobert (match_operand:QI 1 "reg_or_8bit_operand" "rI,0") 3273404b540aSrobert (match_operand:QI 3 "reg_or_8bit_operand" "0,rI")))] 3274404b540aSrobert "" 3275404b540aSrobert "@ 3276404b540aSrobert cmovlbs %r2,%1,%0 3277404b540aSrobert cmovlbc %r2,%3,%0" 3278404b540aSrobert [(set_attr "type" "icmov")]) 3279404b540aSrobert 3280404b540aSrobert(define_insn "*movhicc_lbs" 3281404b540aSrobert [(set (match_operand:HI 0 "register_operand" "=r,r") 3282404b540aSrobert (if_then_else:HI 3283404b540aSrobert (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ") 3284404b540aSrobert (const_int 1) 3285404b540aSrobert (const_int 0)) 3286404b540aSrobert (const_int 0)) 3287404b540aSrobert (match_operand:HI 1 "reg_or_8bit_operand" "rI,0") 3288404b540aSrobert (match_operand:HI 3 "reg_or_8bit_operand" "0,rI")))] 3289404b540aSrobert "" 3290404b540aSrobert "@ 3291404b540aSrobert cmovlbs %r2,%1,%0 3292404b540aSrobert cmovlbc %r2,%3,%0" 3293404b540aSrobert [(set_attr "type" "icmov")]) 3294404b540aSrobert 3295404b540aSrobert(define_insn "*movsicc_lbs" 3296404b540aSrobert [(set (match_operand:SI 0 "register_operand" "=r,r") 3297404b540aSrobert (if_then_else:SI 3298404b540aSrobert (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ") 3299404b540aSrobert (const_int 1) 3300404b540aSrobert (const_int 0)) 3301404b540aSrobert (const_int 0)) 3302404b540aSrobert (match_operand:SI 1 "reg_or_8bit_operand" "rI,0") 3303404b540aSrobert (match_operand:SI 3 "reg_or_8bit_operand" "0,rI")))] 3304404b540aSrobert "" 3305404b540aSrobert "@ 3306404b540aSrobert cmovlbs %r2,%1,%0 3307404b540aSrobert cmovlbc %r2,%3,%0" 3308404b540aSrobert [(set_attr "type" "icmov")]) 3309404b540aSrobert 3310404b540aSrobert(define_insn "*movdicc_lbs" 3311404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r,r") 3312404b540aSrobert (if_then_else:DI 3313404b540aSrobert (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ") 3314404b540aSrobert (const_int 1) 3315404b540aSrobert (const_int 0)) 3316404b540aSrobert (const_int 0)) 3317404b540aSrobert (match_operand:DI 1 "reg_or_8bit_operand" "rI,0") 3318404b540aSrobert (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))] 3319404b540aSrobert "" 3320404b540aSrobert "@ 3321404b540aSrobert cmovlbs %r2,%1,%0 3322404b540aSrobert cmovlbc %r2,%3,%0" 3323404b540aSrobert [(set_attr "type" "icmov")]) 3324404b540aSrobert 3325404b540aSrobert;; For ABS, we have two choices, depending on whether the input and output 3326404b540aSrobert;; registers are the same or not. 3327404b540aSrobert(define_expand "absdi2" 3328404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 3329404b540aSrobert (abs:DI (match_operand:DI 1 "register_operand" "")))] 3330404b540aSrobert "" 3331404b540aSrobert{ 3332404b540aSrobert if (rtx_equal_p (operands[0], operands[1])) 3333404b540aSrobert emit_insn (gen_absdi2_same (operands[0], gen_reg_rtx (DImode))); 3334404b540aSrobert else 3335404b540aSrobert emit_insn (gen_absdi2_diff (operands[0], operands[1])); 3336404b540aSrobert DONE; 3337404b540aSrobert}) 3338404b540aSrobert 3339404b540aSrobert(define_expand "absdi2_same" 3340404b540aSrobert [(set (match_operand:DI 1 "register_operand" "") 3341404b540aSrobert (neg:DI (match_operand:DI 0 "register_operand" ""))) 3342404b540aSrobert (set (match_dup 0) 3343404b540aSrobert (if_then_else:DI (ge (match_dup 0) (const_int 0)) 3344404b540aSrobert (match_dup 0) 3345404b540aSrobert (match_dup 1)))] 3346404b540aSrobert "" 3347404b540aSrobert "") 3348404b540aSrobert 3349404b540aSrobert(define_expand "absdi2_diff" 3350404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 3351404b540aSrobert (neg:DI (match_operand:DI 1 "register_operand" ""))) 3352404b540aSrobert (set (match_dup 0) 3353404b540aSrobert (if_then_else:DI (lt (match_dup 1) (const_int 0)) 3354404b540aSrobert (match_dup 0) 3355404b540aSrobert (match_dup 1)))] 3356404b540aSrobert "" 3357404b540aSrobert "") 3358404b540aSrobert 3359404b540aSrobert(define_split 3360404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 3361404b540aSrobert (abs:DI (match_dup 0))) 3362404b540aSrobert (clobber (match_operand:DI 1 "register_operand" ""))] 3363404b540aSrobert "" 3364404b540aSrobert [(set (match_dup 1) (neg:DI (match_dup 0))) 3365404b540aSrobert (set (match_dup 0) (if_then_else:DI (ge (match_dup 0) (const_int 0)) 3366404b540aSrobert (match_dup 0) (match_dup 1)))] 3367404b540aSrobert "") 3368404b540aSrobert 3369404b540aSrobert(define_split 3370404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 3371404b540aSrobert (abs:DI (match_operand:DI 1 "register_operand" "")))] 3372404b540aSrobert "! rtx_equal_p (operands[0], operands[1])" 3373404b540aSrobert [(set (match_dup 0) (neg:DI (match_dup 1))) 3374404b540aSrobert (set (match_dup 0) (if_then_else:DI (lt (match_dup 1) (const_int 0)) 3375404b540aSrobert (match_dup 0) (match_dup 1)))] 3376404b540aSrobert "") 3377404b540aSrobert 3378404b540aSrobert(define_split 3379404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 3380404b540aSrobert (neg:DI (abs:DI (match_dup 0)))) 3381404b540aSrobert (clobber (match_operand:DI 1 "register_operand" ""))] 3382404b540aSrobert "" 3383404b540aSrobert [(set (match_dup 1) (neg:DI (match_dup 0))) 3384404b540aSrobert (set (match_dup 0) (if_then_else:DI (le (match_dup 0) (const_int 0)) 3385404b540aSrobert (match_dup 0) (match_dup 1)))] 3386404b540aSrobert "") 3387404b540aSrobert 3388404b540aSrobert(define_split 3389404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 3390404b540aSrobert (neg:DI (abs:DI (match_operand:DI 1 "register_operand" ""))))] 3391404b540aSrobert "! rtx_equal_p (operands[0], operands[1])" 3392404b540aSrobert [(set (match_dup 0) (neg:DI (match_dup 1))) 3393404b540aSrobert (set (match_dup 0) (if_then_else:DI (gt (match_dup 1) (const_int 0)) 3394404b540aSrobert (match_dup 0) (match_dup 1)))] 3395404b540aSrobert "") 3396404b540aSrobert 3397404b540aSrobert(define_insn "sminqi3" 3398404b540aSrobert [(set (match_operand:QI 0 "register_operand" "=r") 3399404b540aSrobert (smin:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ") 3400404b540aSrobert (match_operand:QI 2 "reg_or_8bit_operand" "rI")))] 3401404b540aSrobert "TARGET_MAX" 3402404b540aSrobert "minsb8 %r1,%2,%0" 3403404b540aSrobert [(set_attr "type" "mvi")]) 3404404b540aSrobert 3405404b540aSrobert(define_insn "uminqi3" 3406404b540aSrobert [(set (match_operand:QI 0 "register_operand" "=r") 3407404b540aSrobert (umin:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ") 3408404b540aSrobert (match_operand:QI 2 "reg_or_8bit_operand" "rI")))] 3409404b540aSrobert "TARGET_MAX" 3410404b540aSrobert "minub8 %r1,%2,%0" 3411404b540aSrobert [(set_attr "type" "mvi")]) 3412404b540aSrobert 3413404b540aSrobert(define_insn "smaxqi3" 3414404b540aSrobert [(set (match_operand:QI 0 "register_operand" "=r") 3415404b540aSrobert (smax:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ") 3416404b540aSrobert (match_operand:QI 2 "reg_or_8bit_operand" "rI")))] 3417404b540aSrobert "TARGET_MAX" 3418404b540aSrobert "maxsb8 %r1,%2,%0" 3419404b540aSrobert [(set_attr "type" "mvi")]) 3420404b540aSrobert 3421404b540aSrobert(define_insn "umaxqi3" 3422404b540aSrobert [(set (match_operand:QI 0 "register_operand" "=r") 3423404b540aSrobert (umax:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ") 3424404b540aSrobert (match_operand:QI 2 "reg_or_8bit_operand" "rI")))] 3425404b540aSrobert "TARGET_MAX" 3426404b540aSrobert "maxub8 %r1,%2,%0" 3427404b540aSrobert [(set_attr "type" "mvi")]) 3428404b540aSrobert 3429404b540aSrobert(define_insn "sminhi3" 3430404b540aSrobert [(set (match_operand:HI 0 "register_operand" "=r") 3431404b540aSrobert (smin:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ") 3432404b540aSrobert (match_operand:HI 2 "reg_or_8bit_operand" "rI")))] 3433404b540aSrobert "TARGET_MAX" 3434404b540aSrobert "minsw4 %r1,%2,%0" 3435404b540aSrobert [(set_attr "type" "mvi")]) 3436404b540aSrobert 3437404b540aSrobert(define_insn "uminhi3" 3438404b540aSrobert [(set (match_operand:HI 0 "register_operand" "=r") 3439404b540aSrobert (umin:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ") 3440404b540aSrobert (match_operand:HI 2 "reg_or_8bit_operand" "rI")))] 3441404b540aSrobert "TARGET_MAX" 3442404b540aSrobert "minuw4 %r1,%2,%0" 3443404b540aSrobert [(set_attr "type" "mvi")]) 3444404b540aSrobert 3445404b540aSrobert(define_insn "smaxhi3" 3446404b540aSrobert [(set (match_operand:HI 0 "register_operand" "=r") 3447404b540aSrobert (smax:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ") 3448404b540aSrobert (match_operand:HI 2 "reg_or_8bit_operand" "rI")))] 3449404b540aSrobert "TARGET_MAX" 3450404b540aSrobert "maxsw4 %r1,%2,%0" 3451404b540aSrobert [(set_attr "type" "mvi")]) 3452404b540aSrobert 3453404b540aSrobert(define_insn "umaxhi3" 3454404b540aSrobert [(set (match_operand:HI 0 "register_operand" "=r") 3455404b540aSrobert (umax:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ") 3456404b540aSrobert (match_operand:HI 2 "reg_or_8bit_operand" "rI")))] 3457404b540aSrobert "TARGET_MAX" 3458404b540aSrobert "maxuw4 %r1,%2,%0" 3459404b540aSrobert [(set_attr "type" "mvi")]) 3460404b540aSrobert 3461404b540aSrobert(define_expand "smaxdi3" 3462404b540aSrobert [(set (match_dup 3) 3463404b540aSrobert (le:DI (match_operand:DI 1 "reg_or_0_operand" "") 3464404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" ""))) 3465404b540aSrobert (set (match_operand:DI 0 "register_operand" "") 3466404b540aSrobert (if_then_else:DI (eq (match_dup 3) (const_int 0)) 3467404b540aSrobert (match_dup 1) (match_dup 2)))] 3468404b540aSrobert "" 3469404b540aSrobert { operands[3] = gen_reg_rtx (DImode); }) 3470404b540aSrobert 3471404b540aSrobert(define_split 3472404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 3473404b540aSrobert (smax:DI (match_operand:DI 1 "reg_or_0_operand" "") 3474404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" ""))) 3475404b540aSrobert (clobber (match_operand:DI 3 "register_operand" ""))] 3476404b540aSrobert "operands[2] != const0_rtx" 3477404b540aSrobert [(set (match_dup 3) (le:DI (match_dup 1) (match_dup 2))) 3478404b540aSrobert (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0)) 3479404b540aSrobert (match_dup 1) (match_dup 2)))] 3480404b540aSrobert "") 3481404b540aSrobert 3482404b540aSrobert(define_insn "*smax_const0" 3483404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 3484404b540aSrobert (smax:DI (match_operand:DI 1 "register_operand" "0") 3485404b540aSrobert (const_int 0)))] 3486404b540aSrobert "" 3487404b540aSrobert "cmovlt %0,0,%0" 3488404b540aSrobert [(set_attr "type" "icmov")]) 3489404b540aSrobert 3490404b540aSrobert(define_expand "smindi3" 3491404b540aSrobert [(set (match_dup 3) 3492404b540aSrobert (lt:DI (match_operand:DI 1 "reg_or_0_operand" "") 3493404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" ""))) 3494404b540aSrobert (set (match_operand:DI 0 "register_operand" "") 3495404b540aSrobert (if_then_else:DI (ne (match_dup 3) (const_int 0)) 3496404b540aSrobert (match_dup 1) (match_dup 2)))] 3497404b540aSrobert "" 3498404b540aSrobert { operands[3] = gen_reg_rtx (DImode); }) 3499404b540aSrobert 3500404b540aSrobert(define_split 3501404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 3502404b540aSrobert (smin:DI (match_operand:DI 1 "reg_or_0_operand" "") 3503404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" ""))) 3504404b540aSrobert (clobber (match_operand:DI 3 "register_operand" ""))] 3505404b540aSrobert "operands[2] != const0_rtx" 3506404b540aSrobert [(set (match_dup 3) (lt:DI (match_dup 1) (match_dup 2))) 3507404b540aSrobert (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0)) 3508404b540aSrobert (match_dup 1) (match_dup 2)))] 3509404b540aSrobert "") 3510404b540aSrobert 3511404b540aSrobert(define_insn "*smin_const0" 3512404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 3513404b540aSrobert (smin:DI (match_operand:DI 1 "register_operand" "0") 3514404b540aSrobert (const_int 0)))] 3515404b540aSrobert "" 3516404b540aSrobert "cmovgt %0,0,%0" 3517404b540aSrobert [(set_attr "type" "icmov")]) 3518404b540aSrobert 3519404b540aSrobert(define_expand "umaxdi3" 3520404b540aSrobert [(set (match_dup 3) 3521404b540aSrobert (leu:DI (match_operand:DI 1 "reg_or_0_operand" "") 3522404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" ""))) 3523404b540aSrobert (set (match_operand:DI 0 "register_operand" "") 3524404b540aSrobert (if_then_else:DI (eq (match_dup 3) (const_int 0)) 3525404b540aSrobert (match_dup 1) (match_dup 2)))] 3526404b540aSrobert "" 3527404b540aSrobert "operands[3] = gen_reg_rtx (DImode);") 3528404b540aSrobert 3529404b540aSrobert(define_split 3530404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 3531404b540aSrobert (umax:DI (match_operand:DI 1 "reg_or_0_operand" "") 3532404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" ""))) 3533404b540aSrobert (clobber (match_operand:DI 3 "register_operand" ""))] 3534404b540aSrobert "operands[2] != const0_rtx" 3535404b540aSrobert [(set (match_dup 3) (leu:DI (match_dup 1) (match_dup 2))) 3536404b540aSrobert (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0)) 3537404b540aSrobert (match_dup 1) (match_dup 2)))] 3538404b540aSrobert "") 3539404b540aSrobert 3540404b540aSrobert(define_expand "umindi3" 3541404b540aSrobert [(set (match_dup 3) 3542404b540aSrobert (ltu:DI (match_operand:DI 1 "reg_or_0_operand" "") 3543404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" ""))) 3544404b540aSrobert (set (match_operand:DI 0 "register_operand" "") 3545404b540aSrobert (if_then_else:DI (ne (match_dup 3) (const_int 0)) 3546404b540aSrobert (match_dup 1) (match_dup 2)))] 3547404b540aSrobert "" 3548404b540aSrobert "operands[3] = gen_reg_rtx (DImode);") 3549404b540aSrobert 3550404b540aSrobert(define_split 3551404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 3552404b540aSrobert (umin:DI (match_operand:DI 1 "reg_or_0_operand" "") 3553404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" ""))) 3554404b540aSrobert (clobber (match_operand:DI 3 "register_operand" ""))] 3555404b540aSrobert "operands[2] != const0_rtx" 3556404b540aSrobert [(set (match_dup 3) (ltu:DI (match_dup 1) (match_dup 2))) 3557404b540aSrobert (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0)) 3558404b540aSrobert (match_dup 1) (match_dup 2)))] 3559404b540aSrobert "") 3560404b540aSrobert 3561404b540aSrobert(define_insn "*bcc_normal" 3562404b540aSrobert [(set (pc) 3563404b540aSrobert (if_then_else 3564404b540aSrobert (match_operator 1 "signed_comparison_operator" 3565404b540aSrobert [(match_operand:DI 2 "reg_or_0_operand" "rJ") 3566404b540aSrobert (const_int 0)]) 3567404b540aSrobert (label_ref (match_operand 0 "" "")) 3568404b540aSrobert (pc)))] 3569404b540aSrobert "" 3570404b540aSrobert "b%C1 %r2,%0" 3571404b540aSrobert [(set_attr "type" "ibr")]) 3572404b540aSrobert 3573404b540aSrobert(define_insn "*bcc_reverse" 3574404b540aSrobert [(set (pc) 3575404b540aSrobert (if_then_else 3576404b540aSrobert (match_operator 1 "signed_comparison_operator" 3577404b540aSrobert [(match_operand:DI 2 "register_operand" "r") 3578404b540aSrobert (const_int 0)]) 3579404b540aSrobert 3580404b540aSrobert (pc) 3581404b540aSrobert (label_ref (match_operand 0 "" ""))))] 3582404b540aSrobert "" 3583404b540aSrobert "b%c1 %2,%0" 3584404b540aSrobert [(set_attr "type" "ibr")]) 3585404b540aSrobert 3586404b540aSrobert(define_insn "*blbs_normal" 3587404b540aSrobert [(set (pc) 3588404b540aSrobert (if_then_else 3589404b540aSrobert (ne (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") 3590404b540aSrobert (const_int 1) 3591404b540aSrobert (const_int 0)) 3592404b540aSrobert (const_int 0)) 3593404b540aSrobert (label_ref (match_operand 0 "" "")) 3594404b540aSrobert (pc)))] 3595404b540aSrobert "" 3596404b540aSrobert "blbs %r1,%0" 3597404b540aSrobert [(set_attr "type" "ibr")]) 3598404b540aSrobert 3599404b540aSrobert(define_insn "*blbc_normal" 3600404b540aSrobert [(set (pc) 3601404b540aSrobert (if_then_else 3602404b540aSrobert (eq (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") 3603404b540aSrobert (const_int 1) 3604404b540aSrobert (const_int 0)) 3605404b540aSrobert (const_int 0)) 3606404b540aSrobert (label_ref (match_operand 0 "" "")) 3607404b540aSrobert (pc)))] 3608404b540aSrobert "" 3609404b540aSrobert "blbc %r1,%0" 3610404b540aSrobert [(set_attr "type" "ibr")]) 3611404b540aSrobert 3612404b540aSrobert(define_split 3613404b540aSrobert [(parallel 3614404b540aSrobert [(set (pc) 3615404b540aSrobert (if_then_else 3616404b540aSrobert (match_operator 1 "comparison_operator" 3617404b540aSrobert [(zero_extract:DI (match_operand:DI 2 "register_operand" "") 3618404b540aSrobert (const_int 1) 3619404b540aSrobert (match_operand:DI 3 "const_int_operand" "")) 3620404b540aSrobert (const_int 0)]) 3621404b540aSrobert (label_ref (match_operand 0 "" "")) 3622404b540aSrobert (pc))) 3623404b540aSrobert (clobber (match_operand:DI 4 "register_operand" ""))])] 3624404b540aSrobert "INTVAL (operands[3]) != 0" 3625404b540aSrobert [(set (match_dup 4) 3626404b540aSrobert (lshiftrt:DI (match_dup 2) (match_dup 3))) 3627404b540aSrobert (set (pc) 3628404b540aSrobert (if_then_else (match_op_dup 1 3629404b540aSrobert [(zero_extract:DI (match_dup 4) 3630404b540aSrobert (const_int 1) 3631404b540aSrobert (const_int 0)) 3632404b540aSrobert (const_int 0)]) 3633404b540aSrobert (label_ref (match_dup 0)) 3634404b540aSrobert (pc)))] 3635404b540aSrobert "") 3636404b540aSrobert 3637404b540aSrobert;; The following are the corresponding floating-point insns. Recall 3638404b540aSrobert;; we need to have variants that expand the arguments from SFmode 3639404b540aSrobert;; to DFmode. 3640404b540aSrobert 3641404b540aSrobert(define_insn "*cmpdf_ieee" 3642404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=&f") 3643404b540aSrobert (match_operator:DF 1 "alpha_fp_comparison_operator" 3644404b540aSrobert [(match_operand:DF 2 "reg_or_0_operand" "fG") 3645404b540aSrobert (match_operand:DF 3 "reg_or_0_operand" "fG")]))] 3646404b540aSrobert "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" 3647404b540aSrobert "cmp%-%C1%/ %R2,%R3,%0" 3648404b540aSrobert [(set_attr "type" "fadd") 3649404b540aSrobert (set_attr "trap" "yes") 3650404b540aSrobert (set_attr "trap_suffix" "su")]) 3651404b540aSrobert 3652404b540aSrobert(define_insn "*cmpdf_internal" 3653404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f") 3654404b540aSrobert (match_operator:DF 1 "alpha_fp_comparison_operator" 3655404b540aSrobert [(match_operand:DF 2 "reg_or_0_operand" "fG") 3656404b540aSrobert (match_operand:DF 3 "reg_or_0_operand" "fG")]))] 3657404b540aSrobert "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" 3658404b540aSrobert "cmp%-%C1%/ %R2,%R3,%0" 3659404b540aSrobert [(set_attr "type" "fadd") 3660404b540aSrobert (set_attr "trap" "yes") 3661404b540aSrobert (set_attr "trap_suffix" "su")]) 3662404b540aSrobert 3663404b540aSrobert(define_insn "*cmpdf_ieee_ext1" 3664404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=&f") 3665404b540aSrobert (match_operator:DF 1 "alpha_fp_comparison_operator" 3666404b540aSrobert [(float_extend:DF 3667404b540aSrobert (match_operand:SF 2 "reg_or_0_operand" "fG")) 3668404b540aSrobert (match_operand:DF 3 "reg_or_0_operand" "fG")]))] 3669404b540aSrobert "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" 3670404b540aSrobert "cmp%-%C1%/ %R2,%R3,%0" 3671404b540aSrobert [(set_attr "type" "fadd") 3672404b540aSrobert (set_attr "trap" "yes") 3673404b540aSrobert (set_attr "trap_suffix" "su")]) 3674404b540aSrobert 3675404b540aSrobert(define_insn "*cmpdf_ext1" 3676404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f") 3677404b540aSrobert (match_operator:DF 1 "alpha_fp_comparison_operator" 3678404b540aSrobert [(float_extend:DF 3679404b540aSrobert (match_operand:SF 2 "reg_or_0_operand" "fG")) 3680404b540aSrobert (match_operand:DF 3 "reg_or_0_operand" "fG")]))] 3681404b540aSrobert "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" 3682404b540aSrobert "cmp%-%C1%/ %R2,%R3,%0" 3683404b540aSrobert [(set_attr "type" "fadd") 3684404b540aSrobert (set_attr "trap" "yes") 3685404b540aSrobert (set_attr "trap_suffix" "su")]) 3686404b540aSrobert 3687404b540aSrobert(define_insn "*cmpdf_ieee_ext2" 3688404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=&f") 3689404b540aSrobert (match_operator:DF 1 "alpha_fp_comparison_operator" 3690404b540aSrobert [(match_operand:DF 2 "reg_or_0_operand" "fG") 3691404b540aSrobert (float_extend:DF 3692404b540aSrobert (match_operand:SF 3 "reg_or_0_operand" "fG"))]))] 3693404b540aSrobert "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" 3694404b540aSrobert "cmp%-%C1%/ %R2,%R3,%0" 3695404b540aSrobert [(set_attr "type" "fadd") 3696404b540aSrobert (set_attr "trap" "yes") 3697404b540aSrobert (set_attr "trap_suffix" "su")]) 3698404b540aSrobert 3699404b540aSrobert(define_insn "*cmpdf_ext2" 3700404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f") 3701404b540aSrobert (match_operator:DF 1 "alpha_fp_comparison_operator" 3702404b540aSrobert [(match_operand:DF 2 "reg_or_0_operand" "fG") 3703404b540aSrobert (float_extend:DF 3704404b540aSrobert (match_operand:SF 3 "reg_or_0_operand" "fG"))]))] 3705404b540aSrobert "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" 3706404b540aSrobert "cmp%-%C1%/ %R2,%R3,%0" 3707404b540aSrobert [(set_attr "type" "fadd") 3708404b540aSrobert (set_attr "trap" "yes") 3709404b540aSrobert (set_attr "trap_suffix" "su")]) 3710404b540aSrobert 3711404b540aSrobert(define_insn "*cmpdf_ieee_ext3" 3712404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=&f") 3713404b540aSrobert (match_operator:DF 1 "alpha_fp_comparison_operator" 3714404b540aSrobert [(float_extend:DF 3715404b540aSrobert (match_operand:SF 2 "reg_or_0_operand" "fG")) 3716404b540aSrobert (float_extend:DF 3717404b540aSrobert (match_operand:SF 3 "reg_or_0_operand" "fG"))]))] 3718404b540aSrobert "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" 3719404b540aSrobert "cmp%-%C1%/ %R2,%R3,%0" 3720404b540aSrobert [(set_attr "type" "fadd") 3721404b540aSrobert (set_attr "trap" "yes") 3722404b540aSrobert (set_attr "trap_suffix" "su")]) 3723404b540aSrobert 3724404b540aSrobert(define_insn "*cmpdf_ext3" 3725404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f") 3726404b540aSrobert (match_operator:DF 1 "alpha_fp_comparison_operator" 3727404b540aSrobert [(float_extend:DF 3728404b540aSrobert (match_operand:SF 2 "reg_or_0_operand" "fG")) 3729404b540aSrobert (float_extend:DF 3730404b540aSrobert (match_operand:SF 3 "reg_or_0_operand" "fG"))]))] 3731404b540aSrobert "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" 3732404b540aSrobert "cmp%-%C1%/ %R2,%R3,%0" 3733404b540aSrobert [(set_attr "type" "fadd") 3734404b540aSrobert (set_attr "trap" "yes") 3735404b540aSrobert (set_attr "trap_suffix" "su")]) 3736404b540aSrobert 3737404b540aSrobert(define_insn "*movdfcc_internal" 3738404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f,f") 3739404b540aSrobert (if_then_else:DF 3740404b540aSrobert (match_operator 3 "signed_comparison_operator" 3741404b540aSrobert [(match_operand:DF 4 "reg_or_0_operand" "fG,fG") 3742404b540aSrobert (match_operand:DF 2 "const0_operand" "G,G")]) 3743404b540aSrobert (match_operand:DF 1 "reg_or_0_operand" "fG,0") 3744404b540aSrobert (match_operand:DF 5 "reg_or_0_operand" "0,fG")))] 3745404b540aSrobert "TARGET_FP" 3746404b540aSrobert "@ 3747404b540aSrobert fcmov%C3 %R4,%R1,%0 3748404b540aSrobert fcmov%D3 %R4,%R5,%0" 3749404b540aSrobert [(set_attr "type" "fcmov")]) 3750404b540aSrobert 3751404b540aSrobert(define_insn "*movsfcc_internal" 3752404b540aSrobert [(set (match_operand:SF 0 "register_operand" "=f,f") 3753404b540aSrobert (if_then_else:SF 3754404b540aSrobert (match_operator 3 "signed_comparison_operator" 3755404b540aSrobert [(match_operand:DF 4 "reg_or_0_operand" "fG,fG") 3756404b540aSrobert (match_operand:DF 2 "const0_operand" "G,G")]) 3757404b540aSrobert (match_operand:SF 1 "reg_or_0_operand" "fG,0") 3758404b540aSrobert (match_operand:SF 5 "reg_or_0_operand" "0,fG")))] 3759404b540aSrobert "TARGET_FP" 3760404b540aSrobert "@ 3761404b540aSrobert fcmov%C3 %R4,%R1,%0 3762404b540aSrobert fcmov%D3 %R4,%R5,%0" 3763404b540aSrobert [(set_attr "type" "fcmov")]) 3764404b540aSrobert 3765404b540aSrobert(define_insn "*movdfcc_ext1" 3766404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f,f") 3767404b540aSrobert (if_then_else:DF 3768404b540aSrobert (match_operator 3 "signed_comparison_operator" 3769404b540aSrobert [(match_operand:DF 4 "reg_or_0_operand" "fG,fG") 3770404b540aSrobert (match_operand:DF 2 "const0_operand" "G,G")]) 3771404b540aSrobert (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG,0")) 3772404b540aSrobert (match_operand:DF 5 "reg_or_0_operand" "0,fG")))] 3773404b540aSrobert "TARGET_FP" 3774404b540aSrobert "@ 3775404b540aSrobert fcmov%C3 %R4,%R1,%0 3776404b540aSrobert fcmov%D3 %R4,%R5,%0" 3777404b540aSrobert [(set_attr "type" "fcmov")]) 3778404b540aSrobert 3779404b540aSrobert(define_insn "*movdfcc_ext2" 3780404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f,f") 3781404b540aSrobert (if_then_else:DF 3782404b540aSrobert (match_operator 3 "signed_comparison_operator" 3783404b540aSrobert [(float_extend:DF 3784404b540aSrobert (match_operand:SF 4 "reg_or_0_operand" "fG,fG")) 3785404b540aSrobert (match_operand:DF 2 "const0_operand" "G,G")]) 3786404b540aSrobert (match_operand:DF 1 "reg_or_0_operand" "fG,0") 3787404b540aSrobert (match_operand:DF 5 "reg_or_0_operand" "0,fG")))] 3788404b540aSrobert "TARGET_FP" 3789404b540aSrobert "@ 3790404b540aSrobert fcmov%C3 %R4,%R1,%0 3791404b540aSrobert fcmov%D3 %R4,%R5,%0" 3792404b540aSrobert [(set_attr "type" "fcmov")]) 3793404b540aSrobert 3794404b540aSrobert(define_insn "*movdfcc_ext3" 3795404b540aSrobert [(set (match_operand:SF 0 "register_operand" "=f,f") 3796404b540aSrobert (if_then_else:SF 3797404b540aSrobert (match_operator 3 "signed_comparison_operator" 3798404b540aSrobert [(float_extend:DF 3799404b540aSrobert (match_operand:SF 4 "reg_or_0_operand" "fG,fG")) 3800404b540aSrobert (match_operand:DF 2 "const0_operand" "G,G")]) 3801404b540aSrobert (match_operand:SF 1 "reg_or_0_operand" "fG,0") 3802404b540aSrobert (match_operand:SF 5 "reg_or_0_operand" "0,fG")))] 3803404b540aSrobert "TARGET_FP" 3804404b540aSrobert "@ 3805404b540aSrobert fcmov%C3 %R4,%R1,%0 3806404b540aSrobert fcmov%D3 %R4,%R5,%0" 3807404b540aSrobert [(set_attr "type" "fcmov")]) 3808404b540aSrobert 3809404b540aSrobert(define_insn "*movdfcc_ext4" 3810404b540aSrobert [(set (match_operand:DF 0 "register_operand" "=f,f") 3811404b540aSrobert (if_then_else:DF 3812404b540aSrobert (match_operator 3 "signed_comparison_operator" 3813404b540aSrobert [(float_extend:DF 3814404b540aSrobert (match_operand:SF 4 "reg_or_0_operand" "fG,fG")) 3815404b540aSrobert (match_operand:DF 2 "const0_operand" "G,G")]) 3816404b540aSrobert (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG,0")) 3817404b540aSrobert (match_operand:DF 5 "reg_or_0_operand" "0,fG")))] 3818404b540aSrobert "TARGET_FP" 3819404b540aSrobert "@ 3820404b540aSrobert fcmov%C3 %R4,%R1,%0 3821404b540aSrobert fcmov%D3 %R4,%R5,%0" 3822404b540aSrobert [(set_attr "type" "fcmov")]) 3823404b540aSrobert 3824404b540aSrobert(define_expand "smaxdf3" 3825404b540aSrobert [(set (match_dup 3) 3826404b540aSrobert (le:DF (match_operand:DF 1 "reg_or_0_operand" "") 3827404b540aSrobert (match_operand:DF 2 "reg_or_0_operand" ""))) 3828404b540aSrobert (set (match_operand:DF 0 "register_operand" "") 3829404b540aSrobert (if_then_else:DF (eq (match_dup 3) (match_dup 4)) 3830404b540aSrobert (match_dup 1) (match_dup 2)))] 3831404b540aSrobert "TARGET_FP" 3832404b540aSrobert{ 3833404b540aSrobert operands[3] = gen_reg_rtx (DFmode); 3834404b540aSrobert operands[4] = CONST0_RTX (DFmode); 3835404b540aSrobert}) 3836404b540aSrobert 3837404b540aSrobert(define_expand "smindf3" 3838404b540aSrobert [(set (match_dup 3) 3839404b540aSrobert (lt:DF (match_operand:DF 1 "reg_or_0_operand" "") 3840404b540aSrobert (match_operand:DF 2 "reg_or_0_operand" ""))) 3841404b540aSrobert (set (match_operand:DF 0 "register_operand" "") 3842404b540aSrobert (if_then_else:DF (ne (match_dup 3) (match_dup 4)) 3843404b540aSrobert (match_dup 1) (match_dup 2)))] 3844404b540aSrobert "TARGET_FP" 3845404b540aSrobert{ 3846404b540aSrobert operands[3] = gen_reg_rtx (DFmode); 3847404b540aSrobert operands[4] = CONST0_RTX (DFmode); 3848404b540aSrobert}) 3849404b540aSrobert 3850404b540aSrobert(define_expand "smaxsf3" 3851404b540aSrobert [(set (match_dup 3) 3852404b540aSrobert (le:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "")) 3853404b540aSrobert (float_extend:DF (match_operand:SF 2 "reg_or_0_operand" "")))) 3854404b540aSrobert (set (match_operand:SF 0 "register_operand" "") 3855404b540aSrobert (if_then_else:SF (eq (match_dup 3) (match_dup 4)) 3856404b540aSrobert (match_dup 1) (match_dup 2)))] 3857404b540aSrobert "TARGET_FP" 3858404b540aSrobert{ 3859404b540aSrobert operands[3] = gen_reg_rtx (DFmode); 3860404b540aSrobert operands[4] = CONST0_RTX (DFmode); 3861404b540aSrobert}) 3862404b540aSrobert 3863404b540aSrobert(define_expand "sminsf3" 3864404b540aSrobert [(set (match_dup 3) 3865404b540aSrobert (lt:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "")) 3866404b540aSrobert (float_extend:DF (match_operand:SF 2 "reg_or_0_operand" "")))) 3867404b540aSrobert (set (match_operand:SF 0 "register_operand" "") 3868404b540aSrobert (if_then_else:SF (ne (match_dup 3) (match_dup 4)) 3869404b540aSrobert (match_dup 1) (match_dup 2)))] 3870404b540aSrobert "TARGET_FP" 3871404b540aSrobert{ 3872404b540aSrobert operands[3] = gen_reg_rtx (DFmode); 3873404b540aSrobert operands[4] = CONST0_RTX (DFmode); 3874404b540aSrobert}) 3875404b540aSrobert 3876404b540aSrobert(define_insn "*fbcc_normal" 3877404b540aSrobert [(set (pc) 3878404b540aSrobert (if_then_else 3879404b540aSrobert (match_operator 1 "signed_comparison_operator" 3880404b540aSrobert [(match_operand:DF 2 "reg_or_0_operand" "fG") 3881404b540aSrobert (match_operand:DF 3 "const0_operand" "G")]) 3882404b540aSrobert (label_ref (match_operand 0 "" "")) 3883404b540aSrobert (pc)))] 3884404b540aSrobert "TARGET_FP" 3885404b540aSrobert "fb%C1 %R2,%0" 3886404b540aSrobert [(set_attr "type" "fbr")]) 3887404b540aSrobert 3888404b540aSrobert(define_insn "*fbcc_ext_normal" 3889404b540aSrobert [(set (pc) 3890404b540aSrobert (if_then_else 3891404b540aSrobert (match_operator 1 "signed_comparison_operator" 3892404b540aSrobert [(float_extend:DF 3893404b540aSrobert (match_operand:SF 2 "reg_or_0_operand" "fG")) 3894404b540aSrobert (match_operand:DF 3 "const0_operand" "G")]) 3895404b540aSrobert (label_ref (match_operand 0 "" "")) 3896404b540aSrobert (pc)))] 3897404b540aSrobert "TARGET_FP" 3898404b540aSrobert "fb%C1 %R2,%0" 3899404b540aSrobert [(set_attr "type" "fbr")]) 3900404b540aSrobert 3901404b540aSrobert;; These are the main define_expand's used to make conditional branches 3902404b540aSrobert;; and compares. 3903404b540aSrobert 3904404b540aSrobert(define_expand "cmpdf" 3905404b540aSrobert [(set (cc0) (compare (match_operand:DF 0 "reg_or_0_operand" "") 3906404b540aSrobert (match_operand:DF 1 "reg_or_0_operand" "")))] 3907404b540aSrobert "TARGET_FP" 3908404b540aSrobert{ 3909404b540aSrobert alpha_compare.op0 = operands[0]; 3910404b540aSrobert alpha_compare.op1 = operands[1]; 3911404b540aSrobert alpha_compare.fp_p = 1; 3912404b540aSrobert DONE; 3913404b540aSrobert}) 3914404b540aSrobert 3915404b540aSrobert(define_expand "cmptf" 3916404b540aSrobert [(set (cc0) (compare (match_operand:TF 0 "general_operand" "") 3917404b540aSrobert (match_operand:TF 1 "general_operand" "")))] 3918404b540aSrobert "TARGET_HAS_XFLOATING_LIBS" 3919404b540aSrobert{ 3920404b540aSrobert alpha_compare.op0 = operands[0]; 3921404b540aSrobert alpha_compare.op1 = operands[1]; 3922404b540aSrobert alpha_compare.fp_p = 1; 3923404b540aSrobert DONE; 3924404b540aSrobert}) 3925404b540aSrobert 3926404b540aSrobert(define_expand "cmpdi" 3927404b540aSrobert [(set (cc0) (compare (match_operand:DI 0 "some_operand" "") 3928404b540aSrobert (match_operand:DI 1 "some_operand" "")))] 3929404b540aSrobert "" 3930404b540aSrobert{ 3931404b540aSrobert alpha_compare.op0 = operands[0]; 3932404b540aSrobert alpha_compare.op1 = operands[1]; 3933404b540aSrobert alpha_compare.fp_p = 0; 3934404b540aSrobert DONE; 3935404b540aSrobert}) 3936404b540aSrobert 3937404b540aSrobert(define_expand "beq" 3938404b540aSrobert [(set (pc) 3939404b540aSrobert (if_then_else (match_dup 1) 3940404b540aSrobert (label_ref (match_operand 0 "" "")) 3941404b540aSrobert (pc)))] 3942404b540aSrobert "" 3943404b540aSrobert "{ operands[1] = alpha_emit_conditional_branch (EQ); }") 3944404b540aSrobert 3945404b540aSrobert(define_expand "bne" 3946404b540aSrobert [(set (pc) 3947404b540aSrobert (if_then_else (match_dup 1) 3948404b540aSrobert (label_ref (match_operand 0 "" "")) 3949404b540aSrobert (pc)))] 3950404b540aSrobert "" 3951404b540aSrobert "{ operands[1] = alpha_emit_conditional_branch (NE); }") 3952404b540aSrobert 3953404b540aSrobert(define_expand "blt" 3954404b540aSrobert [(set (pc) 3955404b540aSrobert (if_then_else (match_dup 1) 3956404b540aSrobert (label_ref (match_operand 0 "" "")) 3957404b540aSrobert (pc)))] 3958404b540aSrobert "" 3959404b540aSrobert "{ operands[1] = alpha_emit_conditional_branch (LT); }") 3960404b540aSrobert 3961404b540aSrobert(define_expand "ble" 3962404b540aSrobert [(set (pc) 3963404b540aSrobert (if_then_else (match_dup 1) 3964404b540aSrobert (label_ref (match_operand 0 "" "")) 3965404b540aSrobert (pc)))] 3966404b540aSrobert "" 3967404b540aSrobert "{ operands[1] = alpha_emit_conditional_branch (LE); }") 3968404b540aSrobert 3969404b540aSrobert(define_expand "bgt" 3970404b540aSrobert [(set (pc) 3971404b540aSrobert (if_then_else (match_dup 1) 3972404b540aSrobert (label_ref (match_operand 0 "" "")) 3973404b540aSrobert (pc)))] 3974404b540aSrobert "" 3975404b540aSrobert "{ operands[1] = alpha_emit_conditional_branch (GT); }") 3976404b540aSrobert 3977404b540aSrobert(define_expand "bge" 3978404b540aSrobert [(set (pc) 3979404b540aSrobert (if_then_else (match_dup 1) 3980404b540aSrobert (label_ref (match_operand 0 "" "")) 3981404b540aSrobert (pc)))] 3982404b540aSrobert "" 3983404b540aSrobert "{ operands[1] = alpha_emit_conditional_branch (GE); }") 3984404b540aSrobert 3985404b540aSrobert(define_expand "bltu" 3986404b540aSrobert [(set (pc) 3987404b540aSrobert (if_then_else (match_dup 1) 3988404b540aSrobert (label_ref (match_operand 0 "" "")) 3989404b540aSrobert (pc)))] 3990404b540aSrobert "" 3991404b540aSrobert "{ operands[1] = alpha_emit_conditional_branch (LTU); }") 3992404b540aSrobert 3993404b540aSrobert(define_expand "bleu" 3994404b540aSrobert [(set (pc) 3995404b540aSrobert (if_then_else (match_dup 1) 3996404b540aSrobert (label_ref (match_operand 0 "" "")) 3997404b540aSrobert (pc)))] 3998404b540aSrobert "" 3999404b540aSrobert "{ operands[1] = alpha_emit_conditional_branch (LEU); }") 4000404b540aSrobert 4001404b540aSrobert(define_expand "bgtu" 4002404b540aSrobert [(set (pc) 4003404b540aSrobert (if_then_else (match_dup 1) 4004404b540aSrobert (label_ref (match_operand 0 "" "")) 4005404b540aSrobert (pc)))] 4006404b540aSrobert "" 4007404b540aSrobert "{ operands[1] = alpha_emit_conditional_branch (GTU); }") 4008404b540aSrobert 4009404b540aSrobert(define_expand "bgeu" 4010404b540aSrobert [(set (pc) 4011404b540aSrobert (if_then_else (match_dup 1) 4012404b540aSrobert (label_ref (match_operand 0 "" "")) 4013404b540aSrobert (pc)))] 4014404b540aSrobert "" 4015404b540aSrobert "{ operands[1] = alpha_emit_conditional_branch (GEU); }") 4016404b540aSrobert 4017404b540aSrobert(define_expand "bunordered" 4018404b540aSrobert [(set (pc) 4019404b540aSrobert (if_then_else (match_dup 1) 4020404b540aSrobert (label_ref (match_operand 0 "" "")) 4021404b540aSrobert (pc)))] 4022404b540aSrobert "" 4023404b540aSrobert "{ operands[1] = alpha_emit_conditional_branch (UNORDERED); }") 4024404b540aSrobert 4025404b540aSrobert(define_expand "bordered" 4026404b540aSrobert [(set (pc) 4027404b540aSrobert (if_then_else (match_dup 1) 4028404b540aSrobert (label_ref (match_operand 0 "" "")) 4029404b540aSrobert (pc)))] 4030404b540aSrobert "" 4031404b540aSrobert "{ operands[1] = alpha_emit_conditional_branch (ORDERED); }") 4032404b540aSrobert 4033404b540aSrobert(define_expand "seq" 4034404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 4035404b540aSrobert (match_dup 1))] 4036404b540aSrobert "" 4037404b540aSrobert "{ if ((operands[1] = alpha_emit_setcc (EQ)) == NULL_RTX) FAIL; }") 4038404b540aSrobert 4039404b540aSrobert(define_expand "sne" 4040404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 4041404b540aSrobert (match_dup 1))] 4042404b540aSrobert "" 4043404b540aSrobert "{ if ((operands[1] = alpha_emit_setcc (NE)) == NULL_RTX) FAIL; }") 4044404b540aSrobert 4045404b540aSrobert(define_expand "slt" 4046404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 4047404b540aSrobert (match_dup 1))] 4048404b540aSrobert "" 4049404b540aSrobert "{ if ((operands[1] = alpha_emit_setcc (LT)) == NULL_RTX) FAIL; }") 4050404b540aSrobert 4051404b540aSrobert(define_expand "sle" 4052404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 4053404b540aSrobert (match_dup 1))] 4054404b540aSrobert "" 4055404b540aSrobert "{ if ((operands[1] = alpha_emit_setcc (LE)) == NULL_RTX) FAIL; }") 4056404b540aSrobert 4057404b540aSrobert(define_expand "sgt" 4058404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 4059404b540aSrobert (match_dup 1))] 4060404b540aSrobert "" 4061404b540aSrobert "{ if ((operands[1] = alpha_emit_setcc (GT)) == NULL_RTX) FAIL; }") 4062404b540aSrobert 4063404b540aSrobert(define_expand "sge" 4064404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 4065404b540aSrobert (match_dup 1))] 4066404b540aSrobert "" 4067404b540aSrobert "{ if ((operands[1] = alpha_emit_setcc (GE)) == NULL_RTX) FAIL; }") 4068404b540aSrobert 4069404b540aSrobert(define_expand "sltu" 4070404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 4071404b540aSrobert (match_dup 1))] 4072404b540aSrobert "" 4073404b540aSrobert "{ if ((operands[1] = alpha_emit_setcc (LTU)) == NULL_RTX) FAIL; }") 4074404b540aSrobert 4075404b540aSrobert(define_expand "sleu" 4076404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 4077404b540aSrobert (match_dup 1))] 4078404b540aSrobert "" 4079404b540aSrobert "{ if ((operands[1] = alpha_emit_setcc (LEU)) == NULL_RTX) FAIL; }") 4080404b540aSrobert 4081404b540aSrobert(define_expand "sgtu" 4082404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 4083404b540aSrobert (match_dup 1))] 4084404b540aSrobert "" 4085404b540aSrobert "{ if ((operands[1] = alpha_emit_setcc (GTU)) == NULL_RTX) FAIL; }") 4086404b540aSrobert 4087404b540aSrobert(define_expand "sgeu" 4088404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 4089404b540aSrobert (match_dup 1))] 4090404b540aSrobert "" 4091404b540aSrobert "{ if ((operands[1] = alpha_emit_setcc (GEU)) == NULL_RTX) FAIL; }") 4092404b540aSrobert 4093404b540aSrobert(define_expand "sunordered" 4094404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 4095404b540aSrobert (match_dup 1))] 4096404b540aSrobert "" 4097404b540aSrobert "{ if ((operands[1] = alpha_emit_setcc (UNORDERED)) == NULL_RTX) FAIL; }") 4098404b540aSrobert 4099404b540aSrobert(define_expand "sordered" 4100404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 4101404b540aSrobert (match_dup 1))] 4102404b540aSrobert "" 4103404b540aSrobert "{ if ((operands[1] = alpha_emit_setcc (ORDERED)) == NULL_RTX) FAIL; }") 4104404b540aSrobert 4105404b540aSrobert;; These are the main define_expand's used to make conditional moves. 4106404b540aSrobert 4107404b540aSrobert(define_expand "movsicc" 4108404b540aSrobert [(set (match_operand:SI 0 "register_operand" "") 4109404b540aSrobert (if_then_else:SI (match_operand 1 "comparison_operator" "") 4110404b540aSrobert (match_operand:SI 2 "reg_or_8bit_operand" "") 4111404b540aSrobert (match_operand:SI 3 "reg_or_8bit_operand" "")))] 4112404b540aSrobert "" 4113404b540aSrobert{ 4114404b540aSrobert if ((operands[1] = alpha_emit_conditional_move (operands[1], SImode)) == 0) 4115404b540aSrobert FAIL; 4116404b540aSrobert}) 4117404b540aSrobert 4118404b540aSrobert(define_expand "movdicc" 4119404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 4120404b540aSrobert (if_then_else:DI (match_operand 1 "comparison_operator" "") 4121404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "") 4122404b540aSrobert (match_operand:DI 3 "reg_or_8bit_operand" "")))] 4123404b540aSrobert "" 4124404b540aSrobert{ 4125404b540aSrobert if ((operands[1] = alpha_emit_conditional_move (operands[1], DImode)) == 0) 4126404b540aSrobert FAIL; 4127404b540aSrobert}) 4128404b540aSrobert 4129404b540aSrobert(define_expand "movsfcc" 4130404b540aSrobert [(set (match_operand:SF 0 "register_operand" "") 4131404b540aSrobert (if_then_else:SF (match_operand 1 "comparison_operator" "") 4132404b540aSrobert (match_operand:SF 2 "reg_or_8bit_operand" "") 4133404b540aSrobert (match_operand:SF 3 "reg_or_8bit_operand" "")))] 4134404b540aSrobert "" 4135404b540aSrobert{ 4136404b540aSrobert if ((operands[1] = alpha_emit_conditional_move (operands[1], SFmode)) == 0) 4137404b540aSrobert FAIL; 4138404b540aSrobert}) 4139404b540aSrobert 4140404b540aSrobert(define_expand "movdfcc" 4141404b540aSrobert [(set (match_operand:DF 0 "register_operand" "") 4142404b540aSrobert (if_then_else:DF (match_operand 1 "comparison_operator" "") 4143404b540aSrobert (match_operand:DF 2 "reg_or_8bit_operand" "") 4144404b540aSrobert (match_operand:DF 3 "reg_or_8bit_operand" "")))] 4145404b540aSrobert "" 4146404b540aSrobert{ 4147404b540aSrobert if ((operands[1] = alpha_emit_conditional_move (operands[1], DFmode)) == 0) 4148404b540aSrobert FAIL; 4149404b540aSrobert}) 4150404b540aSrobert 4151404b540aSrobert;; These define_split definitions are used in cases when comparisons have 4152404b540aSrobert;; not be stated in the correct way and we need to reverse the second 4153404b540aSrobert;; comparison. For example, x >= 7 has to be done as x < 6 with the 4154404b540aSrobert;; comparison that tests the result being reversed. We have one define_split 4155404b540aSrobert;; for each use of a comparison. They do not match valid insns and need 4156404b540aSrobert;; not generate valid insns. 4157404b540aSrobert;; 4158404b540aSrobert;; We can also handle equality comparisons (and inequality comparisons in 4159404b540aSrobert;; cases where the resulting add cannot overflow) by doing an add followed by 4160404b540aSrobert;; a comparison with zero. This is faster since the addition takes one 4161404b540aSrobert;; less cycle than a compare when feeding into a conditional move. 4162404b540aSrobert;; For this case, we also have an SImode pattern since we can merge the add 4163404b540aSrobert;; and sign extend and the order doesn't matter. 4164404b540aSrobert;; 4165404b540aSrobert;; We do not do this for floating-point, since it isn't clear how the "wrong" 4166404b540aSrobert;; operation could have been generated. 4167404b540aSrobert 4168404b540aSrobert(define_split 4169404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 4170404b540aSrobert (if_then_else:DI 4171404b540aSrobert (match_operator 1 "comparison_operator" 4172404b540aSrobert [(match_operand:DI 2 "reg_or_0_operand" "") 4173404b540aSrobert (match_operand:DI 3 "reg_or_cint_operand" "")]) 4174404b540aSrobert (match_operand:DI 4 "reg_or_cint_operand" "") 4175404b540aSrobert (match_operand:DI 5 "reg_or_cint_operand" ""))) 4176404b540aSrobert (clobber (match_operand:DI 6 "register_operand" ""))] 4177404b540aSrobert "operands[3] != const0_rtx" 4178404b540aSrobert [(set (match_dup 6) (match_dup 7)) 4179404b540aSrobert (set (match_dup 0) 4180404b540aSrobert (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))] 4181404b540aSrobert{ 4182404b540aSrobert enum rtx_code code = GET_CODE (operands[1]); 4183404b540aSrobert int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU); 4184404b540aSrobert 4185404b540aSrobert /* If we are comparing for equality with a constant and that constant 4186404b540aSrobert appears in the arm when the register equals the constant, use the 4187404b540aSrobert register since that is more likely to match (and to produce better code 4188404b540aSrobert if both would). */ 4189404b540aSrobert 4190404b540aSrobert if (code == EQ && GET_CODE (operands[3]) == CONST_INT 4191404b540aSrobert && rtx_equal_p (operands[4], operands[3])) 4192404b540aSrobert operands[4] = operands[2]; 4193404b540aSrobert 4194404b540aSrobert else if (code == NE && GET_CODE (operands[3]) == CONST_INT 4195404b540aSrobert && rtx_equal_p (operands[5], operands[3])) 4196404b540aSrobert operands[5] = operands[2]; 4197404b540aSrobert 4198404b540aSrobert if (code == NE || code == EQ 4199404b540aSrobert || (extended_count (operands[2], DImode, unsignedp) >= 1 4200404b540aSrobert && extended_count (operands[3], DImode, unsignedp) >= 1)) 4201404b540aSrobert { 4202404b540aSrobert if (GET_CODE (operands[3]) == CONST_INT) 4203404b540aSrobert operands[7] = gen_rtx_PLUS (DImode, operands[2], 4204404b540aSrobert GEN_INT (- INTVAL (operands[3]))); 4205404b540aSrobert else 4206404b540aSrobert operands[7] = gen_rtx_MINUS (DImode, operands[2], operands[3]); 4207404b540aSrobert 4208404b540aSrobert operands[8] = gen_rtx_fmt_ee (code, VOIDmode, operands[6], const0_rtx); 4209404b540aSrobert } 4210404b540aSrobert 4211404b540aSrobert else if (code == EQ || code == LE || code == LT 4212404b540aSrobert || code == LEU || code == LTU) 4213404b540aSrobert { 4214404b540aSrobert operands[7] = gen_rtx_fmt_ee (code, DImode, operands[2], operands[3]); 4215404b540aSrobert operands[8] = gen_rtx_NE (VOIDmode, operands[6], const0_rtx); 4216404b540aSrobert } 4217404b540aSrobert else 4218404b540aSrobert { 4219404b540aSrobert operands[7] = gen_rtx_fmt_ee (reverse_condition (code), DImode, 4220404b540aSrobert operands[2], operands[3]); 4221404b540aSrobert operands[8] = gen_rtx_EQ (VOIDmode, operands[6], const0_rtx); 4222404b540aSrobert } 4223404b540aSrobert}) 4224404b540aSrobert 4225404b540aSrobert(define_split 4226404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 4227404b540aSrobert (if_then_else:DI 4228404b540aSrobert (match_operator 1 "comparison_operator" 4229404b540aSrobert [(match_operand:SI 2 "reg_or_0_operand" "") 4230404b540aSrobert (match_operand:SI 3 "reg_or_cint_operand" "")]) 4231404b540aSrobert (match_operand:DI 4 "reg_or_8bit_operand" "") 4232404b540aSrobert (match_operand:DI 5 "reg_or_8bit_operand" ""))) 4233404b540aSrobert (clobber (match_operand:DI 6 "register_operand" ""))] 4234404b540aSrobert "operands[3] != const0_rtx 4235404b540aSrobert && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)" 4236404b540aSrobert [(set (match_dup 6) (match_dup 7)) 4237404b540aSrobert (set (match_dup 0) 4238404b540aSrobert (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))] 4239404b540aSrobert{ 4240404b540aSrobert enum rtx_code code = GET_CODE (operands[1]); 4241404b540aSrobert int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU); 4242404b540aSrobert rtx tem; 4243404b540aSrobert 4244404b540aSrobert if ((code != NE && code != EQ 4245404b540aSrobert && ! (extended_count (operands[2], DImode, unsignedp) >= 1 4246404b540aSrobert && extended_count (operands[3], DImode, unsignedp) >= 1))) 4247404b540aSrobert FAIL; 4248404b540aSrobert 4249404b540aSrobert if (GET_CODE (operands[3]) == CONST_INT) 4250404b540aSrobert tem = gen_rtx_PLUS (SImode, operands[2], 4251404b540aSrobert GEN_INT (- INTVAL (operands[3]))); 4252404b540aSrobert else 4253404b540aSrobert tem = gen_rtx_MINUS (SImode, operands[2], operands[3]); 4254404b540aSrobert 4255404b540aSrobert operands[7] = gen_rtx_SIGN_EXTEND (DImode, tem); 4256404b540aSrobert operands[8] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode, 4257404b540aSrobert operands[6], const0_rtx); 4258404b540aSrobert}) 4259404b540aSrobert 4260404b540aSrobert;; Prefer to use cmp and arithmetic when possible instead of a cmove. 4261404b540aSrobert 4262404b540aSrobert(define_split 4263404b540aSrobert [(set (match_operand 0 "register_operand" "") 4264404b540aSrobert (if_then_else (match_operator 1 "signed_comparison_operator" 4265404b540aSrobert [(match_operand:DI 2 "reg_or_0_operand" "") 4266404b540aSrobert (const_int 0)]) 4267404b540aSrobert (match_operand 3 "const_int_operand" "") 4268404b540aSrobert (match_operand 4 "const_int_operand" "")))] 4269404b540aSrobert "" 4270404b540aSrobert [(const_int 0)] 4271404b540aSrobert{ 4272404b540aSrobert if (alpha_split_conditional_move (GET_CODE (operands[1]), operands[0], 4273404b540aSrobert operands[2], operands[3], operands[4])) 4274404b540aSrobert DONE; 4275404b540aSrobert else 4276404b540aSrobert FAIL; 4277404b540aSrobert}) 4278404b540aSrobert 4279404b540aSrobert;; ??? Why combine is allowed to create such non-canonical rtl, I don't know. 4280404b540aSrobert;; Oh well, we match it in movcc, so it must be partially our fault. 4281404b540aSrobert(define_split 4282404b540aSrobert [(set (match_operand 0 "register_operand" "") 4283404b540aSrobert (if_then_else (match_operator 1 "signed_comparison_operator" 4284404b540aSrobert [(const_int 0) 4285404b540aSrobert (match_operand:DI 2 "reg_or_0_operand" "")]) 4286404b540aSrobert (match_operand 3 "const_int_operand" "") 4287404b540aSrobert (match_operand 4 "const_int_operand" "")))] 4288404b540aSrobert "" 4289404b540aSrobert [(const_int 0)] 4290404b540aSrobert{ 4291404b540aSrobert if (alpha_split_conditional_move (swap_condition (GET_CODE (operands[1])), 4292404b540aSrobert operands[0], operands[2], operands[3], 4293404b540aSrobert operands[4])) 4294404b540aSrobert DONE; 4295404b540aSrobert else 4296404b540aSrobert FAIL; 4297404b540aSrobert}) 4298404b540aSrobert 4299404b540aSrobert(define_insn_and_split "*cmp_sadd_di" 4300404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 4301404b540aSrobert (plus:DI (if_then_else:DI 4302404b540aSrobert (match_operator 1 "alpha_zero_comparison_operator" 4303404b540aSrobert [(match_operand:DI 2 "reg_or_0_operand" "rJ") 4304404b540aSrobert (const_int 0)]) 4305404b540aSrobert (match_operand:DI 3 "const48_operand" "I") 4306404b540aSrobert (const_int 0)) 4307404b540aSrobert (match_operand:DI 4 "sext_add_operand" "rIO"))) 4308404b540aSrobert (clobber (match_scratch:DI 5 "=r"))] 4309404b540aSrobert "" 4310404b540aSrobert "#" 4311404b540aSrobert "! no_new_pseudos || reload_completed" 4312404b540aSrobert [(set (match_dup 5) 4313404b540aSrobert (match_op_dup:DI 1 [(match_dup 2) (const_int 0)])) 4314404b540aSrobert (set (match_dup 0) 4315404b540aSrobert (plus:DI (mult:DI (match_dup 5) (match_dup 3)) 4316404b540aSrobert (match_dup 4)))] 4317404b540aSrobert{ 4318404b540aSrobert if (! no_new_pseudos) 4319404b540aSrobert operands[5] = gen_reg_rtx (DImode); 4320404b540aSrobert else if (reg_overlap_mentioned_p (operands[5], operands[4])) 4321404b540aSrobert operands[5] = operands[0]; 4322404b540aSrobert}) 4323404b540aSrobert 4324404b540aSrobert(define_insn_and_split "*cmp_sadd_si" 4325404b540aSrobert [(set (match_operand:SI 0 "register_operand" "=r") 4326404b540aSrobert (plus:SI (if_then_else:SI 4327404b540aSrobert (match_operator 1 "alpha_zero_comparison_operator" 4328404b540aSrobert [(match_operand:DI 2 "reg_or_0_operand" "rJ") 4329404b540aSrobert (const_int 0)]) 4330404b540aSrobert (match_operand:SI 3 "const48_operand" "I") 4331404b540aSrobert (const_int 0)) 4332404b540aSrobert (match_operand:SI 4 "sext_add_operand" "rIO"))) 4333404b540aSrobert (clobber (match_scratch:SI 5 "=r"))] 4334404b540aSrobert "" 4335404b540aSrobert "#" 4336404b540aSrobert "! no_new_pseudos || reload_completed" 4337404b540aSrobert [(set (match_dup 5) 4338404b540aSrobert (match_op_dup:SI 1 [(match_dup 2) (const_int 0)])) 4339404b540aSrobert (set (match_dup 0) 4340404b540aSrobert (plus:SI (mult:SI (match_dup 5) (match_dup 3)) 4341404b540aSrobert (match_dup 4)))] 4342404b540aSrobert{ 4343404b540aSrobert if (! no_new_pseudos) 4344404b540aSrobert operands[5] = gen_reg_rtx (DImode); 4345404b540aSrobert else if (reg_overlap_mentioned_p (operands[5], operands[4])) 4346404b540aSrobert operands[5] = operands[0]; 4347404b540aSrobert}) 4348404b540aSrobert 4349404b540aSrobert(define_insn_and_split "*cmp_sadd_sidi" 4350404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 4351404b540aSrobert (sign_extend:DI 4352404b540aSrobert (plus:SI (if_then_else:SI 4353404b540aSrobert (match_operator 1 "alpha_zero_comparison_operator" 4354404b540aSrobert [(match_operand:DI 2 "reg_or_0_operand" "rJ") 4355404b540aSrobert (const_int 0)]) 4356404b540aSrobert (match_operand:SI 3 "const48_operand" "I") 4357404b540aSrobert (const_int 0)) 4358404b540aSrobert (match_operand:SI 4 "sext_add_operand" "rIO")))) 4359404b540aSrobert (clobber (match_scratch:SI 5 "=r"))] 4360404b540aSrobert "" 4361404b540aSrobert "#" 4362404b540aSrobert "! no_new_pseudos || reload_completed" 4363404b540aSrobert [(set (match_dup 5) 4364404b540aSrobert (match_op_dup:SI 1 [(match_dup 2) (const_int 0)])) 4365404b540aSrobert (set (match_dup 0) 4366404b540aSrobert (sign_extend:DI (plus:SI (mult:SI (match_dup 5) (match_dup 3)) 4367404b540aSrobert (match_dup 4))))] 4368404b540aSrobert{ 4369404b540aSrobert if (! no_new_pseudos) 4370404b540aSrobert operands[5] = gen_reg_rtx (DImode); 4371404b540aSrobert else if (reg_overlap_mentioned_p (operands[5], operands[4])) 4372404b540aSrobert operands[5] = operands[0]; 4373404b540aSrobert}) 4374404b540aSrobert 4375404b540aSrobert(define_insn_and_split "*cmp_ssub_di" 4376404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 4377404b540aSrobert (minus:DI (if_then_else:DI 4378404b540aSrobert (match_operator 1 "alpha_zero_comparison_operator" 4379404b540aSrobert [(match_operand:DI 2 "reg_or_0_operand" "rJ") 4380404b540aSrobert (const_int 0)]) 4381404b540aSrobert (match_operand:DI 3 "const48_operand" "I") 4382404b540aSrobert (const_int 0)) 4383404b540aSrobert (match_operand:DI 4 "reg_or_8bit_operand" "rI"))) 4384404b540aSrobert (clobber (match_scratch:DI 5 "=r"))] 4385404b540aSrobert "" 4386404b540aSrobert "#" 4387404b540aSrobert "! no_new_pseudos || reload_completed" 4388404b540aSrobert [(set (match_dup 5) 4389404b540aSrobert (match_op_dup:DI 1 [(match_dup 2) (const_int 0)])) 4390404b540aSrobert (set (match_dup 0) 4391404b540aSrobert (minus:DI (mult:DI (match_dup 5) (match_dup 3)) 4392404b540aSrobert (match_dup 4)))] 4393404b540aSrobert{ 4394404b540aSrobert if (! no_new_pseudos) 4395404b540aSrobert operands[5] = gen_reg_rtx (DImode); 4396404b540aSrobert else if (reg_overlap_mentioned_p (operands[5], operands[4])) 4397404b540aSrobert operands[5] = operands[0]; 4398404b540aSrobert}) 4399404b540aSrobert 4400404b540aSrobert(define_insn_and_split "*cmp_ssub_si" 4401404b540aSrobert [(set (match_operand:SI 0 "register_operand" "=r") 4402404b540aSrobert (minus:SI (if_then_else:SI 4403404b540aSrobert (match_operator 1 "alpha_zero_comparison_operator" 4404404b540aSrobert [(match_operand:DI 2 "reg_or_0_operand" "rJ") 4405404b540aSrobert (const_int 0)]) 4406404b540aSrobert (match_operand:SI 3 "const48_operand" "I") 4407404b540aSrobert (const_int 0)) 4408404b540aSrobert (match_operand:SI 4 "reg_or_8bit_operand" "rI"))) 4409404b540aSrobert (clobber (match_scratch:SI 5 "=r"))] 4410404b540aSrobert "" 4411404b540aSrobert "#" 4412404b540aSrobert "! no_new_pseudos || reload_completed" 4413404b540aSrobert [(set (match_dup 5) 4414404b540aSrobert (match_op_dup:SI 1 [(match_dup 2) (const_int 0)])) 4415404b540aSrobert (set (match_dup 0) 4416404b540aSrobert (minus:SI (mult:SI (match_dup 5) (match_dup 3)) 4417404b540aSrobert (match_dup 4)))] 4418404b540aSrobert{ 4419404b540aSrobert if (! no_new_pseudos) 4420404b540aSrobert operands[5] = gen_reg_rtx (DImode); 4421404b540aSrobert else if (reg_overlap_mentioned_p (operands[5], operands[4])) 4422404b540aSrobert operands[5] = operands[0]; 4423404b540aSrobert}) 4424404b540aSrobert 4425404b540aSrobert(define_insn_and_split "*cmp_ssub_sidi" 4426404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 4427404b540aSrobert (sign_extend:DI 4428404b540aSrobert (minus:SI (if_then_else:SI 4429404b540aSrobert (match_operator 1 "alpha_zero_comparison_operator" 4430404b540aSrobert [(match_operand:DI 2 "reg_or_0_operand" "rJ") 4431404b540aSrobert (const_int 0)]) 4432404b540aSrobert (match_operand:SI 3 "const48_operand" "I") 4433404b540aSrobert (const_int 0)) 4434404b540aSrobert (match_operand:SI 4 "reg_or_8bit_operand" "rI")))) 4435404b540aSrobert (clobber (match_scratch:SI 5 "=r"))] 4436404b540aSrobert "" 4437404b540aSrobert "#" 4438404b540aSrobert "! no_new_pseudos || reload_completed" 4439404b540aSrobert [(set (match_dup 5) 4440404b540aSrobert (match_op_dup:SI 1 [(match_dup 2) (const_int 0)])) 4441404b540aSrobert (set (match_dup 0) 4442404b540aSrobert (sign_extend:DI (minus:SI (mult:SI (match_dup 5) (match_dup 3)) 4443404b540aSrobert (match_dup 4))))] 4444404b540aSrobert{ 4445404b540aSrobert if (! no_new_pseudos) 4446404b540aSrobert operands[5] = gen_reg_rtx (DImode); 4447404b540aSrobert else if (reg_overlap_mentioned_p (operands[5], operands[4])) 4448404b540aSrobert operands[5] = operands[0]; 4449404b540aSrobert}) 4450404b540aSrobert 4451404b540aSrobert;; Here are the CALL and unconditional branch insns. Calls on NT and OSF 4452404b540aSrobert;; work differently, so we have different patterns for each. 4453404b540aSrobert 4454404b540aSrobert;; On Unicos/Mk a call information word (CIW) must be generated for each 4455404b540aSrobert;; call. The CIW contains information about arguments passed in registers 4456404b540aSrobert;; and is stored in the caller's SSIB. Its offset relative to the beginning 4457404b540aSrobert;; of the SSIB is passed in $25. Handling this properly is quite complicated 4458404b540aSrobert;; in the presence of inlining since the CIWs for calls performed by the 4459404b540aSrobert;; inlined function must be stored in the SSIB of the function it is inlined 4460404b540aSrobert;; into as well. We encode the CIW in an unspec and append it to the list 4461404b540aSrobert;; of the CIWs for the current function only when the instruction for loading 4462404b540aSrobert;; $25 is generated. 4463404b540aSrobert 4464404b540aSrobert(define_expand "call" 4465404b540aSrobert [(use (match_operand:DI 0 "" "")) 4466404b540aSrobert (use (match_operand 1 "" "")) 4467404b540aSrobert (use (match_operand 2 "" "")) 4468404b540aSrobert (use (match_operand 3 "" ""))] 4469404b540aSrobert "" 4470404b540aSrobert{ 4471404b540aSrobert if (TARGET_ABI_WINDOWS_NT) 4472404b540aSrobert emit_call_insn (gen_call_nt (operands[0], operands[1])); 4473404b540aSrobert else if (TARGET_ABI_OPEN_VMS) 4474404b540aSrobert emit_call_insn (gen_call_vms (operands[0], operands[2])); 4475404b540aSrobert else if (TARGET_ABI_UNICOSMK) 4476404b540aSrobert emit_call_insn (gen_call_umk (operands[0], operands[2])); 4477404b540aSrobert else 4478404b540aSrobert emit_call_insn (gen_call_osf (operands[0], operands[1])); 4479404b540aSrobert DONE; 4480404b540aSrobert}) 4481404b540aSrobert 4482404b540aSrobert(define_expand "sibcall" 4483404b540aSrobert [(parallel [(call (mem:DI (match_operand 0 "" "")) 4484404b540aSrobert (match_operand 1 "" "")) 4485404b540aSrobert (unspec [(reg:DI 29)] UNSPEC_SIBCALL)])] 4486404b540aSrobert "TARGET_ABI_OSF" 4487404b540aSrobert{ 4488404b540aSrobert gcc_assert (GET_CODE (operands[0]) == MEM); 4489404b540aSrobert operands[0] = XEXP (operands[0], 0); 4490404b540aSrobert}) 4491404b540aSrobert 4492404b540aSrobert(define_expand "call_osf" 4493404b540aSrobert [(parallel [(call (mem:DI (match_operand 0 "" "")) 4494404b540aSrobert (match_operand 1 "" "")) 4495404b540aSrobert (use (reg:DI 29)) 4496404b540aSrobert (clobber (reg:DI 26))])] 4497404b540aSrobert "" 4498404b540aSrobert{ 4499404b540aSrobert gcc_assert (GET_CODE (operands[0]) == MEM); 4500404b540aSrobert 4501404b540aSrobert operands[0] = XEXP (operands[0], 0); 4502404b540aSrobert if (! call_operand (operands[0], Pmode)) 4503404b540aSrobert operands[0] = copy_to_mode_reg (Pmode, operands[0]); 4504404b540aSrobert}) 4505404b540aSrobert 4506404b540aSrobert(define_expand "call_nt" 4507404b540aSrobert [(parallel [(call (mem:DI (match_operand 0 "" "")) 4508404b540aSrobert (match_operand 1 "" "")) 4509404b540aSrobert (clobber (reg:DI 26))])] 4510404b540aSrobert "" 4511404b540aSrobert{ 4512404b540aSrobert gcc_assert (GET_CODE (operands[0]) == MEM); 4513404b540aSrobert 4514404b540aSrobert operands[0] = XEXP (operands[0], 0); 4515404b540aSrobert if (GET_CODE (operands[0]) != SYMBOL_REF && GET_CODE (operands[0]) != REG) 4516404b540aSrobert operands[0] = force_reg (DImode, operands[0]); 4517404b540aSrobert}) 4518404b540aSrobert 4519404b540aSrobert;; Calls on Unicos/Mk are always indirect. 4520404b540aSrobert;; op 0: symbol ref for called function 4521404b540aSrobert;; op 1: CIW for $25 represented by an unspec 4522404b540aSrobert 4523404b540aSrobert(define_expand "call_umk" 4524404b540aSrobert [(parallel [(call (mem:DI (match_operand 0 "" "")) 4525404b540aSrobert (match_operand 1 "" "")) 4526404b540aSrobert (use (reg:DI 25)) 4527404b540aSrobert (clobber (reg:DI 26))])] 4528404b540aSrobert "" 4529404b540aSrobert{ 4530404b540aSrobert gcc_assert (GET_CODE (operands[0]) == MEM); 4531404b540aSrobert 4532404b540aSrobert /* Always load the address of the called function into a register; 4533404b540aSrobert load the CIW in $25. */ 4534404b540aSrobert 4535404b540aSrobert operands[0] = XEXP (operands[0], 0); 4536404b540aSrobert if (GET_CODE (operands[0]) != REG) 4537404b540aSrobert operands[0] = force_reg (DImode, operands[0]); 4538404b540aSrobert 4539404b540aSrobert emit_move_insn (gen_rtx_REG (DImode, 25), operands[1]); 4540404b540aSrobert}) 4541404b540aSrobert 4542404b540aSrobert;; 4543404b540aSrobert;; call openvms/alpha 4544404b540aSrobert;; op 0: symbol ref for called function 4545404b540aSrobert;; op 1: next_arg_reg (argument information value for R25) 4546404b540aSrobert;; 4547404b540aSrobert(define_expand "call_vms" 4548404b540aSrobert [(parallel [(call (mem:DI (match_operand 0 "" "")) 4549404b540aSrobert (match_operand 1 "" "")) 4550404b540aSrobert (use (match_dup 2)) 4551404b540aSrobert (use (reg:DI 25)) 4552404b540aSrobert (use (reg:DI 26)) 4553404b540aSrobert (clobber (reg:DI 27))])] 4554404b540aSrobert "" 4555404b540aSrobert{ 4556404b540aSrobert gcc_assert (GET_CODE (operands[0]) == MEM); 4557404b540aSrobert 4558404b540aSrobert operands[0] = XEXP (operands[0], 0); 4559404b540aSrobert 4560404b540aSrobert /* Always load AI with argument information, then handle symbolic and 4561404b540aSrobert indirect call differently. Load RA and set operands[2] to PV in 4562404b540aSrobert both cases. */ 4563404b540aSrobert 4564404b540aSrobert emit_move_insn (gen_rtx_REG (DImode, 25), operands[1]); 4565404b540aSrobert if (GET_CODE (operands[0]) == SYMBOL_REF) 4566404b540aSrobert { 4567404b540aSrobert alpha_need_linkage (XSTR (operands[0], 0), 0); 4568404b540aSrobert 4569404b540aSrobert operands[2] = const0_rtx; 4570404b540aSrobert } 4571404b540aSrobert else 4572404b540aSrobert { 4573404b540aSrobert emit_move_insn (gen_rtx_REG (Pmode, 26), 4574404b540aSrobert gen_rtx_MEM (Pmode, plus_constant (operands[0], 8))); 4575404b540aSrobert operands[2] = operands[0]; 4576404b540aSrobert } 4577404b540aSrobert 4578404b540aSrobert}) 4579404b540aSrobert 4580404b540aSrobert(define_expand "call_value" 4581404b540aSrobert [(use (match_operand 0 "" "")) 4582404b540aSrobert (use (match_operand:DI 1 "" "")) 4583404b540aSrobert (use (match_operand 2 "" "")) 4584404b540aSrobert (use (match_operand 3 "" "")) 4585404b540aSrobert (use (match_operand 4 "" ""))] 4586404b540aSrobert "" 4587404b540aSrobert{ 4588404b540aSrobert if (TARGET_ABI_WINDOWS_NT) 4589404b540aSrobert emit_call_insn (gen_call_value_nt (operands[0], operands[1], operands[2])); 4590404b540aSrobert else if (TARGET_ABI_OPEN_VMS) 4591404b540aSrobert emit_call_insn (gen_call_value_vms (operands[0], operands[1], 4592404b540aSrobert operands[3])); 4593404b540aSrobert else if (TARGET_ABI_UNICOSMK) 4594404b540aSrobert emit_call_insn (gen_call_value_umk (operands[0], operands[1], 4595404b540aSrobert operands[3])); 4596404b540aSrobert else 4597404b540aSrobert emit_call_insn (gen_call_value_osf (operands[0], operands[1], 4598404b540aSrobert operands[2])); 4599404b540aSrobert DONE; 4600404b540aSrobert}) 4601404b540aSrobert 4602404b540aSrobert(define_expand "sibcall_value" 4603404b540aSrobert [(parallel [(set (match_operand 0 "" "") 4604404b540aSrobert (call (mem:DI (match_operand 1 "" "")) 4605404b540aSrobert (match_operand 2 "" ""))) 4606404b540aSrobert (unspec [(reg:DI 29)] UNSPEC_SIBCALL)])] 4607404b540aSrobert "TARGET_ABI_OSF" 4608404b540aSrobert{ 4609404b540aSrobert gcc_assert (GET_CODE (operands[1]) == MEM); 4610404b540aSrobert operands[1] = XEXP (operands[1], 0); 4611404b540aSrobert}) 4612404b540aSrobert 4613404b540aSrobert(define_expand "call_value_osf" 4614404b540aSrobert [(parallel [(set (match_operand 0 "" "") 4615404b540aSrobert (call (mem:DI (match_operand 1 "" "")) 4616404b540aSrobert (match_operand 2 "" ""))) 4617404b540aSrobert (use (reg:DI 29)) 4618404b540aSrobert (clobber (reg:DI 26))])] 4619404b540aSrobert "" 4620404b540aSrobert{ 4621404b540aSrobert gcc_assert (GET_CODE (operands[1]) == MEM); 4622404b540aSrobert 4623404b540aSrobert operands[1] = XEXP (operands[1], 0); 4624404b540aSrobert if (! call_operand (operands[1], Pmode)) 4625404b540aSrobert operands[1] = copy_to_mode_reg (Pmode, operands[1]); 4626404b540aSrobert}) 4627404b540aSrobert 4628404b540aSrobert(define_expand "call_value_nt" 4629404b540aSrobert [(parallel [(set (match_operand 0 "" "") 4630404b540aSrobert (call (mem:DI (match_operand 1 "" "")) 4631404b540aSrobert (match_operand 2 "" ""))) 4632404b540aSrobert (clobber (reg:DI 26))])] 4633404b540aSrobert "" 4634404b540aSrobert{ 4635404b540aSrobert gcc_assert (GET_CODE (operands[1]) == MEM); 4636404b540aSrobert 4637404b540aSrobert operands[1] = XEXP (operands[1], 0); 4638404b540aSrobert if (GET_CODE (operands[1]) != SYMBOL_REF && GET_CODE (operands[1]) != REG) 4639404b540aSrobert operands[1] = force_reg (DImode, operands[1]); 4640404b540aSrobert}) 4641404b540aSrobert 4642404b540aSrobert(define_expand "call_value_vms" 4643404b540aSrobert [(parallel [(set (match_operand 0 "" "") 4644404b540aSrobert (call (mem:DI (match_operand:DI 1 "" "")) 4645404b540aSrobert (match_operand 2 "" ""))) 4646404b540aSrobert (use (match_dup 3)) 4647404b540aSrobert (use (reg:DI 25)) 4648404b540aSrobert (use (reg:DI 26)) 4649404b540aSrobert (clobber (reg:DI 27))])] 4650404b540aSrobert "" 4651404b540aSrobert{ 4652404b540aSrobert gcc_assert (GET_CODE (operands[1]) == MEM); 4653404b540aSrobert 4654404b540aSrobert operands[1] = XEXP (operands[1], 0); 4655404b540aSrobert 4656404b540aSrobert /* Always load AI with argument information, then handle symbolic and 4657404b540aSrobert indirect call differently. Load RA and set operands[3] to PV in 4658404b540aSrobert both cases. */ 4659404b540aSrobert 4660404b540aSrobert emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]); 4661404b540aSrobert if (GET_CODE (operands[1]) == SYMBOL_REF) 4662404b540aSrobert { 4663404b540aSrobert alpha_need_linkage (XSTR (operands[1], 0), 0); 4664404b540aSrobert 4665404b540aSrobert operands[3] = const0_rtx; 4666404b540aSrobert } 4667404b540aSrobert else 4668404b540aSrobert { 4669404b540aSrobert emit_move_insn (gen_rtx_REG (Pmode, 26), 4670404b540aSrobert gen_rtx_MEM (Pmode, plus_constant (operands[1], 8))); 4671404b540aSrobert operands[3] = operands[1]; 4672404b540aSrobert } 4673404b540aSrobert}) 4674404b540aSrobert 4675404b540aSrobert(define_expand "call_value_umk" 4676404b540aSrobert [(parallel [(set (match_operand 0 "" "") 4677404b540aSrobert (call (mem:DI (match_operand 1 "" "")) 4678404b540aSrobert (match_operand 2 "" ""))) 4679404b540aSrobert (use (reg:DI 25)) 4680404b540aSrobert (clobber (reg:DI 26))])] 4681404b540aSrobert "" 4682404b540aSrobert{ 4683404b540aSrobert gcc_assert (GET_CODE (operands[1]) == MEM); 4684404b540aSrobert 4685404b540aSrobert operands[1] = XEXP (operands[1], 0); 4686404b540aSrobert if (GET_CODE (operands[1]) != REG) 4687404b540aSrobert operands[1] = force_reg (DImode, operands[1]); 4688404b540aSrobert 4689404b540aSrobert emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]); 4690404b540aSrobert}) 4691404b540aSrobert 4692404b540aSrobert(define_insn "*call_osf_1_er" 4693404b540aSrobert [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s")) 4694404b540aSrobert (match_operand 1 "" "")) 4695404b540aSrobert (use (reg:DI 29)) 4696404b540aSrobert (clobber (reg:DI 26))] 4697404b540aSrobert "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" 4698404b540aSrobert "@ 4699404b540aSrobert jsr $26,(%0),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%* 4700404b540aSrobert bsr $26,%0\t\t!samegp 4701404b540aSrobert ldq $27,%0($29)\t\t!literal!%#\;jsr $26,($27),%0\t\t!lituse_jsr!%#\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*" 4702404b540aSrobert [(set_attr "type" "jsr") 4703404b540aSrobert (set_attr "length" "12,*,16")]) 4704404b540aSrobert 4705404b540aSrobert;; We must use peep2 instead of a split because we need accurate life 4706404b540aSrobert;; information for $gp. Consider the case of { bar(); while (1); }. 4707404b540aSrobert(define_peephole2 4708404b540aSrobert [(parallel [(call (mem:DI (match_operand:DI 0 "call_operand" "")) 4709404b540aSrobert (match_operand 1 "" "")) 4710404b540aSrobert (use (reg:DI 29)) 4711404b540aSrobert (clobber (reg:DI 26))])] 4712404b540aSrobert "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed 4713404b540aSrobert && ! samegp_function_operand (operands[0], Pmode) 4714404b540aSrobert && (peep2_regno_dead_p (1, 29) 4715404b540aSrobert || find_reg_note (insn, REG_NORETURN, NULL_RTX))" 4716404b540aSrobert [(parallel [(call (mem:DI (match_dup 2)) 4717404b540aSrobert (match_dup 1)) 4718404b540aSrobert (set (reg:DI 26) (plus:DI (pc) (const_int 4))) 4719404b540aSrobert (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE) 4720404b540aSrobert (use (match_dup 0)) 4721404b540aSrobert (use (match_dup 3))])] 4722404b540aSrobert{ 4723404b540aSrobert if (CONSTANT_P (operands[0])) 4724404b540aSrobert { 4725404b540aSrobert operands[2] = gen_rtx_REG (Pmode, 27); 4726404b540aSrobert operands[3] = GEN_INT (alpha_next_sequence_number++); 4727404b540aSrobert emit_insn (gen_movdi_er_high_g (operands[2], pic_offset_table_rtx, 4728404b540aSrobert operands[0], operands[3])); 4729404b540aSrobert } 4730404b540aSrobert else 4731404b540aSrobert { 4732404b540aSrobert operands[2] = operands[0]; 4733404b540aSrobert operands[0] = const0_rtx; 4734404b540aSrobert operands[3] = const0_rtx; 4735404b540aSrobert } 4736404b540aSrobert}) 4737404b540aSrobert 4738404b540aSrobert(define_peephole2 4739404b540aSrobert [(parallel [(call (mem:DI (match_operand:DI 0 "call_operand" "")) 4740404b540aSrobert (match_operand 1 "" "")) 4741404b540aSrobert (use (reg:DI 29)) 4742404b540aSrobert (clobber (reg:DI 26))])] 4743404b540aSrobert "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed 4744404b540aSrobert && ! samegp_function_operand (operands[0], Pmode) 4745404b540aSrobert && ! (peep2_regno_dead_p (1, 29) 4746404b540aSrobert || find_reg_note (insn, REG_NORETURN, NULL_RTX))" 4747404b540aSrobert [(parallel [(call (mem:DI (match_dup 2)) 4748404b540aSrobert (match_dup 1)) 4749404b540aSrobert (set (reg:DI 26) (plus:DI (pc) (const_int 4))) 4750404b540aSrobert (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE) 4751404b540aSrobert (use (match_dup 0)) 4752404b540aSrobert (use (match_dup 4))]) 4753404b540aSrobert (set (reg:DI 29) 4754404b540aSrobert (unspec_volatile:DI [(reg:DI 26) (match_dup 3)] UNSPECV_LDGP1)) 4755404b540aSrobert (set (reg:DI 29) 4756404b540aSrobert (unspec:DI [(reg:DI 29) (match_dup 3)] UNSPEC_LDGP2))] 4757404b540aSrobert{ 4758404b540aSrobert if (CONSTANT_P (operands[0])) 4759404b540aSrobert { 4760404b540aSrobert operands[2] = gen_rtx_REG (Pmode, 27); 4761404b540aSrobert operands[4] = GEN_INT (alpha_next_sequence_number++); 4762404b540aSrobert emit_insn (gen_movdi_er_high_g (operands[2], pic_offset_table_rtx, 4763404b540aSrobert operands[0], operands[4])); 4764404b540aSrobert } 4765404b540aSrobert else 4766404b540aSrobert { 4767404b540aSrobert operands[2] = operands[0]; 4768404b540aSrobert operands[0] = const0_rtx; 4769404b540aSrobert operands[4] = const0_rtx; 4770404b540aSrobert } 4771404b540aSrobert operands[3] = GEN_INT (alpha_next_sequence_number++); 4772404b540aSrobert}) 4773404b540aSrobert 4774404b540aSrobert;; We add a blockage unspec_volatile to prevent insns from moving down 4775404b540aSrobert;; from above the call to in between the call and the ldah gpdisp. 4776404b540aSrobert 4777404b540aSrobert(define_insn "*call_osf_2_er" 4778404b540aSrobert [(call (mem:DI (match_operand:DI 0 "register_operand" "c")) 4779404b540aSrobert (match_operand 1 "" "")) 4780404b540aSrobert (set (reg:DI 26) (plus:DI (pc) (const_int 4))) 4781404b540aSrobert (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE) 4782404b540aSrobert (use (match_operand 2 "" "")) 4783404b540aSrobert (use (match_operand 3 "const_int_operand" ""))] 4784404b540aSrobert "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" 4785404b540aSrobert "jsr $26,(%0),%2%J3" 4786404b540aSrobert [(set_attr "type" "jsr") 4787404b540aSrobert (set_attr "cannot_copy" "true")]) 4788404b540aSrobert 4789404b540aSrobert;; We output a nop after noreturn calls at the very end of the function to 4790404b540aSrobert;; ensure that the return address always remains in the caller's code range, 4791404b540aSrobert;; as not doing so might confuse unwinding engines. 4792404b540aSrobert;; 4793404b540aSrobert;; The potential change in insn length is not reflected in the length 4794404b540aSrobert;; attributes at this stage. Since the extra space is only actually added at 4795404b540aSrobert;; the very end of the compilation process (via final/print_operand), it 4796404b540aSrobert;; really seems harmless and not worth the trouble of some extra computation 4797404b540aSrobert;; cost and complexity. 4798404b540aSrobert 4799404b540aSrobert(define_insn "*call_osf_1_noreturn" 4800404b540aSrobert [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s")) 4801404b540aSrobert (match_operand 1 "" "")) 4802404b540aSrobert (use (reg:DI 29)) 4803404b540aSrobert (clobber (reg:DI 26))] 4804404b540aSrobert "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF 4805404b540aSrobert && find_reg_note (insn, REG_NORETURN, NULL_RTX)" 4806404b540aSrobert "@ 4807404b540aSrobert jsr $26,($27),0%+ 4808404b540aSrobert bsr $26,$%0..ng%+ 4809404b540aSrobert jsr $26,%0%+" 4810404b540aSrobert [(set_attr "type" "jsr") 4811404b540aSrobert (set_attr "length" "*,*,8")]) 4812404b540aSrobert 4813404b540aSrobert(define_insn "*call_osf_1" 4814404b540aSrobert [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s")) 4815404b540aSrobert (match_operand 1 "" "")) 4816404b540aSrobert (use (reg:DI 29)) 4817404b540aSrobert (clobber (reg:DI 26))] 4818404b540aSrobert "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" 4819404b540aSrobert "@ 4820404b540aSrobert jsr $26,($27),0\;ldgp $29,0($26) 4821404b540aSrobert bsr $26,$%0..ng 4822404b540aSrobert jsr $26,%0\;ldgp $29,0($26)" 4823404b540aSrobert [(set_attr "type" "jsr") 4824404b540aSrobert (set_attr "length" "12,*,16")]) 4825404b540aSrobert 4826404b540aSrobert;; Note that the DEC assembler expands "jmp foo" with $at, which 4827404b540aSrobert;; doesn't do what we want. 4828404b540aSrobert(define_insn "*sibcall_osf_1_er" 4829404b540aSrobert [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s")) 4830404b540aSrobert (match_operand 1 "" "")) 4831404b540aSrobert (unspec [(reg:DI 29)] UNSPEC_SIBCALL)] 4832404b540aSrobert "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" 4833404b540aSrobert "@ 4834404b540aSrobert br $31,%0\t\t!samegp 4835404b540aSrobert ldq $27,%0($29)\t\t!literal!%#\;jmp $31,($27),%0\t\t!lituse_jsr!%#" 4836404b540aSrobert [(set_attr "type" "jsr") 4837404b540aSrobert (set_attr "length" "*,8")]) 4838404b540aSrobert 4839404b540aSrobert(define_insn "*sibcall_osf_1" 4840404b540aSrobert [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s")) 4841404b540aSrobert (match_operand 1 "" "")) 4842404b540aSrobert (unspec [(reg:DI 29)] UNSPEC_SIBCALL)] 4843404b540aSrobert "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" 4844404b540aSrobert "@ 4845404b540aSrobert br $31,$%0..ng 4846404b540aSrobert lda $27,%0\;jmp $31,($27),%0" 4847404b540aSrobert [(set_attr "type" "jsr") 4848404b540aSrobert (set_attr "length" "*,8")]) 4849404b540aSrobert 4850404b540aSrobert(define_insn "*call_nt_1" 4851404b540aSrobert [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,s")) 4852404b540aSrobert (match_operand 1 "" "")) 4853404b540aSrobert (clobber (reg:DI 26))] 4854404b540aSrobert "TARGET_ABI_WINDOWS_NT" 4855404b540aSrobert "@ 4856404b540aSrobert jsr $26,(%0) 4857404b540aSrobert bsr $26,%0 4858404b540aSrobert jsr $26,%0" 4859404b540aSrobert [(set_attr "type" "jsr") 4860404b540aSrobert (set_attr "length" "*,*,12")]) 4861404b540aSrobert 4862404b540aSrobert; GAS relies on the order and position of instructions output below in order 4863404b540aSrobert; to generate relocs for VMS link to potentially optimize the call. 4864404b540aSrobert; Please do not molest. 4865404b540aSrobert(define_insn "*call_vms_1" 4866404b540aSrobert [(call (mem:DI (match_operand:DI 0 "call_operand" "r,s")) 4867404b540aSrobert (match_operand 1 "" "")) 4868404b540aSrobert (use (match_operand:DI 2 "nonmemory_operand" "r,n")) 4869404b540aSrobert (use (reg:DI 25)) 4870404b540aSrobert (use (reg:DI 26)) 4871404b540aSrobert (clobber (reg:DI 27))] 4872404b540aSrobert "TARGET_ABI_OPEN_VMS" 4873404b540aSrobert{ 4874404b540aSrobert switch (which_alternative) 4875404b540aSrobert { 4876404b540aSrobert case 0: 4877404b540aSrobert return "mov %2,$27\;jsr $26,0\;ldq $27,0($29)"; 4878404b540aSrobert case 1: 4879404b540aSrobert operands [2] = alpha_use_linkage (operands [0], cfun->decl, 1, 0); 4880404b540aSrobert operands [3] = alpha_use_linkage (operands [0], cfun->decl, 0, 0); 4881404b540aSrobert return "ldq $26,%3\;ldq $27,%2\;jsr $26,%0\;ldq $27,0($29)"; 4882404b540aSrobert default: 4883404b540aSrobert gcc_unreachable (); 4884404b540aSrobert } 4885404b540aSrobert} 4886404b540aSrobert [(set_attr "type" "jsr") 4887404b540aSrobert (set_attr "length" "12,16")]) 4888404b540aSrobert 4889404b540aSrobert(define_insn "*call_umk_1" 4890404b540aSrobert [(call (mem:DI (match_operand:DI 0 "call_operand" "r")) 4891404b540aSrobert (match_operand 1 "" "")) 4892404b540aSrobert (use (reg:DI 25)) 4893404b540aSrobert (clobber (reg:DI 26))] 4894404b540aSrobert "TARGET_ABI_UNICOSMK" 4895404b540aSrobert "jsr $26,(%0)" 4896404b540aSrobert [(set_attr "type" "jsr")]) 4897404b540aSrobert 4898404b540aSrobert;; Call subroutine returning any type. 4899404b540aSrobert 4900404b540aSrobert(define_expand "untyped_call" 4901404b540aSrobert [(parallel [(call (match_operand 0 "" "") 4902404b540aSrobert (const_int 0)) 4903404b540aSrobert (match_operand 1 "" "") 4904404b540aSrobert (match_operand 2 "" "")])] 4905404b540aSrobert "" 4906404b540aSrobert{ 4907404b540aSrobert int i; 4908404b540aSrobert 4909404b540aSrobert emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx)); 4910404b540aSrobert 4911404b540aSrobert for (i = 0; i < XVECLEN (operands[2], 0); i++) 4912404b540aSrobert { 4913404b540aSrobert rtx set = XVECEXP (operands[2], 0, i); 4914404b540aSrobert emit_move_insn (SET_DEST (set), SET_SRC (set)); 4915404b540aSrobert } 4916404b540aSrobert 4917404b540aSrobert /* The optimizer does not know that the call sets the function value 4918404b540aSrobert registers we stored in the result block. We avoid problems by 4919404b540aSrobert claiming that all hard registers are used and clobbered at this 4920404b540aSrobert point. */ 4921404b540aSrobert emit_insn (gen_blockage ()); 4922404b540aSrobert 4923404b540aSrobert DONE; 4924404b540aSrobert}) 4925404b540aSrobert 4926404b540aSrobert;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 4927404b540aSrobert;; all of memory. This blocks insns from being moved across this point. 4928404b540aSrobert 4929404b540aSrobert(define_insn "blockage" 4930404b540aSrobert [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] 4931404b540aSrobert "" 4932404b540aSrobert "" 4933404b540aSrobert [(set_attr "length" "0") 4934404b540aSrobert (set_attr "type" "none")]) 4935404b540aSrobert 4936404b540aSrobert(define_insn "jump" 4937404b540aSrobert [(set (pc) 4938404b540aSrobert (label_ref (match_operand 0 "" "")))] 4939404b540aSrobert "" 4940404b540aSrobert "br $31,%l0" 4941404b540aSrobert [(set_attr "type" "ibr")]) 4942404b540aSrobert 4943404b540aSrobert(define_expand "return" 4944404b540aSrobert [(return)] 4945404b540aSrobert "direct_return ()" 4946404b540aSrobert "") 4947404b540aSrobert 4948404b540aSrobert(define_insn "*return_internal" 4949404b540aSrobert [(return)] 4950404b540aSrobert "reload_completed" 4951404b540aSrobert "ret $31,($26),1" 4952404b540aSrobert [(set_attr "type" "ibr")]) 4953404b540aSrobert 4954404b540aSrobert(define_insn "indirect_jump" 4955404b540aSrobert [(set (pc) (match_operand:DI 0 "register_operand" "r"))] 4956404b540aSrobert "" 4957404b540aSrobert "jmp $31,(%0),0" 4958404b540aSrobert [(set_attr "type" "ibr")]) 4959404b540aSrobert 4960404b540aSrobert(define_expand "tablejump" 4961404b540aSrobert [(parallel [(set (pc) 4962404b540aSrobert (match_operand 0 "register_operand" "")) 4963404b540aSrobert (use (label_ref:DI (match_operand 1 "" "")))])] 4964404b540aSrobert "" 4965404b540aSrobert{ 4966404b540aSrobert if (TARGET_ABI_WINDOWS_NT) 4967404b540aSrobert { 4968404b540aSrobert rtx dest = gen_reg_rtx (DImode); 4969404b540aSrobert emit_insn (gen_extendsidi2 (dest, operands[0])); 4970404b540aSrobert operands[0] = dest; 4971404b540aSrobert } 4972404b540aSrobert else if (TARGET_ABI_OSF) 4973404b540aSrobert { 4974404b540aSrobert rtx dest = gen_reg_rtx (DImode); 4975404b540aSrobert emit_insn (gen_extendsidi2 (dest, operands[0])); 4976404b540aSrobert emit_insn (gen_adddi3 (dest, pic_offset_table_rtx, dest)); 4977404b540aSrobert operands[0] = dest; 4978404b540aSrobert } 4979404b540aSrobert}) 4980404b540aSrobert 4981404b540aSrobert(define_insn "*tablejump_osf_nt_internal" 4982404b540aSrobert [(set (pc) 4983404b540aSrobert (match_operand:DI 0 "register_operand" "r")) 4984404b540aSrobert (use (label_ref:DI (match_operand 1 "" "")))] 4985404b540aSrobert "(TARGET_ABI_OSF || TARGET_ABI_WINDOWS_NT) 4986404b540aSrobert && alpha_tablejump_addr_vec (insn)" 4987404b540aSrobert{ 4988404b540aSrobert operands[2] = alpha_tablejump_best_label (insn); 4989404b540aSrobert return "jmp $31,(%0),%2"; 4990404b540aSrobert} 4991404b540aSrobert [(set_attr "type" "ibr")]) 4992404b540aSrobert 4993404b540aSrobert(define_insn "*tablejump_internal" 4994404b540aSrobert [(set (pc) 4995404b540aSrobert (match_operand:DI 0 "register_operand" "r")) 4996404b540aSrobert (use (label_ref (match_operand 1 "" "")))] 4997404b540aSrobert "" 4998404b540aSrobert "jmp $31,(%0),0" 4999404b540aSrobert [(set_attr "type" "ibr")]) 5000404b540aSrobert 5001404b540aSrobert;; Cache flush. Used by INITIALIZE_TRAMPOLINE. 0x86 is PAL_imb, but we don't 5002404b540aSrobert;; want to have to include pal.h in our .s file. 5003404b540aSrobert;; 5004404b540aSrobert;; Technically the type for call_pal is jsr, but we use that for determining 5005404b540aSrobert;; if we need a GP. Use ibr instead since it has the same EV5 scheduling 5006404b540aSrobert;; characteristics. 5007404b540aSrobert(define_insn "imb" 5008404b540aSrobert [(unspec_volatile [(const_int 0)] UNSPECV_IMB)] 5009404b540aSrobert "" 5010404b540aSrobert "call_pal 0x86" 5011404b540aSrobert [(set_attr "type" "callpal")]) 5012404b540aSrobert 5013404b540aSrobert;; BUGCHK is documented common to OSF/1 and VMS PALcode. 5014404b540aSrobert;; NT does not document anything at 0x81 -- presumably it would generate 5015404b540aSrobert;; the equivalent of SIGILL, but this isn't that important. 5016404b540aSrobert;; ??? Presuming unicosmk uses either OSF/1 or VMS PALcode. 5017404b540aSrobert(define_insn "trap" 5018404b540aSrobert [(trap_if (const_int 1) (const_int 0))] 5019404b540aSrobert "!TARGET_ABI_WINDOWS_NT" 5020404b540aSrobert "call_pal 0x81" 5021404b540aSrobert [(set_attr "type" "callpal")]) 5022404b540aSrobert 5023404b540aSrobert;; For userland, we load the thread pointer from the TCB. 5024404b540aSrobert;; For the kernel, we load the per-cpu private value. 5025404b540aSrobert 5026404b540aSrobert(define_insn "load_tp" 5027404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=v") 5028404b540aSrobert (unspec:DI [(const_int 0)] UNSPEC_TP))] 5029404b540aSrobert "TARGET_ABI_OSF" 5030404b540aSrobert{ 5031404b540aSrobert if (TARGET_TLS_KERNEL) 5032404b540aSrobert return "call_pal 0x32"; 5033404b540aSrobert else 5034404b540aSrobert return "call_pal 0x9e"; 5035404b540aSrobert} 5036404b540aSrobert [(set_attr "type" "callpal")]) 5037404b540aSrobert 5038404b540aSrobert;; For completeness, and possibly a __builtin function, here's how to 5039404b540aSrobert;; set the thread pointer. Since we don't describe enough of this 5040404b540aSrobert;; quantity for CSE, we have to use a volatile unspec, and then there's 5041404b540aSrobert;; not much point in creating an R16_REG register class. 5042404b540aSrobert 5043404b540aSrobert(define_expand "set_tp" 5044404b540aSrobert [(set (reg:DI 16) (match_operand:DI 0 "input_operand" "")) 5045404b540aSrobert (unspec_volatile [(reg:DI 16)] UNSPECV_SET_TP)] 5046404b540aSrobert "TARGET_ABI_OSF" 5047404b540aSrobert "") 5048404b540aSrobert 5049404b540aSrobert(define_insn "*set_tp" 5050404b540aSrobert [(unspec_volatile [(reg:DI 16)] UNSPECV_SET_TP)] 5051404b540aSrobert "TARGET_ABI_OSF" 5052404b540aSrobert{ 5053404b540aSrobert if (TARGET_TLS_KERNEL) 5054404b540aSrobert return "call_pal 0x31"; 5055404b540aSrobert else 5056404b540aSrobert return "call_pal 0x9f"; 5057404b540aSrobert} 5058404b540aSrobert [(set_attr "type" "callpal")]) 5059404b540aSrobert 5060404b540aSrobert;; Finally, we have the basic data motion insns. The byte and word insns 5061404b540aSrobert;; are done via define_expand. Start with the floating-point insns, since 5062404b540aSrobert;; they are simpler. 5063404b540aSrobert 5064404b540aSrobert(define_insn "*movsf_nofix" 5065404b540aSrobert [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m") 5066404b540aSrobert (match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r"))] 5067404b540aSrobert "TARGET_FPREGS && ! TARGET_FIX 5068404b540aSrobert && (register_operand (operands[0], SFmode) 5069404b540aSrobert || reg_or_0_operand (operands[1], SFmode))" 5070404b540aSrobert "@ 5071404b540aSrobert cpys %R1,%R1,%0 5072404b540aSrobert ld%, %0,%1 5073404b540aSrobert bis $31,%r1,%0 5074404b540aSrobert ldl %0,%1 5075404b540aSrobert st%, %R1,%0 5076404b540aSrobert stl %r1,%0" 5077404b540aSrobert [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")]) 5078404b540aSrobert 5079404b540aSrobert(define_insn "*movsf_fix" 5080404b540aSrobert [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r") 5081404b540aSrobert (match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))] 5082404b540aSrobert "TARGET_FPREGS && TARGET_FIX 5083404b540aSrobert && (register_operand (operands[0], SFmode) 5084404b540aSrobert || reg_or_0_operand (operands[1], SFmode))" 5085404b540aSrobert "@ 5086404b540aSrobert cpys %R1,%R1,%0 5087404b540aSrobert ld%, %0,%1 5088404b540aSrobert bis $31,%r1,%0 5089404b540aSrobert ldl %0,%1 5090404b540aSrobert st%, %R1,%0 5091404b540aSrobert stl %r1,%0 5092404b540aSrobert itofs %1,%0 5093404b540aSrobert ftois %1,%0" 5094404b540aSrobert [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")]) 5095404b540aSrobert 5096404b540aSrobert(define_insn "*movsf_nofp" 5097404b540aSrobert [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m") 5098404b540aSrobert (match_operand:SF 1 "input_operand" "rG,m,r"))] 5099404b540aSrobert "! TARGET_FPREGS 5100404b540aSrobert && (register_operand (operands[0], SFmode) 5101404b540aSrobert || reg_or_0_operand (operands[1], SFmode))" 5102404b540aSrobert "@ 5103404b540aSrobert bis $31,%r1,%0 5104404b540aSrobert ldl %0,%1 5105404b540aSrobert stl %r1,%0" 5106404b540aSrobert [(set_attr "type" "ilog,ild,ist")]) 5107404b540aSrobert 5108404b540aSrobert(define_insn "*movdf_nofix" 5109404b540aSrobert [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m") 5110404b540aSrobert (match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r"))] 5111404b540aSrobert "TARGET_FPREGS && ! TARGET_FIX 5112404b540aSrobert && (register_operand (operands[0], DFmode) 5113404b540aSrobert || reg_or_0_operand (operands[1], DFmode))" 5114404b540aSrobert "@ 5115404b540aSrobert cpys %R1,%R1,%0 5116404b540aSrobert ld%- %0,%1 5117404b540aSrobert bis $31,%r1,%0 5118404b540aSrobert ldq %0,%1 5119404b540aSrobert st%- %R1,%0 5120404b540aSrobert stq %r1,%0" 5121404b540aSrobert [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")]) 5122404b540aSrobert 5123404b540aSrobert(define_insn "*movdf_fix" 5124404b540aSrobert [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r") 5125404b540aSrobert (match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))] 5126404b540aSrobert "TARGET_FPREGS && TARGET_FIX 5127404b540aSrobert && (register_operand (operands[0], DFmode) 5128404b540aSrobert || reg_or_0_operand (operands[1], DFmode))" 5129404b540aSrobert "@ 5130404b540aSrobert cpys %R1,%R1,%0 5131404b540aSrobert ld%- %0,%1 5132404b540aSrobert bis $31,%r1,%0 5133404b540aSrobert ldq %0,%1 5134404b540aSrobert st%- %R1,%0 5135404b540aSrobert stq %r1,%0 5136404b540aSrobert itoft %1,%0 5137404b540aSrobert ftoit %1,%0" 5138404b540aSrobert [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")]) 5139404b540aSrobert 5140404b540aSrobert(define_insn "*movdf_nofp" 5141404b540aSrobert [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m") 5142404b540aSrobert (match_operand:DF 1 "input_operand" "rG,m,r"))] 5143404b540aSrobert "! TARGET_FPREGS 5144404b540aSrobert && (register_operand (operands[0], DFmode) 5145404b540aSrobert || reg_or_0_operand (operands[1], DFmode))" 5146404b540aSrobert "@ 5147404b540aSrobert bis $31,%r1,%0 5148404b540aSrobert ldq %0,%1 5149404b540aSrobert stq %r1,%0" 5150404b540aSrobert [(set_attr "type" "ilog,ild,ist")]) 5151404b540aSrobert 5152404b540aSrobert;; Subregs suck for register allocation. Pretend we can move TFmode 5153404b540aSrobert;; data between general registers until after reload. 5154404b540aSrobert 5155404b540aSrobert(define_insn_and_split "*movtf_internal" 5156404b540aSrobert [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o") 5157404b540aSrobert (match_operand:TF 1 "input_operand" "roG,rG"))] 5158404b540aSrobert "register_operand (operands[0], TFmode) 5159404b540aSrobert || reg_or_0_operand (operands[1], TFmode)" 5160404b540aSrobert "#" 5161404b540aSrobert "reload_completed" 5162404b540aSrobert [(set (match_dup 0) (match_dup 2)) 5163404b540aSrobert (set (match_dup 1) (match_dup 3))] 5164404b540aSrobert{ 5165404b540aSrobert alpha_split_tmode_pair (operands, TFmode, true); 5166404b540aSrobert}) 5167404b540aSrobert 5168404b540aSrobert(define_expand "movsf" 5169404b540aSrobert [(set (match_operand:SF 0 "nonimmediate_operand" "") 5170404b540aSrobert (match_operand:SF 1 "general_operand" ""))] 5171404b540aSrobert "" 5172404b540aSrobert{ 5173404b540aSrobert if (GET_CODE (operands[0]) == MEM 5174404b540aSrobert && ! reg_or_0_operand (operands[1], SFmode)) 5175404b540aSrobert operands[1] = force_reg (SFmode, operands[1]); 5176404b540aSrobert}) 5177404b540aSrobert 5178404b540aSrobert(define_expand "movdf" 5179404b540aSrobert [(set (match_operand:DF 0 "nonimmediate_operand" "") 5180404b540aSrobert (match_operand:DF 1 "general_operand" ""))] 5181404b540aSrobert "" 5182404b540aSrobert{ 5183404b540aSrobert if (GET_CODE (operands[0]) == MEM 5184404b540aSrobert && ! reg_or_0_operand (operands[1], DFmode)) 5185404b540aSrobert operands[1] = force_reg (DFmode, operands[1]); 5186404b540aSrobert}) 5187404b540aSrobert 5188404b540aSrobert(define_expand "movtf" 5189404b540aSrobert [(set (match_operand:TF 0 "nonimmediate_operand" "") 5190404b540aSrobert (match_operand:TF 1 "general_operand" ""))] 5191404b540aSrobert "" 5192404b540aSrobert{ 5193404b540aSrobert if (GET_CODE (operands[0]) == MEM 5194404b540aSrobert && ! reg_or_0_operand (operands[1], TFmode)) 5195404b540aSrobert operands[1] = force_reg (TFmode, operands[1]); 5196404b540aSrobert}) 5197404b540aSrobert 5198404b540aSrobert(define_insn "*movsi" 5199404b540aSrobert [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m") 5200404b540aSrobert (match_operand:SI 1 "input_operand" "rJ,K,L,n,m,rJ"))] 5201404b540aSrobert "(TARGET_ABI_OSF || TARGET_ABI_UNICOSMK) 5202404b540aSrobert && (register_operand (operands[0], SImode) 5203404b540aSrobert || reg_or_0_operand (operands[1], SImode))" 5204404b540aSrobert "@ 5205404b540aSrobert bis $31,%r1,%0 5206404b540aSrobert lda %0,%1($31) 5207404b540aSrobert ldah %0,%h1($31) 5208404b540aSrobert # 5209404b540aSrobert ldl %0,%1 5210404b540aSrobert stl %r1,%0" 5211404b540aSrobert [(set_attr "type" "ilog,iadd,iadd,multi,ild,ist")]) 5212404b540aSrobert 5213404b540aSrobert(define_insn "*movsi_nt_vms" 5214404b540aSrobert [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m") 5215404b540aSrobert (match_operand:SI 1 "input_operand" "rJ,K,L,s,n,m,rJ"))] 5216404b540aSrobert "(TARGET_ABI_WINDOWS_NT || TARGET_ABI_OPEN_VMS) 5217404b540aSrobert && (register_operand (operands[0], SImode) 5218404b540aSrobert || reg_or_0_operand (operands[1], SImode))" 5219404b540aSrobert "@ 5220404b540aSrobert bis $31,%1,%0 5221404b540aSrobert lda %0,%1 5222404b540aSrobert ldah %0,%h1 5223404b540aSrobert lda %0,%1 5224404b540aSrobert # 5225404b540aSrobert ldl %0,%1 5226404b540aSrobert stl %r1,%0" 5227404b540aSrobert [(set_attr "type" "ilog,iadd,iadd,ldsym,multi,ild,ist")]) 5228404b540aSrobert 5229404b540aSrobert(define_insn "*movhi_nobwx" 5230404b540aSrobert [(set (match_operand:HI 0 "register_operand" "=r,r") 5231404b540aSrobert (match_operand:HI 1 "input_operand" "rJ,n"))] 5232404b540aSrobert "! TARGET_BWX 5233404b540aSrobert && (register_operand (operands[0], HImode) 5234404b540aSrobert || register_operand (operands[1], HImode))" 5235404b540aSrobert "@ 5236404b540aSrobert bis $31,%r1,%0 5237404b540aSrobert lda %0,%L1($31)" 5238404b540aSrobert [(set_attr "type" "ilog,iadd")]) 5239404b540aSrobert 5240404b540aSrobert(define_insn "*movhi_bwx" 5241404b540aSrobert [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m") 5242404b540aSrobert (match_operand:HI 1 "input_operand" "rJ,n,m,rJ"))] 5243404b540aSrobert "TARGET_BWX 5244404b540aSrobert && (register_operand (operands[0], HImode) 5245404b540aSrobert || reg_or_0_operand (operands[1], HImode))" 5246404b540aSrobert "@ 5247404b540aSrobert bis $31,%r1,%0 5248404b540aSrobert lda %0,%L1($31) 5249404b540aSrobert ldwu %0,%1 5250404b540aSrobert stw %r1,%0" 5251404b540aSrobert [(set_attr "type" "ilog,iadd,ild,ist")]) 5252404b540aSrobert 5253404b540aSrobert(define_insn "*movqi_nobwx" 5254404b540aSrobert [(set (match_operand:QI 0 "register_operand" "=r,r") 5255404b540aSrobert (match_operand:QI 1 "input_operand" "rJ,n"))] 5256404b540aSrobert "! TARGET_BWX 5257404b540aSrobert && (register_operand (operands[0], QImode) 5258404b540aSrobert || register_operand (operands[1], QImode))" 5259404b540aSrobert "@ 5260404b540aSrobert bis $31,%r1,%0 5261404b540aSrobert lda %0,%L1($31)" 5262404b540aSrobert [(set_attr "type" "ilog,iadd")]) 5263404b540aSrobert 5264404b540aSrobert(define_insn "*movqi_bwx" 5265404b540aSrobert [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m") 5266404b540aSrobert (match_operand:QI 1 "input_operand" "rJ,n,m,rJ"))] 5267404b540aSrobert "TARGET_BWX 5268404b540aSrobert && (register_operand (operands[0], QImode) 5269404b540aSrobert || reg_or_0_operand (operands[1], QImode))" 5270404b540aSrobert "@ 5271404b540aSrobert bis $31,%r1,%0 5272404b540aSrobert lda %0,%L1($31) 5273404b540aSrobert ldbu %0,%1 5274404b540aSrobert stb %r1,%0" 5275404b540aSrobert [(set_attr "type" "ilog,iadd,ild,ist")]) 5276404b540aSrobert 5277404b540aSrobert;; We do two major things here: handle mem->mem and construct long 5278404b540aSrobert;; constants. 5279404b540aSrobert 5280404b540aSrobert(define_expand "movsi" 5281404b540aSrobert [(set (match_operand:SI 0 "nonimmediate_operand" "") 5282404b540aSrobert (match_operand:SI 1 "general_operand" ""))] 5283404b540aSrobert "" 5284404b540aSrobert{ 5285404b540aSrobert if (alpha_expand_mov (SImode, operands)) 5286404b540aSrobert DONE; 5287404b540aSrobert}) 5288404b540aSrobert 5289404b540aSrobert;; Split a load of a large constant into the appropriate two-insn 5290404b540aSrobert;; sequence. 5291404b540aSrobert 5292404b540aSrobert(define_split 5293404b540aSrobert [(set (match_operand:SI 0 "register_operand" "") 5294404b540aSrobert (match_operand:SI 1 "non_add_const_operand" ""))] 5295404b540aSrobert "" 5296404b540aSrobert [(const_int 0)] 5297404b540aSrobert{ 5298404b540aSrobert if (alpha_split_const_mov (SImode, operands)) 5299404b540aSrobert DONE; 5300404b540aSrobert else 5301404b540aSrobert FAIL; 5302404b540aSrobert}) 5303404b540aSrobert 5304404b540aSrobert;; Split the load of an address into a four-insn sequence on Unicos/Mk. 5305404b540aSrobert;; Always generate a REG_EQUAL note for the last instruction to facilitate 5306404b540aSrobert;; optimizations. If the symbolic operand is a label_ref, generate REG_LABEL 5307404b540aSrobert;; notes and update LABEL_NUSES because this is not done automatically. 5308404b540aSrobert;; Labels may be incorrectly deleted if we don't do this. 5309404b540aSrobert;; 5310404b540aSrobert;; Describing what the individual instructions do correctly is too complicated 5311404b540aSrobert;; so use UNSPECs for each of the three parts of an address. 5312404b540aSrobert 5313404b540aSrobert(define_split 5314404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 5315404b540aSrobert (match_operand:DI 1 "symbolic_operand" ""))] 5316404b540aSrobert "TARGET_ABI_UNICOSMK && reload_completed" 5317404b540aSrobert [(const_int 0)] 5318404b540aSrobert{ 5319404b540aSrobert rtx insn1, insn2, insn3; 5320404b540aSrobert 5321404b540aSrobert insn1 = emit_insn (gen_umk_laum (operands[0], operands[1])); 5322404b540aSrobert emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32))); 5323404b540aSrobert insn2 = emit_insn (gen_umk_lalm (operands[0], operands[0], operands[1])); 5324404b540aSrobert insn3 = emit_insn (gen_umk_lal (operands[0], operands[0], operands[1])); 5325404b540aSrobert REG_NOTES (insn3) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1], 5326404b540aSrobert REG_NOTES (insn3)); 5327404b540aSrobert if (GET_CODE (operands[1]) == LABEL_REF) 5328404b540aSrobert { 5329404b540aSrobert rtx label; 5330404b540aSrobert 5331404b540aSrobert label = XEXP (operands[1], 0); 5332404b540aSrobert REG_NOTES (insn1) = gen_rtx_EXPR_LIST (REG_LABEL, label, 5333404b540aSrobert REG_NOTES (insn1)); 5334404b540aSrobert REG_NOTES (insn2) = gen_rtx_EXPR_LIST (REG_LABEL, label, 5335404b540aSrobert REG_NOTES (insn2)); 5336404b540aSrobert REG_NOTES (insn3) = gen_rtx_EXPR_LIST (REG_LABEL, label, 5337404b540aSrobert REG_NOTES (insn3)); 5338404b540aSrobert LABEL_NUSES (label) += 3; 5339404b540aSrobert } 5340404b540aSrobert DONE; 5341404b540aSrobert}) 5342404b540aSrobert 5343404b540aSrobert;; Instructions for loading the three parts of an address on Unicos/Mk. 5344404b540aSrobert 5345404b540aSrobert(define_insn "umk_laum" 5346404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 5347404b540aSrobert (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 5348404b540aSrobert UNSPEC_UMK_LAUM))] 5349404b540aSrobert "TARGET_ABI_UNICOSMK" 5350404b540aSrobert "laum %r0,%t1($31)" 5351404b540aSrobert [(set_attr "type" "iadd")]) 5352404b540aSrobert 5353404b540aSrobert(define_insn "umk_lalm" 5354404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 5355404b540aSrobert (plus:DI (match_operand:DI 1 "register_operand" "r") 5356404b540aSrobert (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 5357404b540aSrobert UNSPEC_UMK_LALM)))] 5358404b540aSrobert "TARGET_ABI_UNICOSMK" 5359404b540aSrobert "lalm %r0,%t2(%r1)" 5360404b540aSrobert [(set_attr "type" "iadd")]) 5361404b540aSrobert 5362404b540aSrobert(define_insn "umk_lal" 5363404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 5364404b540aSrobert (plus:DI (match_operand:DI 1 "register_operand" "r") 5365404b540aSrobert (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 5366404b540aSrobert UNSPEC_UMK_LAL)))] 5367404b540aSrobert "TARGET_ABI_UNICOSMK" 5368404b540aSrobert "lal %r0,%t2(%r1)" 5369404b540aSrobert [(set_attr "type" "iadd")]) 5370404b540aSrobert 5371404b540aSrobert;; Add a new call information word to the current function's list of CIWs 5372404b540aSrobert;; and load its index into $25. Doing it here ensures that the CIW will be 5373404b540aSrobert;; associated with the correct function even in the presence of inlining. 5374404b540aSrobert 5375404b540aSrobert(define_insn "*umk_load_ciw" 5376404b540aSrobert [(set (reg:DI 25) 5377404b540aSrobert (unspec:DI [(match_operand 0 "" "")] UNSPEC_UMK_LOAD_CIW))] 5378404b540aSrobert "TARGET_ABI_UNICOSMK" 5379404b540aSrobert{ 5380404b540aSrobert operands[0] = unicosmk_add_call_info_word (operands[0]); 5381404b540aSrobert return "lda $25,%0"; 5382404b540aSrobert} 5383404b540aSrobert [(set_attr "type" "iadd")]) 5384404b540aSrobert 5385404b540aSrobert(define_insn "*movdi_er_low_l" 5386404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 5387404b540aSrobert (lo_sum:DI (match_operand:DI 1 "register_operand" "r") 5388404b540aSrobert (match_operand:DI 2 "local_symbolic_operand" "")))] 5389404b540aSrobert "TARGET_EXPLICIT_RELOCS" 5390404b540aSrobert{ 5391404b540aSrobert if (true_regnum (operands[1]) == 29) 5392404b540aSrobert return "lda %0,%2(%1)\t\t!gprel"; 5393404b540aSrobert else 5394404b540aSrobert return "lda %0,%2(%1)\t\t!gprellow"; 5395404b540aSrobert} 5396404b540aSrobert [(set_attr "usegp" "yes")]) 5397404b540aSrobert 5398404b540aSrobert(define_split 5399404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 5400404b540aSrobert (match_operand:DI 1 "small_symbolic_operand" ""))] 5401404b540aSrobert "TARGET_EXPLICIT_RELOCS && reload_completed" 5402404b540aSrobert [(set (match_dup 0) 5403404b540aSrobert (lo_sum:DI (match_dup 2) (match_dup 1)))] 5404404b540aSrobert "operands[2] = pic_offset_table_rtx;") 5405404b540aSrobert 5406404b540aSrobert(define_split 5407404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 5408404b540aSrobert (match_operand:DI 1 "local_symbolic_operand" ""))] 5409404b540aSrobert "TARGET_EXPLICIT_RELOCS && reload_completed" 5410404b540aSrobert [(set (match_dup 0) 5411404b540aSrobert (plus:DI (match_dup 2) (high:DI (match_dup 1)))) 5412404b540aSrobert (set (match_dup 0) 5413404b540aSrobert (lo_sum:DI (match_dup 0) (match_dup 1)))] 5414404b540aSrobert "operands[2] = pic_offset_table_rtx;") 5415404b540aSrobert 5416404b540aSrobert(define_split 5417404b540aSrobert [(match_operand 0 "some_small_symbolic_operand" "")] 5418404b540aSrobert "" 5419404b540aSrobert [(match_dup 0)] 5420404b540aSrobert "operands[0] = split_small_symbolic_operand (operands[0]);") 5421404b540aSrobert 5422404b540aSrobert;; Accepts any symbolic, not just global, since function calls that 5423404b540aSrobert;; don't go via bsr still use !literal in hopes of linker relaxation. 5424404b540aSrobert(define_insn "movdi_er_high_g" 5425404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 5426404b540aSrobert (unspec:DI [(match_operand:DI 1 "register_operand" "r") 5427404b540aSrobert (match_operand:DI 2 "symbolic_operand" "") 5428404b540aSrobert (match_operand 3 "const_int_operand" "")] 5429404b540aSrobert UNSPEC_LITERAL))] 5430404b540aSrobert "TARGET_EXPLICIT_RELOCS" 5431404b540aSrobert{ 5432404b540aSrobert if (INTVAL (operands[3]) == 0) 5433404b540aSrobert return "ldq %0,%2(%1)\t\t!literal"; 5434404b540aSrobert else 5435404b540aSrobert return "ldq %0,%2(%1)\t\t!literal!%3"; 5436404b540aSrobert} 5437404b540aSrobert [(set_attr "type" "ldsym")]) 5438404b540aSrobert 5439404b540aSrobert(define_split 5440404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 5441404b540aSrobert (match_operand:DI 1 "global_symbolic_operand" ""))] 5442404b540aSrobert "TARGET_EXPLICIT_RELOCS && reload_completed" 5443404b540aSrobert [(set (match_dup 0) 5444404b540aSrobert (unspec:DI [(match_dup 2) 5445404b540aSrobert (match_dup 1) 5446404b540aSrobert (const_int 0)] UNSPEC_LITERAL))] 5447404b540aSrobert "operands[2] = pic_offset_table_rtx;") 5448404b540aSrobert 5449404b540aSrobert(define_insn "movdi_er_tlsgd" 5450404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 5451404b540aSrobert (unspec:DI [(match_operand:DI 1 "register_operand" "r") 5452404b540aSrobert (match_operand:DI 2 "symbolic_operand" "") 5453404b540aSrobert (match_operand 3 "const_int_operand" "")] 5454404b540aSrobert UNSPEC_TLSGD))] 5455404b540aSrobert "HAVE_AS_TLS" 5456404b540aSrobert{ 5457404b540aSrobert if (INTVAL (operands[3]) == 0) 5458404b540aSrobert return "lda %0,%2(%1)\t\t!tlsgd"; 5459404b540aSrobert else 5460404b540aSrobert return "lda %0,%2(%1)\t\t!tlsgd!%3"; 5461404b540aSrobert}) 5462404b540aSrobert 5463404b540aSrobert(define_insn "movdi_er_tlsldm" 5464404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 5465404b540aSrobert (unspec:DI [(match_operand:DI 1 "register_operand" "r") 5466404b540aSrobert (match_operand 2 "const_int_operand" "")] 5467404b540aSrobert UNSPEC_TLSLDM))] 5468404b540aSrobert "HAVE_AS_TLS" 5469404b540aSrobert{ 5470404b540aSrobert if (INTVAL (operands[2]) == 0) 5471404b540aSrobert return "lda %0,%&(%1)\t\t!tlsldm"; 5472404b540aSrobert else 5473404b540aSrobert return "lda %0,%&(%1)\t\t!tlsldm!%2"; 5474404b540aSrobert}) 5475404b540aSrobert 5476404b540aSrobert(define_insn "*movdi_er_gotdtp" 5477404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 5478404b540aSrobert (unspec:DI [(match_operand:DI 1 "register_operand" "r") 5479404b540aSrobert (match_operand:DI 2 "symbolic_operand" "")] 5480404b540aSrobert UNSPEC_DTPREL))] 5481404b540aSrobert "HAVE_AS_TLS" 5482404b540aSrobert "ldq %0,%2(%1)\t\t!gotdtprel" 5483404b540aSrobert [(set_attr "type" "ild") 5484404b540aSrobert (set_attr "usegp" "yes")]) 5485404b540aSrobert 5486404b540aSrobert(define_split 5487404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 5488404b540aSrobert (match_operand:DI 1 "gotdtp_symbolic_operand" ""))] 5489404b540aSrobert "HAVE_AS_TLS && reload_completed" 5490404b540aSrobert [(set (match_dup 0) 5491404b540aSrobert (unspec:DI [(match_dup 2) 5492404b540aSrobert (match_dup 1)] UNSPEC_DTPREL))] 5493404b540aSrobert{ 5494404b540aSrobert operands[1] = XVECEXP (XEXP (operands[1], 0), 0, 0); 5495404b540aSrobert operands[2] = pic_offset_table_rtx; 5496404b540aSrobert}) 5497404b540aSrobert 5498404b540aSrobert(define_insn "*movdi_er_gottp" 5499404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 5500404b540aSrobert (unspec:DI [(match_operand:DI 1 "register_operand" "r") 5501404b540aSrobert (match_operand:DI 2 "symbolic_operand" "")] 5502404b540aSrobert UNSPEC_TPREL))] 5503404b540aSrobert "HAVE_AS_TLS" 5504404b540aSrobert "ldq %0,%2(%1)\t\t!gottprel" 5505404b540aSrobert [(set_attr "type" "ild") 5506404b540aSrobert (set_attr "usegp" "yes")]) 5507404b540aSrobert 5508404b540aSrobert(define_split 5509404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 5510404b540aSrobert (match_operand:DI 1 "gottp_symbolic_operand" ""))] 5511404b540aSrobert "HAVE_AS_TLS && reload_completed" 5512404b540aSrobert [(set (match_dup 0) 5513404b540aSrobert (unspec:DI [(match_dup 2) 5514404b540aSrobert (match_dup 1)] UNSPEC_TPREL))] 5515404b540aSrobert{ 5516404b540aSrobert operands[1] = XVECEXP (XEXP (operands[1], 0), 0, 0); 5517404b540aSrobert operands[2] = pic_offset_table_rtx; 5518404b540aSrobert}) 5519404b540aSrobert 5520404b540aSrobert(define_insn "*movdi_er_nofix" 5521404b540aSrobert [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,r,m,*f,*f,Q") 5522404b540aSrobert (match_operand:DI 1 "input_operand" "rJ,K,L,T,s,n,m,rJ,*fJ,Q,*f"))] 5523404b540aSrobert "TARGET_EXPLICIT_RELOCS && ! TARGET_FIX 5524404b540aSrobert && (register_operand (operands[0], DImode) 5525404b540aSrobert || reg_or_0_operand (operands[1], DImode))" 5526404b540aSrobert "@ 5527404b540aSrobert mov %r1,%0 5528404b540aSrobert lda %0,%1($31) 5529404b540aSrobert ldah %0,%h1($31) 5530404b540aSrobert # 5531404b540aSrobert # 5532404b540aSrobert # 5533404b540aSrobert ldq%A1 %0,%1 5534404b540aSrobert stq%A0 %r1,%0 5535404b540aSrobert fmov %R1,%0 5536404b540aSrobert ldt %0,%1 5537404b540aSrobert stt %R1,%0" 5538404b540aSrobert [(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,multi,ild,ist,fcpys,fld,fst") 5539404b540aSrobert (set_attr "usegp" "*,*,*,yes,*,*,*,*,*,*,*")]) 5540404b540aSrobert 5541404b540aSrobert;; The 'U' constraint matches symbolic operands on Unicos/Mk. Those should 5542404b540aSrobert;; have been split up by the rules above but we shouldn't reject the 5543404b540aSrobert;; possibility of them getting through. 5544404b540aSrobert 5545404b540aSrobert(define_insn "*movdi_nofix" 5546404b540aSrobert [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,r,m,*f,*f,Q") 5547404b540aSrobert (match_operand:DI 1 "input_operand" "rJ,K,L,U,s,n,m,rJ,*fJ,Q,*f"))] 5548404b540aSrobert "! TARGET_FIX 5549404b540aSrobert && (register_operand (operands[0], DImode) 5550404b540aSrobert || reg_or_0_operand (operands[1], DImode))" 5551404b540aSrobert "@ 5552404b540aSrobert bis $31,%r1,%0 5553404b540aSrobert lda %0,%1($31) 5554404b540aSrobert ldah %0,%h1($31) 5555404b540aSrobert laum %0,%t1($31)\;sll %0,32,%0\;lalm %0,%t1(%0)\;lal %0,%t1(%0) 5556404b540aSrobert lda %0,%1 5557404b540aSrobert # 5558404b540aSrobert ldq%A1 %0,%1 5559404b540aSrobert stq%A0 %r1,%0 5560404b540aSrobert cpys %R1,%R1,%0 5561404b540aSrobert ldt %0,%1 5562404b540aSrobert stt %R1,%0" 5563404b540aSrobert [(set_attr "type" "ilog,iadd,iadd,ldsym,ldsym,multi,ild,ist,fcpys,fld,fst") 5564404b540aSrobert (set_attr "length" "*,*,*,16,*,*,*,*,*,*,*")]) 5565404b540aSrobert 5566404b540aSrobert(define_insn "*movdi_er_fix" 5567404b540aSrobert [(set (match_operand:DI 0 "nonimmediate_operand" 5568404b540aSrobert "=r,r,r,r,r,r,r, m, *f,*f, Q, r,*f") 5569404b540aSrobert (match_operand:DI 1 "input_operand" 5570404b540aSrobert "rJ,K,L,T,s,n,m,rJ,*fJ, Q,*f,*f, r"))] 5571404b540aSrobert "TARGET_EXPLICIT_RELOCS && TARGET_FIX 5572404b540aSrobert && (register_operand (operands[0], DImode) 5573404b540aSrobert || reg_or_0_operand (operands[1], DImode))" 5574404b540aSrobert "@ 5575404b540aSrobert mov %r1,%0 5576404b540aSrobert lda %0,%1($31) 5577404b540aSrobert ldah %0,%h1($31) 5578404b540aSrobert # 5579404b540aSrobert # 5580404b540aSrobert # 5581404b540aSrobert ldq%A1 %0,%1 5582404b540aSrobert stq%A0 %r1,%0 5583404b540aSrobert fmov %R1,%0 5584404b540aSrobert ldt %0,%1 5585404b540aSrobert stt %R1,%0 5586404b540aSrobert ftoit %1,%0 5587404b540aSrobert itoft %1,%0" 5588404b540aSrobert [(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,multi,ild,ist,fcpys,fld,fst,ftoi,itof") 5589404b540aSrobert (set_attr "usegp" "*,*,*,yes,*,*,*,*,*,*,*,*,*")]) 5590404b540aSrobert 5591404b540aSrobert(define_insn "*movdi_fix" 5592404b540aSrobert [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,*f,*f,Q,r,*f") 5593404b540aSrobert (match_operand:DI 1 "input_operand" "rJ,K,L,s,n,m,rJ,*fJ,Q,*f,*f,r"))] 5594404b540aSrobert "! TARGET_EXPLICIT_RELOCS && TARGET_FIX 5595404b540aSrobert && (register_operand (operands[0], DImode) 5596404b540aSrobert || reg_or_0_operand (operands[1], DImode))" 5597404b540aSrobert "@ 5598404b540aSrobert bis $31,%r1,%0 5599404b540aSrobert lda %0,%1($31) 5600404b540aSrobert ldah %0,%h1($31) 5601404b540aSrobert lda %0,%1 5602404b540aSrobert # 5603404b540aSrobert ldq%A1 %0,%1 5604404b540aSrobert stq%A0 %r1,%0 5605404b540aSrobert cpys %R1,%R1,%0 5606404b540aSrobert ldt %0,%1 5607404b540aSrobert stt %R1,%0 5608404b540aSrobert ftoit %1,%0 5609404b540aSrobert itoft %1,%0" 5610404b540aSrobert [(set_attr "type" "ilog,iadd,iadd,ldsym,multi,ild,ist,fcpys,fld,fst,ftoi,itof")]) 5611404b540aSrobert 5612404b540aSrobert;; VMS needs to set up "vms_base_regno" for unwinding. This move 5613404b540aSrobert;; often appears dead to the life analysis code, at which point we 5614404b540aSrobert;; die for emitting dead prologue instructions. Force this live. 5615404b540aSrobert 5616404b540aSrobert(define_insn "force_movdi" 5617404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 5618404b540aSrobert (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")] 5619404b540aSrobert UNSPECV_FORCE_MOV))] 5620404b540aSrobert "" 5621404b540aSrobert "mov %1,%0" 5622404b540aSrobert [(set_attr "type" "ilog")]) 5623404b540aSrobert 5624404b540aSrobert;; We do three major things here: handle mem->mem, put 64-bit constants in 5625404b540aSrobert;; memory, and construct long 32-bit constants. 5626404b540aSrobert 5627404b540aSrobert(define_expand "movdi" 5628404b540aSrobert [(set (match_operand:DI 0 "nonimmediate_operand" "") 5629404b540aSrobert (match_operand:DI 1 "general_operand" ""))] 5630404b540aSrobert "" 5631404b540aSrobert{ 5632404b540aSrobert if (alpha_expand_mov (DImode, operands)) 5633404b540aSrobert DONE; 5634404b540aSrobert}) 5635404b540aSrobert 5636404b540aSrobert;; Split a load of a large constant into the appropriate two-insn 5637404b540aSrobert;; sequence. 5638404b540aSrobert 5639404b540aSrobert(define_split 5640404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 5641404b540aSrobert (match_operand:DI 1 "non_add_const_operand" ""))] 5642404b540aSrobert "" 5643404b540aSrobert [(const_int 0)] 5644404b540aSrobert{ 5645404b540aSrobert if (alpha_split_const_mov (DImode, operands)) 5646404b540aSrobert DONE; 5647404b540aSrobert else 5648404b540aSrobert FAIL; 5649404b540aSrobert}) 5650404b540aSrobert 5651404b540aSrobert;; We need to prevent reload from splitting TImode moves, because it 5652404b540aSrobert;; might decide to overwrite a pointer with the value it points to. 5653404b540aSrobert;; In that case we have to do the loads in the appropriate order so 5654404b540aSrobert;; that the pointer is not destroyed too early. 5655404b540aSrobert 5656404b540aSrobert(define_insn_and_split "*movti_internal" 5657404b540aSrobert [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o") 5658404b540aSrobert (match_operand:TI 1 "input_operand" "roJ,rJ"))] 5659404b540aSrobert "(register_operand (operands[0], TImode) 5660404b540aSrobert /* Prevent rematerialization of constants. */ 5661404b540aSrobert && ! CONSTANT_P (operands[1])) 5662404b540aSrobert || reg_or_0_operand (operands[1], TImode)" 5663404b540aSrobert "#" 5664404b540aSrobert "reload_completed" 5665404b540aSrobert [(set (match_dup 0) (match_dup 2)) 5666404b540aSrobert (set (match_dup 1) (match_dup 3))] 5667404b540aSrobert{ 5668404b540aSrobert alpha_split_tmode_pair (operands, TImode, true); 5669404b540aSrobert}) 5670404b540aSrobert 5671404b540aSrobert(define_expand "movti" 5672404b540aSrobert [(set (match_operand:TI 0 "nonimmediate_operand" "") 5673404b540aSrobert (match_operand:TI 1 "general_operand" ""))] 5674404b540aSrobert "" 5675404b540aSrobert{ 5676404b540aSrobert if (GET_CODE (operands[0]) == MEM 5677404b540aSrobert && ! reg_or_0_operand (operands[1], TImode)) 5678404b540aSrobert operands[1] = force_reg (TImode, operands[1]); 5679404b540aSrobert 5680404b540aSrobert if (operands[1] == const0_rtx) 5681404b540aSrobert ; 5682404b540aSrobert /* We must put 64-bit constants in memory. We could keep the 5683404b540aSrobert 32-bit constants in TImode and rely on the splitter, but 5684404b540aSrobert this doesn't seem to be worth the pain. */ 5685404b540aSrobert else if (GET_CODE (operands[1]) == CONST_INT 5686404b540aSrobert || GET_CODE (operands[1]) == CONST_DOUBLE) 5687404b540aSrobert { 5688404b540aSrobert rtx in[2], out[2], target; 5689404b540aSrobert 5690404b540aSrobert gcc_assert (!no_new_pseudos); 5691404b540aSrobert 5692404b540aSrobert split_double (operands[1], &in[0], &in[1]); 5693404b540aSrobert 5694404b540aSrobert if (in[0] == const0_rtx) 5695404b540aSrobert out[0] = const0_rtx; 5696404b540aSrobert else 5697404b540aSrobert { 5698404b540aSrobert out[0] = gen_reg_rtx (DImode); 5699404b540aSrobert emit_insn (gen_movdi (out[0], in[0])); 5700404b540aSrobert } 5701404b540aSrobert 5702404b540aSrobert if (in[1] == const0_rtx) 5703404b540aSrobert out[1] = const0_rtx; 5704404b540aSrobert else 5705404b540aSrobert { 5706404b540aSrobert out[1] = gen_reg_rtx (DImode); 5707404b540aSrobert emit_insn (gen_movdi (out[1], in[1])); 5708404b540aSrobert } 5709404b540aSrobert 5710404b540aSrobert if (GET_CODE (operands[0]) != REG) 5711404b540aSrobert target = gen_reg_rtx (TImode); 5712404b540aSrobert else 5713404b540aSrobert target = operands[0]; 5714404b540aSrobert 5715404b540aSrobert emit_insn (gen_movdi (gen_rtx_SUBREG (DImode, target, 0), out[0])); 5716404b540aSrobert emit_insn (gen_movdi (gen_rtx_SUBREG (DImode, target, 8), out[1])); 5717404b540aSrobert 5718404b540aSrobert if (target != operands[0]) 5719404b540aSrobert emit_insn (gen_rtx_SET (VOIDmode, operands[0], target)); 5720404b540aSrobert 5721404b540aSrobert DONE; 5722404b540aSrobert } 5723404b540aSrobert}) 5724404b540aSrobert 5725404b540aSrobert;; These are the partial-word cases. 5726404b540aSrobert;; 5727404b540aSrobert;; First we have the code to load an aligned word. Operand 0 is the register 5728404b540aSrobert;; in which to place the result. It's mode is QImode or HImode. Operand 1 5729404b540aSrobert;; is an SImode MEM at the low-order byte of the proper word. Operand 2 is the 5730404b540aSrobert;; number of bits within the word that the value is. Operand 3 is an SImode 5731404b540aSrobert;; scratch register. If operand 0 is a hard register, operand 3 may be the 5732404b540aSrobert;; same register. It is allowed to conflict with operand 1 as well. 5733404b540aSrobert 5734404b540aSrobert(define_expand "aligned_loadqi" 5735404b540aSrobert [(set (match_operand:SI 3 "register_operand" "") 5736404b540aSrobert (match_operand:SI 1 "memory_operand" "")) 5737404b540aSrobert (set (match_operand:DI 0 "register_operand" "") 5738404b540aSrobert (zero_extract:DI (subreg:DI (match_dup 3) 0) 5739404b540aSrobert (const_int 8) 5740404b540aSrobert (match_operand:DI 2 "const_int_operand" "")))] 5741404b540aSrobert 5742404b540aSrobert "" 5743404b540aSrobert "") 5744404b540aSrobert 5745404b540aSrobert(define_expand "aligned_loadhi" 5746404b540aSrobert [(set (match_operand:SI 3 "register_operand" "") 5747404b540aSrobert (match_operand:SI 1 "memory_operand" "")) 5748404b540aSrobert (set (match_operand:DI 0 "register_operand" "") 5749404b540aSrobert (zero_extract:DI (subreg:DI (match_dup 3) 0) 5750404b540aSrobert (const_int 16) 5751404b540aSrobert (match_operand:DI 2 "const_int_operand" "")))] 5752404b540aSrobert 5753404b540aSrobert "" 5754404b540aSrobert "") 5755404b540aSrobert 5756404b540aSrobert;; Similar for unaligned loads, where we use the sequence from the 5757404b540aSrobert;; Alpha Architecture manual. We have to distinguish between little-endian 5758404b540aSrobert;; and big-endian systems as the sequences are different. 5759404b540aSrobert;; 5760404b540aSrobert;; Operand 1 is the address. Operands 2 and 3 are temporaries, where 5761404b540aSrobert;; operand 3 can overlap the input and output registers. 5762404b540aSrobert 5763404b540aSrobert(define_expand "unaligned_loadqi" 5764404b540aSrobert [(use (match_operand:DI 0 "register_operand" "")) 5765404b540aSrobert (use (match_operand:DI 1 "address_operand" "")) 5766404b540aSrobert (use (match_operand:DI 2 "register_operand" "")) 5767404b540aSrobert (use (match_operand:DI 3 "register_operand" ""))] 5768404b540aSrobert "" 5769404b540aSrobert{ 5770404b540aSrobert if (WORDS_BIG_ENDIAN) 5771404b540aSrobert emit_insn (gen_unaligned_loadqi_be (operands[0], operands[1], 5772404b540aSrobert operands[2], operands[3])); 5773404b540aSrobert else 5774404b540aSrobert emit_insn (gen_unaligned_loadqi_le (operands[0], operands[1], 5775404b540aSrobert operands[2], operands[3])); 5776404b540aSrobert DONE; 5777404b540aSrobert}) 5778404b540aSrobert 5779404b540aSrobert(define_expand "unaligned_loadqi_le" 5780404b540aSrobert [(set (match_operand:DI 2 "register_operand" "") 5781404b540aSrobert (mem:DI (and:DI (match_operand:DI 1 "address_operand" "") 5782404b540aSrobert (const_int -8)))) 5783404b540aSrobert (set (match_operand:DI 3 "register_operand" "") 5784404b540aSrobert (match_dup 1)) 5785404b540aSrobert (set (match_operand:DI 0 "register_operand" "") 5786404b540aSrobert (zero_extract:DI (match_dup 2) 5787404b540aSrobert (const_int 8) 5788404b540aSrobert (ashift:DI (match_dup 3) (const_int 3))))] 5789404b540aSrobert "! WORDS_BIG_ENDIAN" 5790404b540aSrobert "") 5791404b540aSrobert 5792404b540aSrobert(define_expand "unaligned_loadqi_be" 5793404b540aSrobert [(set (match_operand:DI 2 "register_operand" "") 5794404b540aSrobert (mem:DI (and:DI (match_operand:DI 1 "address_operand" "") 5795404b540aSrobert (const_int -8)))) 5796404b540aSrobert (set (match_operand:DI 3 "register_operand" "") 5797404b540aSrobert (match_dup 1)) 5798404b540aSrobert (set (match_operand:DI 0 "register_operand" "") 5799404b540aSrobert (zero_extract:DI (match_dup 2) 5800404b540aSrobert (const_int 8) 5801404b540aSrobert (minus:DI 5802404b540aSrobert (const_int 56) 5803404b540aSrobert (ashift:DI (match_dup 3) (const_int 3)))))] 5804404b540aSrobert "WORDS_BIG_ENDIAN" 5805404b540aSrobert "") 5806404b540aSrobert 5807404b540aSrobert(define_expand "unaligned_loadhi" 5808404b540aSrobert [(use (match_operand:DI 0 "register_operand" "")) 5809404b540aSrobert (use (match_operand:DI 1 "address_operand" "")) 5810404b540aSrobert (use (match_operand:DI 2 "register_operand" "")) 5811404b540aSrobert (use (match_operand:DI 3 "register_operand" ""))] 5812404b540aSrobert "" 5813404b540aSrobert{ 5814404b540aSrobert if (WORDS_BIG_ENDIAN) 5815404b540aSrobert emit_insn (gen_unaligned_loadhi_be (operands[0], operands[1], 5816404b540aSrobert operands[2], operands[3])); 5817404b540aSrobert else 5818404b540aSrobert emit_insn (gen_unaligned_loadhi_le (operands[0], operands[1], 5819404b540aSrobert operands[2], operands[3])); 5820404b540aSrobert DONE; 5821404b540aSrobert}) 5822404b540aSrobert 5823404b540aSrobert(define_expand "unaligned_loadhi_le" 5824404b540aSrobert [(set (match_operand:DI 2 "register_operand" "") 5825404b540aSrobert (mem:DI (and:DI (match_operand:DI 1 "address_operand" "") 5826404b540aSrobert (const_int -8)))) 5827404b540aSrobert (set (match_operand:DI 3 "register_operand" "") 5828404b540aSrobert (match_dup 1)) 5829404b540aSrobert (set (match_operand:DI 0 "register_operand" "") 5830404b540aSrobert (zero_extract:DI (match_dup 2) 5831404b540aSrobert (const_int 16) 5832404b540aSrobert (ashift:DI (match_dup 3) (const_int 3))))] 5833404b540aSrobert "! WORDS_BIG_ENDIAN" 5834404b540aSrobert "") 5835404b540aSrobert 5836404b540aSrobert(define_expand "unaligned_loadhi_be" 5837404b540aSrobert [(set (match_operand:DI 2 "register_operand" "") 5838404b540aSrobert (mem:DI (and:DI (match_operand:DI 1 "address_operand" "") 5839404b540aSrobert (const_int -8)))) 5840404b540aSrobert (set (match_operand:DI 3 "register_operand" "") 5841404b540aSrobert (plus:DI (match_dup 1) (const_int 1))) 5842404b540aSrobert (set (match_operand:DI 0 "register_operand" "") 5843404b540aSrobert (zero_extract:DI (match_dup 2) 5844404b540aSrobert (const_int 16) 5845404b540aSrobert (minus:DI 5846404b540aSrobert (const_int 56) 5847404b540aSrobert (ashift:DI (match_dup 3) (const_int 3)))))] 5848404b540aSrobert "WORDS_BIG_ENDIAN" 5849404b540aSrobert "") 5850404b540aSrobert 5851404b540aSrobert;; Storing an aligned byte or word requires two temporaries. Operand 0 is the 5852404b540aSrobert;; aligned SImode MEM. Operand 1 is the register containing the 5853404b540aSrobert;; byte or word to store. Operand 2 is the number of bits within the word that 5854404b540aSrobert;; the value should be placed. Operands 3 and 4 are SImode temporaries. 5855404b540aSrobert 5856404b540aSrobert(define_expand "aligned_store" 5857404b540aSrobert [(set (match_operand:SI 3 "register_operand" "") 5858404b540aSrobert (match_operand:SI 0 "memory_operand" "")) 5859404b540aSrobert (set (subreg:DI (match_dup 3) 0) 5860404b540aSrobert (and:DI (subreg:DI (match_dup 3) 0) (match_dup 5))) 5861404b540aSrobert (set (subreg:DI (match_operand:SI 4 "register_operand" "") 0) 5862404b540aSrobert (ashift:DI (zero_extend:DI (match_operand 1 "register_operand" "")) 5863404b540aSrobert (match_operand:DI 2 "const_int_operand" ""))) 5864404b540aSrobert (set (subreg:DI (match_dup 4) 0) 5865404b540aSrobert (ior:DI (subreg:DI (match_dup 4) 0) (subreg:DI (match_dup 3) 0))) 5866404b540aSrobert (set (match_dup 0) (match_dup 4))] 5867404b540aSrobert "" 5868404b540aSrobert{ 5869404b540aSrobert operands[5] = GEN_INT (~ (GET_MODE_MASK (GET_MODE (operands[1])) 5870404b540aSrobert << INTVAL (operands[2]))); 5871404b540aSrobert}) 5872404b540aSrobert 5873404b540aSrobert;; For the unaligned byte and halfword cases, we use code similar to that 5874404b540aSrobert;; in the ;; Architecture book, but reordered to lower the number of registers 5875404b540aSrobert;; required. Operand 0 is the address. Operand 1 is the data to store. 5876404b540aSrobert;; Operands 2, 3, and 4 are DImode temporaries, where operands 2 and 4 may 5877404b540aSrobert;; be the same temporary, if desired. If the address is in a register, 5878404b540aSrobert;; operand 2 can be that register. 5879404b540aSrobert 5880404b540aSrobert(define_expand "unaligned_storeqi" 5881404b540aSrobert [(use (match_operand:DI 0 "address_operand" "")) 5882404b540aSrobert (use (match_operand:QI 1 "register_operand" "")) 5883404b540aSrobert (use (match_operand:DI 2 "register_operand" "")) 5884404b540aSrobert (use (match_operand:DI 3 "register_operand" "")) 5885404b540aSrobert (use (match_operand:DI 4 "register_operand" ""))] 5886404b540aSrobert "" 5887404b540aSrobert{ 5888404b540aSrobert if (WORDS_BIG_ENDIAN) 5889404b540aSrobert emit_insn (gen_unaligned_storeqi_be (operands[0], operands[1], 5890404b540aSrobert operands[2], operands[3], 5891404b540aSrobert operands[4])); 5892404b540aSrobert else 5893404b540aSrobert emit_insn (gen_unaligned_storeqi_le (operands[0], operands[1], 5894404b540aSrobert operands[2], operands[3], 5895404b540aSrobert operands[4])); 5896404b540aSrobert DONE; 5897404b540aSrobert}) 5898404b540aSrobert 5899404b540aSrobert(define_expand "unaligned_storeqi_le" 5900404b540aSrobert [(set (match_operand:DI 3 "register_operand" "") 5901404b540aSrobert (mem:DI (and:DI (match_operand:DI 0 "address_operand" "") 5902404b540aSrobert (const_int -8)))) 5903404b540aSrobert (set (match_operand:DI 2 "register_operand" "") 5904404b540aSrobert (match_dup 0)) 5905404b540aSrobert (set (match_dup 3) 5906404b540aSrobert (and:DI (not:DI (ashift:DI (const_int 255) 5907404b540aSrobert (ashift:DI (match_dup 2) (const_int 3)))) 5908404b540aSrobert (match_dup 3))) 5909404b540aSrobert (set (match_operand:DI 4 "register_operand" "") 5910404b540aSrobert (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "")) 5911404b540aSrobert (ashift:DI (match_dup 2) (const_int 3)))) 5912404b540aSrobert (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3))) 5913404b540aSrobert (set (mem:DI (and:DI (match_dup 0) (const_int -8))) 5914404b540aSrobert (match_dup 4))] 5915404b540aSrobert "! WORDS_BIG_ENDIAN" 5916404b540aSrobert "") 5917404b540aSrobert 5918404b540aSrobert(define_expand "unaligned_storeqi_be" 5919404b540aSrobert [(set (match_operand:DI 3 "register_operand" "") 5920404b540aSrobert (mem:DI (and:DI (match_operand:DI 0 "address_operand" "") 5921404b540aSrobert (const_int -8)))) 5922404b540aSrobert (set (match_operand:DI 2 "register_operand" "") 5923404b540aSrobert (match_dup 0)) 5924404b540aSrobert (set (match_dup 3) 5925404b540aSrobert (and:DI (not:DI (ashift:DI (const_int 255) 5926404b540aSrobert (minus:DI (const_int 56) 5927404b540aSrobert (ashift:DI (match_dup 2) (const_int 3))))) 5928404b540aSrobert (match_dup 3))) 5929404b540aSrobert (set (match_operand:DI 4 "register_operand" "") 5930404b540aSrobert (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "")) 5931404b540aSrobert (minus:DI (const_int 56) 5932404b540aSrobert (ashift:DI (match_dup 2) (const_int 3))))) 5933404b540aSrobert (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3))) 5934404b540aSrobert (set (mem:DI (and:DI (match_dup 0) (const_int -8))) 5935404b540aSrobert (match_dup 4))] 5936404b540aSrobert "WORDS_BIG_ENDIAN" 5937404b540aSrobert "") 5938404b540aSrobert 5939404b540aSrobert(define_expand "unaligned_storehi" 5940404b540aSrobert [(use (match_operand:DI 0 "address_operand" "")) 5941404b540aSrobert (use (match_operand:HI 1 "register_operand" "")) 5942404b540aSrobert (use (match_operand:DI 2 "register_operand" "")) 5943404b540aSrobert (use (match_operand:DI 3 "register_operand" "")) 5944404b540aSrobert (use (match_operand:DI 4 "register_operand" ""))] 5945404b540aSrobert "" 5946404b540aSrobert{ 5947404b540aSrobert if (WORDS_BIG_ENDIAN) 5948404b540aSrobert emit_insn (gen_unaligned_storehi_be (operands[0], operands[1], 5949404b540aSrobert operands[2], operands[3], 5950404b540aSrobert operands[4])); 5951404b540aSrobert else 5952404b540aSrobert emit_insn (gen_unaligned_storehi_le (operands[0], operands[1], 5953404b540aSrobert operands[2], operands[3], 5954404b540aSrobert operands[4])); 5955404b540aSrobert DONE; 5956404b540aSrobert}) 5957404b540aSrobert 5958404b540aSrobert(define_expand "unaligned_storehi_le" 5959404b540aSrobert [(set (match_operand:DI 3 "register_operand" "") 5960404b540aSrobert (mem:DI (and:DI (match_operand:DI 0 "address_operand" "") 5961404b540aSrobert (const_int -8)))) 5962404b540aSrobert (set (match_operand:DI 2 "register_operand" "") 5963404b540aSrobert (match_dup 0)) 5964404b540aSrobert (set (match_dup 3) 5965404b540aSrobert (and:DI (not:DI (ashift:DI (const_int 65535) 5966404b540aSrobert (ashift:DI (match_dup 2) (const_int 3)))) 5967404b540aSrobert (match_dup 3))) 5968404b540aSrobert (set (match_operand:DI 4 "register_operand" "") 5969404b540aSrobert (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "")) 5970404b540aSrobert (ashift:DI (match_dup 2) (const_int 3)))) 5971404b540aSrobert (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3))) 5972404b540aSrobert (set (mem:DI (and:DI (match_dup 0) (const_int -8))) 5973404b540aSrobert (match_dup 4))] 5974404b540aSrobert "! WORDS_BIG_ENDIAN" 5975404b540aSrobert "") 5976404b540aSrobert 5977404b540aSrobert(define_expand "unaligned_storehi_be" 5978404b540aSrobert [(set (match_operand:DI 3 "register_operand" "") 5979404b540aSrobert (mem:DI (and:DI (match_operand:DI 0 "address_operand" "") 5980404b540aSrobert (const_int -8)))) 5981404b540aSrobert (set (match_operand:DI 2 "register_operand" "") 5982404b540aSrobert (plus:DI (match_dup 0) (const_int 1))) 5983404b540aSrobert (set (match_dup 3) 5984404b540aSrobert (and:DI (not:DI (ashift:DI 5985404b540aSrobert (const_int 65535) 5986404b540aSrobert (minus:DI (const_int 56) 5987404b540aSrobert (ashift:DI (match_dup 2) (const_int 3))))) 5988404b540aSrobert (match_dup 3))) 5989404b540aSrobert (set (match_operand:DI 4 "register_operand" "") 5990404b540aSrobert (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "")) 5991404b540aSrobert (minus:DI (const_int 56) 5992404b540aSrobert (ashift:DI (match_dup 2) (const_int 3))))) 5993404b540aSrobert (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3))) 5994404b540aSrobert (set (mem:DI (and:DI (match_dup 0) (const_int -8))) 5995404b540aSrobert (match_dup 4))] 5996404b540aSrobert "WORDS_BIG_ENDIAN" 5997404b540aSrobert "") 5998404b540aSrobert 5999404b540aSrobert;; Here are the define_expand's for QI and HI moves that use the above 6000404b540aSrobert;; patterns. We have the normal sets, plus the ones that need scratch 6001404b540aSrobert;; registers for reload. 6002404b540aSrobert 6003404b540aSrobert(define_expand "movqi" 6004404b540aSrobert [(set (match_operand:QI 0 "nonimmediate_operand" "") 6005404b540aSrobert (match_operand:QI 1 "general_operand" ""))] 6006404b540aSrobert "" 6007404b540aSrobert{ 6008404b540aSrobert if (TARGET_BWX 6009404b540aSrobert ? alpha_expand_mov (QImode, operands) 6010404b540aSrobert : alpha_expand_mov_nobwx (QImode, operands)) 6011404b540aSrobert DONE; 6012404b540aSrobert}) 6013404b540aSrobert 6014404b540aSrobert(define_expand "movhi" 6015404b540aSrobert [(set (match_operand:HI 0 "nonimmediate_operand" "") 6016404b540aSrobert (match_operand:HI 1 "general_operand" ""))] 6017404b540aSrobert "" 6018404b540aSrobert{ 6019404b540aSrobert if (TARGET_BWX 6020404b540aSrobert ? alpha_expand_mov (HImode, operands) 6021404b540aSrobert : alpha_expand_mov_nobwx (HImode, operands)) 6022404b540aSrobert DONE; 6023404b540aSrobert}) 6024404b540aSrobert 6025404b540aSrobert;; Here are the versions for reload. Note that in the unaligned cases 6026404b540aSrobert;; we know that the operand must not be a pseudo-register because stack 6027404b540aSrobert;; slots are always aligned references. 6028404b540aSrobert 6029404b540aSrobert(define_expand "reload_inqi" 6030404b540aSrobert [(parallel [(match_operand:QI 0 "register_operand" "=r") 6031404b540aSrobert (match_operand:QI 1 "any_memory_operand" "m") 6032404b540aSrobert (match_operand:TI 2 "register_operand" "=&r")])] 6033404b540aSrobert "! TARGET_BWX" 6034404b540aSrobert{ 6035404b540aSrobert rtx scratch, seq; 6036404b540aSrobert 6037404b540aSrobert if (aligned_memory_operand (operands[1], QImode)) 6038404b540aSrobert { 6039404b540aSrobert seq = gen_reload_inqi_help (operands[0], operands[1], 6040404b540aSrobert gen_rtx_REG (SImode, REGNO (operands[2]))); 6041404b540aSrobert } 6042404b540aSrobert else 6043404b540aSrobert { 6044404b540aSrobert rtx addr; 6045404b540aSrobert 6046404b540aSrobert /* It is possible that one of the registers we got for operands[2] 6047404b540aSrobert might coincide with that of operands[0] (which is why we made 6048404b540aSrobert it TImode). Pick the other one to use as our scratch. */ 6049404b540aSrobert if (REGNO (operands[0]) == REGNO (operands[2])) 6050404b540aSrobert scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1); 6051404b540aSrobert else 6052404b540aSrobert scratch = gen_rtx_REG (DImode, REGNO (operands[2])); 6053404b540aSrobert 6054404b540aSrobert addr = get_unaligned_address (operands[1]); 6055404b540aSrobert operands[0] = gen_rtx_REG (DImode, REGNO (operands[0])); 6056404b540aSrobert seq = gen_unaligned_loadqi (operands[0], addr, scratch, operands[0]); 6057404b540aSrobert alpha_set_memflags (seq, operands[1]); 6058404b540aSrobert } 6059404b540aSrobert emit_insn (seq); 6060404b540aSrobert DONE; 6061404b540aSrobert}) 6062404b540aSrobert 6063404b540aSrobert(define_expand "reload_inhi" 6064404b540aSrobert [(parallel [(match_operand:HI 0 "register_operand" "=r") 6065404b540aSrobert (match_operand:HI 1 "any_memory_operand" "m") 6066404b540aSrobert (match_operand:TI 2 "register_operand" "=&r")])] 6067404b540aSrobert "! TARGET_BWX" 6068404b540aSrobert{ 6069404b540aSrobert rtx scratch, seq; 6070404b540aSrobert 6071404b540aSrobert if (aligned_memory_operand (operands[1], HImode)) 6072404b540aSrobert { 6073404b540aSrobert seq = gen_reload_inhi_help (operands[0], operands[1], 6074404b540aSrobert gen_rtx_REG (SImode, REGNO (operands[2]))); 6075404b540aSrobert } 6076404b540aSrobert else 6077404b540aSrobert { 6078404b540aSrobert rtx addr; 6079404b540aSrobert 6080404b540aSrobert /* It is possible that one of the registers we got for operands[2] 6081404b540aSrobert might coincide with that of operands[0] (which is why we made 6082404b540aSrobert it TImode). Pick the other one to use as our scratch. */ 6083404b540aSrobert if (REGNO (operands[0]) == REGNO (operands[2])) 6084404b540aSrobert scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1); 6085404b540aSrobert else 6086404b540aSrobert scratch = gen_rtx_REG (DImode, REGNO (operands[2])); 6087404b540aSrobert 6088404b540aSrobert addr = get_unaligned_address (operands[1]); 6089404b540aSrobert operands[0] = gen_rtx_REG (DImode, REGNO (operands[0])); 6090404b540aSrobert seq = gen_unaligned_loadhi (operands[0], addr, scratch, operands[0]); 6091404b540aSrobert alpha_set_memflags (seq, operands[1]); 6092404b540aSrobert } 6093404b540aSrobert emit_insn (seq); 6094404b540aSrobert DONE; 6095404b540aSrobert}) 6096404b540aSrobert 6097404b540aSrobert(define_expand "reload_outqi" 6098404b540aSrobert [(parallel [(match_operand:QI 0 "any_memory_operand" "=m") 6099404b540aSrobert (match_operand:QI 1 "register_operand" "r") 6100404b540aSrobert (match_operand:TI 2 "register_operand" "=&r")])] 6101404b540aSrobert "! TARGET_BWX" 6102404b540aSrobert{ 6103404b540aSrobert if (aligned_memory_operand (operands[0], QImode)) 6104404b540aSrobert { 6105404b540aSrobert emit_insn (gen_reload_outqi_help 6106404b540aSrobert (operands[0], operands[1], 6107404b540aSrobert gen_rtx_REG (SImode, REGNO (operands[2])), 6108404b540aSrobert gen_rtx_REG (SImode, REGNO (operands[2]) + 1))); 6109404b540aSrobert } 6110404b540aSrobert else 6111404b540aSrobert { 6112404b540aSrobert rtx addr = get_unaligned_address (operands[0]); 6113404b540aSrobert rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2])); 6114404b540aSrobert rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1); 6115404b540aSrobert rtx scratch3 = scratch1; 6116404b540aSrobert rtx seq; 6117404b540aSrobert 6118404b540aSrobert if (GET_CODE (addr) == REG) 6119404b540aSrobert scratch1 = addr; 6120404b540aSrobert 6121404b540aSrobert seq = gen_unaligned_storeqi (addr, operands[1], scratch1, 6122404b540aSrobert scratch2, scratch3); 6123404b540aSrobert alpha_set_memflags (seq, operands[0]); 6124404b540aSrobert emit_insn (seq); 6125404b540aSrobert } 6126404b540aSrobert DONE; 6127404b540aSrobert}) 6128404b540aSrobert 6129404b540aSrobert(define_expand "reload_outhi" 6130404b540aSrobert [(parallel [(match_operand:HI 0 "any_memory_operand" "=m") 6131404b540aSrobert (match_operand:HI 1 "register_operand" "r") 6132404b540aSrobert (match_operand:TI 2 "register_operand" "=&r")])] 6133404b540aSrobert "! TARGET_BWX" 6134404b540aSrobert{ 6135404b540aSrobert if (aligned_memory_operand (operands[0], HImode)) 6136404b540aSrobert { 6137404b540aSrobert emit_insn (gen_reload_outhi_help 6138404b540aSrobert (operands[0], operands[1], 6139404b540aSrobert gen_rtx_REG (SImode, REGNO (operands[2])), 6140404b540aSrobert gen_rtx_REG (SImode, REGNO (operands[2]) + 1))); 6141404b540aSrobert } 6142404b540aSrobert else 6143404b540aSrobert { 6144404b540aSrobert rtx addr = get_unaligned_address (operands[0]); 6145404b540aSrobert rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2])); 6146404b540aSrobert rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1); 6147404b540aSrobert rtx scratch3 = scratch1; 6148404b540aSrobert rtx seq; 6149404b540aSrobert 6150404b540aSrobert if (GET_CODE (addr) == REG) 6151404b540aSrobert scratch1 = addr; 6152404b540aSrobert 6153404b540aSrobert seq = gen_unaligned_storehi (addr, operands[1], scratch1, 6154404b540aSrobert scratch2, scratch3); 6155404b540aSrobert alpha_set_memflags (seq, operands[0]); 6156404b540aSrobert emit_insn (seq); 6157404b540aSrobert } 6158404b540aSrobert DONE; 6159404b540aSrobert}) 6160404b540aSrobert 6161404b540aSrobert;; Helpers for the above. The way reload is structured, we can't 6162404b540aSrobert;; always get a proper address for a stack slot during reload_foo 6163404b540aSrobert;; expansion, so we must delay our address manipulations until after. 6164404b540aSrobert 6165404b540aSrobert(define_insn_and_split "reload_inqi_help" 6166404b540aSrobert [(set (match_operand:QI 0 "register_operand" "=r") 6167404b540aSrobert (match_operand:QI 1 "memory_operand" "m")) 6168404b540aSrobert (clobber (match_operand:SI 2 "register_operand" "=r"))] 6169404b540aSrobert "! TARGET_BWX && (reload_in_progress || reload_completed)" 6170404b540aSrobert "#" 6171404b540aSrobert "! TARGET_BWX && reload_completed" 6172404b540aSrobert [(const_int 0)] 6173404b540aSrobert{ 6174404b540aSrobert rtx aligned_mem, bitnum; 6175404b540aSrobert get_aligned_mem (operands[1], &aligned_mem, &bitnum); 6176404b540aSrobert operands[0] = gen_lowpart (DImode, operands[0]); 6177404b540aSrobert emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum, 6178404b540aSrobert operands[2])); 6179404b540aSrobert DONE; 6180404b540aSrobert}) 6181404b540aSrobert 6182404b540aSrobert(define_insn_and_split "reload_inhi_help" 6183404b540aSrobert [(set (match_operand:HI 0 "register_operand" "=r") 6184404b540aSrobert (match_operand:HI 1 "memory_operand" "m")) 6185404b540aSrobert (clobber (match_operand:SI 2 "register_operand" "=r"))] 6186404b540aSrobert "! TARGET_BWX && (reload_in_progress || reload_completed)" 6187404b540aSrobert "#" 6188404b540aSrobert "! TARGET_BWX && reload_completed" 6189404b540aSrobert [(const_int 0)] 6190404b540aSrobert{ 6191404b540aSrobert rtx aligned_mem, bitnum; 6192404b540aSrobert get_aligned_mem (operands[1], &aligned_mem, &bitnum); 6193404b540aSrobert operands[0] = gen_lowpart (DImode, operands[0]); 6194404b540aSrobert emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum, 6195404b540aSrobert operands[2])); 6196404b540aSrobert DONE; 6197404b540aSrobert}) 6198404b540aSrobert 6199404b540aSrobert(define_insn_and_split "reload_outqi_help" 6200404b540aSrobert [(set (match_operand:QI 0 "memory_operand" "=m") 6201404b540aSrobert (match_operand:QI 1 "register_operand" "r")) 6202404b540aSrobert (clobber (match_operand:SI 2 "register_operand" "=r")) 6203404b540aSrobert (clobber (match_operand:SI 3 "register_operand" "=r"))] 6204404b540aSrobert "! TARGET_BWX && (reload_in_progress || reload_completed)" 6205404b540aSrobert "#" 6206404b540aSrobert "! TARGET_BWX && reload_completed" 6207404b540aSrobert [(const_int 0)] 6208404b540aSrobert{ 6209404b540aSrobert rtx aligned_mem, bitnum; 6210404b540aSrobert get_aligned_mem (operands[0], &aligned_mem, &bitnum); 6211404b540aSrobert emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum, 6212404b540aSrobert operands[2], operands[3])); 6213404b540aSrobert DONE; 6214404b540aSrobert}) 6215404b540aSrobert 6216404b540aSrobert(define_insn_and_split "reload_outhi_help" 6217404b540aSrobert [(set (match_operand:HI 0 "memory_operand" "=m") 6218404b540aSrobert (match_operand:HI 1 "register_operand" "r")) 6219404b540aSrobert (clobber (match_operand:SI 2 "register_operand" "=r")) 6220404b540aSrobert (clobber (match_operand:SI 3 "register_operand" "=r"))] 6221404b540aSrobert "! TARGET_BWX && (reload_in_progress || reload_completed)" 6222404b540aSrobert "#" 6223404b540aSrobert "! TARGET_BWX && reload_completed" 6224404b540aSrobert [(const_int 0)] 6225404b540aSrobert{ 6226404b540aSrobert rtx aligned_mem, bitnum; 6227404b540aSrobert get_aligned_mem (operands[0], &aligned_mem, &bitnum); 6228404b540aSrobert emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum, 6229404b540aSrobert operands[2], operands[3])); 6230404b540aSrobert DONE; 6231404b540aSrobert}) 6232404b540aSrobert 6233404b540aSrobert;; Vector operations 6234404b540aSrobert 6235404b540aSrobert(define_mode_macro VEC [V8QI V4HI V2SI]) 6236404b540aSrobert 6237404b540aSrobert(define_expand "mov<mode>" 6238404b540aSrobert [(set (match_operand:VEC 0 "nonimmediate_operand" "") 6239404b540aSrobert (match_operand:VEC 1 "general_operand" ""))] 6240404b540aSrobert "" 6241404b540aSrobert{ 6242404b540aSrobert if (alpha_expand_mov (<MODE>mode, operands)) 6243404b540aSrobert DONE; 6244404b540aSrobert}) 6245404b540aSrobert 6246404b540aSrobert(define_split 6247404b540aSrobert [(set (match_operand:VEC 0 "register_operand" "") 6248404b540aSrobert (match_operand:VEC 1 "non_zero_const_operand" ""))] 6249404b540aSrobert "" 6250404b540aSrobert [(const_int 0)] 6251404b540aSrobert{ 6252404b540aSrobert if (alpha_split_const_mov (<MODE>mode, operands)) 6253404b540aSrobert DONE; 6254404b540aSrobert else 6255404b540aSrobert FAIL; 6256404b540aSrobert}) 6257404b540aSrobert 6258404b540aSrobert 6259404b540aSrobert(define_expand "movmisalign<mode>" 6260404b540aSrobert [(set (match_operand:VEC 0 "nonimmediate_operand" "") 6261404b540aSrobert (match_operand:VEC 1 "general_operand" ""))] 6262404b540aSrobert "" 6263404b540aSrobert{ 6264404b540aSrobert alpha_expand_movmisalign (<MODE>mode, operands); 6265404b540aSrobert DONE; 6266404b540aSrobert}) 6267404b540aSrobert 6268404b540aSrobert(define_insn "*mov<mode>_fix" 6269404b540aSrobert [(set (match_operand:VEC 0 "nonimmediate_operand" "=r,r,r,m,*f,*f,m,r,*f") 6270404b540aSrobert (match_operand:VEC 1 "input_operand" "rW,i,m,rW,*fW,m,*f,*f,r"))] 6271404b540aSrobert "TARGET_FIX 6272404b540aSrobert && (register_operand (operands[0], <MODE>mode) 6273404b540aSrobert || reg_or_0_operand (operands[1], <MODE>mode))" 6274404b540aSrobert "@ 6275404b540aSrobert bis $31,%r1,%0 6276404b540aSrobert # 6277404b540aSrobert ldq %0,%1 6278404b540aSrobert stq %r1,%0 6279404b540aSrobert cpys %R1,%R1,%0 6280404b540aSrobert ldt %0,%1 6281404b540aSrobert stt %R1,%0 6282404b540aSrobert ftoit %1,%0 6283404b540aSrobert itoft %1,%0" 6284404b540aSrobert [(set_attr "type" "ilog,multi,ild,ist,fcpys,fld,fst,ftoi,itof")]) 6285404b540aSrobert 6286404b540aSrobert(define_insn "*mov<mode>_nofix" 6287404b540aSrobert [(set (match_operand:VEC 0 "nonimmediate_operand" "=r,r,r,m,*f,*f,m") 6288404b540aSrobert (match_operand:VEC 1 "input_operand" "rW,i,m,rW,*fW,m,*f"))] 6289404b540aSrobert "! TARGET_FIX 6290404b540aSrobert && (register_operand (operands[0], <MODE>mode) 6291404b540aSrobert || reg_or_0_operand (operands[1], <MODE>mode))" 6292404b540aSrobert "@ 6293404b540aSrobert bis $31,%r1,%0 6294404b540aSrobert # 6295404b540aSrobert ldq %0,%1 6296404b540aSrobert stq %r1,%0 6297404b540aSrobert cpys %R1,%R1,%0 6298404b540aSrobert ldt %0,%1 6299404b540aSrobert stt %R1,%0" 6300404b540aSrobert [(set_attr "type" "ilog,multi,ild,ist,fcpys,fld,fst")]) 6301404b540aSrobert 6302404b540aSrobert(define_insn "uminv8qi3" 6303404b540aSrobert [(set (match_operand:V8QI 0 "register_operand" "=r") 6304404b540aSrobert (umin:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW") 6305404b540aSrobert (match_operand:V8QI 2 "reg_or_0_operand" "rW")))] 6306404b540aSrobert "TARGET_MAX" 6307404b540aSrobert "minub8 %r1,%r2,%0" 6308404b540aSrobert [(set_attr "type" "mvi")]) 6309404b540aSrobert 6310404b540aSrobert(define_insn "sminv8qi3" 6311404b540aSrobert [(set (match_operand:V8QI 0 "register_operand" "=r") 6312404b540aSrobert (smin:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW") 6313404b540aSrobert (match_operand:V8QI 2 "reg_or_0_operand" "rW")))] 6314404b540aSrobert "TARGET_MAX" 6315404b540aSrobert "minsb8 %r1,%r2,%0" 6316404b540aSrobert [(set_attr "type" "mvi")]) 6317404b540aSrobert 6318404b540aSrobert(define_insn "uminv4hi3" 6319404b540aSrobert [(set (match_operand:V4HI 0 "register_operand" "=r") 6320404b540aSrobert (umin:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW") 6321404b540aSrobert (match_operand:V4HI 2 "reg_or_0_operand" "rW")))] 6322404b540aSrobert "TARGET_MAX" 6323404b540aSrobert "minuw4 %r1,%r2,%0" 6324404b540aSrobert [(set_attr "type" "mvi")]) 6325404b540aSrobert 6326404b540aSrobert(define_insn "sminv4hi3" 6327404b540aSrobert [(set (match_operand:V4HI 0 "register_operand" "=r") 6328404b540aSrobert (smin:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW") 6329404b540aSrobert (match_operand:V4HI 2 "reg_or_0_operand" "rW")))] 6330404b540aSrobert "TARGET_MAX" 6331404b540aSrobert "minsw4 %r1,%r2,%0" 6332404b540aSrobert [(set_attr "type" "mvi")]) 6333404b540aSrobert 6334404b540aSrobert(define_insn "umaxv8qi3" 6335404b540aSrobert [(set (match_operand:V8QI 0 "register_operand" "=r") 6336404b540aSrobert (umax:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW") 6337404b540aSrobert (match_operand:V8QI 2 "reg_or_0_operand" "rW")))] 6338404b540aSrobert "TARGET_MAX" 6339404b540aSrobert "maxub8 %r1,%r2,%0" 6340404b540aSrobert [(set_attr "type" "mvi")]) 6341404b540aSrobert 6342404b540aSrobert(define_insn "smaxv8qi3" 6343404b540aSrobert [(set (match_operand:V8QI 0 "register_operand" "=r") 6344404b540aSrobert (smax:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW") 6345404b540aSrobert (match_operand:V8QI 2 "reg_or_0_operand" "rW")))] 6346404b540aSrobert "TARGET_MAX" 6347404b540aSrobert "maxsb8 %r1,%r2,%0" 6348404b540aSrobert [(set_attr "type" "mvi")]) 6349404b540aSrobert 6350404b540aSrobert(define_insn "umaxv4hi3" 6351404b540aSrobert [(set (match_operand:V4HI 0 "register_operand" "=r") 6352404b540aSrobert (umax:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW") 6353404b540aSrobert (match_operand:V4HI 2 "reg_or_0_operand" "rW")))] 6354404b540aSrobert "TARGET_MAX" 6355404b540aSrobert "maxuw4 %r1,%r2,%0" 6356404b540aSrobert [(set_attr "type" "mvi")]) 6357404b540aSrobert 6358404b540aSrobert(define_insn "smaxv4hi3" 6359404b540aSrobert [(set (match_operand:V4HI 0 "register_operand" "=r") 6360404b540aSrobert (smax:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW") 6361404b540aSrobert (match_operand:V4HI 2 "reg_or_0_operand" "rW")))] 6362404b540aSrobert "TARGET_MAX" 6363404b540aSrobert "maxsw4 %r1,%r2,%0" 6364404b540aSrobert [(set_attr "type" "mvi")]) 6365404b540aSrobert 6366404b540aSrobert(define_insn "one_cmpl<mode>2" 6367404b540aSrobert [(set (match_operand:VEC 0 "register_operand" "=r") 6368404b540aSrobert (not:VEC (match_operand:VEC 1 "register_operand" "r")))] 6369404b540aSrobert "" 6370404b540aSrobert "ornot $31,%1,%0" 6371404b540aSrobert [(set_attr "type" "ilog")]) 6372404b540aSrobert 6373404b540aSrobert(define_insn "and<mode>3" 6374404b540aSrobert [(set (match_operand:VEC 0 "register_operand" "=r") 6375404b540aSrobert (and:VEC (match_operand:VEC 1 "register_operand" "r") 6376404b540aSrobert (match_operand:VEC 2 "register_operand" "r")))] 6377404b540aSrobert "" 6378404b540aSrobert "and %1,%2,%0" 6379404b540aSrobert [(set_attr "type" "ilog")]) 6380404b540aSrobert 6381404b540aSrobert(define_insn "*andnot<mode>3" 6382404b540aSrobert [(set (match_operand:VEC 0 "register_operand" "=r") 6383404b540aSrobert (and:VEC (not:VEC (match_operand:VEC 1 "register_operand" "r")) 6384404b540aSrobert (match_operand:VEC 2 "register_operand" "r")))] 6385404b540aSrobert "" 6386404b540aSrobert "bic %2,%1,%0" 6387404b540aSrobert [(set_attr "type" "ilog")]) 6388404b540aSrobert 6389404b540aSrobert(define_insn "ior<mode>3" 6390404b540aSrobert [(set (match_operand:VEC 0 "register_operand" "=r") 6391404b540aSrobert (ior:VEC (match_operand:VEC 1 "register_operand" "r") 6392404b540aSrobert (match_operand:VEC 2 "register_operand" "r")))] 6393404b540aSrobert "" 6394404b540aSrobert "bis %1,%2,%0" 6395404b540aSrobert [(set_attr "type" "ilog")]) 6396404b540aSrobert 6397404b540aSrobert(define_insn "*iornot<mode>3" 6398404b540aSrobert [(set (match_operand:VEC 0 "register_operand" "=r") 6399404b540aSrobert (ior:VEC (not:DI (match_operand:VEC 1 "register_operand" "r")) 6400404b540aSrobert (match_operand:VEC 2 "register_operand" "r")))] 6401404b540aSrobert "" 6402404b540aSrobert "ornot %2,%1,%0" 6403404b540aSrobert [(set_attr "type" "ilog")]) 6404404b540aSrobert 6405404b540aSrobert(define_insn "xor<mode>3" 6406404b540aSrobert [(set (match_operand:VEC 0 "register_operand" "=r") 6407404b540aSrobert (xor:VEC (match_operand:VEC 1 "register_operand" "r") 6408404b540aSrobert (match_operand:VEC 2 "register_operand" "r")))] 6409404b540aSrobert "" 6410404b540aSrobert "xor %1,%2,%0" 6411404b540aSrobert [(set_attr "type" "ilog")]) 6412404b540aSrobert 6413404b540aSrobert(define_insn "*xornot<mode>3" 6414404b540aSrobert [(set (match_operand:VEC 0 "register_operand" "=r") 6415404b540aSrobert (not:VEC (xor:VEC (match_operand:VEC 1 "register_operand" "r") 6416404b540aSrobert (match_operand:VEC 2 "register_operand" "r"))))] 6417404b540aSrobert "" 6418404b540aSrobert "eqv %1,%2,%0" 6419404b540aSrobert [(set_attr "type" "ilog")]) 6420404b540aSrobert 6421404b540aSrobert(define_expand "vec_shl_<mode>" 6422404b540aSrobert [(set (match_operand:VEC 0 "register_operand" "") 6423404b540aSrobert (ashift:DI (match_operand:VEC 1 "register_operand" "") 6424404b540aSrobert (match_operand:DI 2 "reg_or_6bit_operand" "")))] 6425404b540aSrobert "" 6426404b540aSrobert{ 6427404b540aSrobert operands[0] = gen_lowpart (DImode, operands[0]); 6428404b540aSrobert operands[1] = gen_lowpart (DImode, operands[1]); 6429404b540aSrobert}) 6430404b540aSrobert 6431404b540aSrobert(define_expand "vec_shr_<mode>" 6432404b540aSrobert [(set (match_operand:VEC 0 "register_operand" "") 6433404b540aSrobert (lshiftrt:DI (match_operand:VEC 1 "register_operand" "") 6434404b540aSrobert (match_operand:DI 2 "reg_or_6bit_operand" "")))] 6435404b540aSrobert "" 6436404b540aSrobert{ 6437404b540aSrobert operands[0] = gen_lowpart (DImode, operands[0]); 6438404b540aSrobert operands[1] = gen_lowpart (DImode, operands[1]); 6439404b540aSrobert}) 6440404b540aSrobert 6441404b540aSrobert;; Bit field extract patterns which use ext[wlq][lh] 6442404b540aSrobert 6443404b540aSrobert(define_expand "extv" 6444404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 6445404b540aSrobert (sign_extract:DI (match_operand:QI 1 "memory_operand" "") 6446404b540aSrobert (match_operand:DI 2 "immediate_operand" "") 6447404b540aSrobert (match_operand:DI 3 "immediate_operand" "")))] 6448404b540aSrobert "" 6449404b540aSrobert{ 6450404b540aSrobert int ofs; 6451404b540aSrobert 6452404b540aSrobert /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */ 6453404b540aSrobert if (INTVAL (operands[3]) % 8 != 0 6454404b540aSrobert || (INTVAL (operands[2]) != 16 6455404b540aSrobert && INTVAL (operands[2]) != 32 6456404b540aSrobert && INTVAL (operands[2]) != 64)) 6457404b540aSrobert FAIL; 6458404b540aSrobert 6459404b540aSrobert /* From mips.md: extract_bit_field doesn't verify that our source 6460404b540aSrobert matches the predicate, so we force it to be a MEM here. */ 6461404b540aSrobert if (GET_CODE (operands[1]) != MEM) 6462404b540aSrobert FAIL; 6463404b540aSrobert 6464404b540aSrobert /* The bit number is relative to the mode of operand 1 which is 6465404b540aSrobert usually QImode (this might actually be a bug in expmed.c). Note 6466404b540aSrobert that the bit number is negative in big-endian mode in this case. 6467404b540aSrobert We have to convert that to the offset. */ 6468404b540aSrobert if (WORDS_BIG_ENDIAN) 6469404b540aSrobert ofs = GET_MODE_BITSIZE (GET_MODE (operands[1])) 6470404b540aSrobert - INTVAL (operands[2]) - INTVAL (operands[3]); 6471404b540aSrobert else 6472404b540aSrobert ofs = INTVAL (operands[3]); 6473404b540aSrobert 6474404b540aSrobert ofs = ofs / 8; 6475404b540aSrobert 6476404b540aSrobert alpha_expand_unaligned_load (operands[0], operands[1], 6477404b540aSrobert INTVAL (operands[2]) / 8, 6478404b540aSrobert ofs, 1); 6479404b540aSrobert DONE; 6480404b540aSrobert}) 6481404b540aSrobert 6482404b540aSrobert(define_expand "extzv" 6483404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 6484404b540aSrobert (zero_extract:DI (match_operand:DI 1 "nonimmediate_operand" "") 6485404b540aSrobert (match_operand:DI 2 "immediate_operand" "") 6486404b540aSrobert (match_operand:DI 3 "immediate_operand" "")))] 6487404b540aSrobert "" 6488404b540aSrobert{ 6489404b540aSrobert /* We can do 8, 16, 32 and 64 bit fields, if aligned on byte boundaries. */ 6490404b540aSrobert if (INTVAL (operands[3]) % 8 != 0 6491404b540aSrobert || (INTVAL (operands[2]) != 8 6492404b540aSrobert && INTVAL (operands[2]) != 16 6493404b540aSrobert && INTVAL (operands[2]) != 32 6494404b540aSrobert && INTVAL (operands[2]) != 64)) 6495404b540aSrobert FAIL; 6496404b540aSrobert 6497404b540aSrobert if (GET_CODE (operands[1]) == MEM) 6498404b540aSrobert { 6499404b540aSrobert int ofs; 6500404b540aSrobert 6501404b540aSrobert /* Fail 8 bit fields, falling back on a simple byte load. */ 6502404b540aSrobert if (INTVAL (operands[2]) == 8) 6503404b540aSrobert FAIL; 6504404b540aSrobert 6505404b540aSrobert /* The bit number is relative to the mode of operand 1 which is 6506404b540aSrobert usually QImode (this might actually be a bug in expmed.c). Note 6507404b540aSrobert that the bit number is negative in big-endian mode in this case. 6508404b540aSrobert We have to convert that to the offset. */ 6509404b540aSrobert if (WORDS_BIG_ENDIAN) 6510404b540aSrobert ofs = GET_MODE_BITSIZE (GET_MODE (operands[1])) 6511404b540aSrobert - INTVAL (operands[2]) - INTVAL (operands[3]); 6512404b540aSrobert else 6513404b540aSrobert ofs = INTVAL (operands[3]); 6514404b540aSrobert 6515404b540aSrobert ofs = ofs / 8; 6516404b540aSrobert 6517404b540aSrobert alpha_expand_unaligned_load (operands[0], operands[1], 6518404b540aSrobert INTVAL (operands[2]) / 8, 6519404b540aSrobert ofs, 0); 6520404b540aSrobert DONE; 6521404b540aSrobert } 6522404b540aSrobert}) 6523404b540aSrobert 6524404b540aSrobert(define_expand "insv" 6525404b540aSrobert [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "") 6526404b540aSrobert (match_operand:DI 1 "immediate_operand" "") 6527404b540aSrobert (match_operand:DI 2 "immediate_operand" "")) 6528404b540aSrobert (match_operand:DI 3 "register_operand" ""))] 6529404b540aSrobert "" 6530404b540aSrobert{ 6531404b540aSrobert int ofs; 6532404b540aSrobert 6533404b540aSrobert /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */ 6534404b540aSrobert if (INTVAL (operands[2]) % 8 != 0 6535404b540aSrobert || (INTVAL (operands[1]) != 16 6536404b540aSrobert && INTVAL (operands[1]) != 32 6537404b540aSrobert && INTVAL (operands[1]) != 64)) 6538404b540aSrobert FAIL; 6539404b540aSrobert 6540404b540aSrobert /* From mips.md: store_bit_field doesn't verify that our source 6541404b540aSrobert matches the predicate, so we force it to be a MEM here. */ 6542404b540aSrobert if (GET_CODE (operands[0]) != MEM) 6543404b540aSrobert FAIL; 6544404b540aSrobert 6545404b540aSrobert /* The bit number is relative to the mode of operand 1 which is 6546404b540aSrobert usually QImode (this might actually be a bug in expmed.c). Note 6547404b540aSrobert that the bit number is negative in big-endian mode in this case. 6548404b540aSrobert We have to convert that to the offset. */ 6549404b540aSrobert if (WORDS_BIG_ENDIAN) 6550404b540aSrobert ofs = GET_MODE_BITSIZE (GET_MODE (operands[0])) 6551404b540aSrobert - INTVAL (operands[1]) - INTVAL (operands[2]); 6552404b540aSrobert else 6553404b540aSrobert ofs = INTVAL (operands[2]); 6554404b540aSrobert 6555404b540aSrobert ofs = ofs / 8; 6556404b540aSrobert 6557404b540aSrobert alpha_expand_unaligned_store (operands[0], operands[3], 6558404b540aSrobert INTVAL (operands[1]) / 8, ofs); 6559404b540aSrobert DONE; 6560404b540aSrobert}) 6561404b540aSrobert 6562404b540aSrobert;; Block move/clear, see alpha.c for more details. 6563404b540aSrobert;; Argument 0 is the destination 6564404b540aSrobert;; Argument 1 is the source 6565404b540aSrobert;; Argument 2 is the length 6566404b540aSrobert;; Argument 3 is the alignment 6567404b540aSrobert 6568404b540aSrobert(define_expand "movmemqi" 6569404b540aSrobert [(parallel [(set (match_operand:BLK 0 "memory_operand" "") 6570404b540aSrobert (match_operand:BLK 1 "memory_operand" "")) 6571404b540aSrobert (use (match_operand:DI 2 "immediate_operand" "")) 6572404b540aSrobert (use (match_operand:DI 3 "immediate_operand" ""))])] 6573404b540aSrobert "" 6574404b540aSrobert{ 6575404b540aSrobert if (alpha_expand_block_move (operands)) 6576404b540aSrobert DONE; 6577404b540aSrobert else 6578404b540aSrobert FAIL; 6579404b540aSrobert}) 6580404b540aSrobert 6581404b540aSrobert(define_expand "movmemdi" 6582404b540aSrobert [(parallel [(set (match_operand:BLK 0 "memory_operand" "") 6583404b540aSrobert (match_operand:BLK 1 "memory_operand" "")) 6584404b540aSrobert (use (match_operand:DI 2 "immediate_operand" "")) 6585404b540aSrobert (use (match_operand:DI 3 "immediate_operand" "")) 6586404b540aSrobert (use (match_dup 4)) 6587404b540aSrobert (clobber (reg:DI 25)) 6588404b540aSrobert (clobber (reg:DI 16)) 6589404b540aSrobert (clobber (reg:DI 17)) 6590404b540aSrobert (clobber (reg:DI 18)) 6591404b540aSrobert (clobber (reg:DI 19)) 6592404b540aSrobert (clobber (reg:DI 20)) 6593404b540aSrobert (clobber (reg:DI 26)) 6594404b540aSrobert (clobber (reg:DI 27))])] 6595404b540aSrobert "TARGET_ABI_OPEN_VMS" 6596404b540aSrobert{ 6597404b540aSrobert operands[4] = gen_rtx_SYMBOL_REF (Pmode, "OTS$MOVE"); 6598404b540aSrobert alpha_need_linkage (XSTR (operands[4], 0), 0); 6599404b540aSrobert}) 6600404b540aSrobert 6601404b540aSrobert(define_insn "*movmemdi_1" 6602404b540aSrobert [(set (match_operand:BLK 0 "memory_operand" "=m,=m") 6603404b540aSrobert (match_operand:BLK 1 "memory_operand" "m,m")) 6604404b540aSrobert (use (match_operand:DI 2 "nonmemory_operand" "r,i")) 6605404b540aSrobert (use (match_operand:DI 3 "immediate_operand" "")) 6606404b540aSrobert (use (match_operand:DI 4 "call_operand" "i,i")) 6607404b540aSrobert (clobber (reg:DI 25)) 6608404b540aSrobert (clobber (reg:DI 16)) 6609404b540aSrobert (clobber (reg:DI 17)) 6610404b540aSrobert (clobber (reg:DI 18)) 6611404b540aSrobert (clobber (reg:DI 19)) 6612404b540aSrobert (clobber (reg:DI 20)) 6613404b540aSrobert (clobber (reg:DI 26)) 6614404b540aSrobert (clobber (reg:DI 27))] 6615404b540aSrobert "TARGET_ABI_OPEN_VMS" 6616404b540aSrobert{ 6617404b540aSrobert operands [5] = alpha_use_linkage (operands [4], cfun->decl, 0, 1); 6618404b540aSrobert switch (which_alternative) 6619404b540aSrobert { 6620404b540aSrobert case 0: 6621404b540aSrobert return "lda $16,%0\;bis $31,%2,$17\;lda $18,%1\;ldq $26,%5\;lda $25,3($31)\;jsr $26,%4\;ldq $27,0($29)"; 6622404b540aSrobert case 1: 6623404b540aSrobert 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)"; 6624404b540aSrobert default: 6625404b540aSrobert gcc_unreachable (); 6626404b540aSrobert } 6627404b540aSrobert} 6628404b540aSrobert [(set_attr "type" "multi") 6629404b540aSrobert (set_attr "length" "28")]) 6630404b540aSrobert 6631404b540aSrobert(define_expand "setmemqi" 6632404b540aSrobert [(parallel [(set (match_operand:BLK 0 "memory_operand" "") 6633404b540aSrobert (match_operand 2 "const_int_operand" "")) 6634404b540aSrobert (use (match_operand:DI 1 "immediate_operand" "")) 6635404b540aSrobert (use (match_operand:DI 3 "immediate_operand" ""))])] 6636404b540aSrobert "" 6637404b540aSrobert{ 6638404b540aSrobert /* If value to set is not zero, use the library routine. */ 6639404b540aSrobert if (operands[2] != const0_rtx) 6640404b540aSrobert FAIL; 6641404b540aSrobert 6642404b540aSrobert if (alpha_expand_block_clear (operands)) 6643404b540aSrobert DONE; 6644404b540aSrobert else 6645404b540aSrobert FAIL; 6646404b540aSrobert}) 6647404b540aSrobert 6648404b540aSrobert(define_expand "setmemdi" 6649404b540aSrobert [(parallel [(set (match_operand:BLK 0 "memory_operand" "") 6650404b540aSrobert (match_operand 2 "const_int_operand" "")) 6651404b540aSrobert (use (match_operand:DI 1 "immediate_operand" "")) 6652404b540aSrobert (use (match_operand:DI 3 "immediate_operand" "")) 6653404b540aSrobert (use (match_dup 4)) 6654404b540aSrobert (clobber (reg:DI 25)) 6655404b540aSrobert (clobber (reg:DI 16)) 6656404b540aSrobert (clobber (reg:DI 17)) 6657404b540aSrobert (clobber (reg:DI 26)) 6658404b540aSrobert (clobber (reg:DI 27))])] 6659404b540aSrobert "TARGET_ABI_OPEN_VMS" 6660404b540aSrobert{ 6661404b540aSrobert /* If value to set is not zero, use the library routine. */ 6662404b540aSrobert if (operands[2] != const0_rtx) 6663404b540aSrobert FAIL; 6664404b540aSrobert 6665404b540aSrobert operands[4] = gen_rtx_SYMBOL_REF (Pmode, "OTS$ZERO"); 6666404b540aSrobert alpha_need_linkage (XSTR (operands[4], 0), 0); 6667404b540aSrobert}) 6668404b540aSrobert 6669404b540aSrobert(define_insn "*clrmemdi_1" 6670404b540aSrobert [(set (match_operand:BLK 0 "memory_operand" "=m,=m") 6671404b540aSrobert (const_int 0)) 6672404b540aSrobert (use (match_operand:DI 1 "nonmemory_operand" "r,i")) 6673404b540aSrobert (use (match_operand:DI 2 "immediate_operand" "")) 6674404b540aSrobert (use (match_operand:DI 3 "call_operand" "i,i")) 6675404b540aSrobert (clobber (reg:DI 25)) 6676404b540aSrobert (clobber (reg:DI 16)) 6677404b540aSrobert (clobber (reg:DI 17)) 6678404b540aSrobert (clobber (reg:DI 26)) 6679404b540aSrobert (clobber (reg:DI 27))] 6680404b540aSrobert "TARGET_ABI_OPEN_VMS" 6681404b540aSrobert{ 6682404b540aSrobert operands [4] = alpha_use_linkage (operands [3], cfun->decl, 0, 1); 6683404b540aSrobert switch (which_alternative) 6684404b540aSrobert { 6685404b540aSrobert case 0: 6686404b540aSrobert return "lda $16,%0\;bis $31,%1,$17\;ldq $26,%4\;lda $25,2($31)\;jsr $26,%3\;ldq $27,0($29)"; 6687404b540aSrobert case 1: 6688404b540aSrobert return "lda $16,%0\;lda $17,%1($31)\;ldq $26,%4\;lda $25,2($31)\;jsr $26,%3\;ldq $27,0($29)"; 6689404b540aSrobert default: 6690404b540aSrobert gcc_unreachable (); 6691404b540aSrobert } 6692404b540aSrobert} 6693404b540aSrobert [(set_attr "type" "multi") 6694404b540aSrobert (set_attr "length" "24")]) 6695404b540aSrobert 6696404b540aSrobert 6697404b540aSrobert;; Subroutine of stack space allocation. Perform a stack probe. 6698404b540aSrobert(define_expand "probe_stack" 6699404b540aSrobert [(set (match_dup 1) (match_operand:DI 0 "const_int_operand" ""))] 6700404b540aSrobert "" 6701404b540aSrobert{ 6702404b540aSrobert operands[1] = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 6703404b540aSrobert INTVAL (operands[0]))); 6704404b540aSrobert MEM_VOLATILE_P (operands[1]) = 1; 6705404b540aSrobert 6706404b540aSrobert operands[0] = const0_rtx; 6707404b540aSrobert}) 6708404b540aSrobert 6709404b540aSrobert;; This is how we allocate stack space. If we are allocating a 6710404b540aSrobert;; constant amount of space and we know it is less than 4096 6711404b540aSrobert;; bytes, we need do nothing. 6712404b540aSrobert;; 6713404b540aSrobert;; If it is more than 4096 bytes, we need to probe the stack 6714404b540aSrobert;; periodically. 6715404b540aSrobert(define_expand "allocate_stack" 6716404b540aSrobert [(set (reg:DI 30) 6717404b540aSrobert (plus:DI (reg:DI 30) 6718404b540aSrobert (match_operand:DI 1 "reg_or_cint_operand" ""))) 6719404b540aSrobert (set (match_operand:DI 0 "register_operand" "=r") 6720404b540aSrobert (match_dup 2))] 6721404b540aSrobert "" 6722404b540aSrobert{ 6723404b540aSrobert if (GET_CODE (operands[1]) == CONST_INT 6724404b540aSrobert && INTVAL (operands[1]) < 32768) 6725404b540aSrobert { 6726f462341cSnaddy if (INTVAL (operands[1]) >= 4096 6727f462341cSnaddy && (flag_stack_check || STACK_CHECK_BUILTIN)) 6728404b540aSrobert { 6729404b540aSrobert /* We do this the same way as in the prologue and generate explicit 6730404b540aSrobert probes. Then we update the stack by the constant. */ 6731404b540aSrobert 6732404b540aSrobert int probed = 4096; 6733404b540aSrobert 6734404b540aSrobert emit_insn (gen_probe_stack (GEN_INT (- probed))); 6735404b540aSrobert while (probed + 8192 < INTVAL (operands[1])) 6736404b540aSrobert emit_insn (gen_probe_stack (GEN_INT (- (probed += 8192)))); 6737404b540aSrobert 6738404b540aSrobert if (probed + 4096 < INTVAL (operands[1])) 6739404b540aSrobert emit_insn (gen_probe_stack (GEN_INT (- INTVAL(operands[1])))); 6740404b540aSrobert } 6741404b540aSrobert 6742404b540aSrobert operands[1] = GEN_INT (- INTVAL (operands[1])); 6743404b540aSrobert operands[2] = virtual_stack_dynamic_rtx; 6744404b540aSrobert } 6745404b540aSrobert else 6746404b540aSrobert { 6747404b540aSrobert rtx out_label = 0; 6748404b540aSrobert rtx loop_label = gen_label_rtx (); 6749404b540aSrobert rtx want = gen_reg_rtx (Pmode); 6750404b540aSrobert rtx tmp = gen_reg_rtx (Pmode); 6751404b540aSrobert rtx memref; 6752404b540aSrobert 6753404b540aSrobert emit_insn (gen_subdi3 (want, stack_pointer_rtx, 6754404b540aSrobert force_reg (Pmode, operands[1]))); 6755404b540aSrobert emit_insn (gen_adddi3 (tmp, stack_pointer_rtx, GEN_INT (-4096))); 6756404b540aSrobert 6757404b540aSrobert if (GET_CODE (operands[1]) != CONST_INT) 6758404b540aSrobert { 6759404b540aSrobert out_label = gen_label_rtx (); 6760404b540aSrobert emit_insn (gen_cmpdi (want, tmp)); 6761404b540aSrobert emit_jump_insn (gen_bgeu (out_label)); 6762404b540aSrobert } 6763404b540aSrobert 6764404b540aSrobert emit_label (loop_label); 6765404b540aSrobert memref = gen_rtx_MEM (DImode, tmp); 6766404b540aSrobert MEM_VOLATILE_P (memref) = 1; 6767404b540aSrobert emit_move_insn (memref, const0_rtx); 6768404b540aSrobert emit_insn (gen_adddi3 (tmp, tmp, GEN_INT(-8192))); 6769404b540aSrobert emit_insn (gen_cmpdi (tmp, want)); 6770404b540aSrobert emit_jump_insn (gen_bgtu (loop_label)); 6771404b540aSrobert 6772404b540aSrobert memref = gen_rtx_MEM (DImode, want); 6773404b540aSrobert MEM_VOLATILE_P (memref) = 1; 6774404b540aSrobert emit_move_insn (memref, const0_rtx); 6775404b540aSrobert 6776404b540aSrobert if (out_label) 6777404b540aSrobert emit_label (out_label); 6778404b540aSrobert 6779404b540aSrobert emit_move_insn (stack_pointer_rtx, want); 6780404b540aSrobert emit_move_insn (operands[0], virtual_stack_dynamic_rtx); 6781404b540aSrobert DONE; 6782404b540aSrobert } 6783404b540aSrobert}) 6784404b540aSrobert 6785404b540aSrobert;; This is used by alpha_expand_prolog to do the same thing as above, 6786404b540aSrobert;; except we cannot at that time generate new basic blocks, so we hide 6787404b540aSrobert;; the loop in this one insn. 6788404b540aSrobert 6789404b540aSrobert(define_insn "prologue_stack_probe_loop" 6790404b540aSrobert [(unspec_volatile [(match_operand:DI 0 "register_operand" "r") 6791404b540aSrobert (match_operand:DI 1 "register_operand" "r")] 6792404b540aSrobert UNSPECV_PSPL)] 6793404b540aSrobert "" 6794404b540aSrobert{ 6795404b540aSrobert operands[2] = gen_label_rtx (); 6796404b540aSrobert (*targetm.asm_out.internal_label) (asm_out_file, "L", 6797404b540aSrobert CODE_LABEL_NUMBER (operands[2])); 6798404b540aSrobert 6799404b540aSrobert return "stq $31,-8192(%1)\;subq %0,1,%0\;lda %1,-8192(%1)\;bne %0,%l2"; 6800404b540aSrobert} 6801404b540aSrobert [(set_attr "length" "16") 6802404b540aSrobert (set_attr "type" "multi")]) 6803404b540aSrobert 6804404b540aSrobert(define_expand "prologue" 6805404b540aSrobert [(clobber (const_int 0))] 6806404b540aSrobert "" 6807404b540aSrobert{ 6808404b540aSrobert alpha_expand_prologue (); 6809404b540aSrobert DONE; 6810404b540aSrobert}) 6811404b540aSrobert 6812404b540aSrobert;; These take care of emitting the ldgp insn in the prologue. This will be 6813404b540aSrobert;; an lda/ldah pair and we want to align them properly. So we have two 6814404b540aSrobert;; unspec_volatile insns, the first of which emits the ldgp assembler macro 6815404b540aSrobert;; and the second of which emits nothing. However, both are marked as type 6816404b540aSrobert;; IADD (the default) so the alignment code in alpha.c does the right thing 6817404b540aSrobert;; with them. 6818404b540aSrobert 6819404b540aSrobert(define_expand "prologue_ldgp" 6820404b540aSrobert [(set (match_dup 0) 6821404b540aSrobert (unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1)) 6822404b540aSrobert (set (match_dup 0) 6823404b540aSrobert (unspec_volatile:DI [(match_dup 0) (match_dup 2)] UNSPECV_PLDGP2))] 6824404b540aSrobert "" 6825404b540aSrobert{ 6826404b540aSrobert operands[0] = pic_offset_table_rtx; 6827404b540aSrobert operands[1] = gen_rtx_REG (Pmode, 27); 6828404b540aSrobert operands[2] = (TARGET_EXPLICIT_RELOCS 6829404b540aSrobert ? GEN_INT (alpha_next_sequence_number++) 6830404b540aSrobert : const0_rtx); 6831404b540aSrobert}) 6832404b540aSrobert 6833404b540aSrobert(define_insn "*ldgp_er_1" 6834404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 6835404b540aSrobert (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r") 6836404b540aSrobert (match_operand 2 "const_int_operand" "")] 6837404b540aSrobert UNSPECV_LDGP1))] 6838404b540aSrobert "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" 6839404b540aSrobert "ldah %0,0(%1)\t\t!gpdisp!%2" 6840404b540aSrobert [(set_attr "cannot_copy" "true")]) 6841404b540aSrobert 6842404b540aSrobert(define_insn "*ldgp_er_2" 6843404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 6844404b540aSrobert (unspec:DI [(match_operand:DI 1 "register_operand" "r") 6845404b540aSrobert (match_operand 2 "const_int_operand" "")] 6846404b540aSrobert UNSPEC_LDGP2))] 6847404b540aSrobert "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" 6848404b540aSrobert "lda %0,0(%1)\t\t!gpdisp!%2" 6849404b540aSrobert [(set_attr "cannot_copy" "true")]) 6850404b540aSrobert 6851404b540aSrobert(define_insn "*prologue_ldgp_er_2" 6852404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 6853404b540aSrobert (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r") 6854404b540aSrobert (match_operand 2 "const_int_operand" "")] 6855404b540aSrobert UNSPECV_PLDGP2))] 6856404b540aSrobert "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" 6857404b540aSrobert "lda %0,0(%1)\t\t!gpdisp!%2\n$%~..ng:" 6858404b540aSrobert [(set_attr "cannot_copy" "true")]) 6859404b540aSrobert 6860404b540aSrobert(define_insn "*prologue_ldgp_1" 6861404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 6862404b540aSrobert (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r") 6863404b540aSrobert (match_operand 2 "const_int_operand" "")] 6864404b540aSrobert UNSPECV_LDGP1))] 6865404b540aSrobert "" 6866404b540aSrobert "ldgp %0,0(%1)\n$%~..ng:" 6867404b540aSrobert [(set_attr "cannot_copy" "true")]) 6868404b540aSrobert 6869404b540aSrobert(define_insn "*prologue_ldgp_2" 6870404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 6871404b540aSrobert (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r") 6872404b540aSrobert (match_operand 2 "const_int_operand" "")] 6873404b540aSrobert UNSPECV_PLDGP2))] 6874404b540aSrobert "" 6875404b540aSrobert "") 6876404b540aSrobert 6877404b540aSrobert;; The _mcount profiling hook has special calling conventions, and 6878404b540aSrobert;; does not clobber all the registers that a normal call would. So 6879404b540aSrobert;; hide the fact this is a call at all. 6880404b540aSrobert 6881404b540aSrobert(define_insn "prologue_mcount" 6882404b540aSrobert [(unspec_volatile [(const_int 0)] UNSPECV_MCOUNT)] 6883404b540aSrobert "" 6884404b540aSrobert{ 6885404b540aSrobert if (TARGET_EXPLICIT_RELOCS) 6886404b540aSrobert /* Note that we cannot use a lituse_jsr reloc, since _mcount 6887404b540aSrobert cannot be called via the PLT. */ 6888404b540aSrobert return "ldq $28,_mcount($29)\t\t!literal\;jsr $28,($28),_mcount"; 6889404b540aSrobert else 6890404b540aSrobert return "lda $28,_mcount\;jsr $28,($28),_mcount"; 6891404b540aSrobert} 6892404b540aSrobert [(set_attr "type" "multi") 6893404b540aSrobert (set_attr "length" "8")]) 6894404b540aSrobert 6895404b540aSrobert(define_insn "init_fp" 6896404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 6897404b540aSrobert (match_operand:DI 1 "register_operand" "r")) 6898404b540aSrobert (clobber (mem:BLK (match_operand:DI 2 "register_operand" "=r")))] 6899404b540aSrobert "" 6900404b540aSrobert "bis $31,%1,%0") 6901404b540aSrobert 6902404b540aSrobert(define_expand "epilogue" 6903404b540aSrobert [(return)] 6904404b540aSrobert "" 6905404b540aSrobert{ 6906404b540aSrobert alpha_expand_epilogue (); 6907404b540aSrobert}) 6908404b540aSrobert 6909404b540aSrobert(define_expand "sibcall_epilogue" 6910404b540aSrobert [(return)] 6911404b540aSrobert "TARGET_ABI_OSF" 6912404b540aSrobert{ 6913404b540aSrobert alpha_expand_epilogue (); 6914404b540aSrobert DONE; 6915404b540aSrobert}) 6916404b540aSrobert 6917404b540aSrobert(define_expand "builtin_longjmp" 6918404b540aSrobert [(use (match_operand:DI 0 "register_operand" "r"))] 6919404b540aSrobert "TARGET_ABI_OSF" 6920404b540aSrobert{ 6921404b540aSrobert /* The elements of the buffer are, in order: */ 6922404b540aSrobert rtx fp = gen_rtx_MEM (Pmode, operands[0]); 6923404b540aSrobert rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 8)); 6924404b540aSrobert rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 16)); 6925404b540aSrobert rtx pv = gen_rtx_REG (Pmode, 27); 6926404b540aSrobert 6927404b540aSrobert /* This bit is the same as expand_builtin_longjmp. */ 6928404b540aSrobert emit_move_insn (hard_frame_pointer_rtx, fp); 6929404b540aSrobert emit_move_insn (pv, lab); 6930404b540aSrobert emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX); 6931404b540aSrobert emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx)); 6932404b540aSrobert emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx)); 6933404b540aSrobert 6934404b540aSrobert /* Load the label we are jumping through into $27 so that we know 6935404b540aSrobert where to look for it when we get back to setjmp's function for 6936404b540aSrobert restoring the gp. */ 6937404b540aSrobert emit_jump_insn (gen_builtin_longjmp_internal (pv)); 6938404b540aSrobert emit_barrier (); 6939404b540aSrobert DONE; 6940404b540aSrobert}) 6941404b540aSrobert 6942404b540aSrobert;; This is effectively a copy of indirect_jump, but constrained such 6943404b540aSrobert;; that register renaming cannot foil our cunning plan with $27. 6944404b540aSrobert(define_insn "builtin_longjmp_internal" 6945404b540aSrobert [(set (pc) 6946404b540aSrobert (unspec_volatile [(match_operand:DI 0 "register_operand" "c")] 6947404b540aSrobert UNSPECV_LONGJMP))] 6948404b540aSrobert "" 6949404b540aSrobert "jmp $31,(%0),0" 6950404b540aSrobert [(set_attr "type" "ibr")]) 6951404b540aSrobert 6952404b540aSrobert(define_expand "builtin_setjmp_receiver" 6953404b540aSrobert [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)] 6954404b540aSrobert "TARGET_ABI_OSF" 6955404b540aSrobert "") 6956404b540aSrobert 6957404b540aSrobert(define_insn_and_split "*builtin_setjmp_receiver_1" 6958404b540aSrobert [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR)] 6959404b540aSrobert "TARGET_ABI_OSF" 6960404b540aSrobert{ 6961404b540aSrobert if (TARGET_EXPLICIT_RELOCS) 6962404b540aSrobert return "#"; 6963404b540aSrobert else 6964404b540aSrobert return "br $27,$LSJ%=\n$LSJ%=:\;ldgp $29,0($27)"; 6965404b540aSrobert} 6966404b540aSrobert "&& TARGET_EXPLICIT_RELOCS && reload_completed" 6967404b540aSrobert [(set (match_dup 1) 6968404b540aSrobert (unspec_volatile:DI [(match_dup 2) (match_dup 3)] UNSPECV_LDGP1)) 6969404b540aSrobert (set (match_dup 1) 6970404b540aSrobert (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_LDGP2))] 6971404b540aSrobert{ 6972404b540aSrobert if (prev_nonnote_insn (curr_insn) != XEXP (operands[0], 0)) 6973404b540aSrobert emit_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, operands[0]), 6974404b540aSrobert UNSPECV_SETJMPR_ER)); 6975404b540aSrobert operands[1] = pic_offset_table_rtx; 6976404b540aSrobert operands[2] = gen_rtx_REG (Pmode, 27); 6977404b540aSrobert operands[3] = GEN_INT (alpha_next_sequence_number++); 6978404b540aSrobert} 6979404b540aSrobert [(set_attr "length" "12") 6980404b540aSrobert (set_attr "type" "multi")]) 6981404b540aSrobert 6982404b540aSrobert(define_insn "*builtin_setjmp_receiver_er_sl_1" 6983404b540aSrobert [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR_ER)] 6984404b540aSrobert "TARGET_ABI_OSF && TARGET_EXPLICIT_RELOCS && TARGET_AS_CAN_SUBTRACT_LABELS" 6985404b540aSrobert "lda $27,$LSJ%=-%l0($27)\n$LSJ%=:") 6986404b540aSrobert 6987404b540aSrobert(define_insn "*builtin_setjmp_receiver_er_1" 6988404b540aSrobert [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR_ER)] 6989404b540aSrobert "TARGET_ABI_OSF && TARGET_EXPLICIT_RELOCS" 6990404b540aSrobert "br $27,$LSJ%=\n$LSJ%=:" 6991404b540aSrobert [(set_attr "type" "ibr")]) 6992404b540aSrobert 6993404b540aSrobert(define_expand "exception_receiver" 6994404b540aSrobert [(unspec_volatile [(match_dup 0)] UNSPECV_EHR)] 6995404b540aSrobert "TARGET_ABI_OSF" 6996404b540aSrobert{ 6997404b540aSrobert if (TARGET_LD_BUGGY_LDGP) 6998404b540aSrobert operands[0] = alpha_gp_save_rtx (); 6999404b540aSrobert else 7000404b540aSrobert operands[0] = const0_rtx; 7001404b540aSrobert}) 7002404b540aSrobert 7003404b540aSrobert(define_insn "*exception_receiver_2" 7004404b540aSrobert [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_EHR)] 7005404b540aSrobert "TARGET_ABI_OSF && TARGET_LD_BUGGY_LDGP" 7006404b540aSrobert "ldq $29,%0" 7007404b540aSrobert [(set_attr "type" "ild")]) 7008404b540aSrobert 7009404b540aSrobert(define_insn_and_split "*exception_receiver_1" 7010404b540aSrobert [(unspec_volatile [(const_int 0)] UNSPECV_EHR)] 7011404b540aSrobert "TARGET_ABI_OSF" 7012404b540aSrobert{ 7013404b540aSrobert if (TARGET_EXPLICIT_RELOCS) 7014404b540aSrobert return "ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*"; 7015404b540aSrobert else 7016404b540aSrobert return "ldgp $29,0($26)"; 7017404b540aSrobert} 7018404b540aSrobert "&& TARGET_EXPLICIT_RELOCS && reload_completed" 7019404b540aSrobert [(set (match_dup 0) 7020404b540aSrobert (unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1)) 7021404b540aSrobert (set (match_dup 0) 7022404b540aSrobert (unspec:DI [(match_dup 0) (match_dup 2)] UNSPEC_LDGP2))] 7023404b540aSrobert{ 7024404b540aSrobert operands[0] = pic_offset_table_rtx; 7025404b540aSrobert operands[1] = gen_rtx_REG (Pmode, 26); 7026404b540aSrobert operands[2] = GEN_INT (alpha_next_sequence_number++); 7027404b540aSrobert} 7028404b540aSrobert [(set_attr "length" "8") 7029404b540aSrobert (set_attr "type" "multi")]) 7030404b540aSrobert 7031404b540aSrobert(define_expand "nonlocal_goto_receiver" 7032404b540aSrobert [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 7033404b540aSrobert (set (reg:DI 27) (mem:DI (reg:DI 29))) 7034404b540aSrobert (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 7035404b540aSrobert (use (reg:DI 27))] 7036404b540aSrobert "TARGET_ABI_OPEN_VMS" 7037404b540aSrobert "") 7038404b540aSrobert 7039404b540aSrobert(define_insn "arg_home" 7040404b540aSrobert [(unspec [(const_int 0)] UNSPEC_ARG_HOME) 7041404b540aSrobert (use (reg:DI 1)) 7042404b540aSrobert (use (reg:DI 25)) 7043404b540aSrobert (use (reg:DI 16)) 7044404b540aSrobert (use (reg:DI 17)) 7045404b540aSrobert (use (reg:DI 18)) 7046404b540aSrobert (use (reg:DI 19)) 7047404b540aSrobert (use (reg:DI 20)) 7048404b540aSrobert (use (reg:DI 21)) 7049404b540aSrobert (use (reg:DI 48)) 7050404b540aSrobert (use (reg:DI 49)) 7051404b540aSrobert (use (reg:DI 50)) 7052404b540aSrobert (use (reg:DI 51)) 7053404b540aSrobert (use (reg:DI 52)) 7054404b540aSrobert (use (reg:DI 53)) 7055404b540aSrobert (clobber (mem:BLK (const_int 0))) 7056404b540aSrobert (clobber (reg:DI 24)) 7057404b540aSrobert (clobber (reg:DI 25)) 7058404b540aSrobert (clobber (reg:DI 0))] 7059404b540aSrobert "TARGET_ABI_OPEN_VMS" 7060404b540aSrobert "lda $0,OTS$HOME_ARGS\;ldq $0,8($0)\;jsr $0,OTS$HOME_ARGS" 7061404b540aSrobert [(set_attr "length" "16") 7062404b540aSrobert (set_attr "type" "multi")]) 7063404b540aSrobert 7064404b540aSrobert;; Load the CIW into r2 for calling __T3E_MISMATCH 7065404b540aSrobert 7066404b540aSrobert(define_expand "umk_mismatch_args" 7067404b540aSrobert [(set:DI (match_dup 1) (mem:DI (plus:DI (reg:DI 15) (const_int -16)))) 7068404b540aSrobert (set:DI (match_dup 2) (mem:DI (plus:DI (match_dup 1) (const_int -32)))) 7069404b540aSrobert (set:DI (reg:DI 1) (match_operand:DI 0 "const_int_operand" "")) 7070404b540aSrobert (set:DI (match_dup 3) (plus:DI (mult:DI (reg:DI 25) 7071404b540aSrobert (const_int 8)) 7072404b540aSrobert (match_dup 2))) 7073404b540aSrobert (set:DI (reg:DI 2) (mem:DI (match_dup 3)))] 7074404b540aSrobert "TARGET_ABI_UNICOSMK" 7075404b540aSrobert{ 7076404b540aSrobert operands[1] = gen_reg_rtx (DImode); 7077404b540aSrobert operands[2] = gen_reg_rtx (DImode); 7078404b540aSrobert operands[3] = gen_reg_rtx (DImode); 7079404b540aSrobert}) 7080404b540aSrobert 7081404b540aSrobert(define_insn "arg_home_umk" 7082404b540aSrobert [(unspec [(const_int 0)] UNSPEC_ARG_HOME) 7083404b540aSrobert (use (reg:DI 1)) 7084404b540aSrobert (use (reg:DI 2)) 7085404b540aSrobert (use (reg:DI 16)) 7086404b540aSrobert (use (reg:DI 17)) 7087404b540aSrobert (use (reg:DI 18)) 7088404b540aSrobert (use (reg:DI 19)) 7089404b540aSrobert (use (reg:DI 20)) 7090404b540aSrobert (use (reg:DI 21)) 7091404b540aSrobert (use (reg:DI 48)) 7092404b540aSrobert (use (reg:DI 49)) 7093404b540aSrobert (use (reg:DI 50)) 7094404b540aSrobert (use (reg:DI 51)) 7095404b540aSrobert (use (reg:DI 52)) 7096404b540aSrobert (use (reg:DI 53)) 7097404b540aSrobert (clobber (mem:BLK (const_int 0))) 7098404b540aSrobert (parallel [ 7099404b540aSrobert (clobber (reg:DI 22)) 7100404b540aSrobert (clobber (reg:DI 23)) 7101404b540aSrobert (clobber (reg:DI 24)) 7102404b540aSrobert (clobber (reg:DI 0)) 7103404b540aSrobert (clobber (reg:DI 1)) 7104404b540aSrobert (clobber (reg:DI 2)) 7105404b540aSrobert (clobber (reg:DI 3)) 7106404b540aSrobert (clobber (reg:DI 4)) 7107404b540aSrobert (clobber (reg:DI 5)) 7108404b540aSrobert (clobber (reg:DI 6)) 7109404b540aSrobert (clobber (reg:DI 7)) 7110404b540aSrobert (clobber (reg:DI 8))])] 7111404b540aSrobert "TARGET_ABI_UNICOSMK" 7112404b540aSrobert "laum $4,__T3E_MISMATCH($31)\;sll $4,32,$4\;lalm $4,__T3E_MISMATCH($4)\;lal $4,__T3E_MISMATCH($4)\;jsr $3,($4)" 7113404b540aSrobert [(set_attr "length" "16") 7114404b540aSrobert (set_attr "type" "multi")]) 7115404b540aSrobert 7116404b540aSrobert;; Prefetch data. 7117404b540aSrobert;; 7118404b540aSrobert;; On EV4, these instructions are nops -- no load occurs. 7119404b540aSrobert;; 7120404b540aSrobert;; On EV5, these instructions act as a normal load, and thus can trap 7121404b540aSrobert;; if the address is invalid. The OS may (or may not) handle this in 7122404b540aSrobert;; the entMM fault handler and suppress the fault. If so, then this 7123404b540aSrobert;; has the effect of a read prefetch instruction. 7124404b540aSrobert;; 7125404b540aSrobert;; On EV6, these become official prefetch instructions. 7126404b540aSrobert 7127404b540aSrobert(define_insn "prefetch" 7128404b540aSrobert [(prefetch (match_operand:DI 0 "address_operand" "p") 7129404b540aSrobert (match_operand:DI 1 "const_int_operand" "n") 7130404b540aSrobert (match_operand:DI 2 "const_int_operand" "n"))] 7131404b540aSrobert "TARGET_FIXUP_EV5_PREFETCH || alpha_cpu == PROCESSOR_EV6" 7132404b540aSrobert{ 7133404b540aSrobert /* Interpret "no temporal locality" as this data should be evicted once 7134404b540aSrobert it is used. The "evict next" alternatives load the data into the cache 7135404b540aSrobert and leave the LRU eviction counter pointing to that block. */ 7136404b540aSrobert static const char * const alt[2][2] = { 7137404b540aSrobert { 7138404b540aSrobert "ldq $31,%a0", /* read, evict next */ 7139404b540aSrobert "ldl $31,%a0", /* read, evict last */ 7140404b540aSrobert }, 7141404b540aSrobert { 7142404b540aSrobert "ldt $f31,%a0", /* write, evict next */ 7143404b540aSrobert "lds $f31,%a0", /* write, evict last */ 7144404b540aSrobert } 7145404b540aSrobert }; 7146404b540aSrobert 7147404b540aSrobert bool write = INTVAL (operands[1]) != 0; 7148404b540aSrobert bool lru = INTVAL (operands[2]) != 0; 7149404b540aSrobert 7150404b540aSrobert return alt[write][lru]; 7151404b540aSrobert} 7152404b540aSrobert [(set_attr "type" "ild")]) 7153404b540aSrobert 7154404b540aSrobert;; Close the trap shadow of preceding instructions. This is generated 7155404b540aSrobert;; by alpha_reorg. 7156404b540aSrobert 7157404b540aSrobert(define_insn "trapb" 7158404b540aSrobert [(unspec_volatile [(const_int 0)] UNSPECV_TRAPB)] 7159404b540aSrobert "" 7160404b540aSrobert "trapb" 7161404b540aSrobert [(set_attr "type" "misc")]) 7162404b540aSrobert 7163404b540aSrobert;; No-op instructions used by machine-dependent reorg to preserve 7164404b540aSrobert;; alignment for instruction issue. 7165404b540aSrobert;; The Unicos/Mk assembler does not support these opcodes. 7166404b540aSrobert 7167404b540aSrobert(define_insn "nop" 7168404b540aSrobert [(const_int 0)] 7169404b540aSrobert "" 7170404b540aSrobert "bis $31,$31,$31" 7171404b540aSrobert [(set_attr "type" "ilog")]) 7172404b540aSrobert 7173404b540aSrobert(define_insn "fnop" 7174404b540aSrobert [(const_int 1)] 7175404b540aSrobert "TARGET_FP" 7176404b540aSrobert "cpys $f31,$f31,$f31" 7177404b540aSrobert [(set_attr "type" "fcpys")]) 7178404b540aSrobert 7179404b540aSrobert(define_insn "unop" 7180404b540aSrobert [(const_int 2)] 7181404b540aSrobert "" 7182404b540aSrobert "ldq_u $31,0($30)") 7183404b540aSrobert 7184404b540aSrobert;; On Unicos/Mk we use a macro for aligning code. 7185404b540aSrobert 7186404b540aSrobert(define_insn "realign" 7187404b540aSrobert [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] 7188404b540aSrobert UNSPECV_REALIGN)] 7189404b540aSrobert "" 7190404b540aSrobert{ 7191404b540aSrobert if (TARGET_ABI_UNICOSMK) 7192404b540aSrobert return "gcc@code@align %0"; 7193404b540aSrobert else 7194404b540aSrobert return ".align %0 #realign"; 7195404b540aSrobert}) 7196404b540aSrobert 7197404b540aSrobert;; Instructions to be emitted from __builtins. 7198404b540aSrobert 7199404b540aSrobert(define_insn "builtin_cmpbge" 7200404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 7201404b540aSrobert (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rJ") 7202404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "rI")] 7203404b540aSrobert UNSPEC_CMPBGE))] 7204404b540aSrobert "" 7205404b540aSrobert "cmpbge %r1,%2,%0" 7206404b540aSrobert ;; The EV6 data sheets list this as ILOG. OTOH, EV6 doesn't 7207404b540aSrobert ;; actually differentiate between ILOG and ICMP in the schedule. 7208404b540aSrobert [(set_attr "type" "icmp")]) 7209404b540aSrobert 7210404b540aSrobert(define_expand "builtin_extbl" 7211404b540aSrobert [(match_operand:DI 0 "register_operand" "") 7212404b540aSrobert (match_operand:DI 1 "reg_or_0_operand" "") 7213404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "")] 7214404b540aSrobert "" 7215404b540aSrobert{ 7216404b540aSrobert rtx (*gen) (rtx, rtx, rtx, rtx); 7217404b540aSrobert if (WORDS_BIG_ENDIAN) 7218404b540aSrobert gen = gen_extxl_be; 7219404b540aSrobert else 7220404b540aSrobert gen = gen_extxl_le; 7221404b540aSrobert emit_insn ((*gen) (operands[0], operands[1], GEN_INT (8), operands[2])); 7222404b540aSrobert DONE; 7223404b540aSrobert}) 7224404b540aSrobert 7225404b540aSrobert(define_expand "builtin_extwl" 7226404b540aSrobert [(match_operand:DI 0 "register_operand" "") 7227404b540aSrobert (match_operand:DI 1 "reg_or_0_operand" "") 7228404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "")] 7229404b540aSrobert "" 7230404b540aSrobert{ 7231404b540aSrobert rtx (*gen) (rtx, rtx, rtx, rtx); 7232404b540aSrobert if (WORDS_BIG_ENDIAN) 7233404b540aSrobert gen = gen_extxl_be; 7234404b540aSrobert else 7235404b540aSrobert gen = gen_extxl_le; 7236404b540aSrobert emit_insn ((*gen) (operands[0], operands[1], GEN_INT (16), operands[2])); 7237404b540aSrobert DONE; 7238404b540aSrobert}) 7239404b540aSrobert 7240404b540aSrobert(define_expand "builtin_extll" 7241404b540aSrobert [(match_operand:DI 0 "register_operand" "") 7242404b540aSrobert (match_operand:DI 1 "reg_or_0_operand" "") 7243404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "")] 7244404b540aSrobert "" 7245404b540aSrobert{ 7246404b540aSrobert rtx (*gen) (rtx, rtx, rtx, rtx); 7247404b540aSrobert if (WORDS_BIG_ENDIAN) 7248404b540aSrobert gen = gen_extxl_be; 7249404b540aSrobert else 7250404b540aSrobert gen = gen_extxl_le; 7251404b540aSrobert emit_insn ((*gen) (operands[0], operands[1], GEN_INT (32), operands[2])); 7252404b540aSrobert DONE; 7253404b540aSrobert}) 7254404b540aSrobert 7255404b540aSrobert(define_expand "builtin_extql" 7256404b540aSrobert [(match_operand:DI 0 "register_operand" "") 7257404b540aSrobert (match_operand:DI 1 "reg_or_0_operand" "") 7258404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "")] 7259404b540aSrobert "" 7260404b540aSrobert{ 7261404b540aSrobert rtx (*gen) (rtx, rtx, rtx, rtx); 7262404b540aSrobert if (WORDS_BIG_ENDIAN) 7263404b540aSrobert gen = gen_extxl_be; 7264404b540aSrobert else 7265404b540aSrobert gen = gen_extxl_le; 7266404b540aSrobert emit_insn ((*gen) (operands[0], operands[1], GEN_INT (64), operands[2])); 7267404b540aSrobert DONE; 7268404b540aSrobert}) 7269404b540aSrobert 7270404b540aSrobert(define_expand "builtin_extwh" 7271404b540aSrobert [(match_operand:DI 0 "register_operand" "") 7272404b540aSrobert (match_operand:DI 1 "reg_or_0_operand" "") 7273404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "")] 7274404b540aSrobert "" 7275404b540aSrobert{ 7276404b540aSrobert rtx (*gen) (rtx, rtx, rtx); 7277404b540aSrobert if (WORDS_BIG_ENDIAN) 7278404b540aSrobert gen = gen_extwh_be; 7279404b540aSrobert else 7280404b540aSrobert gen = gen_extwh_le; 7281404b540aSrobert emit_insn ((*gen) (operands[0], operands[1], operands[2])); 7282404b540aSrobert DONE; 7283404b540aSrobert}) 7284404b540aSrobert 7285404b540aSrobert(define_expand "builtin_extlh" 7286404b540aSrobert [(match_operand:DI 0 "register_operand" "") 7287404b540aSrobert (match_operand:DI 1 "reg_or_0_operand" "") 7288404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "")] 7289404b540aSrobert "" 7290404b540aSrobert{ 7291404b540aSrobert rtx (*gen) (rtx, rtx, rtx); 7292404b540aSrobert if (WORDS_BIG_ENDIAN) 7293404b540aSrobert gen = gen_extlh_be; 7294404b540aSrobert else 7295404b540aSrobert gen = gen_extlh_le; 7296404b540aSrobert emit_insn ((*gen) (operands[0], operands[1], operands[2])); 7297404b540aSrobert DONE; 7298404b540aSrobert}) 7299404b540aSrobert 7300404b540aSrobert(define_expand "builtin_extqh" 7301404b540aSrobert [(match_operand:DI 0 "register_operand" "") 7302404b540aSrobert (match_operand:DI 1 "reg_or_0_operand" "") 7303404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "")] 7304404b540aSrobert "" 7305404b540aSrobert{ 7306404b540aSrobert rtx (*gen) (rtx, rtx, rtx); 7307404b540aSrobert if (WORDS_BIG_ENDIAN) 7308404b540aSrobert gen = gen_extqh_be; 7309404b540aSrobert else 7310404b540aSrobert gen = gen_extqh_le; 7311404b540aSrobert emit_insn ((*gen) (operands[0], operands[1], operands[2])); 7312404b540aSrobert DONE; 7313404b540aSrobert}) 7314404b540aSrobert 7315404b540aSrobert(define_expand "builtin_insbl" 7316404b540aSrobert [(match_operand:DI 0 "register_operand" "") 7317404b540aSrobert (match_operand:DI 1 "register_operand" "") 7318404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "")] 7319404b540aSrobert "" 7320404b540aSrobert{ 7321404b540aSrobert rtx (*gen) (rtx, rtx, rtx); 7322404b540aSrobert if (WORDS_BIG_ENDIAN) 7323404b540aSrobert gen = gen_insbl_be; 7324404b540aSrobert else 7325404b540aSrobert gen = gen_insbl_le; 7326404b540aSrobert operands[1] = gen_lowpart (QImode, operands[1]); 7327404b540aSrobert emit_insn ((*gen) (operands[0], operands[1], operands[2])); 7328404b540aSrobert DONE; 7329404b540aSrobert}) 7330404b540aSrobert 7331404b540aSrobert(define_expand "builtin_inswl" 7332404b540aSrobert [(match_operand:DI 0 "register_operand" "") 7333404b540aSrobert (match_operand:DI 1 "register_operand" "") 7334404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "")] 7335404b540aSrobert "" 7336404b540aSrobert{ 7337404b540aSrobert rtx (*gen) (rtx, rtx, rtx); 7338404b540aSrobert if (WORDS_BIG_ENDIAN) 7339404b540aSrobert gen = gen_inswl_be; 7340404b540aSrobert else 7341404b540aSrobert gen = gen_inswl_le; 7342404b540aSrobert operands[1] = gen_lowpart (HImode, operands[1]); 7343404b540aSrobert emit_insn ((*gen) (operands[0], operands[1], operands[2])); 7344404b540aSrobert DONE; 7345404b540aSrobert}) 7346404b540aSrobert 7347404b540aSrobert(define_expand "builtin_insll" 7348404b540aSrobert [(match_operand:DI 0 "register_operand" "") 7349404b540aSrobert (match_operand:DI 1 "register_operand" "") 7350404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "")] 7351404b540aSrobert "" 7352404b540aSrobert{ 7353404b540aSrobert rtx (*gen) (rtx, rtx, rtx); 7354404b540aSrobert if (WORDS_BIG_ENDIAN) 7355404b540aSrobert gen = gen_insll_be; 7356404b540aSrobert else 7357404b540aSrobert gen = gen_insll_le; 7358404b540aSrobert operands[1] = gen_lowpart (SImode, operands[1]); 7359404b540aSrobert emit_insn ((*gen) (operands[0], operands[1], operands[2])); 7360404b540aSrobert emit_insn ((*gen) (operands[0], operands[1], operands[2])); 7361404b540aSrobert DONE; 7362404b540aSrobert}) 7363404b540aSrobert 7364404b540aSrobert(define_expand "builtin_insql" 7365404b540aSrobert [(match_operand:DI 0 "register_operand" "") 7366404b540aSrobert (match_operand:DI 1 "reg_or_0_operand" "") 7367404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "")] 7368404b540aSrobert "" 7369404b540aSrobert{ 7370404b540aSrobert rtx (*gen) (rtx, rtx, rtx); 7371404b540aSrobert if (WORDS_BIG_ENDIAN) 7372404b540aSrobert gen = gen_insql_be; 7373404b540aSrobert else 7374404b540aSrobert gen = gen_insql_le; 7375404b540aSrobert emit_insn ((*gen) (operands[0], operands[1], operands[2])); 7376404b540aSrobert DONE; 7377404b540aSrobert}) 7378404b540aSrobert 7379404b540aSrobert(define_expand "builtin_inswh" 7380404b540aSrobert [(match_operand:DI 0 "register_operand" "") 7381404b540aSrobert (match_operand:DI 1 "register_operand" "") 7382404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "")] 7383404b540aSrobert "" 7384404b540aSrobert{ 7385404b540aSrobert emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (16), operands[2])); 7386404b540aSrobert DONE; 7387404b540aSrobert}) 7388404b540aSrobert 7389404b540aSrobert(define_expand "builtin_inslh" 7390404b540aSrobert [(match_operand:DI 0 "register_operand" "") 7391404b540aSrobert (match_operand:DI 1 "register_operand" "") 7392404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "")] 7393404b540aSrobert "" 7394404b540aSrobert{ 7395404b540aSrobert emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (32), operands[2])); 7396404b540aSrobert DONE; 7397404b540aSrobert}) 7398404b540aSrobert 7399404b540aSrobert(define_expand "builtin_insqh" 7400404b540aSrobert [(match_operand:DI 0 "register_operand" "") 7401404b540aSrobert (match_operand:DI 1 "register_operand" "") 7402404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "")] 7403404b540aSrobert "" 7404404b540aSrobert{ 7405404b540aSrobert emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (64), operands[2])); 7406404b540aSrobert DONE; 7407404b540aSrobert}) 7408404b540aSrobert 7409404b540aSrobert(define_expand "builtin_mskbl" 7410404b540aSrobert [(match_operand:DI 0 "register_operand" "") 7411404b540aSrobert (match_operand:DI 1 "reg_or_0_operand" "") 7412404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "")] 7413404b540aSrobert "" 7414404b540aSrobert{ 7415404b540aSrobert rtx (*gen) (rtx, rtx, rtx, rtx); 7416404b540aSrobert rtx mask; 7417404b540aSrobert if (WORDS_BIG_ENDIAN) 7418404b540aSrobert gen = gen_mskxl_be; 7419404b540aSrobert else 7420404b540aSrobert gen = gen_mskxl_le; 7421404b540aSrobert mask = GEN_INT (0xff); 7422404b540aSrobert emit_insn ((*gen) (operands[0], operands[1], mask, operands[2])); 7423404b540aSrobert DONE; 7424404b540aSrobert}) 7425404b540aSrobert 7426404b540aSrobert(define_expand "builtin_mskwl" 7427404b540aSrobert [(match_operand:DI 0 "register_operand" "") 7428404b540aSrobert (match_operand:DI 1 "reg_or_0_operand" "") 7429404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "")] 7430404b540aSrobert "" 7431404b540aSrobert{ 7432404b540aSrobert rtx (*gen) (rtx, rtx, rtx, rtx); 7433404b540aSrobert rtx mask; 7434404b540aSrobert if (WORDS_BIG_ENDIAN) 7435404b540aSrobert gen = gen_mskxl_be; 7436404b540aSrobert else 7437404b540aSrobert gen = gen_mskxl_le; 7438404b540aSrobert mask = GEN_INT (0xffff); 7439404b540aSrobert emit_insn ((*gen) (operands[0], operands[1], mask, operands[2])); 7440404b540aSrobert DONE; 7441404b540aSrobert}) 7442404b540aSrobert 7443404b540aSrobert(define_expand "builtin_mskll" 7444404b540aSrobert [(match_operand:DI 0 "register_operand" "") 7445404b540aSrobert (match_operand:DI 1 "reg_or_0_operand" "") 7446404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "")] 7447404b540aSrobert "" 7448404b540aSrobert{ 7449404b540aSrobert rtx (*gen) (rtx, rtx, rtx, rtx); 7450404b540aSrobert rtx mask; 7451404b540aSrobert if (WORDS_BIG_ENDIAN) 7452404b540aSrobert gen = gen_mskxl_be; 7453404b540aSrobert else 7454404b540aSrobert gen = gen_mskxl_le; 7455404b540aSrobert mask = immed_double_const (0xffffffff, 0, DImode); 7456404b540aSrobert emit_insn ((*gen) (operands[0], operands[1], mask, operands[2])); 7457404b540aSrobert DONE; 7458404b540aSrobert}) 7459404b540aSrobert 7460404b540aSrobert(define_expand "builtin_mskql" 7461404b540aSrobert [(match_operand:DI 0 "register_operand" "") 7462404b540aSrobert (match_operand:DI 1 "reg_or_0_operand" "") 7463404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "")] 7464404b540aSrobert "" 7465404b540aSrobert{ 7466404b540aSrobert rtx (*gen) (rtx, rtx, rtx, rtx); 7467404b540aSrobert rtx mask; 7468404b540aSrobert if (WORDS_BIG_ENDIAN) 7469404b540aSrobert gen = gen_mskxl_be; 7470404b540aSrobert else 7471404b540aSrobert gen = gen_mskxl_le; 7472404b540aSrobert mask = constm1_rtx; 7473404b540aSrobert emit_insn ((*gen) (operands[0], operands[1], mask, operands[2])); 7474404b540aSrobert DONE; 7475404b540aSrobert}) 7476404b540aSrobert 7477404b540aSrobert(define_expand "builtin_mskwh" 7478404b540aSrobert [(match_operand:DI 0 "register_operand" "") 7479404b540aSrobert (match_operand:DI 1 "register_operand" "") 7480404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "")] 7481404b540aSrobert "" 7482404b540aSrobert{ 7483404b540aSrobert emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (16), operands[2])); 7484404b540aSrobert DONE; 7485404b540aSrobert}) 7486404b540aSrobert 7487404b540aSrobert(define_expand "builtin_msklh" 7488404b540aSrobert [(match_operand:DI 0 "register_operand" "") 7489404b540aSrobert (match_operand:DI 1 "register_operand" "") 7490404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "")] 7491404b540aSrobert "" 7492404b540aSrobert{ 7493404b540aSrobert emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (32), operands[2])); 7494404b540aSrobert DONE; 7495404b540aSrobert}) 7496404b540aSrobert 7497404b540aSrobert(define_expand "builtin_mskqh" 7498404b540aSrobert [(match_operand:DI 0 "register_operand" "") 7499404b540aSrobert (match_operand:DI 1 "register_operand" "") 7500404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "")] 7501404b540aSrobert "" 7502404b540aSrobert{ 7503404b540aSrobert emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (64), operands[2])); 7504404b540aSrobert DONE; 7505404b540aSrobert}) 7506404b540aSrobert 7507404b540aSrobert(define_expand "builtin_zap" 7508404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 7509404b540aSrobert (and:DI (unspec:DI 7510404b540aSrobert [(match_operand:DI 2 "reg_or_cint_operand" "")] 7511404b540aSrobert UNSPEC_ZAP) 7512404b540aSrobert (match_operand:DI 1 "reg_or_cint_operand" "")))] 7513404b540aSrobert "" 7514404b540aSrobert{ 7515404b540aSrobert if (GET_CODE (operands[2]) == CONST_INT) 7516404b540aSrobert { 7517404b540aSrobert rtx mask = alpha_expand_zap_mask (INTVAL (operands[2])); 7518404b540aSrobert 7519404b540aSrobert if (mask == const0_rtx) 7520404b540aSrobert { 7521404b540aSrobert emit_move_insn (operands[0], const0_rtx); 7522404b540aSrobert DONE; 7523404b540aSrobert } 7524404b540aSrobert if (mask == constm1_rtx) 7525404b540aSrobert { 7526404b540aSrobert emit_move_insn (operands[0], operands[1]); 7527404b540aSrobert DONE; 7528404b540aSrobert } 7529404b540aSrobert 7530404b540aSrobert operands[1] = force_reg (DImode, operands[1]); 7531404b540aSrobert emit_insn (gen_anddi3 (operands[0], operands[1], mask)); 7532404b540aSrobert DONE; 7533404b540aSrobert } 7534404b540aSrobert 7535404b540aSrobert operands[1] = force_reg (DImode, operands[1]); 7536404b540aSrobert operands[2] = gen_lowpart (QImode, operands[2]); 7537404b540aSrobert}) 7538404b540aSrobert 7539404b540aSrobert(define_insn "*builtin_zap_1" 7540404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r,r,r,r") 7541404b540aSrobert (and:DI (unspec:DI 7542404b540aSrobert [(match_operand:QI 2 "reg_or_cint_operand" "n,n,r,r")] 7543404b540aSrobert UNSPEC_ZAP) 7544404b540aSrobert (match_operand:DI 1 "reg_or_cint_operand" "n,r,J,r")))] 7545404b540aSrobert "" 7546404b540aSrobert "@ 7547404b540aSrobert # 7548404b540aSrobert # 7549404b540aSrobert bis $31,$31,%0 7550404b540aSrobert zap %r1,%2,%0" 7551404b540aSrobert [(set_attr "type" "shift,shift,ilog,shift")]) 7552404b540aSrobert 7553404b540aSrobert(define_split 7554404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 7555404b540aSrobert (and:DI (unspec:DI 7556404b540aSrobert [(match_operand:QI 2 "const_int_operand" "")] 7557404b540aSrobert UNSPEC_ZAP) 7558404b540aSrobert (match_operand:DI 1 "const_int_operand" "")))] 7559404b540aSrobert "" 7560404b540aSrobert [(const_int 0)] 7561404b540aSrobert{ 7562404b540aSrobert rtx mask = alpha_expand_zap_mask (INTVAL (operands[2])); 7563404b540aSrobert if (HOST_BITS_PER_WIDE_INT >= 64 || GET_CODE (mask) == CONST_INT) 7564404b540aSrobert operands[1] = gen_int_mode (INTVAL (operands[1]) & INTVAL (mask), DImode); 7565404b540aSrobert else 7566404b540aSrobert { 7567404b540aSrobert HOST_WIDE_INT c_lo = INTVAL (operands[1]); 7568404b540aSrobert HOST_WIDE_INT c_hi = (c_lo < 0 ? -1 : 0); 7569404b540aSrobert operands[1] = immed_double_const (c_lo & CONST_DOUBLE_LOW (mask), 7570404b540aSrobert c_hi & CONST_DOUBLE_HIGH (mask), 7571404b540aSrobert DImode); 7572404b540aSrobert } 7573404b540aSrobert emit_move_insn (operands[0], operands[1]); 7574404b540aSrobert DONE; 7575404b540aSrobert}) 7576404b540aSrobert 7577404b540aSrobert(define_split 7578404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 7579404b540aSrobert (and:DI (unspec:DI 7580404b540aSrobert [(match_operand:QI 2 "const_int_operand" "")] 7581404b540aSrobert UNSPEC_ZAP) 7582404b540aSrobert (match_operand:DI 1 "register_operand" "")))] 7583404b540aSrobert "" 7584404b540aSrobert [(set (match_dup 0) 7585404b540aSrobert (and:DI (match_dup 1) (match_dup 2)))] 7586404b540aSrobert{ 7587404b540aSrobert operands[2] = alpha_expand_zap_mask (INTVAL (operands[2])); 7588404b540aSrobert if (operands[2] == const0_rtx) 7589404b540aSrobert { 7590404b540aSrobert emit_move_insn (operands[0], const0_rtx); 7591404b540aSrobert DONE; 7592404b540aSrobert } 7593404b540aSrobert if (operands[2] == constm1_rtx) 7594404b540aSrobert { 7595404b540aSrobert emit_move_insn (operands[0], operands[1]); 7596404b540aSrobert DONE; 7597404b540aSrobert } 7598404b540aSrobert}) 7599404b540aSrobert 7600404b540aSrobert(define_expand "builtin_zapnot" 7601404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 7602404b540aSrobert (and:DI (unspec:DI 7603404b540aSrobert [(not:QI (match_operand:DI 2 "reg_or_cint_operand" ""))] 7604404b540aSrobert UNSPEC_ZAP) 7605404b540aSrobert (match_operand:DI 1 "reg_or_cint_operand" "")))] 7606404b540aSrobert "" 7607404b540aSrobert{ 7608404b540aSrobert if (GET_CODE (operands[2]) == CONST_INT) 7609404b540aSrobert { 7610404b540aSrobert rtx mask = alpha_expand_zap_mask (~ INTVAL (operands[2])); 7611404b540aSrobert 7612404b540aSrobert if (mask == const0_rtx) 7613404b540aSrobert { 7614404b540aSrobert emit_move_insn (operands[0], const0_rtx); 7615404b540aSrobert DONE; 7616404b540aSrobert } 7617404b540aSrobert if (mask == constm1_rtx) 7618404b540aSrobert { 7619404b540aSrobert emit_move_insn (operands[0], operands[1]); 7620404b540aSrobert DONE; 7621404b540aSrobert } 7622404b540aSrobert 7623404b540aSrobert operands[1] = force_reg (DImode, operands[1]); 7624404b540aSrobert emit_insn (gen_anddi3 (operands[0], operands[1], mask)); 7625404b540aSrobert DONE; 7626404b540aSrobert } 7627404b540aSrobert 7628404b540aSrobert operands[1] = force_reg (DImode, operands[1]); 7629404b540aSrobert operands[2] = gen_lowpart (QImode, operands[2]); 7630404b540aSrobert}) 7631404b540aSrobert 7632404b540aSrobert(define_insn "*builtin_zapnot_1" 7633404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 7634404b540aSrobert (and:DI (unspec:DI 7635404b540aSrobert [(not:QI (match_operand:QI 2 "register_operand" "r"))] 7636404b540aSrobert UNSPEC_ZAP) 7637404b540aSrobert (match_operand:DI 1 "reg_or_0_operand" "rJ")))] 7638404b540aSrobert "" 7639404b540aSrobert "zapnot %r1,%2,%0" 7640404b540aSrobert [(set_attr "type" "shift")]) 7641404b540aSrobert 7642404b540aSrobert(define_insn "builtin_amask" 7643404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 7644404b540aSrobert (unspec:DI [(match_operand:DI 1 "reg_or_8bit_operand" "rI")] 7645404b540aSrobert UNSPEC_AMASK))] 7646404b540aSrobert "" 7647404b540aSrobert "amask %1,%0" 7648404b540aSrobert [(set_attr "type" "ilog")]) 7649404b540aSrobert 7650404b540aSrobert(define_insn "builtin_implver" 7651404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 7652404b540aSrobert (unspec:DI [(const_int 0)] UNSPEC_IMPLVER))] 7653404b540aSrobert "" 7654404b540aSrobert "implver %0" 7655404b540aSrobert [(set_attr "type" "ilog")]) 7656404b540aSrobert 7657404b540aSrobert(define_insn "builtin_rpcc" 7658404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 7659404b540aSrobert (unspec_volatile:DI [(const_int 0)] UNSPECV_RPCC))] 7660404b540aSrobert "" 7661404b540aSrobert "rpcc %0" 7662404b540aSrobert [(set_attr "type" "ilog")]) 7663404b540aSrobert 7664404b540aSrobert(define_expand "builtin_minub8" 7665404b540aSrobert [(match_operand:DI 0 "register_operand" "") 7666404b540aSrobert (match_operand:DI 1 "reg_or_0_operand" "") 7667404b540aSrobert (match_operand:DI 2 "reg_or_0_operand" "")] 7668404b540aSrobert "TARGET_MAX" 7669404b540aSrobert{ 7670404b540aSrobert alpha_expand_builtin_vector_binop (gen_uminv8qi3, V8QImode, operands[0], 7671404b540aSrobert operands[1], operands[2]); 7672404b540aSrobert DONE; 7673404b540aSrobert}) 7674404b540aSrobert 7675404b540aSrobert(define_expand "builtin_minsb8" 7676404b540aSrobert [(match_operand:DI 0 "register_operand" "") 7677404b540aSrobert (match_operand:DI 1 "reg_or_0_operand" "") 7678404b540aSrobert (match_operand:DI 2 "reg_or_0_operand" "")] 7679404b540aSrobert "TARGET_MAX" 7680404b540aSrobert{ 7681404b540aSrobert alpha_expand_builtin_vector_binop (gen_sminv8qi3, V8QImode, operands[0], 7682404b540aSrobert operands[1], operands[2]); 7683404b540aSrobert DONE; 7684404b540aSrobert}) 7685404b540aSrobert 7686404b540aSrobert(define_expand "builtin_minuw4" 7687404b540aSrobert [(match_operand:DI 0 "register_operand" "") 7688404b540aSrobert (match_operand:DI 1 "reg_or_0_operand" "") 7689404b540aSrobert (match_operand:DI 2 "reg_or_0_operand" "")] 7690404b540aSrobert "TARGET_MAX" 7691404b540aSrobert{ 7692404b540aSrobert alpha_expand_builtin_vector_binop (gen_uminv4hi3, V4HImode, operands[0], 7693404b540aSrobert operands[1], operands[2]); 7694404b540aSrobert DONE; 7695404b540aSrobert}) 7696404b540aSrobert 7697404b540aSrobert(define_expand "builtin_minsw4" 7698404b540aSrobert [(match_operand:DI 0 "register_operand" "") 7699404b540aSrobert (match_operand:DI 1 "reg_or_0_operand" "") 7700404b540aSrobert (match_operand:DI 2 "reg_or_0_operand" "")] 7701404b540aSrobert "TARGET_MAX" 7702404b540aSrobert{ 7703404b540aSrobert alpha_expand_builtin_vector_binop (gen_sminv4hi3, V4HImode, operands[0], 7704404b540aSrobert operands[1], operands[2]); 7705404b540aSrobert DONE; 7706404b540aSrobert}) 7707404b540aSrobert 7708404b540aSrobert(define_expand "builtin_maxub8" 7709404b540aSrobert [(match_operand:DI 0 "register_operand" "") 7710404b540aSrobert (match_operand:DI 1 "reg_or_0_operand" "") 7711404b540aSrobert (match_operand:DI 2 "reg_or_0_operand" "")] 7712404b540aSrobert "TARGET_MAX" 7713404b540aSrobert{ 7714404b540aSrobert alpha_expand_builtin_vector_binop (gen_umaxv8qi3, V8QImode, operands[0], 7715404b540aSrobert operands[1], operands[2]); 7716404b540aSrobert DONE; 7717404b540aSrobert}) 7718404b540aSrobert 7719404b540aSrobert(define_expand "builtin_maxsb8" 7720404b540aSrobert [(match_operand:DI 0 "register_operand" "") 7721404b540aSrobert (match_operand:DI 1 "reg_or_0_operand" "") 7722404b540aSrobert (match_operand:DI 2 "reg_or_0_operand" "")] 7723404b540aSrobert "TARGET_MAX" 7724404b540aSrobert{ 7725404b540aSrobert alpha_expand_builtin_vector_binop (gen_smaxv8qi3, V8QImode, operands[0], 7726404b540aSrobert operands[1], operands[2]); 7727404b540aSrobert DONE; 7728404b540aSrobert}) 7729404b540aSrobert 7730404b540aSrobert(define_expand "builtin_maxuw4" 7731404b540aSrobert [(match_operand:DI 0 "register_operand" "") 7732404b540aSrobert (match_operand:DI 1 "reg_or_0_operand" "") 7733404b540aSrobert (match_operand:DI 2 "reg_or_0_operand" "")] 7734404b540aSrobert "TARGET_MAX" 7735404b540aSrobert{ 7736404b540aSrobert alpha_expand_builtin_vector_binop (gen_umaxv4hi3, V4HImode, operands[0], 7737404b540aSrobert operands[1], operands[2]); 7738404b540aSrobert DONE; 7739404b540aSrobert}) 7740404b540aSrobert 7741404b540aSrobert(define_expand "builtin_maxsw4" 7742404b540aSrobert [(match_operand:DI 0 "register_operand" "") 7743404b540aSrobert (match_operand:DI 1 "reg_or_0_operand" "") 7744404b540aSrobert (match_operand:DI 2 "reg_or_0_operand" "")] 7745404b540aSrobert "TARGET_MAX" 7746404b540aSrobert{ 7747404b540aSrobert alpha_expand_builtin_vector_binop (gen_smaxv4hi3, V4HImode, operands[0], 7748404b540aSrobert operands[1], operands[2]); 7749404b540aSrobert DONE; 7750404b540aSrobert}) 7751404b540aSrobert 7752404b540aSrobert(define_insn "builtin_perr" 7753404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r") 7754404b540aSrobert (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "%rJ") 7755404b540aSrobert (match_operand:DI 2 "reg_or_8bit_operand" "rJ")] 7756404b540aSrobert UNSPEC_PERR))] 7757404b540aSrobert "TARGET_MAX" 7758404b540aSrobert "perr %r1,%r2,%0" 7759404b540aSrobert [(set_attr "type" "mvi")]) 7760404b540aSrobert 7761404b540aSrobert(define_expand "builtin_pklb" 7762404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 7763404b540aSrobert (vec_concat:V8QI 7764404b540aSrobert (vec_concat:V4QI 7765404b540aSrobert (truncate:V2QI (match_operand:DI 1 "register_operand" "")) 7766404b540aSrobert (match_dup 2)) 7767404b540aSrobert (match_dup 3)))] 7768404b540aSrobert "TARGET_MAX" 7769404b540aSrobert{ 7770404b540aSrobert operands[0] = gen_lowpart (V8QImode, operands[0]); 7771404b540aSrobert operands[1] = gen_lowpart (V2SImode, operands[1]); 7772404b540aSrobert operands[2] = CONST0_RTX (V2QImode); 7773404b540aSrobert operands[3] = CONST0_RTX (V4QImode); 7774404b540aSrobert}) 7775404b540aSrobert 7776404b540aSrobert(define_insn "*pklb" 7777404b540aSrobert [(set (match_operand:V8QI 0 "register_operand" "=r") 7778404b540aSrobert (vec_concat:V8QI 7779404b540aSrobert (vec_concat:V4QI 7780404b540aSrobert (truncate:V2QI (match_operand:V2SI 1 "register_operand" "r")) 7781404b540aSrobert (match_operand:V2QI 2 "const0_operand" "")) 7782404b540aSrobert (match_operand:V4QI 3 "const0_operand" "")))] 7783404b540aSrobert "TARGET_MAX" 7784404b540aSrobert "pklb %r1,%0" 7785404b540aSrobert [(set_attr "type" "mvi")]) 7786404b540aSrobert 7787404b540aSrobert(define_expand "builtin_pkwb" 7788404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 7789404b540aSrobert (vec_concat:V8QI 7790404b540aSrobert (truncate:V4QI (match_operand:DI 1 "register_operand" "")) 7791404b540aSrobert (match_dup 2)))] 7792404b540aSrobert "TARGET_MAX" 7793404b540aSrobert{ 7794404b540aSrobert operands[0] = gen_lowpart (V8QImode, operands[0]); 7795404b540aSrobert operands[1] = gen_lowpart (V4HImode, operands[1]); 7796404b540aSrobert operands[2] = CONST0_RTX (V4QImode); 7797404b540aSrobert}) 7798404b540aSrobert 7799404b540aSrobert(define_insn "*pkwb" 7800404b540aSrobert [(set (match_operand:V8QI 0 "register_operand" "=r") 7801404b540aSrobert (vec_concat:V8QI 7802404b540aSrobert (truncate:V4QI (match_operand:V4HI 1 "register_operand" "r")) 7803404b540aSrobert (match_operand:V4QI 2 "const0_operand" "")))] 7804404b540aSrobert "TARGET_MAX" 7805404b540aSrobert "pkwb %r1,%0" 7806404b540aSrobert [(set_attr "type" "mvi")]) 7807404b540aSrobert 7808404b540aSrobert(define_expand "builtin_unpkbl" 7809404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 7810404b540aSrobert (zero_extend:V2SI 7811404b540aSrobert (vec_select:V2QI (match_operand:DI 1 "register_operand" "") 7812404b540aSrobert (parallel [(const_int 0) (const_int 1)]))))] 7813404b540aSrobert "TARGET_MAX" 7814404b540aSrobert{ 7815404b540aSrobert operands[0] = gen_lowpart (V2SImode, operands[0]); 7816404b540aSrobert operands[1] = gen_lowpart (V8QImode, operands[1]); 7817404b540aSrobert}) 7818404b540aSrobert 7819404b540aSrobert(define_insn "*unpkbl" 7820404b540aSrobert [(set (match_operand:V2SI 0 "register_operand" "=r") 7821404b540aSrobert (zero_extend:V2SI 7822404b540aSrobert (vec_select:V2QI (match_operand:V8QI 1 "reg_or_0_operand" "rW") 7823404b540aSrobert (parallel [(const_int 0) (const_int 1)]))))] 7824404b540aSrobert "TARGET_MAX" 7825404b540aSrobert "unpkbl %r1,%0" 7826404b540aSrobert [(set_attr "type" "mvi")]) 7827404b540aSrobert 7828404b540aSrobert(define_expand "builtin_unpkbw" 7829404b540aSrobert [(set (match_operand:DI 0 "register_operand" "") 7830404b540aSrobert (zero_extend:V4HI 7831404b540aSrobert (vec_select:V4QI (match_operand:DI 1 "register_operand" "") 7832404b540aSrobert (parallel [(const_int 0) 7833404b540aSrobert (const_int 1) 7834404b540aSrobert (const_int 2) 7835404b540aSrobert (const_int 3)]))))] 7836404b540aSrobert "TARGET_MAX" 7837404b540aSrobert{ 7838404b540aSrobert operands[0] = gen_lowpart (V4HImode, operands[0]); 7839404b540aSrobert operands[1] = gen_lowpart (V8QImode, operands[1]); 7840404b540aSrobert}) 7841404b540aSrobert 7842404b540aSrobert(define_insn "*unpkbw" 7843404b540aSrobert [(set (match_operand:V4HI 0 "register_operand" "=r") 7844404b540aSrobert (zero_extend:V4HI 7845404b540aSrobert (vec_select:V4QI (match_operand:V8QI 1 "reg_or_0_operand" "rW") 7846404b540aSrobert (parallel [(const_int 0) 7847404b540aSrobert (const_int 1) 7848404b540aSrobert (const_int 2) 7849404b540aSrobert (const_int 3)]))))] 7850404b540aSrobert "TARGET_MAX" 7851404b540aSrobert "unpkbw %r1,%0" 7852404b540aSrobert [(set_attr "type" "mvi")]) 7853404b540aSrobert 7854404b540aSrobert(include "sync.md") 7855404b540aSrobert 7856404b540aSrobert;; The call patterns are at the end of the file because their 7857404b540aSrobert;; wildcard operand0 interferes with nice recognition. 7858404b540aSrobert 7859404b540aSrobert(define_insn "*call_value_osf_1_er" 7860404b540aSrobert [(set (match_operand 0 "" "") 7861404b540aSrobert (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s")) 7862404b540aSrobert (match_operand 2 "" ""))) 7863404b540aSrobert (use (reg:DI 29)) 7864404b540aSrobert (clobber (reg:DI 26))] 7865404b540aSrobert "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" 7866404b540aSrobert "@ 7867404b540aSrobert jsr $26,(%1),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%* 7868404b540aSrobert bsr $26,%1\t\t!samegp 7869404b540aSrobert ldq $27,%1($29)\t\t!literal!%#\;jsr $26,($27),0\t\t!lituse_jsr!%#\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*" 7870404b540aSrobert [(set_attr "type" "jsr") 7871404b540aSrobert (set_attr "length" "12,*,16")]) 7872404b540aSrobert 7873404b540aSrobert;; We must use peep2 instead of a split because we need accurate life 7874404b540aSrobert;; information for $gp. Consider the case of { bar(); while (1); }. 7875404b540aSrobert(define_peephole2 7876404b540aSrobert [(parallel [(set (match_operand 0 "" "") 7877404b540aSrobert (call (mem:DI (match_operand:DI 1 "call_operand" "")) 7878404b540aSrobert (match_operand 2 "" ""))) 7879404b540aSrobert (use (reg:DI 29)) 7880404b540aSrobert (clobber (reg:DI 26))])] 7881404b540aSrobert "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed 7882404b540aSrobert && ! samegp_function_operand (operands[1], Pmode) 7883404b540aSrobert && (peep2_regno_dead_p (1, 29) 7884404b540aSrobert || find_reg_note (insn, REG_NORETURN, NULL_RTX))" 7885404b540aSrobert [(parallel [(set (match_dup 0) 7886404b540aSrobert (call (mem:DI (match_dup 3)) 7887404b540aSrobert (match_dup 2))) 7888404b540aSrobert (set (reg:DI 26) (plus:DI (pc) (const_int 4))) 7889404b540aSrobert (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE) 7890404b540aSrobert (use (match_dup 1)) 7891404b540aSrobert (use (match_dup 4))])] 7892404b540aSrobert{ 7893404b540aSrobert if (CONSTANT_P (operands[1])) 7894404b540aSrobert { 7895404b540aSrobert operands[3] = gen_rtx_REG (Pmode, 27); 7896404b540aSrobert operands[4] = GEN_INT (alpha_next_sequence_number++); 7897404b540aSrobert emit_insn (gen_movdi_er_high_g (operands[3], pic_offset_table_rtx, 7898404b540aSrobert operands[1], operands[4])); 7899404b540aSrobert } 7900404b540aSrobert else 7901404b540aSrobert { 7902404b540aSrobert operands[3] = operands[1]; 7903404b540aSrobert operands[1] = const0_rtx; 7904404b540aSrobert operands[4] = const0_rtx; 7905404b540aSrobert } 7906404b540aSrobert}) 7907404b540aSrobert 7908404b540aSrobert(define_peephole2 7909404b540aSrobert [(parallel [(set (match_operand 0 "" "") 7910404b540aSrobert (call (mem:DI (match_operand:DI 1 "call_operand" "")) 7911404b540aSrobert (match_operand 2 "" ""))) 7912404b540aSrobert (use (reg:DI 29)) 7913404b540aSrobert (clobber (reg:DI 26))])] 7914404b540aSrobert "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed 7915404b540aSrobert && ! samegp_function_operand (operands[1], Pmode) 7916404b540aSrobert && ! (peep2_regno_dead_p (1, 29) 7917404b540aSrobert || find_reg_note (insn, REG_NORETURN, NULL_RTX))" 7918404b540aSrobert [(parallel [(set (match_dup 0) 7919404b540aSrobert (call (mem:DI (match_dup 3)) 7920404b540aSrobert (match_dup 2))) 7921404b540aSrobert (set (reg:DI 26) (plus:DI (pc) (const_int 4))) 7922404b540aSrobert (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE) 7923404b540aSrobert (use (match_dup 1)) 7924404b540aSrobert (use (match_dup 5))]) 7925404b540aSrobert (set (reg:DI 29) 7926404b540aSrobert (unspec_volatile:DI [(reg:DI 26) (match_dup 4)] UNSPECV_LDGP1)) 7927404b540aSrobert (set (reg:DI 29) 7928404b540aSrobert (unspec:DI [(reg:DI 29) (match_dup 4)] UNSPEC_LDGP2))] 7929404b540aSrobert{ 7930404b540aSrobert if (CONSTANT_P (operands[1])) 7931404b540aSrobert { 7932404b540aSrobert operands[3] = gen_rtx_REG (Pmode, 27); 7933404b540aSrobert operands[5] = GEN_INT (alpha_next_sequence_number++); 7934404b540aSrobert emit_insn (gen_movdi_er_high_g (operands[3], pic_offset_table_rtx, 7935404b540aSrobert operands[1], operands[5])); 7936404b540aSrobert } 7937404b540aSrobert else 7938404b540aSrobert { 7939404b540aSrobert operands[3] = operands[1]; 7940404b540aSrobert operands[1] = const0_rtx; 7941404b540aSrobert operands[5] = const0_rtx; 7942404b540aSrobert } 7943404b540aSrobert operands[4] = GEN_INT (alpha_next_sequence_number++); 7944404b540aSrobert}) 7945404b540aSrobert 7946404b540aSrobert;; We add a blockage unspec_volatile to prevent insns from moving down 7947404b540aSrobert;; from above the call to in between the call and the ldah gpdisp. 7948404b540aSrobert(define_insn "*call_value_osf_2_er" 7949404b540aSrobert [(set (match_operand 0 "" "") 7950404b540aSrobert (call (mem:DI (match_operand:DI 1 "register_operand" "c")) 7951404b540aSrobert (match_operand 2 "" ""))) 7952404b540aSrobert (set (reg:DI 26) 7953404b540aSrobert (plus:DI (pc) (const_int 4))) 7954404b540aSrobert (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE) 7955404b540aSrobert (use (match_operand 3 "" "")) 7956404b540aSrobert (use (match_operand 4 "" ""))] 7957404b540aSrobert "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" 7958404b540aSrobert "jsr $26,(%1),%3%J4" 7959404b540aSrobert [(set_attr "type" "jsr") 7960404b540aSrobert (set_attr "cannot_copy" "true")]) 7961404b540aSrobert 7962404b540aSrobert(define_insn "*call_value_osf_1_noreturn" 7963404b540aSrobert [(set (match_operand 0 "" "") 7964404b540aSrobert (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s")) 7965404b540aSrobert (match_operand 2 "" ""))) 7966404b540aSrobert (use (reg:DI 29)) 7967404b540aSrobert (clobber (reg:DI 26))] 7968404b540aSrobert "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF 7969404b540aSrobert && find_reg_note (insn, REG_NORETURN, NULL_RTX)" 7970404b540aSrobert "@ 7971404b540aSrobert jsr $26,($27),0%+ 7972404b540aSrobert bsr $26,$%1..ng%+ 7973404b540aSrobert jsr $26,%1%+" 7974404b540aSrobert [(set_attr "type" "jsr") 7975404b540aSrobert (set_attr "length" "*,*,8")]) 7976404b540aSrobert 7977404b540aSrobert(define_insn_and_split "call_value_osf_tlsgd" 7978404b540aSrobert [(set (match_operand 0 "" "") 7979404b540aSrobert (call (mem:DI (match_operand:DI 1 "symbolic_operand" "")) 7980404b540aSrobert (const_int 0))) 7981404b540aSrobert (unspec [(match_operand:DI 2 "const_int_operand" "")] UNSPEC_TLSGD_CALL) 7982404b540aSrobert (use (reg:DI 29)) 7983404b540aSrobert (clobber (reg:DI 26))] 7984404b540aSrobert "HAVE_AS_TLS" 7985404b540aSrobert "#" 7986404b540aSrobert "&& reload_completed" 7987404b540aSrobert [(set (match_dup 3) 7988404b540aSrobert (unspec:DI [(match_dup 5) 7989404b540aSrobert (match_dup 1) 7990404b540aSrobert (match_dup 2)] UNSPEC_LITERAL)) 7991404b540aSrobert (parallel [(set (match_dup 0) 7992404b540aSrobert (call (mem:DI (match_dup 3)) 7993404b540aSrobert (const_int 0))) 7994404b540aSrobert (set (reg:DI 26) (plus:DI (pc) (const_int 4))) 7995404b540aSrobert (unspec_volatile [(match_dup 5)] UNSPECV_BLOCKAGE) 7996404b540aSrobert (use (match_dup 1)) 7997404b540aSrobert (use (unspec [(match_dup 2)] UNSPEC_TLSGD_CALL))]) 7998404b540aSrobert (set (match_dup 5) 7999404b540aSrobert (unspec_volatile:DI [(reg:DI 26) (match_dup 4)] UNSPECV_LDGP1)) 8000404b540aSrobert (set (match_dup 5) 8001404b540aSrobert (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP2))] 8002404b540aSrobert{ 8003404b540aSrobert operands[3] = gen_rtx_REG (Pmode, 27); 8004404b540aSrobert operands[4] = GEN_INT (alpha_next_sequence_number++); 8005404b540aSrobert operands[5] = pic_offset_table_rtx; 8006404b540aSrobert} 8007404b540aSrobert [(set_attr "type" "multi")]) 8008404b540aSrobert 8009404b540aSrobert(define_insn_and_split "call_value_osf_tlsldm" 8010404b540aSrobert [(set (match_operand 0 "" "") 8011404b540aSrobert (call (mem:DI (match_operand:DI 1 "symbolic_operand" "")) 8012404b540aSrobert (const_int 0))) 8013404b540aSrobert (unspec [(match_operand:DI 2 "const_int_operand" "")] UNSPEC_TLSLDM_CALL) 8014404b540aSrobert (use (reg:DI 29)) 8015404b540aSrobert (clobber (reg:DI 26))] 8016404b540aSrobert "HAVE_AS_TLS" 8017404b540aSrobert "#" 8018404b540aSrobert "&& reload_completed" 8019404b540aSrobert [(set (match_dup 3) 8020404b540aSrobert (unspec:DI [(match_dup 5) 8021404b540aSrobert (match_dup 1) 8022404b540aSrobert (match_dup 2)] UNSPEC_LITERAL)) 8023404b540aSrobert (parallel [(set (match_dup 0) 8024404b540aSrobert (call (mem:DI (match_dup 3)) 8025404b540aSrobert (const_int 0))) 8026404b540aSrobert (set (reg:DI 26) (plus:DI (pc) (const_int 4))) 8027404b540aSrobert (unspec_volatile [(match_dup 5)] UNSPECV_BLOCKAGE) 8028404b540aSrobert (use (match_dup 1)) 8029404b540aSrobert (use (unspec [(match_dup 2)] UNSPEC_TLSLDM_CALL))]) 8030404b540aSrobert (set (reg:DI 29) 8031404b540aSrobert (unspec_volatile:DI [(reg:DI 26) (match_dup 4)] UNSPECV_LDGP1)) 8032404b540aSrobert (set (reg:DI 29) 8033404b540aSrobert (unspec:DI [(reg:DI 29) (match_dup 4)] UNSPEC_LDGP2))] 8034404b540aSrobert{ 8035404b540aSrobert operands[3] = gen_rtx_REG (Pmode, 27); 8036404b540aSrobert operands[4] = GEN_INT (alpha_next_sequence_number++); 8037404b540aSrobert operands[5] = pic_offset_table_rtx; 8038404b540aSrobert} 8039404b540aSrobert [(set_attr "type" "multi")]) 8040404b540aSrobert 8041404b540aSrobert(define_insn "*call_value_osf_1" 8042404b540aSrobert [(set (match_operand 0 "" "") 8043404b540aSrobert (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s")) 8044404b540aSrobert (match_operand 2 "" ""))) 8045404b540aSrobert (use (reg:DI 29)) 8046404b540aSrobert (clobber (reg:DI 26))] 8047404b540aSrobert "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" 8048404b540aSrobert "@ 8049404b540aSrobert jsr $26,($27),0\;ldgp $29,0($26) 8050404b540aSrobert bsr $26,$%1..ng 8051404b540aSrobert jsr $26,%1\;ldgp $29,0($26)" 8052404b540aSrobert [(set_attr "type" "jsr") 8053404b540aSrobert (set_attr "length" "12,*,16")]) 8054404b540aSrobert 8055404b540aSrobert(define_insn "*sibcall_value_osf_1_er" 8056404b540aSrobert [(set (match_operand 0 "" "") 8057404b540aSrobert (call (mem:DI (match_operand:DI 1 "symbolic_operand" "R,s")) 8058404b540aSrobert (match_operand 2 "" ""))) 8059404b540aSrobert (unspec [(reg:DI 29)] UNSPEC_SIBCALL)] 8060404b540aSrobert "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" 8061404b540aSrobert "@ 8062404b540aSrobert br $31,%1\t\t!samegp 8063404b540aSrobert ldq $27,%1($29)\t\t!literal!%#\;jmp $31,($27),%1\t\t!lituse_jsr!%#" 8064404b540aSrobert [(set_attr "type" "jsr") 8065404b540aSrobert (set_attr "length" "*,8")]) 8066404b540aSrobert 8067404b540aSrobert(define_insn "*sibcall_value_osf_1" 8068404b540aSrobert [(set (match_operand 0 "" "") 8069404b540aSrobert (call (mem:DI (match_operand:DI 1 "symbolic_operand" "R,s")) 8070404b540aSrobert (match_operand 2 "" ""))) 8071404b540aSrobert (unspec [(reg:DI 29)] UNSPEC_SIBCALL)] 8072404b540aSrobert "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" 8073404b540aSrobert "@ 8074404b540aSrobert br $31,$%1..ng 8075404b540aSrobert lda $27,%1\;jmp $31,($27),%1" 8076404b540aSrobert [(set_attr "type" "jsr") 8077404b540aSrobert (set_attr "length" "*,8")]) 8078404b540aSrobert 8079404b540aSrobert(define_insn "*call_value_nt_1" 8080404b540aSrobert [(set (match_operand 0 "" "") 8081404b540aSrobert (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,s")) 8082404b540aSrobert (match_operand 2 "" ""))) 8083404b540aSrobert (clobber (reg:DI 26))] 8084404b540aSrobert "TARGET_ABI_WINDOWS_NT" 8085404b540aSrobert "@ 8086404b540aSrobert jsr $26,(%1) 8087404b540aSrobert bsr $26,%1 8088404b540aSrobert jsr $26,%1" 8089404b540aSrobert [(set_attr "type" "jsr") 8090404b540aSrobert (set_attr "length" "*,*,12")]) 8091404b540aSrobert 8092404b540aSrobert; GAS relies on the order and position of instructions output below in order 8093404b540aSrobert; to generate relocs for VMS link to potentially optimize the call. 8094404b540aSrobert; Please do not molest. 8095404b540aSrobert(define_insn "*call_value_vms_1" 8096404b540aSrobert [(set (match_operand 0 "" "") 8097404b540aSrobert (call (mem:DI (match_operand:DI 1 "call_operand" "r,s")) 8098404b540aSrobert (match_operand 2 "" ""))) 8099404b540aSrobert (use (match_operand:DI 3 "nonmemory_operand" "r,n")) 8100404b540aSrobert (use (reg:DI 25)) 8101404b540aSrobert (use (reg:DI 26)) 8102404b540aSrobert (clobber (reg:DI 27))] 8103404b540aSrobert "TARGET_ABI_OPEN_VMS" 8104404b540aSrobert{ 8105404b540aSrobert switch (which_alternative) 8106404b540aSrobert { 8107404b540aSrobert case 0: 8108404b540aSrobert return "mov %3,$27\;jsr $26,0\;ldq $27,0($29)"; 8109404b540aSrobert case 1: 8110404b540aSrobert operands [3] = alpha_use_linkage (operands [1], cfun->decl, 1, 0); 8111404b540aSrobert operands [4] = alpha_use_linkage (operands [1], cfun->decl, 0, 0); 8112404b540aSrobert return "ldq $26,%4\;ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)"; 8113404b540aSrobert default: 8114404b540aSrobert gcc_unreachable (); 8115404b540aSrobert } 8116404b540aSrobert} 8117404b540aSrobert [(set_attr "type" "jsr") 8118404b540aSrobert (set_attr "length" "12,16")]) 8119404b540aSrobert 8120404b540aSrobert(define_insn "*call_value_umk" 8121404b540aSrobert [(set (match_operand 0 "" "") 8122404b540aSrobert (call (mem:DI (match_operand:DI 1 "call_operand" "r")) 8123404b540aSrobert (match_operand 2 "" ""))) 8124404b540aSrobert (use (reg:DI 25)) 8125404b540aSrobert (clobber (reg:DI 26))] 8126404b540aSrobert "TARGET_ABI_UNICOSMK" 8127404b540aSrobert "jsr $26,(%1)" 8128404b540aSrobert [(set_attr "type" "jsr")]) 8129