aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.8/gcc/config/tilegx/tilegx.md
diff options
context:
space:
mode:
authorBen Cheng <bccheng@google.com>2013-03-28 11:14:20 -0700
committerBen Cheng <bccheng@google.com>2013-03-28 12:40:33 -0700
commitaf0c51ac87ab2a87caa03fa108f0d164987a2764 (patch)
tree4b8b470f7c5b69642fdab8d0aa1fbc148d02196b /gcc-4.8/gcc/config/tilegx/tilegx.md
parentd87cae247d39ebf4f5a6bf25c932a14d2fdb9384 (diff)
downloadtoolchain_gcc-af0c51ac87ab2a87caa03fa108f0d164987a2764.tar.gz
toolchain_gcc-af0c51ac87ab2a87caa03fa108f0d164987a2764.tar.bz2
toolchain_gcc-af0c51ac87ab2a87caa03fa108f0d164987a2764.zip
[GCC 4.8] Initial check-in of GCC 4.8.0
Change-Id: I0719d8a6d0f69b367a6ab6f10eb75622dbf12771
Diffstat (limited to 'gcc-4.8/gcc/config/tilegx/tilegx.md')
-rw-r--r--gcc-4.8/gcc/config/tilegx/tilegx.md5233
1 files changed, 5233 insertions, 0 deletions
diff --git a/gcc-4.8/gcc/config/tilegx/tilegx.md b/gcc-4.8/gcc/config/tilegx/tilegx.md
new file mode 100644
index 000000000..da1155395
--- /dev/null
+++ b/gcc-4.8/gcc/config/tilegx/tilegx.md
@@ -0,0 +1,5233 @@
+;; Machine description for Tilera TILE-Gx chip for GCC.
+;; Copyright (C) 2011-2013 Free Software Foundation, Inc.
+;; Contributed by Walter Lee (walt@tilera.com)
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 3, or (at your
+;; option) any later version.
+;;
+;; GCC is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+;; License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3. If not see
+;; <http://www.gnu.org/licenses/>.
+
+(define_constants [
+ ;;
+ ;; The following represent intrinsic insns, organized by latency.
+ ;;
+
+ ;; single cycle
+ (UNSPEC_INSN_ADDR_SHL16INSLI 1)
+ (UNSPEC_INSN_BFEXTS 2)
+ (UNSPEC_INSN_BFEXTU 3)
+ (UNSPEC_INSN_BFINS 4)
+ (UNSPEC_INSN_CRC32_32 5)
+ (UNSPEC_INSN_CRC32_8 6)
+ (UNSPEC_INSN_DBLALIGN 7)
+ (UNSPEC_INSN_DBLALIGN2 8)
+ (UNSPEC_INSN_DBLALIGN4 9)
+ (UNSPEC_INSN_DBLALIGN6 10)
+ (UNSPEC_INSN_DRAIN 11)
+ (UNSPEC_INSN_DTLBPR 12)
+ (UNSPEC_INSN_FINV 13)
+ (UNSPEC_INSN_FLUSH 14)
+ (UNSPEC_INSN_FLUSHWB 15)
+ (UNSPEC_INSN_FNOP 16)
+ (UNSPEC_INSN_ICOH 17)
+ (UNSPEC_INSN_ILL 18)
+ (UNSPEC_INSN_INFO 19)
+ (UNSPEC_INSN_INFOL 20)
+ (UNSPEC_INSN_INV 21)
+ (UNSPEC_INSN_LNK 22)
+ (UNSPEC_INSN_MFSPR 23)
+ (UNSPEC_INSN_MM 24)
+ (UNSPEC_INSN_MTSPR 25)
+ (UNSPEC_INSN_NAP 26)
+ (UNSPEC_INSN_PREFETCH_L1_FAULT 27)
+ (UNSPEC_INSN_PREFETCH_L2_FAULT 28)
+ (UNSPEC_INSN_PREFETCH_L3_FAULT 29)
+ (UNSPEC_INSN_REVBITS 30)
+ (UNSPEC_INSN_SHUFFLEBYTES 31)
+ (UNSPEC_INSN_TBLIDXB0 32)
+ (UNSPEC_INSN_TBLIDXB1 33)
+ (UNSPEC_INSN_TBLIDXB2 34)
+ (UNSPEC_INSN_TBLIDXB3 35)
+ (UNSPEC_INSN_V1AVGU 36)
+ (UNSPEC_INSN_V2AVGS 37)
+ (UNSPEC_INSN_WH64 38)
+
+ ;; 2 cycles
+ (UNSPEC_INSN_CMUL 100)
+ (UNSPEC_INSN_CMULA 101)
+ (UNSPEC_INSN_CMULAF 102)
+ (UNSPEC_INSN_CMULFR 103)
+ (UNSPEC_INSN_CMULHR 104)
+ (UNSPEC_INSN_CMULF 105)
+ (UNSPEC_INSN_CMULH 106)
+ (UNSPEC_INSN_EXCH 107)
+ (UNSPEC_INSN_FDOUBLE_ADDSUB 108)
+ (UNSPEC_INSN_FDOUBLE_ADD_FLAGS 109)
+ (UNSPEC_INSN_FDOUBLE_MUL_FLAGS 110)
+ (UNSPEC_INSN_FDOUBLE_PACK1 111)
+ (UNSPEC_INSN_FDOUBLE_PACK2 112)
+ (UNSPEC_INSN_FDOUBLE_SUB_FLAGS 113)
+ (UNSPEC_INSN_FDOUBLE_UNPACK_MAX 114)
+ (UNSPEC_INSN_FDOUBLE_UNPACK_MIN 115)
+ (UNSPEC_INSN_FETCHADDGEZ 116)
+ (UNSPEC_INSN_FSINGLE_ADD1 117)
+ (UNSPEC_INSN_FSINGLE_ADDSUB2 118)
+ (UNSPEC_INSN_FSINGLE_MUL1 119)
+ (UNSPEC_INSN_FSINGLE_MUL2 120)
+ (UNSPEC_INSN_FSINGLE_PACK1 121)
+ (UNSPEC_INSN_FSINGLE_PACK2 122)
+ (UNSPEC_INSN_FSINGLE_SUB1 123)
+ (UNSPEC_INSN_MULAX 124)
+ (UNSPEC_INSN_MULA_HS_HS 125)
+ (UNSPEC_INSN_MULA_HS_HU 126)
+ (UNSPEC_INSN_MULA_HS_LS 127)
+ (UNSPEC_INSN_MULA_HS_LU 128)
+ (UNSPEC_INSN_MULA_HU_HU 129)
+ (UNSPEC_INSN_MULA_HU_LS 130)
+ (UNSPEC_INSN_MULA_HU_LU 131)
+ (UNSPEC_INSN_MULA_LS_LS 132)
+ (UNSPEC_INSN_MULA_LS_LU 133)
+ (UNSPEC_INSN_MULA_LU_LU 134)
+ (UNSPEC_INSN_MUL_HS_HS 135)
+ (UNSPEC_INSN_MUL_HS_HU 136)
+ (UNSPEC_INSN_MUL_HS_LS 137)
+ (UNSPEC_INSN_MUL_HS_LU 138)
+ (UNSPEC_INSN_MUL_HU_HU 139)
+ (UNSPEC_INSN_MUL_HU_LS 140)
+ (UNSPEC_INSN_MUL_HU_LU 141)
+ (UNSPEC_INSN_MUL_LS_LS 142)
+ (UNSPEC_INSN_MUL_LS_LU 143)
+ (UNSPEC_INSN_MUL_LU_LU 144)
+ (UNSPEC_INSN_V1ADIFFU 145)
+ (UNSPEC_INSN_V1DDOTPU 146)
+ (UNSPEC_INSN_V1DDOTPUA 147)
+ (UNSPEC_INSN_V1DDOTPUS 148)
+ (UNSPEC_INSN_V1DDOTPUSA 149)
+ (UNSPEC_INSN_V1DOTP 150)
+ (UNSPEC_INSN_V1DOTPA 151)
+ (UNSPEC_INSN_V1DOTPU 152)
+ (UNSPEC_INSN_V1DOTPUA 153)
+ (UNSPEC_INSN_V1DOTPUS 154)
+ (UNSPEC_INSN_V1DOTPUSA 155)
+ (UNSPEC_INSN_V1SADAU 156)
+ (UNSPEC_INSN_V1SADU 157)
+ (UNSPEC_INSN_V2ADIFFS 158)
+ (UNSPEC_INSN_V2DOTP 159)
+ (UNSPEC_INSN_V2DOTPA 160)
+ (UNSPEC_INSN_V2MULFSC 161)
+ (UNSPEC_INSN_V2SADAS 162)
+ (UNSPEC_INSN_V2SADAU 163)
+ (UNSPEC_INSN_V2SADS 164)
+ (UNSPEC_INSN_V2SADU 165)
+
+ ;; 11 cycles
+ (UNSPEC_INSN_CMPEXCH 200)
+
+ ;;
+ ;; The following are special insns.
+ ;;
+
+ ;; Blockage
+ (UNSPEC_BLOCKAGE 201)
+
+ ;; Lnk and its label
+ (UNSPEC_LNK_AND_LABEL 202)
+
+ ;; Memory fence
+ (UNSPEC_MF 203)
+
+ ;; Insns generating difference of two labels
+ (UNSPEC_MOV_PCREL_STEP3 204)
+ (UNSPEC_MOV_LARGE_PCREL_STEP4 205)
+
+ ;; Latency specifying loads.
+ (UNSPEC_LATENCY_L2 206)
+ (UNSPEC_LATENCY_MISS 207)
+
+ ;; A pseudo-op that prevents network operations from being ordered.
+ (UNSPEC_NETWORK_BARRIER 208)
+
+ ;; Operations that access network registers.
+ (UNSPEC_NETWORK_RECEIVE 209)
+ (UNSPEC_NETWORK_SEND 210)
+
+ ;; Stack protector operations
+ (UNSPEC_SP_SET 211)
+ (UNSPEC_SP_TEST 212)
+
+ ;; This is used to move a value to a SPR.
+ (UNSPEC_SPR_MOVE 213)
+
+ ;; A call to __tls_get_addr
+ (UNSPEC_TLS_GD_CALL 214)
+
+ ;; An opaque TLS "add" operation for TLS general dynamic model
+ ;; access.
+ (UNSPEC_TLS_GD_ADD 215)
+
+ ;; An opaque TLS "load" operation for TLS initial exec model access.
+ (UNSPEC_TLS_IE_LOAD 216)
+
+ ;; An opaque TLS "add" operation for TLS access.
+ (UNSPEC_TLS_ADD 217)
+
+ ;; Atomics
+ (UNSPEC_ATOMIC 218)
+ (UNSPEC_CMPXCHG 219)
+ (UNSPEC_XCHG 220)
+
+ ;;
+ ;; The following are operands.
+ ;;
+ (UNSPEC_HW0 300)
+ (UNSPEC_HW1 301)
+ (UNSPEC_HW2 302)
+ (UNSPEC_HW3 303)
+ (UNSPEC_HW0_LAST 304)
+ (UNSPEC_HW1_LAST 305)
+ (UNSPEC_HW2_LAST 306)
+
+ (UNSPEC_HW0_PCREL 307)
+ (UNSPEC_HW1_PCREL 308)
+ (UNSPEC_HW1_LAST_PCREL 309)
+ (UNSPEC_HW2_LAST_PCREL 310)
+
+ (UNSPEC_HW0_GOT 311)
+ (UNSPEC_HW0_LAST_GOT 312)
+ (UNSPEC_HW1_LAST_GOT 313)
+
+ (UNSPEC_HW0_TLS_GD 314)
+ (UNSPEC_HW1_LAST_TLS_GD 315)
+
+ (UNSPEC_HW0_TLS_IE 316)
+ (UNSPEC_HW1_LAST_TLS_IE 317)
+
+ (UNSPEC_HW0_TLS_LE 318)
+ (UNSPEC_HW1_LAST_TLS_LE 319)
+
+ (UNSPEC_HW0_PLT_PCREL 320)
+ (UNSPEC_HW1_PLT_PCREL 321)
+
+ (UNSPEC_HW1_LAST_PLT_PCREL 322)
+ (UNSPEC_HW2_LAST_PLT_PCREL 323)
+
+ ;; This is used to wrap around the addresses of non-temporal load/store
+ ;; intrinsics.
+ (UNSPEC_NON_TEMPORAL 324)
+])
+
+;; Mark the last instruction of various latencies, used to
+;; determine the rtx costs of unspec insns.
+(define_constants [
+ (TILEGX_LAST_LATENCY_1_INSN 99)
+ (TILEGX_LAST_LATENCY_2_INSN 199)
+ (TILEGX_LAST_LATENCY_INSN 299)
+])
+
+(define_constants [
+ (TILEGX_NETREG_IDN0 0)
+ (TILEGX_NETREG_IDN1 1)
+ (TILEGX_NETREG_UDN0 2)
+ (TILEGX_NETREG_UDN1 3)
+ (TILEGX_NETREG_UDN2 4)
+ (TILEGX_NETREG_UDN3 5)
+])
+
+(define_constants [
+ (TILEGX_CMPEXCH_REG 66)
+ (TILEGX_NETORDER_REG 67)
+])
+
+
+;; Operand and operator predicates and constraints
+
+(include "predicates.md")
+(include "constraints.md")
+(include "tilegx-generic.md")
+
+;; Define an insn type attribute. This defines what pipes things can go in.
+(define_attr "type"
+ "X0,X0_2cycle,X1,X1_branch,X1_2cycle,X1_L2,X1_remote,X1_miss,X01,Y0,Y0_2cycle,Y1,Y2,Y2_2cycle,Y2_L2,Y2_miss,Y01,cannot_bundle,cannot_bundle_3cycle,cannot_bundle_4cycle,nothing"
+ (const_string "Y01"))
+
+(define_attr "length" ""
+ (cond [(eq_attr "type" "X1_branch")
+ (if_then_else
+ (and (le (minus (match_dup 0) (pc)) (const_int 524280))
+ (le (minus (pc) (match_dup 0)) (const_int 524288)))
+ (const_int 8)
+ (const_int 16))
+ ]
+ (const_int 8)))
+
+
+;; Define some iterators.
+(define_mode_iterator IVMODE [SI DI V8QI V4HI V2SI])
+(define_mode_iterator IVNMODE [SI V8QI V4HI V2SI])
+(define_mode_iterator I48MODE [SI DI])
+(define_mode_iterator I48MODE2 [SI DI])
+(define_mode_iterator I124MODE [QI HI SI])
+(define_mode_iterator FI48MODE [SF DF SI DI])
+(define_mode_iterator VEC48MODE [V8QI V4HI])
+(define_mode_iterator VEC248MODE [V8QI V4HI V2SI])
+
+(define_mode_attr n [(QI "1") (HI "2") (SI "4") (DI "")
+ (V8QI "1") (V4HI "2") (V2SI "4")])
+(define_mode_attr x [(SI "x") (DI "")])
+(define_mode_attr bitsuffix [(SI "_32bit") (DI "")])
+(define_mode_attr four_if_si [(SI "4") (DI "")])
+(define_mode_attr four_s_if_si [(SI "4s") (DI "")])
+(define_mode_attr nbits [(SI "5") (DI "6")])
+(define_mode_attr shift_pipe [(SI "X01") (DI "*")])
+
+;; Code iterator for either extend.
+(define_code_iterator any_extend [sign_extend zero_extend])
+
+;; Code iterator for all three shifts.
+(define_code_iterator any_shift [ashift ashiftrt lshiftrt])
+
+;; Code iterator for all byte ops without immediate variants.
+(define_code_iterator v1op [us_minus us_plus minus ne le leu mult])
+
+;; Code iterator for all 2-byte vector ops without immediate variants.
+(define_code_iterator v2op [ss_minus ss_plus minus ne le leu])
+
+;; Code iterator for all 4-byte vector ops without immediate variants.
+(define_code_iterator v4op [ss_minus ss_plus minus plus])
+
+;; Code iterator for all byte vector ops with immediate variants.
+(define_code_iterator v1op_immed [plus umax umin eq lt ltu])
+
+;; Code iterator for all 2-byte vector ops with immediate variants.
+(define_code_iterator v2op_immed [plus smax smin eq lt ltu])
+
+;; Code iterator for all 2-byte vector shifts without immediate variants.
+(define_code_iterator v2shift [ss_ashift])
+
+;; Code iterator for all 4-byte vector shifts without immediate variants.
+(define_code_iterator v4shift [ashift ashiftrt lshiftrt ss_ashift])
+
+;; <optab> expands to the name of the optab for a particular code.
+(define_code_attr optab [(ashift "ashl")
+ (ashiftrt "ashr")
+ (lshiftrt "lshr")
+ (ss_ashift "ssashl")
+ (eq "seq")
+ (ne "sne")
+ (lt "slt")
+ (ltu "sltu")
+ (le "sle")
+ (leu "sleu")
+ (minus "sub")
+ (plus "add")
+ (mult "mul")
+ (smax "smax")
+ (smin "smin")
+ (ss_minus "sssub")
+ (ss_plus "ssadd")
+ (umax "umax")
+ (umin "umin")
+ (us_minus "ussub")
+ (us_plus "usadd")
+ ])
+
+;; <insn> expands to the name of the insn that implements a particular
+;; code.
+(define_code_attr insn [(ashift "shl")
+ (ashiftrt "shrs")
+ (lshiftrt "shru")
+ (ss_ashift "shlsc")
+ (eq "cmpeq")
+ (ne "cmpne")
+ (lt "cmplts")
+ (ltu "cmpltu")
+ (le "cmples")
+ (leu "cmpleu")
+ (minus "sub")
+ (plus "add")
+ (mult "multu")
+ (smax "maxs")
+ (smin "mins")
+ (umax "maxu")
+ (umin "minu")
+ (ss_minus "subsc")
+ (ss_plus "addsc")
+ (us_minus "subuc")
+ (us_plus "adduc")
+ ])
+
+;; <pipe> expands to the pipeline resource that contains the
+;; particular code.
+(define_code_attr pipe [(ashift "X01")
+ (ashiftrt "X01")
+ (lshiftrt "X01")
+ (ss_ashift "X01")
+ (eq "X01")
+ (ne "X01")
+ (lt "X01")
+ (ltu "X01")
+ (le "X01")
+ (leu "X01")
+ (minus "X01")
+ (plus "X01")
+ (mult "X0_2cycle")
+ (smax "X01")
+ (smin "X01")
+ (umax "X01")
+ (umin "X01")
+ (ss_minus "X01")
+ (ss_plus "X01")
+ (us_minus "X01")
+ (us_plus "X01")
+ ])
+
+;; <comm> indicates whether a particular code is commutative, using
+;; the "%" commutative opterator constraint.
+(define_code_attr comm [(ashift "")
+ (ashiftrt "")
+ (lshiftrt "")
+ (ss_ashift "")
+ (eq "%")
+ (ne "%")
+ (lt "")
+ (ltu "")
+ (le "")
+ (leu "")
+ (minus "")
+ (plus "%")
+ (mult "%")
+ (smin "%")
+ (umin "%")
+ (smax "%")
+ (umax "%")
+ (ss_plus "%")
+ (us_plus "%")
+ (ss_minus "")
+ (us_minus "")
+ ])
+
+;; <s> is the load/store extension suffix.
+(define_code_attr s [(zero_extend "u")
+ (sign_extend "s")])
+
+;; Code for packing two 2-byte vectors.
+(define_code_iterator v2pack [truncate us_truncate])
+
+;; <pack_optab> expands to the part of the optab name describing how
+;; two vectors are packed.
+(define_code_attr pack_optab [(truncate "trunc")
+ (us_truncate "usat")
+ (ss_truncate "ssat")])
+
+;; <pack_insn> expands to the insn that implements a particular vector
+;; packing code.
+(define_code_attr pack_insn [(truncate "packl")
+ (us_truncate "packuc")
+ (ss_truncate "packsc")])
+
+;;
+;; The basic data move insns.
+;;
+
+(define_expand "movqi"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "")
+ (match_operand:QI 1 "nonautoinc_operand" ""))]
+ ""
+{
+ if (tilegx_expand_mov (QImode, operands))
+ DONE;
+})
+
+(define_insn "*movqi_insn"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,r,U,m")
+ (match_operand:QI 1 "move_operand" "r,I,U,m,rO,rO"))]
+ "(register_operand (operands[0], QImode)
+ || reg_or_0_operand (operands[1], QImode))"
+ "@
+ move\t%0, %r1
+ movei\t%0, %1
+ ld1u\t%0, %1
+ ld1u_add\t%0, %I1, %i1
+ st1\t%0, %r1
+ st1_add\t%I0, %r1, %i0"
+ [(set_attr "type" "*,*,Y2_2cycle,X1_2cycle,Y2,X1")])
+
+(define_expand "movhi"
+ [(set (match_operand:HI 0 "nonimmediate_operand" "")
+ (match_operand:HI 1 "nonautoinc_operand" ""))]
+ ""
+{
+ if (tilegx_expand_mov (HImode, operands))
+ DONE;
+})
+
+(define_insn "*movhi_insn"
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,r,r,U,m")
+ (match_operand:HI 1 "move_operand" "r,I,JT,U,m,rO,rO"))]
+ "(register_operand (operands[0], HImode)
+ || reg_or_0_operand (operands[1], HImode))"
+ "@
+ move\t%0, %r1
+ movei\t%0, %1
+ moveli\t%0, %H1
+ ld2u\t%0, %1
+ ld2u_add\t%0, %I1, %i1
+ st2\t%0, %r1
+ st2_add\t%I0, %r1, %i0"
+ [(set_attr "type" "*,*,X01,Y2_2cycle,X1_2cycle,Y2,X1")])
+
+(define_expand "movsi"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
+ (match_operand:SI 1 "nonautoinc_operand" ""))]
+ ""
+{
+ if (tilegx_expand_mov (SImode, operands))
+ DONE;
+})
+
+(define_insn "*movsi_insn"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,U,m")
+ (match_operand:SI 1 "move_operand" "r,I,JT,K,U,m,rO,rO"))]
+ "(register_operand (operands[0], SImode)
+ || reg_or_0_operand (operands[1], SImode))"
+ "@
+ move\t%0, %r1
+ movei\t%0, %1
+ moveli\t%0, %H1
+ shl16insli\t%0, zero, %h1
+ ld4s\t%0, %1
+ ld4s_add\t%0, %I1, %i1
+ st4\t%0, %r1
+ st4_add\t%I0, %r1, %i0"
+ [(set_attr "type" "*,*,X01,X01,Y2_2cycle,X1_2cycle,Y2,X1")])
+
+(define_expand "movdi"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
+ (match_operand:DI 1 "nonautoinc_operand" ""))]
+ ""
+{
+ if (tilegx_expand_mov (DImode, operands))
+ DONE;
+})
+
+(define_insn "*movdi_insn"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,r,r,U,m")
+ (match_operand:DI 1 "move_operand" "r,I,JT,K,N,P,U,m,rO,rO"))]
+ "(register_operand (operands[0], DImode)
+ || reg_or_0_operand (operands[1], DImode))"
+ "@
+ move\t%0, %r1
+ movei\t%0, %1
+ moveli\t%0, %H1
+ shl16insli\t%0, zero, %h1
+ v1addi\t%0, zero, %j1
+ v2addi\t%0, zero, %h1
+ ld\t%0, %1
+ ld_add\t%0, %I1, %i1
+ st\t%0, %r1
+ st_add\t%I0, %r1, %i0"
+ [(set_attr "type" "*,*,X01,X01,X01,X01,Y2_2cycle,X1_2cycle,Y2,X1")])
+
+(define_expand "movmisalign<mode>"
+ [(set (match_operand:VEC248MODE 0 "nonautoincmem_nonimmediate_operand" "")
+ (match_operand:VEC248MODE 1 "nonautoincmem_general_operand" ""))]
+ ""
+{
+ tilegx_expand_movmisalign (<MODE>mode, operands);
+ DONE;
+})
+
+(define_expand "movsf"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "")
+ (match_operand:SF 1 "general_operand" ""))]
+ ""
+{
+ /* Materialize immediates using clever SImode code, but don't
+ do this after reload starts, since gen_lowpart will choke
+ during reload if given an illegitimate address. */
+ if (immediate_operand (operands[1], SFmode)
+ && operands[1] != const0_rtx
+ && (register_operand (operands[0], SFmode)
+ || (!reload_in_progress && !reload_completed)))
+ {
+ emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
+ gen_lowpart (SImode, operands[1])));
+ DONE;
+ }
+})
+
+(define_insn "*movsf"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,U,m")
+ (match_operand:SF 1 "general_operand" "rO,U,m,rO,rO"))]
+ ""
+ "@
+ move\t%0, %r1
+ ld4s\t%0, %1
+ ld4s_add\t%0, %I1, %i1
+ st4\t%0, %r1
+ st4_add\t%I0, %r1, %i0"
+ [(set_attr "type" "*,Y2_2cycle,X1_2cycle,Y2,X1")])
+
+(define_expand "movdf"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "")
+ (match_operand:DF 1 "general_operand" ""))]
+ ""
+{
+ /* Materialize immediates using clever DImode code, but don't
+ do this after reload starts, since gen_lowpart will choke
+ during reload if given an illegitimate address. */
+ if (immediate_operand (operands[1], DFmode)
+ && operands[1] != const0_rtx
+ && (register_operand (operands[0], DFmode)
+ || (!reload_in_progress && !reload_completed)))
+ {
+ emit_insn (gen_movdi (gen_lowpart (DImode, operands[0]),
+ gen_lowpart (DImode, operands[1])));
+ DONE;
+ }
+})
+
+(define_insn "*movdf"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,r,U,m")
+ (match_operand:DF 1 "general_operand" "rO,U,m,rO,rO"))]
+ ""
+ "@
+ move\t%0, %r1
+ ld\t%0, %1
+ ld_add\t%0, %I1, %i1
+ st\t%0, %r1
+ st_add\t%I0, %r1, %i0"
+ [(set_attr "type" "*,Y2_2cycle,X1_2cycle,Y2,X1")])
+
+(define_expand "mov<mode>"
+ [(set (match_operand:VEC248MODE 0 "nonimmediate_operand" "")
+ (match_operand:VEC248MODE 1 "general_operand" ""))]
+ ""
+{
+ /* Materialize immediates using clever DImode code, but don't
+ do this after reload starts, since gen_lowpart will choke
+ during reload if given an illegitimate address. */
+ if (immediate_operand (operands[1], <MODE>mode)
+ && operands[1] != const0_rtx
+ && (register_operand (operands[0], <MODE>mode)
+ || (!reload_in_progress && !reload_completed)))
+ {
+ emit_insn (gen_movdi (gen_lowpart (DImode, operands[0]),
+ gen_lowpart (DImode, operands[1])));
+ DONE;
+ }
+})
+
+(define_insn "*mov<mode>"
+ [(set (match_operand:VEC248MODE 0 "nonimmediate_operand" "=r,r,r,U,m")
+ (match_operand:VEC248MODE 1 "general_operand" "rO,U,m,rO,rO"))]
+ ""
+ "@
+ move\t%0, %r1
+ ld\t%0, %1
+ ld_add\t%0, %I1, %i1
+ st\t%0, %r1
+ st_add\t%I0, %r1, %i0"
+ [(set_attr "type" "*,Y2_2cycle,X1_2cycle,Y2,X1")])
+
+(define_insn "movstrictqi"
+ [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r"))
+ (match_operand:QI 1 "reg_or_0_operand" "rO"))]
+ ""
+ "bfins\t%0, %r1, 0, 7"
+ [(set_attr "type" "X0")])
+
+(define_insn "movstricthi"
+ [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
+ (match_operand:HI 1 "reg_or_0_operand" "rO"))]
+ ""
+ "bfins\t%0, %r1, 0, 15"
+ [(set_attr "type" "X0")])
+
+(define_insn "movstrictsi"
+ [(set (strict_low_part (match_operand:SI 0 "register_operand" "+r"))
+ (match_operand:SI 1 "reg_or_0_operand" "rO"))]
+ ""
+ "bfins\t%0, %r1, 0, 31"
+ [(set_attr "type" "X0")])
+
+
+;;
+;; Bit-field extracts/inserts
+;;
+
+(define_expand "insv"
+ [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "u6bit_cint_operand" "")
+ (match_operand:DI 2 "u6bit_cint_operand" ""))
+ (match_operand:DI 3 "reg_or_cint_operand" ""))]
+ ""
+{
+ rtx first_rtx = operands[2];
+ HOST_WIDE_INT first = INTVAL (first_rtx);
+ HOST_WIDE_INT width = INTVAL (operands[1]);
+ rtx v = operands[3];
+
+ if (CONST_INT_P (v))
+ {
+ /* Which bits are we affecting? */
+ HOST_WIDE_INT mask = ((((HOST_WIDE_INT) 1) << width) - 1) << first;
+
+ /* Extract just the bits we need, sign extending them to make the
+ constant easier to materialize in a register. */
+ int shift = sizeof(HOST_WIDE_INT) * 8 - width;
+ HOST_WIDE_INT n = (INTVAL (v) << shift) >> shift;
+
+ if (n == 0)
+ {
+ /* We are setting every bit in the bitfield to zero. Try to use
+ andi instead, since that is more efficient. */
+ rtx mask_rtx = GEN_INT (~mask);
+ if (satisfies_constraint_I (mask_rtx))
+ {
+ emit_insn (gen_anddi3 (operands[0], operands[0], mask_rtx));
+ DONE;
+ }
+
+ operands[3] = const0_rtx;
+ }
+ else
+ {
+ if (n == -1)
+ {
+ /* We are setting every bit in the bitfield to one. Try to use
+ ori instead, since that is more efficient. */
+ rtx mask_rtx = GEN_INT (mask);
+ if (satisfies_constraint_I (mask_rtx))
+ {
+ emit_insn (gen_iordi3 (operands[0], operands[0], mask_rtx));
+ DONE;
+ }
+ }
+
+ if (!can_create_pseudo_p ())
+ FAIL;
+
+ operands[3] = force_reg (DImode, GEN_INT (n));
+ }
+ }
+})
+
+(define_insn "*insv_tblidxb0"
+ [(set (zero_extract:DI
+ (match_operand:DI 0 "register_operand" "+r")
+ (const_int 8)
+ (const_int 2))
+ (match_operand:DI 1 "register_operand" "rO"))]
+ ""
+ "tblidxb0\t%0, %r1"
+ [(set_attr "type" "Y0")])
+
+(define_insn "*insv_tblidxb1"
+ [(set (zero_extract:DI
+ (match_operand:DI 0 "register_operand" "+r")
+ (const_int 8)
+ (const_int 2))
+ (zero_extract:DI
+ (const_int 8)
+ (const_int 8)
+ (match_operand:DI 1 "register_operand" "rO")))]
+ ""
+ "tblidxb1\t%0, %r1"
+ [(set_attr "type" "Y0")])
+
+(define_insn "*insv_tblidxb2"
+ [(set (zero_extract:DI
+ (match_operand:DI 0 "register_operand" "+r")
+ (const_int 8)
+ (const_int 2))
+ (zero_extract:DI
+ (const_int 8)
+ (const_int 16)
+ (match_operand:DI 1 "register_operand" "rO")))]
+ ""
+ "tblidxb2\t%0, %r1"
+ [(set_attr "type" "Y0")])
+
+(define_insn "*insv_tblidxb3"
+ [(set (zero_extract:DI
+ (match_operand:DI 0 "register_operand" "+r")
+ (const_int 8)
+ (const_int 2))
+ (zero_extract:DI
+ (const_int 8)
+ (const_int 24)
+ (match_operand:DI 1 "register_operand" "rO")))]
+ ""
+ "tblidxb3\t%0, %r1"
+ [(set_attr "type" "Y0")])
+
+(define_insn "*insv_bfins"
+ [(set (zero_extract:DI
+ (match_operand:DI 0 "register_operand" "+r")
+ (match_operand:DI 1 "u6bit_cint_operand" "n")
+ (match_operand:DI 2 "u6bit_cint_operand" "n"))
+ (match_operand:DI 3 "reg_or_cint_operand" "rO"))]
+ ""
+ "bfins\t%0, %r3, %2, %2+%1-1"
+ [(set_attr "type" "X0")])
+
+(define_insn "*insv_mm"
+ [(set (zero_extract:DI
+ (match_operand:DI 0 "register_operand" "+r")
+ (match_operand:DI 1 "u6bit_cint_operand" "n")
+ (match_operand:DI 2 "u6bit_cint_operand" "n"))
+ (zero_extract:DI
+ (match_operand:DI 3 "register_operand" "rO")
+ (match_dup 1)
+ (match_dup 2)))]
+ ""
+{
+ int n;
+
+ operands[1] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[2]));
+
+ n = INTVAL (operands[2]);
+ n = (n == 0) ? 63 : n - 1;
+ operands[2] = GEN_INT (n);
+
+ return "mm\t%0, %r3, %1, %2";
+}
+ [(set_attr "type" "X0")])
+
+(define_expand "extv"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (sign_extract:DI (match_operand 1 "nonautoincmem_general_operand" "")
+ (match_operand:DI 2 "immediate_operand" "")
+ (match_operand:DI 3 "immediate_operand" "")))]
+ ""
+{
+ if (MEM_P (operands[1]))
+ {
+ HOST_WIDE_INT bit_offset, bit_width;
+ HOST_WIDE_INT first_byte_offset, last_byte_offset;
+
+ if (GET_MODE (operands[1]) != QImode)
+ FAIL;
+
+ bit_width = INTVAL (operands[2]);
+ bit_offset = INTVAL (operands[3]);
+
+ /* Reject bitfields that can be done with a normal load. */
+ if (MEM_ALIGN (operands[1]) >= bit_offset + bit_width)
+ FAIL;
+
+ /* The value in memory cannot span more than 8 bytes. */
+ first_byte_offset = bit_offset / BITS_PER_UNIT;
+ last_byte_offset = (bit_offset + bit_width - 1) / BITS_PER_UNIT;
+ if (last_byte_offset - first_byte_offset > 7)
+ FAIL;
+
+ tilegx_expand_unaligned_load (operands[0], operands[1],
+ bit_width, bit_offset, 1);
+
+ DONE;
+ }
+
+ operands[1] = force_reg (DImode, operands[1]);
+})
+
+(define_expand "extzv"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (zero_extract:DI (match_operand 1 "nonautoincmem_general_operand" "")
+ (match_operand:DI 2 "immediate_operand" "")
+ (match_operand:DI 3 "immediate_operand" "")))]
+ ""
+{
+ HOST_WIDE_INT bit_width = INTVAL (operands[2]);
+ HOST_WIDE_INT bit_offset = INTVAL (operands[3]);
+
+ if (MEM_P (operands[1]))
+ {
+ HOST_WIDE_INT first_byte_offset, last_byte_offset;
+
+ if (GET_MODE (operands[1]) != QImode)
+ FAIL;
+
+ /* Reject bitfields that can be done with a normal load. */
+ if (MEM_ALIGN (operands[1]) >= bit_offset + bit_width)
+ FAIL;
+
+ /* The value in memory cannot span more than 8 bytes. */
+ first_byte_offset = bit_offset / BITS_PER_UNIT;
+ last_byte_offset = (bit_offset + bit_width - 1) / BITS_PER_UNIT;
+ if (last_byte_offset - first_byte_offset > 7)
+ FAIL;
+
+ tilegx_expand_unaligned_load (operands[0], operands[1],
+ bit_width, bit_offset, 0);
+
+ DONE;
+ }
+
+ operands[1] = force_reg (DImode, operands[1]);
+
+ if (bit_offset == 0)
+ {
+ /* Extracting the low bits is just a bitwise AND. */
+ HOST_WIDE_INT mask = ((HOST_WIDE_INT)1 << bit_width) - 1;
+ emit_insn (gen_anddi3 (operands[0], operands[1], GEN_INT (mask)));
+ DONE;
+ }
+})
+
+
+;;
+;; Addresses
+;;
+
+;; The next three patterns are used to to materialize a position
+;; independent address by adding the difference of two labels to a base
+;; label in the text segment, assuming that the difference fits in 32
+;; signed bits.
+(define_expand "mov_address_step1"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (const:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
+ UNSPEC_HW2_LAST)))])
+
+(define_expand "mov_address_step2"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (unspec:DI
+ [(match_operand:DI 1 "reg_or_0_operand" "")
+ (const:DI (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
+ UNSPEC_HW1))]
+ UNSPEC_INSN_ADDR_SHL16INSLI))])
+
+(define_expand "mov_address_step3"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (unspec:DI
+ [(match_operand:DI 1 "reg_or_0_operand" "")
+ (const:DI (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
+ UNSPEC_HW0))]
+ UNSPEC_INSN_ADDR_SHL16INSLI))])
+
+;; First step of the 2-insn sequence to materialize a 32-bit symbolic
+;; address.
+(define_expand "mov_address_32bit_step1"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (const:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "")]
+ UNSPEC_HW1_LAST)))])
+
+;; Second step of the 2-insn sequence to materialize a 32-bit symbolic
+;; address.
+(define_expand "mov_address_32bit_step2"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (unspec:SI
+ [(match_operand:SI 1 "reg_or_0_operand" "")
+ (const:SI (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")]
+ UNSPEC_HW0))]
+ UNSPEC_INSN_ADDR_SHL16INSLI))])
+
+
+;;
+;; pic related instructions
+;;
+
+;; NOTE: We compute the label in this unusual way because if we place
+;; the label after the lnk, whether it is at the same address as the
+;; lnk will vary depending on whether the optimization level chooses
+;; to insert bundling braces.
+(define_insn "insn_lnk_and_label<bitsuffix>"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (unspec_volatile:I48MODE
+ [(match_operand:I48MODE 1 "symbolic_operand" "")]
+ UNSPEC_LNK_AND_LABEL))]
+ ""
+ "%1 = . + 8\n\tlnk\t%0"
+ [(set_attr "type" "Y1")])
+
+;; The next three patterns are used to to materialize a position
+;; independent address by adding the difference of two labels to a
+;; base label in the text segment, assuming that the difference fits
+;; in 32 signed bits.
+(define_expand "mov_pcrel_step1<bitsuffix>"
+ [(set (match_operand:I48MODE 0 "register_operand" "")
+ (const:I48MODE (unspec:I48MODE
+ [(match_operand:I48MODE 1 "symbolic_operand" "")
+ (match_operand:I48MODE 2 "symbolic_operand" "")]
+ UNSPEC_HW1_LAST_PCREL)))]
+ "flag_pic")
+
+(define_expand "mov_pcrel_step2<bitsuffix>"
+ [(set (match_operand:I48MODE 0 "register_operand" "")
+ (unspec:I48MODE
+ [(match_operand:I48MODE 1 "reg_or_0_operand" "")
+ (const:I48MODE
+ (unspec:I48MODE [(match_operand:I48MODE 2 "symbolic_operand" "")
+ (match_operand:I48MODE 3 "symbolic_operand" "")]
+ UNSPEC_HW0_PCREL))]
+ UNSPEC_INSN_ADDR_SHL16INSLI))]
+ "flag_pic")
+
+(define_insn "mov_pcrel_step3<bitsuffix>"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (unspec:I48MODE [(match_operand:I48MODE 1 "reg_or_0_operand" "rO")
+ (match_operand:I48MODE 2 "reg_or_0_operand" "rO")
+ (match_operand:I48MODE 3 "symbolic_operand" "in")
+ (match_operand:I48MODE 4 "symbolic_operand" "in")]
+ UNSPEC_MOV_PCREL_STEP3))]
+ "flag_pic"
+ "add<x>\t%0, %r1, %r2")
+
+;; The next three patterns are used to to materialize a position
+;; independent 64-bit address by adding the difference of two labels to
+;; a base label in the text segment, without any limitation on the size
+;; of the difference.
+(define_expand "mov_large_pcrel_step1"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (const:DI (unspec:DI
+ [(match_operand:DI 1 "symbolic_operand" "")
+ (match_operand:DI 2 "symbolic_operand" "")]
+ UNSPEC_HW2_LAST_PCREL)))]
+ "flag_pic")
+
+(define_expand "mov_large_pcrel_step2"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (unspec:DI
+ [(match_operand:DI 1 "reg_or_0_operand" "")
+ (const:DI
+ (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")
+ (match_operand:DI 3 "symbolic_operand" "")]
+ UNSPEC_HW1_PCREL))]
+ UNSPEC_INSN_ADDR_SHL16INSLI))]
+ "flag_pic")
+
+;; Note: step 3 is same as move_pcrel_step2.
+(define_expand "mov_large_pcrel_step3"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (unspec:DI
+ [(match_operand:DI 1 "reg_or_0_operand" "")
+ (const:DI
+ (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")
+ (match_operand:DI 3 "symbolic_operand" "")]
+ UNSPEC_HW0_PCREL))]
+ UNSPEC_INSN_ADDR_SHL16INSLI))]
+ "flag_pic")
+
+(define_insn "mov_large_pcrel_step4"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")
+ (match_operand:DI 3 "symbolic_operand" "in")
+ (match_operand:DI 4 "symbolic_operand" "in")]
+ UNSPEC_MOV_LARGE_PCREL_STEP4))]
+ "flag_pic"
+ "add\t%0, %r1, %r2")
+
+;; The next three patterns are used to materialize a position
+;; independent 64-bit plt address by adding the difference of two
+;; labels to a base label in the text segment.
+(define_expand "mov_plt_pcrel_step1"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (const:DI (unspec:DI
+ [(match_operand:DI 1 "symbolic_operand" "")
+ (match_operand:DI 2 "symbolic_operand" "")]
+ UNSPEC_HW2_LAST_PLT_PCREL)))]
+ "flag_pic")
+
+(define_expand "mov_plt_pcrel_step2"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (unspec:DI
+ [(match_operand:DI 1 "reg_or_0_operand" "")
+ (const:DI
+ (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")
+ (match_operand:DI 3 "symbolic_operand" "")]
+ UNSPEC_HW1_PLT_PCREL))]
+ UNSPEC_INSN_ADDR_SHL16INSLI))]
+ "flag_pic")
+
+(define_expand "mov_plt_pcrel_step3"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (unspec:DI
+ [(match_operand:DI 1 "reg_or_0_operand" "")
+ (const:DI
+ (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")
+ (match_operand:DI 3 "symbolic_operand" "")]
+ UNSPEC_HW0_PLT_PCREL))]
+ UNSPEC_INSN_ADDR_SHL16INSLI))]
+ "flag_pic")
+
+;; The next two patterns are used to materialize a position independent
+;; 32-bit plt address by adding the difference of two labels to a base
+;; label in the text segment.
+(define_expand "mov_plt_pcrel_step1_32bit"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (const:SI (unspec:SI
+ [(match_operand:SI 1 "symbolic_operand" "")
+ (match_operand:SI 2 "symbolic_operand" "")]
+ UNSPEC_HW1_LAST_PLT_PCREL)))]
+ "flag_pic")
+
+(define_expand "mov_plt_pcrel_step2_32bit"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (unspec:SI
+ [(match_operand:SI 1 "reg_or_0_operand" "")
+ (const:SI
+ (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")
+ (match_operand:SI 3 "symbolic_operand" "")]
+ UNSPEC_HW0_PLT_PCREL))]
+ UNSPEC_INSN_ADDR_SHL16INSLI))]
+ "flag_pic")
+
+(define_expand "add_got16<bitsuffix>"
+ [(set (match_operand:I48MODE 0 "register_operand" "")
+ (plus:I48MODE
+ (match_operand:I48MODE 1 "reg_or_0_operand" "")
+ (const:I48MODE
+ (unspec:I48MODE [(match_operand:I48MODE 2 "symbolic_operand" "")]
+ UNSPEC_HW0_LAST_GOT))))]
+ "flag_pic == 1")
+
+(define_expand "mov_got32_step1<bitsuffix>"
+ [(set (match_operand:I48MODE 0 "register_operand" "")
+ (const:I48MODE
+ (unspec:I48MODE [(match_operand:I48MODE 1 "symbolic_operand" "")]
+ UNSPEC_HW1_LAST_GOT)))]
+ "flag_pic == 2")
+
+(define_expand "mov_got32_step2<bitsuffix>"
+ [(set (match_operand:I48MODE 0 "register_operand" "")
+ (unspec:I48MODE
+ [(match_operand:I48MODE 1 "reg_or_0_operand" "")
+ (const:I48MODE
+ (unspec:I48MODE [(match_operand:I48MODE 2 "symbolic_operand" "")]
+ UNSPEC_HW0_GOT))]
+ UNSPEC_INSN_ADDR_SHL16INSLI))]
+ "flag_pic == 2")
+
+
+;;
+;; TLS
+;;
+
+(define_expand "mov_tls_gd_step1<bitsuffix>"
+ [(set (match_operand:I48MODE 0 "register_operand" "")
+ (const:I48MODE
+ (unspec:I48MODE [(match_operand:I48MODE 1 "tls_symbolic_operand" "")]
+ UNSPEC_HW1_LAST_TLS_GD)))]
+ "HAVE_AS_TLS")
+
+(define_expand "mov_tls_gd_step2<bitsuffix>"
+ [(set (match_operand:I48MODE 0 "register_operand" "")
+ (unspec:I48MODE
+ [(match_operand:I48MODE 1 "reg_or_0_operand" "")
+ (const:I48MODE
+ (unspec:I48MODE [(match_operand:I48MODE 2 "tls_symbolic_operand" "")]
+ UNSPEC_HW0_TLS_GD))]
+ UNSPEC_INSN_ADDR_SHL16INSLI))]
+ "HAVE_AS_TLS")
+
+(define_expand "mov_tls_ie_step1<bitsuffix>"
+ [(set (match_operand:I48MODE 0 "register_operand" "")
+ (const:I48MODE
+ (unspec:I48MODE [(match_operand:I48MODE 1 "tls_symbolic_operand" "")]
+ UNSPEC_HW1_LAST_TLS_IE)))]
+ "HAVE_AS_TLS")
+
+(define_expand "mov_tls_ie_step2<bitsuffix>"
+ [(set (match_operand:I48MODE 0 "register_operand" "")
+ (unspec:I48MODE
+ [(match_operand:I48MODE 1 "reg_or_0_operand" "")
+ (const:I48MODE
+ (unspec:I48MODE [(match_operand:I48MODE 2 "tls_symbolic_operand" "")]
+ UNSPEC_HW0_TLS_IE))]
+ UNSPEC_INSN_ADDR_SHL16INSLI))]
+ "HAVE_AS_TLS")
+
+(define_expand "mov_tls_le_step1<bitsuffix>"
+ [(set (match_operand:I48MODE 0 "register_operand" "")
+ (const:I48MODE
+ (unspec:I48MODE [(match_operand:I48MODE 1 "tls_symbolic_operand" "")]
+ UNSPEC_HW1_LAST_TLS_LE)))]
+ "HAVE_AS_TLS")
+
+(define_expand "mov_tls_le_step2<bitsuffix>"
+ [(set (match_operand:I48MODE 0 "register_operand" "")
+ (unspec:I48MODE
+ [(match_operand:I48MODE 1 "reg_or_0_operand" "")
+ (const:I48MODE
+ (unspec:I48MODE [(match_operand:I48MODE 2 "tls_symbolic_operand" "")]
+ UNSPEC_HW0_TLS_LE))]
+ UNSPEC_INSN_ADDR_SHL16INSLI))]
+ "HAVE_AS_TLS")
+
+(define_expand "tls_gd_call<bitsuffix>"
+ [(parallel
+ [(set (reg:I48MODE 0)
+ (unspec:I48MODE [(match_operand:I48MODE 0 "tls_symbolic_operand" "")
+ (reg:I48MODE 0)]
+ UNSPEC_TLS_GD_CALL))
+ (clobber (reg:I48MODE 25))
+ (clobber (reg:I48MODE 26))
+ (clobber (reg:I48MODE 27))
+ (clobber (reg:I48MODE 28))
+ (clobber (reg:I48MODE 29))
+ (clobber (reg:I48MODE 55))])]
+ ""
+{
+ cfun->machine->calls_tls_get_addr = true;
+})
+
+(define_insn "*tls_gd_call<bitsuffix>"
+ [(set (reg:I48MODE 0)
+ (unspec:I48MODE [(match_operand:I48MODE 0 "tls_symbolic_operand" "")
+ (reg:I48MODE 0)]
+ UNSPEC_TLS_GD_CALL))
+ (clobber (reg:I48MODE 25))
+ (clobber (reg:I48MODE 26))
+ (clobber (reg:I48MODE 27))
+ (clobber (reg:I48MODE 28))
+ (clobber (reg:I48MODE 29))
+ (clobber (reg:I48MODE 55))]
+ ""
+ "jal\ttls_gd_call(%0)"
+ [(set_attr "type" "X1")])
+
+(define_insn "tls_gd_add<bitsuffix>"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (unspec:I48MODE [(match_operand:I48MODE 1 "register_operand" "r")
+ (match_operand:I48MODE 2 "tls_symbolic_operand" "")]
+ UNSPEC_TLS_GD_ADD))]
+ "HAVE_AS_TLS"
+ "add<x>i\t%0, %1, tls_gd_add(%2)")
+
+(define_insn "tls_add<bitsuffix>"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (unspec:I48MODE [(match_operand:I48MODE 1 "register_operand" "r")
+ (match_operand:I48MODE 2 "register_operand" "0")
+ (match_operand:I48MODE 3 "tls_symbolic_operand" "")]
+ UNSPEC_TLS_ADD))]
+ "HAVE_AS_TLS"
+ "add<x>i\t%0, %1, tls_add(%3)")
+
+(define_insn "tls_ie_load<bitsuffix>"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (unspec:I48MODE [(match_operand:I48MODE 1 "register_operand" "r")
+ (match_operand:I48MODE 2 "tls_symbolic_operand" "")]
+ UNSPEC_TLS_IE_LOAD))]
+ "HAVE_AS_TLS"
+ "ld<four_s_if_si>_tls\t%0, %1, tls_ie_load(%2)"
+ [(set_attr "type" "X1_2cycle")])
+
+(define_insn "*zero_extract<mode>"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (zero_extract:I48MODE
+ (match_operand:I48MODE 1 "reg_or_0_operand" "r")
+ (match_operand:I48MODE 2 "u6bit_cint_operand" "n")
+ (match_operand:I48MODE 3 "u6bit_cint_operand" "n")))]
+ ""
+ "bfextu\t%0, %r1, %3, %3+%2-1"
+ [(set_attr "type" "X0")])
+
+(define_insn "*sign_extract_low32"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (sign_extract:DI
+ (match_operand:DI 1 "reg_or_0_operand" "r")
+ (match_operand:DI 2 "u6bit_cint_operand" "n")
+ (match_operand:DI 3 "u6bit_cint_operand" "n")))]
+ "INTVAL (operands[3]) == 0 && INTVAL (operands[2]) == 32"
+ "addxi\t%0, %r1, 0")
+
+(define_insn "*sign_extract"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (sign_extract:I48MODE
+ (match_operand:I48MODE 1 "reg_or_0_operand" "r")
+ (match_operand:I48MODE 2 "u6bit_cint_operand" "n")
+ (match_operand:I48MODE 3 "u6bit_cint_operand" "n")))]
+ ""
+ "bfexts\t%0, %r1, %3, %3+%2-1"
+ [(set_attr "type" "X0")])
+
+
+;;
+;; Arithmetic ops
+;;
+
+(define_insn "add<mode>3"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r,r,r")
+ (plus:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "%rO,rO,rO")
+ (match_operand:I48MODE 2 "add_operand" "r,I,JT")))]
+ ""
+ "@
+ add<x>\t%0, %r1, %r2
+ add<x>i\t%0, %r1, %2
+ add<x>li\t%0, %r1, %H2"
+ [(set_attr "type" "*,*,X01")])
+
+(define_insn "*addsi3_sext"
+ [(set (match_operand:DI 0 "register_operand" "=r,r,r")
+ (sign_extend:DI
+ (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO,rO")
+ (match_operand:SI 2 "add_operand" "r,I,JT"))))]
+ ""
+ "@
+ addx\t%0, %r1, %r2
+ addxi\t%0, %r1, %2
+ addxli\t%0, %r1, %H2"
+ [(set_attr "type" "*,*,X01")])
+
+(define_insn "sub<mode>3"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (minus:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "rO")
+ (match_operand:I48MODE 2 "reg_or_0_operand" "rO")))]
+ ""
+ "sub<x>\t%0, %r1, %r2")
+
+(define_insn "*subsi3_sext"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (sign_extend:DI
+ (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
+ (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
+ ""
+ "subx\t%0, %r1, %r2")
+
+(define_insn "neg<mode>2"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (neg:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "rO")))]
+ ""
+ "sub<x>\t%0, zero, %r1")
+
+(define_insn "*negsi2_sext"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (sign_extend:DI
+ (neg:SI (match_operand:SI 1 "reg_or_0_operand" "rO"))))]
+ ""
+ "subx\t%0, zero, %r1")
+
+(define_insn "ssaddsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ss_plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
+ (match_operand:SI 2 "reg_or_0_operand" "rO")))]
+ ""
+ "addxsc\t%0, %r1, %r2"
+ [(set_attr "type" "X01")])
+
+(define_insn "*ssaddsi3_sext"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (sign_extend:DI
+ (ss_plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
+ (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
+ ""
+ "addxsc\t%0, %r1, %r2"
+ [(set_attr "type" "X01")])
+
+(define_insn "sssubsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ss_minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
+ (match_operand:SI 2 "reg_or_0_operand" "rO")))]
+ ""
+ "subxsc\t%0, %r1, %r2"
+ [(set_attr "type" "X01")])
+
+(define_insn "*sssubsi3_sext"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (sign_extend:DI
+ (ss_minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
+ (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
+ ""
+ "subxsc\t%0, %r1, %r2"
+ [(set_attr "type" "X01")])
+
+(define_expand "addsf3"
+ [(set (match_operand:SF 0 "register_operand" "")
+ (plus:SF (match_operand:SF 1 "register_operand" "")
+ (match_operand:SF 2 "register_operand" "")))]
+ ""
+{
+ rtx result = gen_lowpart (DImode, operands[0]);
+ rtx a = gen_lowpart (DImode, operands[1]);
+ rtx b = gen_lowpart (DImode, operands[2]);
+
+ rtx tmp = gen_reg_rtx (DImode);
+ rtx flags = gen_reg_rtx (DImode);
+
+ emit_insn (gen_insn_fsingle_add1 (tmp, a, b));
+ emit_insn (gen_insn_fsingle_addsub2 (tmp, tmp, a, b));
+ emit_insn (gen_insn_fsingle_pack1 (flags, tmp));
+ emit_insn (gen_insn_fsingle_pack2 (result, tmp, flags));
+
+ DONE;
+})
+
+(define_expand "subsf3"
+ [(set (match_operand:SF 0 "register_operand" "")
+ (minus:SF (match_operand:SF 1 "register_operand" "")
+ (match_operand:SF 2 "register_operand" "")))]
+ ""
+{
+ rtx result = gen_lowpart (DImode, operands[0]);
+ rtx a = gen_lowpart (DImode, operands[1]);
+ rtx b = gen_lowpart (DImode, operands[2]);
+
+ rtx tmp = gen_reg_rtx (DImode);
+ rtx flags = gen_reg_rtx (DImode);
+
+ emit_insn (gen_insn_fsingle_sub1 (tmp, a, b));
+ emit_insn (gen_insn_fsingle_addsub2 (tmp, tmp, a, b));
+ emit_insn (gen_insn_fsingle_pack1 (flags, tmp));
+ emit_insn (gen_insn_fsingle_pack2 (result, tmp, flags));
+
+ DONE;
+})
+
+(define_expand "mulsf3"
+ [(set (match_operand:SF 0 "register_operand" "")
+ (mult:SF (match_operand:SF 1 "register_operand" "")
+ (match_operand:SF 2 "register_operand" "")))]
+ ""
+{
+ rtx result = gen_lowpart (DImode, operands[0]);
+ rtx a = gen_lowpart (DImode, operands[1]);
+ rtx b = gen_lowpart (DImode, operands[2]);
+
+ rtx tmp1 = gen_reg_rtx (DImode);
+ rtx tmp2 = gen_reg_rtx (DImode);
+ rtx flags = gen_reg_rtx (DImode);
+
+ emit_insn (gen_insn_fsingle_mul1 (tmp1, a, b));
+ emit_insn (gen_insn_fsingle_mul2 (tmp2, tmp1, b));
+ emit_insn (gen_insn_fsingle_pack1 (flags, tmp2));
+ emit_insn (gen_insn_fsingle_pack2 (result, tmp2, flags));
+
+ DONE;
+})
+
+(define_expand "adddf3"
+ [(set (match_operand:DF 0 "register_operand" "")
+ (plus:DF (match_operand:DF 1 "register_operand" "")
+ (match_operand:DF 2 "register_operand" "")))]
+ ""
+{
+ rtx result = gen_lowpart (DImode, operands[0]);
+ rtx a = gen_lowpart (DImode, operands[1]);
+ rtx b = gen_lowpart (DImode, operands[2]);
+
+ rtx min = gen_reg_rtx (DImode);
+ rtx max = gen_reg_rtx (DImode);
+ rtx flags = gen_reg_rtx (DImode);
+
+ emit_insn (gen_insn_fdouble_unpack_min (min, a, b));
+ emit_insn (gen_insn_fdouble_unpack_max (max, a, b));
+ emit_insn (gen_insn_fdouble_add_flags (flags, a, b));
+ emit_insn (gen_insn_fdouble_addsub (max, max, min, flags));
+ emit_insn (gen_insn_fdouble_pack1 (result, max, flags));
+ emit_insn (gen_insn_fdouble_pack2 (result, result, max, const0_rtx));
+
+ DONE;
+})
+
+(define_expand "subdf3"
+ [(set (match_operand:DF 0 "register_operand" "")
+ (minus:DF (match_operand:DF 1 "register_operand" "")
+ (match_operand:DF 2 "register_operand" "")))]
+ ""
+{
+ rtx result = gen_lowpart (DImode, operands[0]);
+ rtx a = gen_lowpart (DImode, operands[1]);
+ rtx b = gen_lowpart (DImode, operands[2]);
+
+ rtx min = gen_reg_rtx (DImode);
+ rtx max = gen_reg_rtx (DImode);
+ rtx flags = gen_reg_rtx (DImode);
+
+ emit_insn (gen_insn_fdouble_unpack_min (min, a, b));
+ emit_insn (gen_insn_fdouble_unpack_max (max, a, b));
+ emit_insn (gen_insn_fdouble_sub_flags (flags, a, b));
+ emit_insn (gen_insn_fdouble_addsub (max, max, min, flags));
+ emit_insn (gen_insn_fdouble_pack1 (result, max, flags));
+ emit_insn (gen_insn_fdouble_pack2 (result, result, max, const0_rtx));
+
+ DONE;
+})
+
+(define_expand "muldf3"
+ [(set (match_operand:DF 0 "register_operand" "")
+ (mult:DF (match_operand:DF 1 "register_operand" "")
+ (match_operand:DF 2 "register_operand" "")))]
+ ""
+ ;; TODO: Decide if we should not inline this with -Os.
+ ;; "optimize_function_for_speed_p (cfun)"
+{
+ rtx result = gen_lowpart (DImode, operands[0]);
+ rtx a = gen_lowpart (DImode, operands[1]);
+ rtx b = gen_lowpart (DImode, operands[2]);
+
+ rtx a_unpacked = gen_reg_rtx (DImode);
+ rtx b_unpacked = gen_reg_rtx (DImode);
+ rtx flags = gen_reg_rtx (DImode);
+
+ rtx low1 = gen_reg_rtx (DImode);
+ rtx low = gen_reg_rtx (DImode);
+ rtx low_carry = gen_reg_rtx (DImode);
+
+ rtx mid = gen_reg_rtx (DImode);
+ rtx mid_l32 = gen_reg_rtx (DImode);
+ rtx mid_r32 = gen_reg_rtx (DImode);
+
+ rtx high1 = gen_reg_rtx (DImode);
+ rtx high = gen_reg_rtx (DImode);
+ rtx high1_plus_mid_r32 = gen_reg_rtx (DImode);
+
+ /* NOTE: We compute using max(a, 0) and max(b, 0) rather than
+ min(a, b) and max(a, b) because for multiply we just need to unpack,
+ we don't actually care which is min and which is max. And this
+ formulation gives the scheduler more freedom in case one of a or b
+ would stall at the start of this code sequence. */
+ emit_insn (gen_insn_fdouble_unpack_max (a_unpacked, a, const0_rtx));
+ emit_insn (gen_insn_fdouble_unpack_max (b_unpacked, b, const0_rtx));
+ emit_insn (gen_insn_fdouble_mul_flags (flags, a, b));
+
+ /* This depends on the fact that the high few bits of the unpacked
+ mantissa are zero, so we can't have a carry out from the mid sum. */
+ emit_insn (gen_insn_mul_lu_lu (low1, a_unpacked, b_unpacked));
+ emit_insn (gen_insn_mul_hu_lu (mid, a_unpacked, b_unpacked));
+ emit_insn (gen_insn_mula_hu_lu (mid, mid, b_unpacked, a_unpacked));
+ emit_insn (gen_insn_mul_hu_hu (high1, a_unpacked, b_unpacked));
+
+ emit_insn (gen_ashldi3 (mid_l32, mid, GEN_INT (32)));
+ emit_insn (gen_lshrdi3 (mid_r32, mid, GEN_INT (32)));
+
+ emit_insn (gen_adddi3 (high1_plus_mid_r32, high1, mid_r32));
+
+ emit_insn (gen_adddi3 (low, low1, mid_l32));
+ emit_insn (gen_insn_cmpltu_didi (low_carry, low, mid_l32));
+
+ emit_insn (gen_adddi3 (high, high1_plus_mid_r32, low_carry));
+
+ emit_insn (gen_insn_fdouble_pack1 (result, high, flags));
+ emit_insn (gen_insn_fdouble_pack2 (result, result, high, low));
+
+ DONE;
+})
+
+
+;;
+;; Shifts
+;;
+
+(define_insn "ashl<mode>3"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r,r")
+ (ashift:I48MODE
+ (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
+ (match_operand:SI 2 "reg_or_u<nbits>bit_operand" "I,rO")))]
+ ""
+ "@
+ shl<x>i\t%0, %r1, %2
+ shl<x>\t%0, %r1, %r2"
+ [(set_attr "type" "<shift_pipe>,<shift_pipe>")])
+
+(define_insn "*ashlsi3_sext"
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+ (sign_extend:DI
+ (ashift:SI
+ (match_operand:SI 1 "reg_or_0_operand" "rO,rO")
+ (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO"))))]
+ ""
+ "@
+ shlxi\t%0, %r1, %2
+ shlx\t%0, %r1, %r2"
+ [(set_attr "type" "X01,X01")])
+
+(define_insn "ashr<mode>3"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r,r")
+ (ashiftrt:I48MODE
+ (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
+ (match_operand:SI 2 "reg_or_u<nbits>bit_operand" "I,rO")))]
+ ""
+ "@
+ shrsi\t%0, %r1, %2
+ shrs\t%0, %r1, %r2")
+
+(define_insn "*ashrsi3_sext"
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+ (sign_extend:DI
+ (ashiftrt:SI (match_operand:SI 1 "reg_or_0_operand" "rO,rO")
+ (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO"))))]
+ ""
+ "@
+ shrsi\t%0, %r1, %2
+ shrs\t%0, %r1, %r2")
+
+(define_insn "lshr<mode>3"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r,r")
+ (lshiftrt:I48MODE
+ (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
+ (match_operand:SI 2 "reg_or_u<nbits>bit_operand" "I,rO")))]
+ ""
+ "@
+ shru<x>i\t%0, %r1, %2
+ shru<x>\t%0, %r1, %r2"
+ [(set_attr "type" "<shift_pipe>,<shift_pipe>")])
+
+(define_insn "*lshrsi3_sext"
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+ (sign_extend:DI
+ (lshiftrt:SI
+ (match_operand:SI 1 "reg_or_0_operand" "rO,rO")
+ (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO"))))]
+ ""
+ "@
+ shruxi\t%0, %r1, %2
+ shrux\t%0, %r1, %r2"
+ [(set_attr "type" "X01,X01")])
+
+(define_insn "rotldi3"
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+ (rotate:DI (match_operand:DI 1 "reg_or_0_operand" "rO,rO")
+ (match_operand:SI 2 "reg_or_u6bit_operand" "I,rO")))]
+ ""
+ "@
+ rotli\t%0, %r1, %2
+ rotl\t%0, %r1, %r2")
+
+(define_insn "insn_shl16insli"
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+ (ior:DI
+ (ashift:DI
+ (match_operand:DI 1 "reg_or_0_operand" "rO,rO")
+ (const_int 16))
+ (match_operand:DI 2 "u16bit_or_const_symbolic_operand" "O,KT")))]
+ ""
+ "@
+ shli\t%0, %r1, 16
+ shl16insli\t%0, %r1, %H2"
+ [(set_attr "type" "*,X01")])
+
+(define_insn "insn_addr_shl16insli<bitsuffix>"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (unspec:I48MODE
+ [(match_operand:I48MODE 1 "reg_or_0_operand" "rO")
+ (match_operand:I48MODE 2 "const_symbolic_operand" "T")]
+ UNSPEC_INSN_ADDR_SHL16INSLI))]
+ ""
+ "shl16insli\t%0, %r1, %H2"
+ [(set_attr "type" "X01")])
+
+
+;;
+;; Compares
+;;
+
+(define_expand "cstore<mode>4"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (match_operator:DI 1 "ordered_comparison_operator"
+ [(match_operand:FI48MODE 2 "reg_or_cint_operand" "")
+ (match_operand:FI48MODE 3 "reg_or_cint_operand" "")]))]
+ ""
+{
+ if (!tilegx_emit_setcc (operands, GET_MODE (operands[2])))
+ FAIL;
+ else
+ DONE;
+})
+
+
+(define_insn "insn_cmpne_<I48MODE:mode><I48MODE2:mode>"
+ [(set (match_operand:I48MODE2 0 "register_operand" "=r")
+ (ne:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "rO")
+ (match_operand:I48MODE 2 "reg_or_cint_operand" "rO")))]
+ ""
+ "cmpne\t%0, %r1, %r2")
+
+(define_insn "insn_cmpeq_<I48MODE:mode><I48MODE2:mode>"
+ [(set (match_operand:I48MODE2 0 "register_operand" "=r,r")
+ (eq:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "%rO,rO")
+ (match_operand:I48MODE 2 "reg_or_cint_operand" "I,rO")))]
+ ""
+ "@
+ cmpeqi\t%0, %r1, %2
+ cmpeq\t%0, %r1, %r2")
+
+(define_insn "insn_cmplts_<I48MODE:mode><I48MODE2:mode>"
+ [(set (match_operand:I48MODE2 0 "register_operand" "=r,r")
+ (lt:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
+ (match_operand:I48MODE 2 "reg_or_cint_operand" "I,rO")))]
+ ""
+ "@
+ cmpltsi\t%0, %r1, %2
+ cmplts\t%0, %r1, %r2")
+
+(define_insn "insn_cmpltu_<I48MODE:mode><I48MODE2:mode>"
+ [(set (match_operand:I48MODE2 0 "register_operand" "=r,r")
+ (ltu:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
+ (match_operand:I48MODE 2 "reg_or_cint_operand" "I,rO")))]
+ ""
+ "@
+ cmpltui\t%0, %r1, %2
+ cmpltu\t%0, %r1, %r2"
+ [(set_attr "type" "X01,*")])
+
+(define_insn "insn_cmples_<I48MODE:mode><I48MODE2:mode>"
+ [(set (match_operand:I48MODE2 0 "register_operand" "=r,r")
+ (le:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
+ (match_operand:I48MODE 2 "reg_or_cint_operand" "L,rO")))]
+ ""
+ "@
+ cmpltsi\t%0, %r1, %P2
+ cmples\t%0, %r1, %r2")
+
+(define_insn "insn_cmpleu_<I48MODE:mode><I48MODE2:mode>"
+ [(set (match_operand:I48MODE2 0 "register_operand" "=r,r")
+ (leu:I48MODE2 (match_operand:I48MODE 1 "reg_or_0_operand" "rO,rO")
+ (match_operand:I48MODE 2 "reg_or_cint_operand" "Q,rO")))]
+ ""
+ "@
+ cmpltui\t%0, %r1, %P2
+ cmpleu\t%0, %r1, %r2"
+ [(set_attr "type" "X01,*")])
+
+
+;;
+;; Logical ops
+;;
+
+(define_insn "and<mode>3"
+ [(set (match_operand:IVNMODE 0 "register_operand" "=r,r,r,r")
+ (and:IVNMODE (match_operand:IVNMODE 1 "reg_or_0_operand" "%rO,rO,0,rO")
+ (match_operand:IVNMODE 2 "and_operand" "I,S,M,rO")))]
+ ""
+ "@
+ andi\t%0, %r1, %2
+ bfextu\t%0, %r1, %M2
+ bfins\t%0, zero, %m2
+ and\t%0, %r1, %r2"
+ [(set_attr "type" "*,X0,X0,*")])
+
+(define_insn "*andsi3_sext"
+ [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
+ (sign_extend:DI
+ (and:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO,0,rO")
+ (match_operand:SI 2 "and_operand" "I,S,M,rO"))))]
+ ""
+ "@
+ andi\t%0, %r1, %2
+ bfextu\t%0, %r1, %M2
+ bfins\t%0, zero, %m2
+ and\t%0, %r1, %r2"
+ [(set_attr "type" "*,X0,X0,*")])
+
+(define_insn "anddi3"
+ [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r")
+ (and:DI (match_operand:DI 1 "reg_or_0_operand" "%rO,rO,rO,rO,0,rO")
+ (match_operand:DI 2 "and_operand" "I,Z0,Z1,S,M,rO")))]
+ ""
+ "@
+ andi\t%0, %r1, %2
+ v4int_l\t%0, zero, %r1
+ v4int_h\t%0, %r1, zero
+ bfextu\t%0, %r1, %M2
+ bfins\t%0, zero, %m2
+ and\t%0, %r1, %r2"
+ [(set_attr "type" "*,X01,X01,X0,X0,*")])
+
+(define_insn "ior<mode>3"
+ [(set (match_operand:IVMODE 0 "register_operand" "=r,r")
+ (ior:IVMODE (match_operand:IVMODE 1 "reg_or_0_operand" "%rO,rO")
+ (match_operand:IVMODE 2 "reg_or_s8bit_operand" "rO,I")))]
+ ""
+ "@
+ or\t%0, %r1, %r2
+ ori\t%0, %r1, %2"
+ [(set_attr "type" "*,X01")])
+
+(define_insn "*iorsi3_sext"
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+ (sign_extend:DI
+ (ior:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO")
+ (match_operand:SI 2 "reg_or_s8bit_operand" "rO,I"))))]
+ ""
+ "@
+ or\t%0, %r1, %r2
+ ori\t%0, %r1, %2"
+ [(set_attr "type" "*,X01")])
+
+(define_insn "xor<mode>3"
+ [(set (match_operand:IVMODE 0 "register_operand" "=r,r")
+ (xor:IVMODE (match_operand:IVMODE 1 "reg_or_0_operand" "%rO,rO")
+ (match_operand:IVMODE 2 "reg_or_s8bit_operand" "rO,I")))]
+ ""
+ "@
+ xor\t%0, %r1, %r2
+ xori\t%0, %r1, %2"
+ [(set_attr "type" "*,X01")])
+
+(define_insn "*xorsi3_sext"
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+ (sign_extend:DI
+ (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO")
+ (match_operand:SI 2 "reg_or_s8bit_operand" "rO,I"))))]
+ ""
+ "@
+ xor\t%0, %r1, %r2
+ xori\t%0, %r1, %2"
+ [(set_attr "type" "*,X01")])
+
+(define_insn "clzdi2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (clz:DI (match_operand:DI 1 "reg_or_0_operand" "rO")))]
+ ""
+ "clz\t%0, %r1"
+ [(set_attr "type" "Y0")])
+
+(define_expand "clzsi2"
+ [(set (match_dup 2)
+ (ashift:DI (match_operand:SI 1 "reg_or_0_operand" "")
+ (const_int 32)))
+ (set (subreg:DI (match_operand:SI 0 "register_operand" "") 0)
+ (clz:DI (match_dup 2)))]
+ ""
+ {
+ operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);
+ operands[2] = gen_reg_rtx (DImode);
+ })
+
+(define_insn "ctz<mode>2"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (ctz:I48MODE (match_operand:DI 1 "reg_or_0_operand" "rO")))]
+ ""
+ "ctz\t%0, %r1"
+ [(set_attr "type" "Y0")])
+
+(define_insn "popcount<mode>2"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (popcount:I48MODE (match_operand:DI 1 "reg_or_0_operand" "rO")))]
+ ""
+ "pcnt\t%0, %r1"
+ [(set_attr "type" "Y0")])
+
+(define_expand "parity<mode>2"
+ [(set (match_operand:I48MODE 0 "register_operand" "")
+ (parity:I48MODE (match_operand:DI 1 "reg_or_0_operand" "")))]
+ ""
+ {
+ rtx tmp = gen_reg_rtx (<MODE>mode);
+ emit_insn (gen_popcount<mode>2 (tmp, operands[1]));
+ emit_insn (gen_and<mode>3 (operands[0], tmp, const1_rtx));
+ DONE;
+ })
+
+(define_insn "bswapdi2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (bswap:DI (match_operand:DI 1 "reg_or_0_operand" "rO")))]
+ ""
+ "revbytes\t%0, %r1"
+ [(set_attr "type" "Y0")])
+
+(define_expand "bswapsi2"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (bswap:SI (match_operand:SI 1 "reg_or_0_operand" "")))]
+ ""
+ {
+ rtx tmp = gen_reg_rtx (DImode);
+ emit_insn (gen_bswapdi2 (tmp, gen_lowpart (DImode, operands[1])));
+ emit_insn (gen_ashrdi3 (gen_lowpart (DImode, operands[0]),
+ tmp, GEN_INT (32)));
+ DONE;
+ })
+
+(define_insn "one_cmpl<mode>2"
+ [(set (match_operand:IVMODE 0 "register_operand" "=r")
+ (not:IVMODE (match_operand:IVMODE 1 "reg_or_0_operand" "rO")))]
+ ""
+ "nor\t%0, %r1, zero")
+
+
+;;
+;; Conditional moves
+;;
+
+(define_expand "mov<mode>cc"
+ [(set (match_operand:I48MODE 0 "register_operand" "")
+ (if_then_else:I48MODE
+ (match_operand 1 "comparison_operator" "")
+ (match_operand:I48MODE 2 "reg_or_0_operand" "")
+ (match_operand:I48MODE 3 "reg_or_0_operand" "")))]
+ ""
+ { operands[1] = tilegx_emit_conditional_move (operands[1]); })
+
+(define_insn "movcc_insn_<I48MODE2:mode><I48MODE:mode>"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r,r,r,r")
+ (if_then_else:I48MODE
+ (match_operator 4 "eqne_operator"
+ [(match_operand:I48MODE2 1 "reg_or_0_operand" "rO,rO,rO,rO")
+ (const_int 0)])
+ (match_operand:I48MODE 2 "reg_or_0_operand" "rO,O,rO,0")
+ (match_operand:I48MODE 3 "reg_or_0_operand" "O,rO,0,rO")))]
+ ""
+ "@
+ m%c4\t%0, %r1, %r2
+ m%C4\t%0, %r1, %r3
+ cmov%d4z\t%0, %r1, %r2
+ cmov%D4z\t%0, %r1, %r3"
+ [(set_attr "type" "*,*,Y0,Y0")])
+
+(define_expand "insn_mz"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (if_then_else:DI
+ (eq (match_operand:DI 1 "reg_or_0_operand" "")
+ (const_int 0))
+ (match_operand:DI 2 "reg_or_0_operand" "")
+ (const_int 0)))])
+
+(define_expand "insn_mnz"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (if_then_else:DI
+ (ne (match_operand:DI 1 "reg_or_0_operand" "")
+ (const_int 0))
+ (match_operand:DI 2 "reg_or_0_operand" "")
+ (const_int 0)))])
+
+(define_expand "insn_cmoveqz"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (if_then_else:DI
+ (eq (match_operand:DI 2 "reg_or_0_operand" "")
+ (const_int 0))
+ (match_operand:DI 3 "reg_or_0_operand" "")
+ (match_operand:DI 1 "reg_or_0_operand" "")))])
+
+(define_expand "insn_cmovnez"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (if_then_else:DI
+ (ne (match_operand:DI 2 "reg_or_0_operand" "")
+ (const_int 0))
+ (match_operand:DI 3 "reg_or_0_operand" "")
+ (match_operand:DI 1 "reg_or_0_operand" "")))])
+
+
+;;
+;; Conversions
+;;
+
+(define_insn "zero_extendqi<mode>2"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r,r,r")
+ (zero_extend:I48MODE (match_operand:QI 1 "move_operand" "rO,U,m")))]
+ ""
+ "@
+ bfextu\t%0, %r1, 0, 7
+ ld1u\t%0, %1
+ ld1u_add\t%0, %I1, %i1"
+ [(set_attr "type" "X0,Y2_2cycle,X1_2cycle")])
+
+(define_insn "zero_extendhi<mode>2"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r,r,r")
+ (zero_extend:I48MODE (match_operand:HI 1 "move_operand" "rO,U,m")))]
+ ""
+ "@
+ bfextu\t%0, %r1, 0, 15
+ ld2u\t%0, %1
+ ld2u_add\t%0, %I1, %i1"
+ [(set_attr "type" "X0,Y2_2cycle,X1_2cycle")])
+
+(define_insn "zero_extendsidi2"
+ [(set (match_operand:DI 0 "register_operand" "=r,r,r")
+ (zero_extend:DI (match_operand:SI 1 "move_operand" "rO,U,m")))]
+ ""
+ "@
+ v4int_l\t%0, zero, %r1
+ ld4u\t%0, %1
+ ld4u_add\t%0, %I1, %i1"
+ [(set_attr "type" "X01,Y2_2cycle,X1_2cycle")])
+
+(define_insn "extendqi<mode>2"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r,r,r")
+ (sign_extend:I48MODE (match_operand:QI 1 "move_operand" "rO,U,m")))]
+ ""
+ "@
+ bfexts\t%0, %r1, 0, 7
+ ld1s\t%0, %1
+ ld1s_add\t%0, %I1, %i1"
+ [(set_attr "type" "X0,Y2_2cycle,X1_2cycle")])
+
+(define_insn "extendhi<mode>2"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r,r,r")
+ (sign_extend:I48MODE (match_operand:HI 1 "move_operand" "rO,U,m")))]
+ ""
+ "@
+ bfexts\t%0, %r1, 0, 15
+ ld2s\t%0, %1
+ ld2s_add\t%0, %I1, %i1"
+ [(set_attr "type" "X0,Y2_2cycle,X1_2cycle")])
+
+;; All SImode integer registers should already be in sign-extended
+;; form (see TRULY_NOOP_TRUNCATION and truncdisi2). We can therefore
+;; get rid of register->register instructions if we constrain the
+;; source to be in the same register as the destination.
+(define_insn_and_split "extendsidi2"
+ [(set (match_operand:DI 0 "register_operand" "=r,r,r")
+ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,U,m")))]
+ ""
+ "@
+ #
+ ld4s\t%0, %1
+ ld4s_add\t%0, %I1, %i1"
+ "&& reload_completed && register_operand (operands[1], VOIDmode)"
+ [(const_int 0)]
+{
+ emit_note (NOTE_INSN_DELETED);
+ DONE;
+}
+ [(set_attr "type" "*,Y2_2cycle,X1_2cycle")])
+
+;; Integer truncation patterns. Truncating SImode values to smaller
+;; modes is a no-op, as it is for most other GCC ports. Truncating
+;; DImode values to SImode is not a no-op since we
+;; need to make sure that the lower 32 bits are properly sign-extended
+;; (see TRULY_NOOP_TRUNCATION). Truncating DImode values into modes
+;; smaller than SImode is equivalent to two separate truncations:
+;;
+;; A B
+;; DI ---> HI == DI ---> SI ---> HI
+;; DI ---> QI == DI ---> SI ---> QI
+;;
+;; Step A needs a real instruction but step B does not.
+
+(define_insn "truncdisi2"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,U,m")
+ (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO,rO,rO")))]
+ ""
+ "@
+ addxi\t%0, %r1, 0
+ st4\t%0, %r1
+ st4_add\t%I0, %r1, %i0"
+ [(set_attr "type" "Y01,Y2,X1")])
+
+(define_insn "truncdihi2"
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=r,U,m")
+ (truncate:HI (match_operand:DI 1 "reg_or_0_operand" "rO,rO,rO")))]
+ ""
+ "@
+ addxi\t%0, %r1, 0
+ st2\t%0, %r1
+ st2_add\t%I0, %r1, %i0"
+ [(set_attr "type" "Y01,Y2,X1")])
+
+(define_insn "truncdiqi2"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=r,U,m")
+ (truncate:QI (match_operand:DI 1 "reg_or_0_operand" "rO,rO,rO")))]
+ ""
+ "@
+ addxi\t%0, %r1, 0
+ st1\t%0, %r1
+ st1_add\t%I0, %r1, %i0"
+ [(set_attr "type" "Y01,Y2,X1")])
+
+;; Combiner patterns to optimize away unnecessary truncates.
+
+(define_insn "*zero_extendsidi_truncdisi"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI
+ (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO"))))]
+ ""
+ "v4int_l\t%0, zero, %r1"
+ [(set_attr "type" "X01")])
+
+(define_insn "*addsi_truncdisi"
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r")
+ (plus:SI
+ (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "%rO,rO,rO"))
+ (match_operand:SI 2 "add_operand" "r,I,JT")))]
+ ""
+ "@
+ addx\t%0, %r1, %r2
+ addxi\t%0, %r1, %2
+ addxli\t%0, %r1, %H2"
+ [(set_attr "type" "*,*,X01")])
+
+(define_insn "*addsi_truncdisi2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI
+ (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO"))
+ (truncate:SI (match_operand:DI 2 "reg_or_0_operand" "rO"))))]
+ ""
+ "addx\t%0, %r1, %r2")
+
+(define_insn "*ashldi_truncdisi"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (ashift:DI
+ (match_operand:DI 1 "reg_or_0_operand" "rO")
+ (truncate:SI (match_operand:DI 2 "reg_or_u6bit_operand" "rO"))))]
+ ""
+ "shl\t%0, %r1, %r2")
+
+(define_insn "*ashlsi_truncdisi"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (ashift:SI
+ (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO,rO"))
+ (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO")))]
+ ""
+ "@
+ shlxi\t%0, %r1, %2
+ shlx\t%0, %r1, %r2"
+ [(set_attr "type" "X01,X01")])
+
+(define_insn "*ashlsi_truncdisi2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ashift:SI
+ (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO"))
+ (truncate:SI (match_operand:DI 2 "reg_or_0_operand" "rO"))))]
+ ""
+ "shlx\t%0, %r1, %r2"
+ [(set_attr "type" "X01")])
+
+(define_insn "*ashrdi3_truncdisi"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (ashiftrt:DI
+ (match_operand:DI 1 "reg_or_0_operand" "rO")
+ (truncate:SI (match_operand:DI 2 "reg_or_u6bit_operand" "rO"))))]
+ ""
+ "shrs\t%0, %r1, %r2")
+
+(define_insn "*lshrsi_truncdisi"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (lshiftrt:SI
+ (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO,rO"))
+ (match_operand:SI 2 "reg_or_u5bit_operand" "I,rO")))]
+ ""
+ "@
+ shruxi\t%0, %r1, %2
+ shrux\t%0, %r1, %r2"
+ [(set_attr "type" "X01,X01")])
+
+(define_insn "*lshrsi_truncdisi2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (lshiftrt:SI
+ (truncate:SI (match_operand:DI 1 "reg_or_0_operand" "rO"))
+ (truncate:SI (match_operand:DI 2 "reg_or_0_operand" "rO"))))]
+ ""
+ "shrux\t%0, %r1, %r2"
+ [(set_attr "type" "X01")])
+
+(define_insn "*lshrdi_truncdisi"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (lshiftrt:DI
+ (match_operand:DI 1 "reg_or_0_operand" "rO")
+ (truncate:SI (match_operand:DI 2 "reg_or_u6bit_operand" "rO"))))]
+ ""
+ "shru\t%0, %r1, %r2")
+
+(define_insn "*rotldi_truncdisi"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (rotate:DI
+ (match_operand:DI 1 "reg_or_0_operand" "rO")
+ (truncate:SI (match_operand:DI 2 "reg_or_u6bit_operand" "rO"))))]
+ ""
+ "rotl\t%0, %r1, %r2")
+
+
+;;
+;; Multiplies
+;;
+
+(define_insn "mulsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rO")
+ (match_operand:SI 2 "reg_or_0_operand" "rO")))]
+ ""
+ "mulx\t%0, %r1, %r2"
+ [(set_attr "type" "Y0_2cycle")])
+
+(define_insn "mulsidi3"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (mult:DI (sign_extend:DI
+ (match_operand:SI 1 "reg_or_0_operand" "%rO"))
+ (sign_extend:DI
+ (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
+ ""
+ "mul_ls_ls\t%0, %r1, %r2"
+ [(set_attr "type" "Y0_2cycle")])
+
+(define_insn "umulsidi3"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (mult:DI (zero_extend:DI
+ (match_operand:SI 1 "reg_or_0_operand" "%rO"))
+ (zero_extend:DI
+ (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
+ ""
+ "mul_lu_lu\t%0, %r1, %r2"
+ [(set_attr "type" "Y0_2cycle")])
+
+(define_expand "muldi3"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (unspec:DI [(match_operand:DI 1 "nonmemory_operand" "")
+ (match_operand:DI 2 "nonmemory_operand" "")]
+ UNSPEC_INSN_MUL_HU_LU))
+ (set (match_dup 0)
+ (unspec:DI [(match_dup 0) (match_dup 2) (match_dup 1)]
+ UNSPEC_INSN_MULA_HU_LU))
+ (set (match_dup 0)
+ (ashift:DI (match_dup 0) (const_int 32)))
+ (set (match_dup 0)
+ (unspec:DI [(match_dup 0) (match_dup 2) (match_dup 1)]
+ UNSPEC_INSN_MULA_LU_LU))]
+ ""
+ {
+ operands[1] = force_reg (DImode, operands[1]);
+ operands[1] = make_safe_from (operands[1], operands[0]);
+
+ if (tilegx_expand_muldi (operands[0], operands[1], operands[2]))
+ DONE;
+ else
+ {
+ operands[2] = force_reg (DImode, operands[2]);
+ operands[2] = make_safe_from (operands[2], operands[0]);
+ }
+ })
+
+(define_insn "usmulsidi3"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (mult:DI (zero_extend:DI
+ (match_operand:SI 1 "reg_or_0_operand" "rO"))
+ (sign_extend:DI
+ (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
+ ""
+ "mul_ls_lu\t%0, %r2, %r1"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "maddsidi4"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI
+ (mult:DI (sign_extend:DI
+ (match_operand:SI 1 "reg_or_0_operand" "rO"))
+ (sign_extend:DI
+ (match_operand:SI 2 "reg_or_0_operand" "rO")))
+ (match_operand:DI 3 "register_operand" "0")))]
+ ""
+ "mula_ls_ls\t%0, %r1, %r2"
+ [(set_attr "type" "Y0_2cycle")])
+
+(define_insn "umaddsidi4"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI
+ (mult:DI (zero_extend:DI
+ (match_operand:SI 1 "reg_or_0_operand" "rO"))
+ (zero_extend:DI
+ (match_operand:SI 2 "reg_or_0_operand" "rO")))
+ (match_operand:DI 3 "register_operand" "0")))]
+ ""
+ "mula_lu_lu\t%0, %r1, %r2"
+ [(set_attr "type" "Y0_2cycle")])
+
+(define_expand "smulsi3_highpart"
+ [(set (match_dup 3)
+ (mult:DI (sign_extend:DI (match_operand:SI 1 "reg_or_0_operand" ""))
+ (sign_extend:DI (match_operand:SI 2 "reg_or_0_operand" ""))))
+ (set (match_dup 4)
+ (ashiftrt:DI (match_dup 3) (const_int 32)))
+ (set (match_operand:SI 0 "register_operand" "")
+ (truncate:SI (match_dup 4)))]
+ ""
+ {
+ operands[3] = gen_reg_rtx (DImode);
+ operands[4] = gen_reg_rtx (DImode);
+ })
+
+(define_expand "umulsi3_highpart"
+ [(set (match_dup 3)
+ (mult:DI (zero_extend:DI (match_operand:SI 1 "reg_or_0_operand" ""))
+ (zero_extend:DI (match_operand:SI 2 "reg_or_0_operand" ""))))
+ (set (match_dup 4)
+ (lshiftrt:DI (match_dup 3) (const_int 32)))
+ (set (match_operand:SI 0 "register_operand" "")
+ (truncate:SI (match_dup 4)))]
+ ""
+ {
+ operands[3] = gen_reg_rtx (DImode);
+ operands[4] = gen_reg_rtx (DImode);
+ })
+
+(define_expand "smuldi3_highpart"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (truncate:DI
+ (ashiftrt:TI
+ (mult:TI (sign_extend:TI (match_operand:DI 1 "reg_or_0_operand" ""))
+ (sign_extend:TI (match_operand:DI 2 "reg_or_0_operand" "")))
+ (const_int 64))))]
+ ""
+ {
+ tilegx_expand_smuldi3_highpart (operands[0], operands[1], operands[2]);
+ DONE;
+ })
+
+(define_expand "umuldi3_highpart"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (truncate:DI
+ (lshiftrt:TI
+ (mult:TI (zero_extend:TI (match_operand:DI 1 "reg_or_0_operand" ""))
+ (zero_extend:TI (match_operand:DI 2 "reg_or_0_operand" "")))
+ (const_int 64))))]
+ ""
+{
+ tilegx_expand_umuldi3_highpart (operands[0], operands[1], operands[2]);
+ DONE;
+})
+
+
+;;
+;; Divide stubs. These exist to work around a bug in expmed.c, which
+;; will not attempt to convert a divide by constant into a multiply
+;; unless there is a pattern for a divide of the same mode. The end
+;; result is a 32-bit divide turns into 64-bit multiply.
+;;
+
+(define_expand "divsi3"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (div:SI (match_operand:SI 1 "reg_or_0_operand" "")
+ (match_operand:SI 2 "reg_or_0_operand" "")))]
+ ""
+{
+ FAIL;
+})
+
+(define_expand "udivsi3"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (udiv:SI (match_operand:SI 1 "reg_or_0_operand" "")
+ (match_operand:SI 2 "reg_or_0_operand" "")))]
+ ""
+{
+ FAIL;
+})
+
+
+;;
+;; Loops
+;;
+
+;; Define the subtract-one-and-jump insns so loop.c knows what to
+;; generate.
+(define_expand "doloop_end"
+ [(use (match_operand 0 "" "")) ;; loop pseudo
+ (use (match_operand 1 "" "")) ;; iterations; zero if unknown
+ (use (match_operand 2 "" "")) ;; max iterations
+ (use (match_operand 3 "" "")) ;; loop level
+ (use (match_operand 4 "" "")) ;; label
+ (use (match_operand 5 "" ""))] ;; flag: 1 if loop entered at top, else 0
+ ""
+{
+ if (optimize > 0 && flag_modulo_sched)
+ {
+ rtx s0;
+ rtx bcomp;
+ rtx loc_ref;
+ enum machine_mode mode = GET_MODE (operands[0]);
+
+ /* only do inner loop */
+ if (INTVAL (operands[3]) > 1)
+ FAIL;
+ /* only deal with loop counters in SImode or DImode */
+ if (mode != SImode && mode != DImode)
+ FAIL;
+
+ s0 = operands [0];
+ emit_move_insn (s0, gen_rtx_PLUS (mode, s0, GEN_INT (-1)));
+ bcomp = gen_rtx_NE(mode, s0, const0_rtx);
+ loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [4]);
+ emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
+ gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
+ loc_ref, pc_rtx)));
+ DONE;
+ }
+ else
+ FAIL;
+
+})
+
+;;
+;; Prologue/epilogue
+;;
+(define_expand "prologue"
+ [(const_int 0)]
+ ""
+{
+ tilegx_expand_prologue ();
+ DONE;
+})
+
+(define_expand "epilogue"
+ [(const_int 0)]
+ ""
+{
+ tilegx_expand_epilogue (false);
+ DONE;
+})
+
+(define_expand "sibcall_epilogue"
+ [(const_int 0)]
+ ""
+{
+ tilegx_expand_epilogue (true);
+ DONE;
+})
+
+;;
+;; Stack manipulations
+;;
+
+;; An insn to allocate new stack space for dynamic use (e.g., alloca).
+(define_expand "allocate_stack"
+ [(set (match_operand 0 "register_operand" "")
+ (minus (reg 54) (match_operand 1 "nonmemory_operand" "")))
+ (set (reg 54)
+ (minus (reg 54) (match_dup 1)))]
+ ""
+ "tilegx_allocate_stack (operands[0], operands[1]); DONE;")
+
+;;
+;; Branches
+;;
+
+(define_expand "call"
+ [(parallel [(call (match_operand:DI 0 "call_operand" "")
+ (match_operand 1 "" ""))
+ (use (reg:DI 54))
+ (clobber (reg:DI 55))])]
+ ""
+{
+ rtx orig_addr = XEXP (operands[0], 0);
+ rtx addr;
+ if (GET_CODE (orig_addr) == SYMBOL_REF)
+ {
+ if (tilegx_cmodel == CM_LARGE)
+ {
+ addr = gen_reg_rtx (Pmode);
+ tilegx_expand_set_const64 (addr, orig_addr);
+ operands[0] = gen_rtx_MEM (DImode, addr);
+ }
+ else if (tilegx_cmodel == CM_LARGE_PIC)
+ {
+ crtl->uses_pic_offset_table = 1;
+ addr = gen_reg_rtx (Pmode);
+ if (SYMBOL_REF_LOCAL_P (orig_addr))
+ tilegx_compute_pcrel_address (addr, orig_addr);
+ else
+ tilegx_compute_pcrel_plt_address (addr, orig_addr);
+ operands[0] = gen_rtx_MEM (DImode, addr);
+ }
+ }
+})
+
+(define_insn "*call_insn"
+ [(call (mem:DI (match_operand:I48MODE 0 "call_address_operand" "rO,i"))
+ (match_operand 1 "" ""))
+ (use (reg:DI 54))
+ (clobber (reg:DI 55))]
+ ""
+ "@
+ jalr\t%r0
+ jal\t%p0"
+ [(set_attr "type" "Y1,X1")])
+
+(define_expand "call_value"
+ [(parallel [(set (match_operand 0 "register_operand" "")
+ (call (match_operand:DI 1 "call_operand" "")
+ (match_operand 2 "" "")))
+ (use (reg:DI 54))
+ (clobber (reg:DI 55))])]
+ ""
+{
+ rtx orig_addr = XEXP (operands[1], 0);
+ rtx addr;
+ if (GET_CODE (orig_addr) == SYMBOL_REF)
+ {
+ if (tilegx_cmodel == CM_LARGE)
+ {
+ addr = gen_reg_rtx (Pmode);
+ tilegx_expand_set_const64 (addr, orig_addr);
+ operands[1] = gen_rtx_MEM (DImode, addr);
+ }
+ else if (tilegx_cmodel == CM_LARGE_PIC)
+ {
+ crtl->uses_pic_offset_table = 1;
+ addr = gen_reg_rtx (Pmode);
+ if (SYMBOL_REF_LOCAL_P (orig_addr))
+ tilegx_compute_pcrel_address (addr, orig_addr);
+ else
+ tilegx_compute_pcrel_plt_address (addr, orig_addr);
+ operands[1] = gen_rtx_MEM (DImode, addr);
+ }
+ }
+})
+
+(define_insn "*call_value_insn"
+ [(set (match_operand 0 "register_operand" "=r,r")
+ (call (mem:DI (match_operand:I48MODE 1 "call_address_operand" "rO,i"))
+ (match_operand 2 "" "")))
+ (use (reg:DI 54))
+ (clobber (reg:DI 55))]
+ ""
+ "@
+ jalr\t%r1
+ jal\t%p1"
+ [(set_attr "type" "Y1,X1")])
+
+(define_expand "sibcall"
+ [(parallel [(call (match_operand:DI 0 "call_operand" "")
+ (match_operand 1 "" ""))
+ (use (reg:DI 54))])]
+ ""
+ "")
+
+(define_insn "*sibcall_insn"
+ [(call (mem:DI (match_operand:I48MODE 0 "call_address_operand" "rO,i"))
+ (match_operand 1 "" ""))
+ (use (reg:DI 54))]
+ "SIBLING_CALL_P(insn)"
+ "@
+ jr\t%r0
+ j\t%p0"
+ [(set_attr "type" "X1,X1")])
+
+(define_expand "sibcall_value"
+ [(parallel [(set (match_operand 0 "" "")
+ (call (match_operand:DI 1 "call_operand" "")
+ (match_operand 2 "" "")))
+ (use (reg:DI 54))])]
+ ""
+ "")
+
+(define_insn "*sibcall_value"
+ [(set (match_operand 0 "" "")
+ (call (mem:DI (match_operand:I48MODE 1 "call_address_operand" "rO,i"))
+ (match_operand 2 "" "")))
+ (use (reg:DI 54))]
+ "SIBLING_CALL_P(insn)"
+ "@
+ jr\t%r1
+ j\t%p1"
+ [(set_attr "type" "X1,X1")])
+
+(define_insn "jump"
+ [(set (pc) (label_ref (match_operand 0 "" "")))]
+ ""
+ "j\t%l0"
+ [(set_attr "type" "X1")])
+
+(define_insn "indirect_jump"
+ [(set (pc) (match_operand 0 "pointer_operand" "rO"))]
+ ""
+ "jr\t%r0"
+ [(set_attr "type" "Y1")])
+
+(define_expand "return"
+ [(parallel
+ [(return)
+ (use (reg:DI 55))])]
+ "tilegx_can_use_return_insn_p ()"
+ "")
+
+(define_insn "_return"
+ [(return)
+ (use (reg:DI 55))]
+ "reload_completed"
+ "jrp\tlr"
+ [(set_attr "type" "Y1")])
+
+(define_expand "tablejump"
+ [(set (pc) (match_operand 0 "pointer_operand" ""))
+ (use (label_ref (match_operand 1 "" "")))]
+ ""
+{
+ tilegx_expand_tablejump (operands[0], operands[1]);
+ DONE;
+})
+
+(define_insn "tablejump_aux"
+ [(set (pc) (match_operand 0 "pointer_operand" "rO"))
+ (use (label_ref (match_operand 1 "" "")))]
+ ""
+ "jr\t%r0"
+ [(set_attr "type" "Y1")])
+
+;; Call subroutine returning any type.
+(define_expand "untyped_call"
+ [(parallel [(call (match_operand 0 "" "")
+ (const_int 0))
+ (match_operand 1 "" "")
+ (match_operand 2 "" "")])]
+ ""
+{
+ int i;
+
+ emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
+
+ for (i = 0; i < XVECLEN (operands[2], 0); i++)
+ {
+ rtx set = XVECEXP (operands[2], 0, i);
+ emit_move_insn (SET_DEST (set), SET_SRC (set));
+ }
+
+ /* The optimizer does not know that the call sets the function value
+ registers we stored in the result block. We avoid problems by
+ claiming that all hard registers are used and clobbered at this
+ point. */
+ emit_insn (gen_blockage ());
+
+ DONE;
+})
+
+;; UNSPEC_VOLATILE is considered to use and clobber all hard registers
+;; and all of memory. This blocks insns from being moved across this
+;; point.
+(define_insn "blockage"
+ [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
+ ""
+ "pseudo"
+ [(set_attr "type" "nothing")
+ (set_attr "length" "0")])
+
+;; Internal expanders to prevent memory ops from moving around frame
+;; allocation/deallocation.
+;;
+;; TODO: really this clobber should just clobber the frame memory. Is
+;; this possibly by clobbering memory @ the sp reg (as alpha does?)
+;; or by explicitly setting the alias set to the frame?
+(define_insn "sp_adjust"
+ [(set (match_operand:DI 0 "register_operand" "=r,r,r")
+ (plus:DI
+ (match_operand:DI 1 "register_operand" "%r,r,r")
+ (match_operand:DI 2 "add_operand" "r,I,JT")))
+ (clobber (mem:BLK (scratch)))]
+ ""
+ "@
+ add\t%0, %1, %2
+ addi\t%0, %1, %2
+ addli\t%0, %1, %H2"
+ [(set_attr "type" "*,*,X01")])
+
+(define_insn "sp_adjust_32bit"
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r")
+ (plus:SI
+ (match_operand:SI 1 "register_operand" "%r,r,r")
+ (match_operand:SI 2 "add_operand" "r,I,JT")))
+ (clobber (mem:BLK (scratch)))]
+ ""
+ "@
+ addx\t%0, %1, %2
+ addxi\t%0, %1, %2
+ addxli\t%0, %1, %H2"
+ [(set_attr "type" "*,*,X01")])
+
+;; Used for move sp, r52, to pop a stack frame. We need to make sure
+;; that stack frame memory operations have been issued before we do
+;; this. TODO: see above TODO.
+(define_insn "sp_restore<bitsuffix>"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (match_operand:I48MODE 1 "register_operand" "r"))
+ (clobber (mem:BLK (scratch)))]
+ ""
+ "move\t%0, %1")
+
+(define_insn "nop"
+ [(const_int 0)]
+ ""
+ "nop"
+ [(set_attr "type" "Y01")])
+
+
+;;
+;; Conditional branches
+;;
+
+(define_expand "cbranch<mode>4"
+ [(set (pc)
+ (if_then_else (match_operator 0 "ordered_comparison_operator"
+ [(match_operand:FI48MODE 1 "reg_or_cint_operand")
+ (match_operand:FI48MODE 2 "reg_or_cint_operand")])
+ (label_ref (match_operand 3 ""))
+ (pc)))]
+ ""
+{
+ tilegx_emit_conditional_branch (operands, GET_MODE (operands[1]));
+ DONE;
+})
+
+(define_insn "*bcc_normal<mode>"
+ [(set (pc)
+ (if_then_else
+ (match_operator 1 "signed_comparison_operator"
+ [(match_operand:I48MODE 2 "reg_or_0_operand" "rO")
+ (const_int 0)])
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ { return tilegx_output_cbranch (insn, operands, false); }
+ [(set_attr "type" "X1_branch")])
+
+(define_insn "*bcc_reverse<mode>"
+ [(set (pc)
+ (if_then_else
+ (match_operator 1 "signed_comparison_operator"
+ [(match_operand:I48MODE 2 "reg_or_0_operand" "rO")
+ (const_int 0)])
+ (pc)
+ (label_ref (match_operand 0 "" ""))))]
+ ""
+ { return tilegx_output_cbranch (insn, operands, true); }
+ [(set_attr "type" "X1_branch")])
+
+(define_insn "*blbs_normal<mode>"
+ [(set (pc)
+ (if_then_else
+ (ne (zero_extract:I48MODE
+ (match_operand:I48MODE 1 "reg_or_0_operand" "rO")
+ (const_int 1)
+ (const_int 0))
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ { return tilegx_output_cbranch_with_opcode (insn, operands, "blbs", "blbc",
+ 1); }
+ [(set_attr "type" "X1_branch")])
+
+(define_insn "*blbc_normal<mode>"
+ [(set (pc)
+ (if_then_else
+ (eq (zero_extract:I48MODE
+ (match_operand:I48MODE 1 "reg_or_0_operand" "rO")
+ (const_int 1)
+ (const_int 0))
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ { return tilegx_output_cbranch_with_opcode (insn, operands, "blbc", "blbs",
+ 1); }
+ [(set_attr "type" "X1_branch")])
+
+;; Note that __insn_mf() expands to this.
+(define_expand "memory_barrier"
+ [(set (match_dup 0)
+ (unspec_volatile:BLK [(match_dup 0)] UNSPEC_MF))]
+ ""
+{
+ operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
+ MEM_VOLATILE_P (operands[0]) = 1;
+})
+
+(define_insn "*memory_barrier"
+ [(set (match_operand:BLK 0 "" "")
+ (unspec_volatile:BLK [(match_dup 0)] UNSPEC_MF))]
+ ""
+ "mf"
+ [(set_attr "type" "X1")])
+
+(define_insn "prefetch"
+ [(prefetch (match_operand 0 "address_operand" "rO")
+ (match_operand 1 "const_int_operand" "")
+ (match_operand 2 "const_int_operand" ""))]
+ ""
+{
+ switch (INTVAL (operands[2]))
+ {
+ case 0:
+ case 1: return "prefetch_l3\t%r0";
+ case 2: return "prefetch_l2\t%r0";
+ case 3: return "prefetch_l1\t%r0";
+ default: gcc_unreachable ();
+ }
+}
+ [(set_attr "type" "Y2")])
+
+
+;;
+;; "__insn" Intrinsics (some expand directly to normal patterns above).
+;;
+
+(define_insn "insn_bfexts"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "u6bit_cint_operand" "n")
+ (match_operand:DI 3 "u6bit_cint_operand" "n")]
+ UNSPEC_INSN_BFEXTS))]
+ ""
+ "bfexts\t%0, %r1, %2, %3"
+ [(set_attr "type" "X0")])
+
+(define_insn "insn_bfextu"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "u6bit_cint_operand" "n")
+ (match_operand:DI 3 "u6bit_cint_operand" "n")]
+ UNSPEC_INSN_BFEXTU))]
+ ""
+ "bfextu\t%0, %r1, %2, %3"
+ [(set_attr "type" "X0")])
+
+(define_insn "insn_bfins"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")
+ (match_operand:DI 3 "u6bit_cint_operand" "n")
+ (match_operand:DI 4 "u6bit_cint_operand" "n")]
+ UNSPEC_INSN_BFINS))]
+ ""
+ "bfins\t%0, %r2, %3, %4"
+ [(set_attr "type" "X0")])
+
+(define_insn "insn_cmpexch<four_if_si>"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (mem:I48MODE (match_operand 1 "pointer_operand" "rO")))
+ (set (mem:I48MODE (match_dup 1))
+ (unspec_volatile:I48MODE
+ [(mem:I48MODE (match_dup 1))
+ (reg:I48MODE TILEGX_CMPEXCH_REG)
+ (match_operand:I48MODE 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_CMPEXCH))]
+ ""
+ "cmpexch<four_if_si>\t%0, %r1, %r2"
+ [(set_attr "type" "X1_remote")])
+
+(define_insn "insn_cmul"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_CMUL))]
+ ""
+ "cmul\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_cmula"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")
+ (match_operand:DI 3 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_CMULA))]
+ ""
+ "cmula\t%0, %r2, %r3"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_cmulaf"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")
+ (match_operand:DI 3 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_CMULAF))]
+ ""
+ "cmulaf\t%0, %r2, %r3"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_cmulf"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_CMULF))]
+ ""
+ "cmulf\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_cmulfr"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_CMULFR))]
+ ""
+ "cmulfr\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_cmulh"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_CMULH))]
+ ""
+ "cmulh\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_cmulhr"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_CMULHR))]
+ ""
+ "cmulhr\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_crc32_32"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_CRC32_32))]
+ ""
+ "crc32_32\t%0, %r1, %r2"
+ [(set_attr "type" "X0")])
+
+(define_insn "insn_crc32_8"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_CRC32_8))]
+ ""
+ "crc32_8\t%0, %r1, %r2"
+ [(set_attr "type" "X0")])
+
+(define_insn "insn_dblalign"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")
+ (match_operand 3 "pointer_operand" "rO")]
+ UNSPEC_INSN_DBLALIGN))]
+ ""
+ "dblalign\t%0, %r2, %r3"
+ [(set_attr "type" "X0")])
+
+(define_insn "insn_dblalign2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_DBLALIGN2))]
+ ""
+ "dblalign2\t%0, %r1, %r2"
+ [(set_attr "type" "X01")])
+
+(define_insn "insn_dblalign4"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_DBLALIGN4))]
+ ""
+ "dblalign4\t%0, %r1, %r2"
+ [(set_attr "type" "X01")])
+
+(define_insn "insn_dblalign6"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_DBLALIGN6))]
+ ""
+ "dblalign6\t%0, %r1, %r2"
+ [(set_attr "type" "X01")])
+
+(define_insn "insn_dtlbpr"
+ [(unspec_volatile:VOID [(match_operand:DI 0 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_DTLBPR)]
+ ""
+ "dtlbpr\t%r0"
+ [(set_attr "type" "X1")])
+
+(define_insn "insn_exch<four_if_si>"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (mem:I48MODE (match_operand 1 "pointer_operand" "rO")))
+ (set (mem:I48MODE (match_dup 1))
+ (unspec_volatile:I48MODE
+ [(match_operand:I48MODE 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_EXCH))]
+ ""
+ "exch<four_if_si>\t%0, %r1, %r2"
+ [(set_attr "type" "X1_remote")])
+
+(define_insn "insn_fdouble_add_flags"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_FDOUBLE_ADD_FLAGS))]
+ ""
+ "fdouble_add_flags\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_fdouble_addsub"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")
+ (match_operand:DI 3 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_FDOUBLE_ADDSUB))]
+ ""
+ "fdouble_addsub\t%0, %r2, %r3"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_fdouble_mul_flags"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_FDOUBLE_MUL_FLAGS))]
+ ""
+ "fdouble_mul_flags\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_fdouble_pack1"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_FDOUBLE_PACK1))]
+ ""
+ "fdouble_pack1\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_fdouble_pack2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")
+ (match_operand:DI 3 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_FDOUBLE_PACK2))]
+ ""
+ "fdouble_pack2\t%0, %r2, %r3"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_fdouble_sub_flags"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_FDOUBLE_SUB_FLAGS))]
+ ""
+ "fdouble_sub_flags\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_fdouble_unpack_max"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_FDOUBLE_UNPACK_MAX))]
+ ""
+ "fdouble_unpack_max\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_fdouble_unpack_min"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_FDOUBLE_UNPACK_MIN))]
+ ""
+ "fdouble_unpack_min\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_fetchadd<four_if_si>"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (unspec_volatile:I48MODE
+ [(mem:I48MODE (match_operand 1 "pointer_operand" "rO"))]
+ UNSPEC_ATOMIC))
+ (set (mem:I48MODE (match_dup 1))
+ (plus:I48MODE (mem:I48MODE (match_dup 1))
+ (match_operand:I48MODE 2 "reg_or_0_operand" "rO")))]
+ ""
+ "fetchadd<four_if_si>\t%0, %r1, %r2"
+ [(set_attr "type" "X1_remote")])
+
+(define_insn "insn_fetchaddgez<four_if_si>"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (unspec_volatile:I48MODE
+ [(mem:I48MODE (match_operand 1 "pointer_operand" "rO"))]
+ UNSPEC_ATOMIC))
+ (set (mem:I48MODE (match_dup 1))
+ (unspec:I48MODE [(match_operand:I48MODE 2 "reg_or_0_operand" "rO")
+ (mem:I48MODE (match_dup 1))]
+ UNSPEC_INSN_FETCHADDGEZ))]
+ ""
+ "fetchaddgez<four_if_si>\t%0, %r1, %r2"
+ [(set_attr "type" "X1_remote")])
+
+(define_insn "insn_fetchand<four_if_si>"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (unspec_volatile:I48MODE
+ [(mem:I48MODE (match_operand 1 "pointer_operand" "rO"))]
+ UNSPEC_ATOMIC))
+ (set (mem:I48MODE (match_dup 1))
+ (and:I48MODE (mem:I48MODE (match_dup 1))
+ (match_operand:I48MODE 2 "reg_or_0_operand" "rO")))]
+ ""
+ "fetchand<four_if_si>\t%0, %r1, %r2"
+ [(set_attr "type" "X1_remote")])
+
+(define_insn "insn_fetchor<four_if_si>"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (unspec_volatile:I48MODE
+ [(mem:I48MODE (match_operand 1 "pointer_operand" "rO"))]
+ UNSPEC_ATOMIC))
+ (set (mem:I48MODE (match_dup 1))
+ (ior:I48MODE (mem:I48MODE (match_dup 1))
+ (match_operand:I48MODE 2 "reg_or_0_operand" "rO")))]
+ ""
+ "fetchor<four_if_si>\t%0, %r1, %r2"
+ [(set_attr "type" "X1_remote")])
+
+(define_insn "insn_finv"
+ [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
+ UNSPEC_INSN_FINV)]
+ ""
+ "finv\t%r0"
+ [(set_attr "type" "X1")])
+
+(define_insn "insn_flush"
+ [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
+ UNSPEC_INSN_FLUSH)]
+ ""
+ "flush\t%r0"
+ [(set_attr "type" "X1")])
+
+(define_insn "insn_flushwb"
+ [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_FLUSHWB)]
+ ""
+ "flushwb"
+ [(set_attr "type" "X1")])
+
+(define_insn "insn_fnop"
+ [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_FNOP)]
+ ""
+ "fnop")
+
+(define_insn "insn_fsingle_add1"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_FSINGLE_ADD1))]
+ ""
+ "fsingle_add1\t%0, %r1, %r2"
+ [(set_attr "type" "X0")])
+
+(define_insn "insn_fsingle_addsub2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")
+ (match_operand:DI 3 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_FSINGLE_ADDSUB2))]
+ ""
+ "fsingle_addsub2\t%0, %r2, %r3"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_fsingle_mul1"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_FSINGLE_MUL1))]
+ ""
+ "fsingle_mul1\t%0, %r1, %r2"
+ [(set_attr "type" "X0")])
+
+(define_insn "insn_fsingle_mul2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_FSINGLE_MUL2))]
+ ""
+ "fsingle_mul2\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_fsingle_pack1"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_FSINGLE_PACK1))]
+ ""
+ "fsingle_pack1\t%0, %r1"
+ [(set_attr "type" "Y0_2cycle")])
+
+(define_insn "insn_fsingle_pack2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_FSINGLE_PACK2))]
+ ""
+ "fsingle_pack2\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_fsingle_sub1"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_FSINGLE_SUB1))]
+ ""
+ "fsingle_sub1\t%0, %r1, %r2"
+ [(set_attr "type" "X0")])
+
+(define_insn "insn_drain"
+ [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_DRAIN)]
+ ""
+ "drain"
+ [(set_attr "type" "cannot_bundle")])
+
+(define_insn "insn_icoh"
+ [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
+ UNSPEC_INSN_ICOH)]
+ ""
+ "icoh\t%r0"
+ [(set_attr "type" "X1")])
+
+(define_insn "insn_ill"
+ [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_ILL)]
+ ""
+ "ill"
+ [(set_attr "type" "cannot_bundle")])
+
+(define_insn "insn_info"
+ [(unspec_volatile:VOID [(match_operand:DI 0 "s8bit_cint_operand" "i")]
+ UNSPEC_INSN_INFO)]
+ ""
+ "info\t%0")
+
+(define_insn "insn_infol"
+ [(unspec_volatile:VOID [(match_operand:DI 0 "s16bit_cint_operand" "i")]
+ UNSPEC_INSN_INFOL)]
+ ""
+ "infol\t%0"
+ [(set_attr "type" "X01")])
+
+(define_insn "insn_inv"
+ [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
+ UNSPEC_INSN_INV)]
+ ""
+ "inv\t%r0"
+ [(set_attr "type" "X1")])
+
+;; loads
+
+(define_expand "insn_ld"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (mem:DI (match_operand 1 "pointer_operand" "")))]
+ "")
+
+(define_insn "insn_ld_add<bitsuffix>"
+ [(set (match_operand:I48MODE 1 "pointer_operand" "=r")
+ (plus:I48MODE (match_operand 3 "pointer_operand" "1")
+ (match_operand 2 "s8bit_cint_operand" "i")))
+ (set (match_operand:DI 0 "register_operand" "=r")
+ (mem:DI (match_dup 3)))]
+ ""
+ "ld_add\t%0, %1, %2"
+ [(set_attr "type" "X1_2cycle")])
+
+(define_insn "insn_ldna"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (mem:DI (and:DI (match_operand 1 "pointer_operand" "rO")
+ (const_int -8))))]
+ ""
+ "ldna\t%0, %r1"
+ [(set_attr "type" "X1_2cycle")])
+
+(define_insn "insn_ldna_add<bitsuffix>"
+ [(set (match_operand:I48MODE 1 "pointer_operand" "=r")
+ (plus:I48MODE (match_operand 3 "pointer_operand" "1")
+ (match_operand 2 "s8bit_cint_operand" "i")))
+ (set (match_operand:DI 0 "register_operand" "=r")
+ (mem:DI (and:DI (match_dup 3) (const_int -8))))]
+ ""
+ "ldna_add\t%0, %1, %2"
+ [(set_attr "type" "X1_2cycle")])
+
+(define_expand "insn_ld<n><s>"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (any_extend:DI
+ (mem:I124MODE (match_operand 1 "pointer_operand" ""))))]
+ "")
+
+(define_insn "insn_ld<I124MODE:n><s>_add<I48MODE:bitsuffix>"
+ [(set (match_operand:I48MODE 1 "pointer_operand" "=r")
+ (plus:I48MODE (match_operand 3 "pointer_operand" "1")
+ (match_operand 2 "s8bit_cint_operand" "i")))
+ (set (match_operand:DI 0 "register_operand" "=r")
+ (any_extend:DI (mem:I124MODE (match_dup 3))))]
+ ""
+ "ld<I124MODE:n><s>_add\t%0, %1, %2"
+ [(set_attr "type" "X1_2cycle")])
+
+;; non temporal loads
+
+(define_insn "insn_ldnt"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(mem:DI (match_operand 1 "pointer_operand" "rO"))]
+ UNSPEC_NON_TEMPORAL))]
+ ""
+ "ldnt\t%0, %r1"
+ [(set_attr "type" "X1_2cycle")])
+
+(define_insn "insn_ldnt_add<bitsuffix>"
+ [(set (match_operand:I48MODE 1 "pointer_operand" "=r")
+ (plus:I48MODE (match_operand 3 "pointer_operand" "1")
+ (match_operand 2 "s8bit_cint_operand" "i")))
+ (set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(mem:DI (match_dup 3))]
+ UNSPEC_NON_TEMPORAL))]
+ ""
+ "ldnt_add\t%0, %1, %2"
+ [(set_attr "type" "X1_2cycle")])
+
+(define_insn "insn_ldnt<n><s>"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (any_extend:DI
+ (unspec:I124MODE
+ [(mem:I124MODE (match_operand 1 "pointer_operand" "rO"))]
+ UNSPEC_NON_TEMPORAL)))]
+ ""
+ "ldnt<n><s>\t%0, %r1"
+ [(set_attr "type" "X1_2cycle")])
+
+(define_insn "insn_ldnt<I124MODE:n><s>_add<I48MODE:bitsuffix>"
+ [(set (match_operand:I48MODE 1 "pointer_operand" "=r")
+ (plus:I48MODE (match_operand 3 "pointer_operand" "1")
+ (match_operand 2 "s8bit_cint_operand" "i")))
+ (set (match_operand:DI 0 "register_operand" "=r")
+ (any_extend:DI (unspec:I124MODE [(mem:I124MODE (match_dup 3))]
+ UNSPEC_NON_TEMPORAL)))]
+ ""
+ "ldnt<I124MODE:n><s>_add\t%0, %1, %2"
+ [(set_attr "type" "X1_2cycle")])
+
+;; L2 hits
+
+(define_insn "insn_ld_L2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(mem:DI (match_operand 1 "pointer_operand" "rO"))]
+ UNSPEC_LATENCY_L2))]
+ ""
+ "ld\t%0, %r1"
+ [(set_attr "type" "Y2_L2")])
+
+(define_insn "insn_ld_add_L2<bitsuffix>"
+ [(set (match_operand:I48MODE 1 "pointer_operand" "=r")
+ (plus:I48MODE (match_operand 3 "pointer_operand" "1")
+ (match_operand 2 "s8bit_cint_operand" "i")))
+ (set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(mem:DI (match_dup 3))]
+ UNSPEC_LATENCY_L2))]
+ ""
+ "ld_add\t%0, %1, %2"
+ [(set_attr "type" "X1_L2")])
+
+(define_insn "insn_ldna_L2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(mem:DI (and:DI (match_operand 1 "pointer_operand" "rO")
+ (const_int -8)))]
+ UNSPEC_LATENCY_L2))]
+ ""
+ "ldna\t%0, %r1"
+ [(set_attr "type" "X1_L2")])
+
+(define_insn "insn_ldna_add_L2<bitsuffix>"
+ [(set (match_operand:I48MODE 1 "pointer_operand" "=r")
+ (plus:I48MODE (match_operand 3 "pointer_operand" "1")
+ (match_operand 2 "s8bit_cint_operand" "i")))
+ (set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(mem:DI (and:DI (match_dup 3) (const_int -8)))]
+ UNSPEC_LATENCY_L2))]
+ ""
+ "ldna_add\t%0, %1, %2"
+ [(set_attr "type" "X1_L2")])
+
+(define_insn "insn_ld<n><s>_L2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (any_extend:DI
+ (unspec:I124MODE
+ [(mem:I124MODE (match_operand 1 "pointer_operand" "rO"))]
+ UNSPEC_LATENCY_L2)))]
+ ""
+ "ld<n><s>\t%0, %r1"
+ [(set_attr "type" "Y2_L2")])
+
+(define_insn "insn_ld<I124MODE:n><s>_add_L2<I48MODE:bitsuffix>"
+ [(set (match_operand:I48MODE 1 "pointer_operand" "=r")
+ (plus:I48MODE (match_operand 3 "pointer_operand" "1")
+ (match_operand 2 "s8bit_cint_operand" "i")))
+ (set (match_operand:DI 0 "register_operand" "=r")
+ (any_extend:DI (unspec:I124MODE [(mem:I124MODE (match_dup 3))]
+ UNSPEC_LATENCY_L2)))]
+ ""
+ "ld<I124MODE:n><s>_add\t%0, %1, %2"
+ [(set_attr "type" "X1_L2")])
+
+;; L2 hits, non temporal loads
+
+(define_insn "insn_ldnt_L2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(unspec:DI
+ [(mem:DI (match_operand 1 "pointer_operand" "rO"))]
+ UNSPEC_NON_TEMPORAL)]
+ UNSPEC_LATENCY_L2))]
+ ""
+ "ldnt\t%0, %r1"
+ [(set_attr "type" "X1_L2")])
+
+(define_insn "insn_ldnt_add_L2<bitsuffix>"
+ [(set (match_operand:I48MODE 1 "pointer_operand" "=r")
+ (plus:I48MODE (match_operand 3 "pointer_operand" "1")
+ (match_operand 2 "s8bit_cint_operand" "i")))
+ (set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(unspec:DI
+ [(mem:DI (match_dup 3))]
+ UNSPEC_NON_TEMPORAL)]
+ UNSPEC_LATENCY_L2))]
+ ""
+ "ldnt_add\t%0, %1, %2"
+ [(set_attr "type" "X1_L2")])
+
+(define_insn "insn_ldnt<n><s>_L2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (any_extend:DI
+ (unspec:I124MODE
+ [(unspec:I124MODE
+ [(mem:I124MODE (match_operand 1 "pointer_operand" "rO"))]
+ UNSPEC_NON_TEMPORAL)]
+ UNSPEC_LATENCY_L2)))]
+ ""
+ "ldnt<n><s>\t%0, %r1"
+ [(set_attr "type" "X1_L2")])
+
+(define_insn "insn_ldnt<I124MODE:n><s>_add_L2<I48MODE:bitsuffix>"
+ [(set (match_operand:I48MODE 1 "pointer_operand" "=r")
+ (plus:I48MODE (match_operand 3 "pointer_operand" "1")
+ (match_operand 2 "s8bit_cint_operand" "i")))
+ (set (match_operand:DI 0 "register_operand" "=r")
+ (any_extend:DI
+ (unspec:I124MODE [(unspec:I124MODE
+ [(mem:I124MODE (match_dup 3))]
+ UNSPEC_NON_TEMPORAL)]
+ UNSPEC_LATENCY_L2)))]
+ ""
+ "ldnt<I124MODE:n><s>_add\t%0, %1, %2"
+ [(set_attr "type" "X1_L2")])
+
+;; L2 miss
+
+(define_insn "insn_ld_miss"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(mem:DI (match_operand 1 "pointer_operand" "rO"))]
+ UNSPEC_LATENCY_MISS))]
+ ""
+ "ld\t%0, %r1"
+ [(set_attr "type" "Y2_miss")])
+
+(define_insn "insn_ld_add_miss<bitsuffix>"
+ [(set (match_operand:I48MODE 1 "pointer_operand" "=r")
+ (plus:I48MODE (match_operand 3 "pointer_operand" "1")
+ (match_operand 2 "s8bit_cint_operand" "i")))
+ (set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(mem:DI (match_dup 3))]
+ UNSPEC_LATENCY_MISS))]
+ ""
+ "ld_add\t%0, %1, %2"
+ [(set_attr "type" "X1_miss")])
+
+(define_insn "insn_ldna_miss"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(mem:DI (and:DI (match_operand 1 "pointer_operand" "rO")
+ (const_int -8)))]
+ UNSPEC_LATENCY_MISS))]
+ ""
+ "ldna\t%0, %r1"
+ [(set_attr "type" "X1_miss")])
+
+(define_insn "insn_ldna_add_miss<bitsuffix>"
+ [(set (match_operand:I48MODE 1 "pointer_operand" "=r")
+ (plus:I48MODE (match_operand 3 "pointer_operand" "1")
+ (match_operand 2 "s8bit_cint_operand" "i")))
+ (set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(mem:DI (and:DI (match_dup 3) (const_int -8)))]
+ UNSPEC_LATENCY_MISS))]
+ ""
+ "ldna_add\t%0, %1, %2"
+ [(set_attr "type" "X1_miss")])
+
+(define_insn "insn_ld<n><s>_miss"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (any_extend:DI
+ (unspec:I124MODE
+ [(mem:I124MODE (match_operand 1 "pointer_operand" "rO"))]
+ UNSPEC_LATENCY_MISS)))]
+ ""
+ "ld<n><s>\t%0, %r1"
+ [(set_attr "type" "Y2_miss")])
+
+(define_insn "insn_ld<I124MODE:n><s>_add_miss<I48MODE:bitsuffix>"
+ [(set (match_operand:I48MODE 1 "pointer_operand" "=r")
+ (plus:I48MODE (match_operand 3 "pointer_operand" "1")
+ (match_operand 2 "s8bit_cint_operand" "i")))
+ (set (match_operand:DI 0 "register_operand" "=r")
+ (any_extend:DI (unspec:I124MODE [(mem:I124MODE (match_dup 3))]
+ UNSPEC_LATENCY_MISS)))]
+ ""
+ "ld<I124MODE:n><s>_add\t%0, %1, %2"
+ [(set_attr "type" "X1_miss")])
+
+;; L2 miss, non temporal loads
+
+(define_insn "insn_ldnt_miss"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(unspec:DI
+ [(mem:DI (match_operand 1 "pointer_operand" "rO"))]
+ UNSPEC_NON_TEMPORAL)]
+ UNSPEC_LATENCY_MISS))]
+ ""
+ "ldnt\t%0, %r1"
+ [(set_attr "type" "X1_miss")])
+
+(define_insn "insn_ldnt_add_miss<bitsuffix>"
+ [(set (match_operand:I48MODE 1 "pointer_operand" "=r")
+ (plus:I48MODE (match_operand 3 "pointer_operand" "1")
+ (match_operand 2 "s8bit_cint_operand" "i")))
+ (set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(unspec:DI
+ [(mem:DI (match_dup 3))]
+ UNSPEC_NON_TEMPORAL)]
+ UNSPEC_LATENCY_MISS))]
+ ""
+ "ldnt_add\t%0, %1, %2"
+ [(set_attr "type" "X1_miss")])
+
+(define_insn "insn_ldnt<n><s>_miss"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (any_extend:DI
+ (unspec:I124MODE
+ [(unspec:I124MODE
+ [(mem:I124MODE (match_operand 1 "pointer_operand" "rO"))]
+ UNSPEC_NON_TEMPORAL)]
+ UNSPEC_LATENCY_MISS)))]
+ ""
+ "ldnt<n><s>\t%0, %r1"
+ [(set_attr "type" "X1_miss")])
+
+(define_insn "insn_ldnt<I124MODE:n><s>_add_miss<I48MODE:bitsuffix>"
+ [(set (match_operand:I48MODE 1 "pointer_operand" "=r")
+ (plus:I48MODE (match_operand 3 "pointer_operand" "1")
+ (match_operand 2 "s8bit_cint_operand" "i")))
+ (set (match_operand:DI 0 "register_operand" "=r")
+ (any_extend:DI
+ (unspec:I124MODE [(unspec:I124MODE
+ [(mem:I124MODE (match_dup 3))]
+ UNSPEC_NON_TEMPORAL)]
+ UNSPEC_LATENCY_MISS)))]
+ ""
+ "ldnt<I124MODE:n><s>_add\t%0, %1, %2"
+ [(set_attr "type" "X1_miss")])
+
+;; end loads
+
+(define_insn "insn_lnk"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(const_int 0)] UNSPEC_INSN_LNK))]
+ ""
+ "lnk\t%0"
+ [(set_attr "type" "Y1")])
+
+(define_insn "insn_mfspr"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec_volatile:DI [(match_operand:DI 1 "u14bit_cint_operand" "i")]
+ UNSPEC_INSN_MFSPR))
+ (clobber (mem:BLK (const_int 0)))]
+ ""
+ "mfspr\t%0, %1"
+ [(set_attr "type" "X1")])
+
+(define_insn "insn_mtspr"
+ [(unspec_volatile:DI [(match_operand:DI 0 "u14bit_cint_operand" "i")
+ (match_operand:DI 1 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_MTSPR)
+ (clobber (mem:BLK (const_int 0)))]
+ ""
+ "mtspr\t%0, %r1"
+ [(set_attr "type" "X1")])
+
+(define_insn "insn_mm"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")
+ (match_operand:DI 3 "u6bit_cint_operand" "i")
+ (match_operand:DI 4 "u6bit_cint_operand" "i")]
+ UNSPEC_INSN_MM))]
+ ""
+ "mm\t%0, %r2, %3, %4"
+ [(set_attr "type" "X0")])
+
+(define_insn "insn_mul_hs_hs"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_MUL_HS_HS))]
+ ""
+ "mul_hs_hs\t%0, %r1, %r2"
+ [(set_attr "type" "Y0_2cycle")])
+
+(define_insn "insn_mul_hs_hu"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_MUL_HS_HU))]
+ ""
+ "mul_hs_hu\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_mul_hs_ls"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_MUL_HS_LS))]
+ ""
+ "mul_hs_ls\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_mul_hs_lu"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_MUL_HS_LU))]
+ ""
+ "mul_hs_lu\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_mul_hu_hu"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_MUL_HU_HU))]
+ ""
+ "mul_hu_hu\t%0, %r1, %r2"
+ [(set_attr "type" "Y0_2cycle")])
+
+(define_insn "insn_mul_hu_ls"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_MUL_HU_LS))]
+ ""
+ "mul_hu_ls\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_mul_hu_lu"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_MUL_HU_LU))]
+ ""
+ "mul_hu_lu\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_mul_ls_ls"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_MUL_LS_LS))]
+ ""
+ "mul_ls_ls\t%0, %r1, %r2"
+ [(set_attr "type" "Y0_2cycle")])
+
+(define_insn "insn_mul_ls_lu"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_MUL_LS_LU))]
+ ""
+ "mul_ls_lu\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_mul_lu_lu"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_MUL_LU_LU))]
+ ""
+ "mul_lu_lu\t%0, %r1, %r2"
+ [(set_attr "type" "Y0_2cycle")])
+
+(define_insn "insn_mula_hs_hs"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")
+ (match_operand:DI 3 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_MULA_HS_HS))]
+ ""
+ "mula_hs_hs\t%0, %r2, %r3"
+ [(set_attr "type" "Y0_2cycle")])
+
+(define_insn "insn_mula_hs_hu"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")
+ (match_operand:DI 3 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_MULA_HS_HU))]
+ ""
+ "mula_hs_hu\t%0, %r2, %r3"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_mula_hs_ls"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")
+ (match_operand:DI 3 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_MULA_HS_LS))]
+ ""
+ "mula_hs_ls\t%0, %r2, %r3"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_mula_hs_lu"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")
+ (match_operand:DI 3 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_MULA_HS_LU))]
+ ""
+ "mula_hs_lu\t%0, %r2, %r3"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_mula_hu_hu"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")
+ (match_operand:DI 3 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_MULA_HU_HU))]
+ ""
+ "mula_hu_hu\t%0, %r2, %r3"
+ [(set_attr "type" "Y0_2cycle")])
+
+(define_insn "insn_mula_hu_ls"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")
+ (match_operand:DI 3 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_MULA_HU_LS))]
+ ""
+ "mula_hu_ls\t%0, %r2, %r3"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_mula_hu_lu"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")
+ (match_operand:DI 3 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_MULA_HU_LU))]
+ ""
+ "mula_hu_lu\t%0, %r2, %r3"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_mula_ls_ls"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")
+ (match_operand:DI 3 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_MULA_LS_LS))]
+ ""
+ "mula_ls_ls\t%0, %r2, %r3"
+ [(set_attr "type" "Y0_2cycle")])
+
+(define_insn "insn_mula_ls_lu"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")
+ (match_operand:DI 3 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_MULA_LS_LU))]
+ ""
+ "mula_ls_lu\t%0, %r2, %r3"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_mula_lu_lu"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")
+ (match_operand:DI 3 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_MULA_LU_LU))]
+ ""
+ "mula_lu_lu\t%0, %r2, %r3"
+ [(set_attr "type" "Y0_2cycle")])
+
+(define_insn "insn_mulax"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "0")
+ (match_operand:SI 2 "reg_or_0_operand" "rO")
+ (match_operand:SI 3 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_MULAX))]
+ ""
+ "mulax\t%0, %r2, %r3"
+ [(set_attr "type" "Y0_2cycle")])
+
+(define_insn "insn_nap"
+ [(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_NAP)]
+ ""
+ "nap"
+ [(set_attr "type" "cannot_bundle")])
+
+(define_insn "insn_nor_<mode>"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (and:I48MODE
+ (not:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "rO"))
+ (not:I48MODE (match_operand:I48MODE 2 "reg_or_0_operand" "rO"))))]
+ ""
+ "nor\t%0, %r1, %r2")
+
+(define_expand "insn_prefetch_l1"
+ [(prefetch (match_operand 0 "pointer_operand" "")
+ (const_int 0)
+ (const_int 3))]
+ "")
+
+(define_expand "insn_prefetch_l2"
+ [(prefetch (match_operand 0 "pointer_operand" "")
+ (const_int 0)
+ (const_int 2))]
+ "")
+
+(define_expand "insn_prefetch_l3"
+ [(prefetch (match_operand 0 "pointer_operand" "")
+ (const_int 0)
+ (const_int 1))]
+ "")
+
+(define_insn "insn_prefetch_l1_fault"
+ [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
+ UNSPEC_INSN_PREFETCH_L1_FAULT)]
+ ""
+ "prefetch_l1_fault\t%r0"
+ [(set_attr "type" "Y2")])
+
+(define_insn "insn_prefetch_l2_fault"
+ [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
+ UNSPEC_INSN_PREFETCH_L2_FAULT)]
+ ""
+ "prefetch_l2_fault\t%r0"
+ [(set_attr "type" "Y2")])
+
+(define_insn "insn_prefetch_l3_fault"
+ [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
+ UNSPEC_INSN_PREFETCH_L3_FAULT)]
+ ""
+ "prefetch_l3_fault\t%r0"
+ [(set_attr "type" "Y2")])
+
+(define_insn "insn_revbits"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_REVBITS))]
+ ""
+ "revbits\t%0, %r1"
+ [(set_attr "type" "Y0")])
+
+(define_insn "insn_shl1add"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rO")
+ (const_int 2))
+ (match_operand:DI 2 "reg_or_0_operand" "rO")))]
+ ""
+ "shl1add\t%0, %r1, %r2")
+
+(define_insn "insn_shl1addx"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
+ (const_int 2))
+ (match_operand:SI 2 "reg_or_0_operand" "rO")))]
+ ""
+ "shl1addx\t%0, %r1, %r2")
+
+(define_insn "insn_shl2add"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rO")
+ (const_int 4))
+ (match_operand:DI 2 "reg_or_0_operand" "rO")))]
+ ""
+ "shl2add\t%0, %r1, %r2")
+
+(define_insn "insn_shl2addx"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
+ (const_int 4))
+ (match_operand:SI 2 "reg_or_0_operand" "rO")))]
+ ""
+ "shl2addx\t%0, %r1, %r2")
+
+(define_insn "insn_shl3add"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rO")
+ (const_int 8))
+ (match_operand:DI 2 "reg_or_0_operand" "rO")))]
+ ""
+ "shl3add\t%0, %r1, %r2")
+
+(define_insn "insn_shl3addx"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
+ (const_int 8))
+ (match_operand:SI 2 "reg_or_0_operand" "rO")))]
+ ""
+ "shl3addx\t%0, %r1, %r2")
+
+(define_insn "insn_shufflebytes"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")
+ (match_operand:DI 3 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_SHUFFLEBYTES))]
+ ""
+ "shufflebytes\t%0, %r2, %r3"
+ [(set_attr "type" "X0")])
+
+;; stores
+
+(define_expand "insn_st"
+ [(set (mem:DI (match_operand 0 "pointer_operand" ""))
+ (match_operand:DI 1 "reg_or_0_operand" ""))]
+ "")
+
+(define_insn "insn_st_add<bitsuffix>"
+ [(set (match_operand:I48MODE 0 "pointer_operand" "=r")
+ (plus:I48MODE (match_operand 3 "pointer_operand" "0")
+ (match_operand 2 "s8bit_cint_operand" "i")))
+ (set (mem:DI (match_dup 3))
+ (match_operand:DI 1 "reg_or_0_operand" "rO"))]
+ ""
+ "st_add\t%0, %r1, %2"
+ [(set_attr "type" "X1")])
+
+(define_expand "insn_st<n>"
+ [(set (mem:I124MODE (match_operand 0 "pointer_operand" ""))
+ (match_operand:DI 1 "reg_or_0_operand" ""))]
+ ""
+{
+ operands[1] = simplify_gen_subreg (<MODE>mode, operands[1], DImode, 0);
+})
+
+(define_expand "insn_st<I124MODE:n>_add<I48MODE:bitsuffix>"
+ [(parallel
+ [(set (match_operand:I48MODE 0 "pointer_operand" "")
+ (plus:I48MODE (match_operand 3 "pointer_operand" "")
+ (match_operand 2 "s8bit_cint_operand" "")))
+ (set (mem:I124MODE (match_dup 3))
+ (match_operand:DI 1 "reg_or_0_operand" ""))])]
+ ""
+{
+ operands[1] = simplify_gen_subreg (<I124MODE:MODE>mode, operands[1],
+ DImode, 0);
+})
+
+(define_insn "*insn_st<I124MODE:n>_add<I48MODE:bitsuffix>"
+ [(set (match_operand:I48MODE 0 "pointer_operand" "=r")
+ (plus:I48MODE (match_operand 3 "pointer_operand" "0")
+ (match_operand 2 "s8bit_cint_operand" "i")))
+ (set (mem:I124MODE (match_dup 3))
+ (match_operand:I124MODE 1 "reg_or_0_operand" "rO"))]
+ ""
+ "st<I124MODE:n>_add\t%0, %r1, %2"
+ [(set_attr "type" "X1")])
+
+;; non-temporal stores
+
+(define_insn "insn_stnt"
+ [(set (mem:DI (unspec [(match_operand 0 "pointer_operand" "rO")]
+ UNSPEC_NON_TEMPORAL))
+ (match_operand:DI 1 "reg_or_0_operand" "rO"))]
+ ""
+ "stnt\t%0, %r1"
+ [(set_attr "type" "X1")])
+
+(define_insn "insn_stnt_add<bitsuffix>"
+ [(set (match_operand:I48MODE 0 "pointer_operand" "=r")
+ (plus:I48MODE (match_operand 3 "pointer_operand" "0")
+ (match_operand 2 "s8bit_cint_operand" "i")))
+ (set (mem:DI (unspec:I48MODE [(match_dup 3)] UNSPEC_NON_TEMPORAL))
+ (match_operand:DI 1 "reg_or_0_operand" "rO"))]
+ ""
+ "stnt_add\t%0, %r1, %2"
+ [(set_attr "type" "X1")])
+
+(define_expand "insn_stnt<n>"
+ [(set (mem:I124MODE (unspec [(match_operand 0 "pointer_operand" "")]
+ UNSPEC_NON_TEMPORAL))
+ (match_operand:DI 1 "reg_or_0_operand" ""))]
+ ""
+{
+ operands[1] = simplify_gen_subreg (<MODE>mode, operands[1], DImode, 0);
+})
+
+(define_insn "*insn_stnt<n>"
+ [(set (mem:I124MODE (unspec [(match_operand 0 "pointer_operand" "rO")]
+ UNSPEC_NON_TEMPORAL))
+ (match_operand:I124MODE 1 "reg_or_0_operand" "rO"))]
+ ""
+ "stnt<n>\t%0, %r1"
+ [(set_attr "type" "X1")])
+
+(define_expand "insn_stnt<I124MODE:n>_add<I48MODE:bitsuffix>"
+ [(parallel
+ [(set (match_operand:I48MODE 0 "pointer_operand" "")
+ (plus:I48MODE (match_operand 3 "pointer_operand" "")
+ (match_operand 2 "s8bit_cint_operand" "")))
+ (set (mem:I124MODE (unspec:I48MODE [(match_dup 3)] UNSPEC_NON_TEMPORAL))
+ (match_operand:DI 1 "reg_or_0_operand" "rO"))])]
+ ""
+{
+ operands[1] = simplify_gen_subreg (<I124MODE:MODE>mode, operands[1],
+ DImode, 0);
+})
+
+(define_insn "*insn_stnt<I124MODE:n>_add<I48MODE:bitsuffix>"
+ [(set (match_operand:I48MODE 0 "pointer_operand" "=r")
+ (plus:I48MODE (match_operand 3 "pointer_operand" "0")
+ (match_operand 2 "s8bit_cint_operand" "i")))
+ (set (mem:I124MODE (unspec:I48MODE [(match_dup 3)] UNSPEC_NON_TEMPORAL))
+ (match_operand:I124MODE 1 "reg_or_0_operand" "rO"))]
+ ""
+ "stnt<I124MODE:n>_add\t%0, %r1, %2"
+ [(set_attr "type" "X1")])
+
+;; end stores
+
+(define_insn "insn_tblidxb0"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_TBLIDXB0))]
+ ""
+ "tblidxb0\t%0, %r2"
+ [(set_attr "type" "Y0")])
+
+(define_insn "insn_tblidxb1"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_TBLIDXB1))]
+ ""
+ "tblidxb1\t%0, %r2"
+ [(set_attr "type" "Y0")])
+
+(define_insn "insn_tblidxb2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_TBLIDXB2))]
+ ""
+ "tblidxb2\t%0, %r2"
+ [(set_attr "type" "Y0")])
+
+(define_insn "insn_tblidxb3"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_TBLIDXB3))]
+ ""
+ "tblidxb3\t%0, %r2"
+ [(set_attr "type" "Y0")])
+
+;; insn_v1add
+;; insn_v1addi
+;; insn_v1cmpeq
+;; insn_v1cmpeqi
+;; insn_v1cmplts
+;; insn_v1cmpltsi
+;; insn_v1cmpltu
+;; insn_v1cmpltui
+;; insn_v1maxu
+;; insn_v1maxui
+;; insn_v1minu
+;; insn_v1minui
+(define_insn "<optab>v8qi3"
+ [(set (match_operand:V8QI 0 "register_operand" "=r,r")
+ (v1op_immed:V8QI
+ (match_operand:V8QI 1 "reg_or_0_operand" "<comm>rO,rO")
+ (match_operand:V8QI 2 "reg_or_v8s8bit_operand" "W,rO")))]
+ ""
+ "@
+ v1<insn>i\t%0, %r1, %j2
+ v1<insn>\t%0, %r1, %r2"
+ [(set_attr "type" "<pipe>,<pipe>")])
+
+(define_expand "insn_v1<insn>"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (v1op_immed:V8QI
+ (match_operand:DI 1 "reg_or_0_operand" "")
+ (match_operand:DI 2 "reg_or_0_operand" "")))]
+ ""
+{
+ tilegx_expand_builtin_vector_binop (gen_<optab>v8qi3, V8QImode, operands[0],
+ V8QImode, operands[1], operands[2], true);
+ DONE;
+})
+
+(define_expand "insn_v1<insn>i"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (v1op_immed:V8QI
+ (match_operand:DI 1 "reg_or_0_operand" "")
+ (match_operand:DI 2 "s8bit_cint_operand" "")))]
+ ""
+{
+ /* Tile out immediate and expand to general case. */
+ rtx n = tilegx_simd_int (operands[2], QImode);
+ tilegx_expand_builtin_vector_binop (gen_<optab>v8qi3, V8QImode, operands[0],
+ V8QImode, operands[1], n, true);
+ DONE;
+})
+
+;; insn_v1shl
+;; insn_v1shli
+;; insn_v1shrs
+;; insn_v1shrsi
+;; insn_v1shru
+;; insn_v1shrui
+(define_insn "<optab>v8qi3"
+ [(set (match_operand:V8QI 0 "register_operand" "=r,r")
+ (any_shift:V8QI
+ (match_operand:V8QI 1 "reg_or_0_operand" "rO,rO")
+ (match_operand:DI 2 "reg_or_u5bit_operand" "I,rO")))]
+ ""
+ "@
+ v1<insn>i\t%0, %r1, %2
+ v1<insn>\t%0, %r1, %r2"
+ [(set_attr "type" "<pipe>,<pipe>")])
+
+(define_expand "insn_v1<insn>"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (any_shift:V8QI
+ (match_operand:DI 1 "reg_or_0_operand" "")
+ (match_operand:DI 2 "reg_or_u5bit_operand" "")))]
+ ""
+{
+ tilegx_expand_builtin_vector_binop (gen_<optab>v8qi3, V8QImode, operands[0],
+ V8QImode, operands[1], operands[2], false);
+ DONE;
+})
+
+;; insn_v2add
+;; insn_v2addi
+;; insn_v2maxs
+;; insn_v2maxsi
+;; insn_v2mins
+;; insn_v2minsi
+;; insn_v2cmpeq
+;; insn_v2cmpeqi
+;; insn_v2cmplts
+;; insn_v2cmpltsi
+;; insn_v2cmpltu
+;; insn_v2cmpltui
+(define_insn "<optab>v4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=r,r")
+ (v2op_immed:V4HI
+ (match_operand:V4HI 1 "reg_or_0_operand" "<comm>rO,rO")
+ (match_operand:V4HI 2 "reg_or_v4s8bit_operand" "Y,rO")))]
+ ""
+ "@
+ v2<insn>i\t%0, %r1, %j2
+ v2<insn>\t%0, %r1, %r2"
+ [(set_attr "type" "<pipe>,<pipe>")])
+
+(define_expand "insn_v2<insn>"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (v2op_immed:V4HI
+ (match_operand:DI 1 "reg_or_0_operand" "")
+ (match_operand:DI 2 "reg_or_0_operand" "")))]
+ ""
+{
+ tilegx_expand_builtin_vector_binop (gen_<optab>v4hi3, V4HImode, operands[0],
+ V4HImode, operands[1], operands[2], true);
+ DONE;
+})
+
+(define_expand "insn_v2<insn>i"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (v2op_immed:V4HI
+ (match_operand:DI 1 "reg_or_0_operand" "")
+ (match_operand:DI 2 "s8bit_cint_operand" "")))]
+ ""
+{
+ /* Tile out immediate and expand to general case. */
+ rtx n = tilegx_simd_int (operands[2], HImode);
+ tilegx_expand_builtin_vector_binop (gen_<optab>v4hi3, V4HImode, operands[0],
+ V4HImode, operands[1], n, true);
+ DONE;
+})
+
+;; insn_v2shl
+;; insn_v2shli
+;; insn_v2shrs
+;; insn_v2shrsi
+;; insn_v2shru
+;; insn_v2shrui
+(define_insn "<optab>v4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=r,r")
+ (any_shift:V4HI
+ (match_operand:V4HI 1 "reg_or_0_operand" "rO,rO")
+ (match_operand:DI 2 "reg_or_u5bit_operand" "I,rO")))]
+ ""
+ "@
+ v2<insn>i\t%0, %r1, %2
+ v2<insn>\t%0, %r1, %r2"
+ [(set_attr "type" "<pipe>,<pipe>")])
+
+(define_expand "insn_v2<insn>"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (any_shift:V4HI
+ (match_operand:DI 1 "reg_or_0_operand" "")
+ (match_operand:DI 2 "reg_or_u5bit_operand" "")))]
+ ""
+{
+ tilegx_expand_builtin_vector_binop (gen_<optab>v4hi3, V4HImode, operands[0],
+ V4HImode, operands[1], operands[2], false);
+ DONE;
+})
+
+;; insn_v1adduc
+;; insn_v1subuc
+;; insn_v1sub
+;; insn_v1cmpne
+;; insn_v1cmples
+;; insn_v1cmpleu
+;; insn_v1multu
+(define_insn "<optab>v8qi3"
+ [(set (match_operand:V8QI 0 "register_operand" "=r")
+ (v1op:V8QI
+ (match_operand:V8QI 1 "reg_or_0_operand" "<comm>rO")
+ (match_operand:V8QI 2 "reg_or_0_operand" "rO")))]
+ ""
+ "v1<insn>\t%0, %r1, %r2"
+ [(set_attr "type" "<pipe>")])
+
+(define_expand "insn_v1<insn>"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (v1op:V8QI
+ (match_operand:DI 1 "reg_or_0_operand" "")
+ (match_operand:DI 2 "reg_or_0_operand" "")))]
+ ""
+{
+ tilegx_expand_builtin_vector_binop (gen_<optab>v8qi3, V8QImode, operands[0],
+ V8QImode, operands[1], operands[2], true);
+ DONE;
+})
+
+;; insn_v2addsc
+;; insn_v2subsc
+;; insn_v2sub
+;; insn_v2cmpne
+;; insn_v2cmples
+;; insn_v2cmpleu
+(define_insn "<optab>v4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=r")
+ (v2op:V4HI
+ (match_operand:V4HI 1 "reg_or_0_operand" "<comm>rO")
+ (match_operand:V4HI 2 "reg_or_0_operand" "rO")))]
+ ""
+ "v2<insn>\t%0, %r1, %r2"
+ [(set_attr "type" "<pipe>")])
+
+(define_expand "insn_v2<insn>"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (v2op:V4HI
+ (match_operand:DI 1 "reg_or_0_operand" "")
+ (match_operand:DI 2 "reg_or_0_operand" "")))]
+ ""
+{
+ tilegx_expand_builtin_vector_binop (gen_<optab>v4hi3, V4HImode, operands[0],
+ V4HImode, operands[1], operands[2], true);
+ DONE;
+})
+
+;; insn_v2mults
+(define_insn "mulv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=r")
+ (mult:V4HI
+ (match_operand:V4HI 1 "reg_or_0_operand" "%rO")
+ (match_operand:V4HI 2 "reg_or_0_operand" "rO")))]
+ ""
+ "v2mults\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_expand "insn_v2mults"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (mult:V4HI
+ (match_operand:DI 1 "reg_or_0_operand" "")
+ (match_operand:DI 2 "reg_or_0_operand" "")))]
+ ""
+{
+ tilegx_expand_builtin_vector_binop (gen_mulv4hi3, V4HImode, operands[0],
+ V4HImode, operands[1], operands[2], true);
+ DONE;
+})
+
+;; insn_v2shlsc
+(define_insn "<optab>v4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=r")
+ (v2shift:V4HI
+ (match_operand:V4HI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")))]
+ ""
+ "v2<insn>\t%0, %r1, %r2"
+ [(set_attr "type" "<pipe>")])
+
+(define_expand "insn_v2<insn>"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (v2shift:V4HI
+ (match_operand:DI 1 "reg_or_0_operand" "")
+ (match_operand:DI 2 "reg_or_0_operand" "")))]
+ ""
+{
+ tilegx_expand_builtin_vector_binop (gen_<optab>v4hi3, V4HImode, operands[0],
+ V4HImode, operands[1], operands[2], false);
+ DONE;
+})
+
+;; insn_v4addsc
+;; insn_v4subsc
+;; insn_v4add
+;; insn_v4sub
+(define_insn "<optab>v2si3"
+ [(set (match_operand:V2SI 0 "register_operand" "=r")
+ (v4op:V2SI
+ (match_operand:V2SI 1 "reg_or_0_operand" "<comm>rO")
+ (match_operand:V2SI 2 "reg_or_0_operand" "rO")))]
+ ""
+ "v4<insn>\t%0, %r1, %r2"
+ [(set_attr "type" "<pipe>")])
+
+(define_expand "insn_v4<insn>"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (v4op:V2SI
+ (match_operand:DI 1 "reg_or_0_operand" "")
+ (match_operand:DI 2 "reg_or_0_operand" "")))]
+ ""
+{
+ tilegx_expand_builtin_vector_binop (gen_<optab>v2si3, V2SImode, operands[0],
+ V2SImode, operands[1], operands[2], true);
+ DONE;
+})
+
+;; insn_v4shl
+;; insn_v4shrs
+;; insn_v4shru
+;; insn_v4shlsc
+(define_insn "<optab>v2si3"
+ [(set (match_operand:V2SI 0 "register_operand" "=r")
+ (v4shift:V2SI
+ (match_operand:V2SI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")))]
+ ""
+ "v4<insn>\t%0, %r1, %r2"
+ [(set_attr "type" "<pipe>")])
+
+(define_expand "insn_v4<insn>"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (v4shift:V2SI
+ (match_operand:DI 1 "reg_or_0_operand" "")
+ (match_operand:DI 2 "reg_or_0_operand" "")))]
+ ""
+{
+ tilegx_expand_builtin_vector_binop (gen_<optab>v2si3, V2SImode, operands[0],
+ V2SImode, operands[1], operands[2], false);
+ DONE;
+})
+
+;; insn_v1int_h
+;; {B7,B6,B5,B4,B3,B2,B1,B0} {A7,A6,A5,A4,A3,A2,A1,A0}
+;; => {A7,A6,A5,A4,A3,A2,A1,A0,B7,B6,B5,B4,B3,B2,B1,B0}
+;; => {A7,B7,A6,B6,A5,B5,A4,B4}
+(define_insn "vec_interleave_highv8qi"
+ [(set (match_operand:V8QI 0 "register_operand" "=r")
+ (vec_select:V8QI
+ (vec_concat:V16QI (match_operand:V8QI 1 "reg_or_0_operand" "rO")
+ (match_operand:V8QI 2 "reg_or_0_operand" "rO"))
+ (parallel [(const_int 4) (const_int 12)
+ (const_int 5) (const_int 13)
+ (const_int 6) (const_int 14)
+ (const_int 7) (const_int 15)])))]
+ ""
+ "v1int_h\t%0, %r2, %r1"
+ [(set_attr "type" "X01")])
+
+(define_expand "insn_v1int_h"
+ [(match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "reg_or_0_operand" "")
+ (match_operand:DI 2 "reg_or_0_operand" "")]
+ ""
+{
+ /* Our instruction interleaves opposite of the way vec_interleave
+ works, so we need to reverse the source operands. */
+ tilegx_expand_builtin_vector_binop (gen_vec_interleave_highv8qi, V8QImode,
+ operands[0], V8QImode, operands[2],
+ operands[1], true);
+ DONE;
+})
+
+;; insn_v1int_l
+;; {B7,B6,B5,B4,B3,B2,B1,B0} {A7,A6,A5,A4,A3,A2,A1,A0}
+;; => {A7,A6,A5,A4,A3,A2,A1,A0,B7,B6,B5,B4,B3,B2,B1,B0}
+;; => {A3,B3,A2,B2,A1,B1,A0,B0}
+(define_insn "vec_interleave_lowv8qi"
+ [(set (match_operand:V8QI 0 "register_operand" "=r")
+ (vec_select:V8QI
+ (vec_concat:V16QI (match_operand:V8QI 1 "reg_or_0_operand" "rO")
+ (match_operand:V8QI 2 "reg_or_0_operand" "rO"))
+ (parallel [(const_int 0) (const_int 8)
+ (const_int 1) (const_int 9)
+ (const_int 2) (const_int 10)
+ (const_int 3) (const_int 11)])))]
+ ""
+ "v1int_l\t%0, %r2, %r1"
+ [(set_attr "type" "X01")])
+
+(define_expand "insn_v1int_l"
+ [(match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "reg_or_0_operand" "")
+ (match_operand:DI 2 "reg_or_0_operand" "")]
+ ""
+{
+ /* Our instruction interleaves opposite of the way vec_interleave
+ works, so we need to reverse the source operands. */
+ tilegx_expand_builtin_vector_binop (gen_vec_interleave_lowv8qi, V8QImode,
+ operands[0], V8QImode, operands[2],
+ operands[1], true);
+ DONE;
+})
+
+;; insn_v2int_h
+;; {B3,B2,B1,B0} {A3,A2,A1,A0}
+;; => {A3,A2,A1,A0,B3,B2,B1,B0}
+;; => {A3,B3,A2,B2}
+(define_insn "vec_interleave_highv4hi"
+ [(set (match_operand:V4HI 0 "register_operand" "=r")
+ (vec_select:V4HI
+ (vec_concat:V8HI (match_operand:V4HI 1 "reg_or_0_operand" "rO")
+ (match_operand:V4HI 2 "reg_or_0_operand" "rO"))
+ (parallel [(const_int 2) (const_int 6)
+ (const_int 3) (const_int 7)])))]
+ ""
+ "v2int_h\t%0, %r2, %r1"
+ [(set_attr "type" "X01")])
+
+(define_expand "insn_v2int_h"
+ [(match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "reg_or_0_operand" "")
+ (match_operand:DI 2 "reg_or_0_operand" "")]
+ ""
+{
+ /* Our instruction interleaves opposite of the way vec_interleave
+ works, so we need to reverse the source operands. */
+ tilegx_expand_builtin_vector_binop (gen_vec_interleave_highv4hi, V4HImode,
+ operands[0], V4HImode, operands[2],
+ operands[1], true);
+ DONE;
+})
+
+;; insn_v2int_l
+;; {B3,B2,B1,B0} {A3,A2,A1,A0}
+;; => {A3,A2,A1,A0,B3,B2,B1,B0}
+;; => {A1,B1,A0,B0}
+(define_insn "vec_interleave_lowv4hi"
+ [(set (match_operand:V4HI 0 "register_operand" "=r")
+ (vec_select:V4HI
+ (vec_concat:V8HI (match_operand:V4HI 1 "reg_or_0_operand" "rO")
+ (match_operand:V4HI 2 "reg_or_0_operand" "rO"))
+ (parallel [(const_int 0) (const_int 4)
+ (const_int 1) (const_int 5)])))]
+ ""
+ "v2int_l\t%0, %r2, %r1"
+ [(set_attr "type" "X01")])
+
+(define_expand "insn_v2int_l"
+ [(match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "reg_or_0_operand" "")
+ (match_operand:DI 2 "reg_or_0_operand" "")]
+ ""
+{
+ tilegx_expand_builtin_vector_binop (gen_vec_interleave_lowv4hi, V4HImode,
+ operands[0], V4HImode, operands[2],
+ operands[1], true);
+ DONE;
+})
+
+;; insn_v4int_h
+;; {B1,B0} {A1,A0}
+;; => {A1,A0,B1,B0}
+;; => {A1,B1}
+(define_insn "vec_interleave_highv2si"
+ [(set (match_operand:V2SI 0 "register_operand" "=r")
+ (vec_select:V2SI
+ (vec_concat:V4SI (match_operand:V2SI 1 "reg_or_0_operand" "rO")
+ (match_operand:V2SI 2 "reg_or_0_operand" "rO"))
+ (parallel [(const_int 1) (const_int 3)])))]
+ ""
+ "v4int_h\t%0, %r2, %r1"
+ [(set_attr "type" "X01")])
+
+(define_expand "insn_v4int_h"
+ [(match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "reg_or_0_operand" "")
+ (match_operand:DI 2 "reg_or_0_operand" "")]
+ ""
+{
+ /* Our instruction interleaves opposite of the way vec_interleave
+ works, so we need to reverse the source operands. */
+ tilegx_expand_builtin_vector_binop (gen_vec_interleave_highv2si, V2SImode,
+ operands[0], V2SImode, operands[2],
+ operands[1], true);
+ DONE;
+})
+
+;; insn_v4int_l
+;; {B1,B0} {A1,A0}
+;; => {A1,A0,B1,B0}
+;; => {A0,B0}
+(define_insn "vec_interleave_lowv2si"
+ [(set (match_operand:V2SI 0 "register_operand" "=r")
+ (vec_select:V2SI
+ (vec_concat:V4SI (match_operand:V2SI 1 "reg_or_0_operand" "rO")
+ (match_operand:V2SI 2 "reg_or_0_operand" "rO"))
+ (parallel [(const_int 0) (const_int 2)])))]
+ ""
+ "v4int_l\t%0, %r2, %r1"
+ [(set_attr "type" "X01")])
+
+(define_expand "insn_v4int_l"
+ [(match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "reg_or_0_operand" "")
+ (match_operand:DI 2 "reg_or_0_operand" "")]
+ ""
+{
+ /* Our instruction interleaves opposite of the way vec_interleave
+ works, so we need to reverse the source operands. */
+ tilegx_expand_builtin_vector_binop (gen_vec_interleave_lowv2si, V2SImode,
+ operands[0], V2SImode, operands[2],
+ operands[1], true);
+ DONE;
+})
+
+;; insn_v1mnz
+;; insn_v1mz
+;; insn_v2mnz
+;; insn_v2mz
+(define_insn "insn_mnz_<mode>"
+ [(set (match_operand:VEC48MODE 0 "register_operand" "=r")
+ (if_then_else:VEC48MODE
+ (ne:VEC48MODE
+ (match_operand:VEC48MODE 1 "reg_or_0_operand" "rO")
+ (const_int 0))
+ (match_operand:VEC48MODE 2 "reg_or_0_operand" "rO")
+ (const_int 0)))]
+ ""
+ "v<n>mnz\t%0, %r1, %r2"
+ [(set_attr "type" "X01")])
+
+(define_expand "insn_v<n>mnz"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (if_then_else:VEC48MODE
+ (ne:VEC48MODE
+ (match_operand:DI 1 "reg_or_0_operand" "")
+ (const_int 0))
+ (match_operand:DI 2 "reg_or_0_operand" "")
+ (const_int 0)))]
+ ""
+{
+ tilegx_expand_builtin_vector_binop (gen_insn_mnz_<mode>, <MODE>mode,
+ operands[0], <MODE>mode, operands[1],
+ operands[2], true);
+ DONE;
+})
+
+(define_insn "insn_mz_<mode>"
+ [(set (match_operand:VEC48MODE 0 "register_operand" "=r")
+ (if_then_else:VEC48MODE
+ (ne:VEC48MODE
+ (match_operand:VEC48MODE 1 "reg_or_0_operand" "rO")
+ (const_int 0))
+ (const_int 0)
+ (match_operand:VEC48MODE 2 "reg_or_0_operand" "rO")))]
+ ""
+ "v<n>mz\t%0, %r1, %r2"
+ [(set_attr "type" "X01")])
+(define_expand "insn_v<n>mz"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (if_then_else:VEC48MODE
+ (ne:VEC48MODE
+ (match_operand:DI 1 "reg_or_0_operand" "")
+ (const_int 0))
+ (const_int 0)
+ (match_operand:DI 2 "reg_or_0_operand" "")))]
+ ""
+{
+ tilegx_expand_builtin_vector_binop (gen_insn_mz_<mode>, <MODE>mode,
+ operands[0], <MODE>mode, operands[1],
+ operands[2], true);
+ DONE;
+})
+
+;; insn_v1mulu
+(define_insn "vec_widen_umult_lo_v8qi"
+ [(set (match_operand:V4HI 0 "register_operand" "=r")
+ (mult:V4HI
+ (zero_extend:V4HI
+ (vec_select:V4QI
+ (match_operand:V8QI 1 "register_operand" "r")
+ (parallel [(const_int 0) (const_int 1)
+ (const_int 2) (const_int 3)])))
+ (zero_extend:V4HI
+ (vec_select:V4QI
+ (match_operand:V8QI 2 "register_operand" "r")
+ (parallel [(const_int 0) (const_int 1)
+ (const_int 2) (const_int 3)])))))]
+ ""
+ "v1mulu\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_expand "insn_v1mulu"
+ [(match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "reg_or_0_operand" "")
+ (match_operand:DI 2 "reg_or_0_operand" "")]
+ ""
+{
+ tilegx_expand_builtin_vector_binop (gen_vec_widen_umult_lo_v8qi, V4HImode,
+ operands[0], V8QImode, operands[1],
+ operands[2], true);
+ DONE;
+})
+
+;; insn_v1mulus
+(define_insn "vec_widen_usmult_lo_v8qi"
+ [(set (match_operand:V4HI 0 "register_operand" "=r")
+ (mult:V4HI
+ (zero_extend:V4HI
+ (vec_select:V4QI
+ (match_operand:V8QI 1 "register_operand" "r")
+ (parallel [(const_int 0) (const_int 1)
+ (const_int 2) (const_int 3)])))
+ (sign_extend:V4HI
+ (vec_select:V4QI
+ (match_operand:V8QI 2 "register_operand" "r")
+ (parallel [(const_int 0) (const_int 1)
+ (const_int 2) (const_int 3)])))))]
+ ""
+ "v1mulus\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_expand "insn_v1mulus"
+ [(match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "reg_or_0_operand" "")
+ (match_operand:DI 2 "reg_or_0_operand" "")]
+ ""
+{
+ tilegx_expand_builtin_vector_binop (gen_vec_widen_usmult_lo_v8qi, V4HImode,
+ operands[0], V8QImode, operands[1],
+ operands[2], true);
+ DONE;
+})
+
+;; insn_v2muls
+(define_insn "vec_widen_smult_lo_v4qi"
+ [(set (match_operand:V2SI 0 "register_operand" "=r")
+ (mult:V2SI
+ (sign_extend:V2SI
+ (vec_select:V2HI
+ (match_operand:V4HI 1 "register_operand" "r")
+ (parallel [(const_int 0) (const_int 1)])))
+ (sign_extend:V2SI
+ (vec_select:V2HI
+ (match_operand:V4HI 2 "register_operand" "r")
+ (parallel [(const_int 0) (const_int 1)])))))]
+ ""
+ "v2muls\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_expand "insn_v2muls"
+ [(match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "reg_or_0_operand" "")
+ (match_operand:DI 2 "reg_or_0_operand" "")]
+ ""
+{
+ tilegx_expand_builtin_vector_binop (gen_vec_widen_smult_lo_v4qi, V2SImode,
+ operands[0], V4HImode, operands[1],
+ operands[2], true);
+ DONE;
+})
+
+;; v2packl
+;; v2packuc
+;; {B3,B2,B1,B0} {A3,A2,A1,A0}
+;; => {A3,A2,A1,A0,B3,B2,B1,B0}
+(define_insn "vec_pack_<pack_optab>_v4hi"
+ [(set (match_operand:V8QI 0 "reg_or_0_operand" "=r")
+ (vec_concat:V8QI
+ (v2pack:V4QI (match_operand:V4HI 1 "reg_or_0_operand" "rO"))
+ (v2pack:V4QI (match_operand:V4HI 2 "reg_or_0_operand" "rO"))))]
+ ""
+ "v2<pack_insn>\t%0, %r2, %r1"
+ [(set_attr "type" "X01")])
+
+(define_expand "insn_v2<pack_insn>"
+ [(set (match_operand:DI 0 "reg_or_0_operand" "")
+ (vec_concat:V8QI
+ (v2pack:V4QI (match_operand:DI 2 "reg_or_0_operand" ""))
+ (v2pack:V4QI (match_operand:DI 1 "reg_or_0_operand" ""))))]
+ ""
+{
+ /* Our instruction concats opposite of the way vec_pack works, so we
+ need to reverse the source operands. */
+ tilegx_expand_builtin_vector_binop (gen_vec_pack_<pack_optab>_v4hi,
+ V8QImode, operands[0], V4HImode,
+ operands[2], operands[1], true);
+ DONE;
+})
+
+;; v2packh
+;; {B3,B2,B1,B0} {A3,A2,A1,A0}
+;; => {A3_hi,A2_hi,A1_hi,A0_hi,B3_hi,B2_hi,B1_hi,B0_hi}
+(define_insn "vec_pack_hipart_v4hi"
+ [(set (match_operand:V8QI 0 "reg_or_0_operand" "=r")
+ (vec_concat:V8QI
+ (truncate:V4QI
+ (ashiftrt:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rO")
+ (const_int 8)))
+ (truncate:V4QI
+ (ashiftrt:V4HI (match_operand:V4HI 2 "reg_or_0_operand" "rO")
+ (const_int 8)))))]
+ ""
+ "v2packh\t%0, %r2, %r1"
+ [(set_attr "type" "X01")])
+
+(define_expand "insn_v2packh"
+ [(set (match_operand:DI 0 "reg_or_0_operand" "")
+ (vec_concat:V8QI
+ (truncate:V4QI
+ (ashiftrt:V4HI (match_operand:DI 2 "reg_or_0_operand" "")
+ (const_int 8)))
+ (truncate:V4QI
+ (ashiftrt:V4HI (match_operand:DI 1 "reg_or_0_operand" "")
+ (const_int 8)))))]
+ ""
+{
+ /* Our instruction concats opposite of the way vec_pack works, so we
+ need to reverse the source operands. */
+ tilegx_expand_builtin_vector_binop (gen_vec_pack_hipart_v4hi, V8QImode,
+ operands[0], V4HImode, operands[2],
+ operands[1], true);
+ DONE;
+})
+
+;; v4packsc
+;; {B1,B0} {A1,A0}
+;; => {A1,A0,B1,B0}
+(define_insn "vec_pack_ssat_v2si"
+ [(set (match_operand:V4HI 0 "reg_or_0_operand" "=r")
+ (vec_concat:V4HI
+ (us_truncate:V2HI (match_operand:V2SI 1 "reg_or_0_operand" "rO"))
+ (us_truncate:V2HI (match_operand:V2SI 2 "reg_or_0_operand" "rO"))))]
+ ""
+ "v4packsc\t%0, %r2, %r1"
+ [(set_attr "type" "X01")])
+
+(define_expand "insn_v4packsc"
+ [(set (match_operand:DI 0 "reg_or_0_operand" "")
+ (vec_concat:V4HI
+ (us_truncate:V2HI (match_operand:DI 2 "reg_or_0_operand" ""))
+ (us_truncate:V2HI (match_operand:DI 1 "reg_or_0_operand" ""))))]
+ ""
+{
+ /* Our instruction concats opposite of the way vec_pack works, so we
+ need to reverse the source operands. */
+ tilegx_expand_builtin_vector_binop (gen_vec_pack_ssat_v2si, V4HImode,
+ operands[0], V2SImode, operands[2],
+ operands[1], true);
+ DONE;
+})
+
+;; Rest of the vector intrinsics
+(define_insn "insn_v1adiffu"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_V1ADIFFU))]
+ ""
+ "v1adiffu\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_v1avgu"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_V1AVGU))]
+ ""
+ "v1avgu\t%0, %r1, %r2"
+ [(set_attr "type" "X0")])
+
+(define_insn "insn_v1ddotpu"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_V1DDOTPU))]
+ ""
+ "v1ddotpu\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_v1ddotpua"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")
+ (match_operand:DI 3 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_V1DDOTPUA))]
+ ""
+ "v1ddotpua\t%0, %r2, %r3"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_v1ddotpus"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_V1DDOTPUS))]
+ ""
+ "v1ddotpus\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_v1ddotpusa"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")
+ (match_operand:DI 3 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_V1DDOTPUSA))]
+ ""
+ "v1ddotpusa\t%0, %r2, %r3"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_v1dotp"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_V1DOTP))]
+ ""
+ "v1dotp\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_v1dotpa"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")
+ (match_operand:DI 3 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_V1DOTPA))]
+ ""
+ "v1dotpa\t%0, %r2, %r3"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_v1dotpu"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_V1DOTPU))]
+ ""
+ "v1dotpu\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_v1dotpua"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")
+ (match_operand:DI 3 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_V1DOTPUA))]
+ ""
+ "v1dotpua\t%0, %r2, %r3"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_v1dotpus"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_V1DOTPUS))]
+ ""
+ "v1dotpus\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_v1dotpusa"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")
+ (match_operand:DI 3 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_V1DOTPUSA))]
+ ""
+ "v1dotpusa\t%0, %r2, %r3"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_v1sadau"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")
+ (match_operand:DI 3 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_V1SADAU))]
+ ""
+ "v1sadau\t%0, %r2, %r3"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_v1sadu"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_V1SADU))]
+ ""
+ "v1sadu\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "*insn_v1sadu"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (truncate:SI
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_V1SADU)))]
+ ""
+ "v1sadu\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_v2adiffs"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_V2ADIFFS))]
+ ""
+ "v2adiffs\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_v2avgs"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_V2AVGS))]
+ ""
+ "v2avgs\t%0, %r1, %r2"
+ [(set_attr "type" "X0")])
+
+(define_insn "insn_v2dotp"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_V2DOTP))]
+ ""
+ "v2dotp\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_v2dotpa"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")
+ (match_operand:DI 3 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_V2DOTPA))]
+ ""
+ "v2dotpa\t%0, %r2, %r3"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_v2mulfsc"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_V2MULFSC))]
+ ""
+ "v2mulfsc\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_v2sadas"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")
+ (match_operand:DI 3 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_V2SADAS))]
+ ""
+ "v2sadas\t%0, %r2, %r3"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_v2sadau"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "0")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")
+ (match_operand:DI 3 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_V2SADAU))]
+ ""
+ "v2sadau\t%0, %r2, %r3"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_v2sads"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_V2SADS))]
+ ""
+ "v2sads\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "*insn_v2sads"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (truncate:SI
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_V2SADS)))]
+ ""
+ "v2sads\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_v2sadu"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_V2SADU))]
+ ""
+ "v2sadu\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "*insn_v2sadu"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (truncate:SI
+ (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
+ (match_operand:DI 2 "reg_or_0_operand" "rO")]
+ UNSPEC_INSN_V2SADU)))]
+ ""
+ "v2sadu\t%0, %r1, %r2"
+ [(set_attr "type" "X0_2cycle")])
+
+(define_insn "insn_wh64"
+ [(unspec_volatile:VOID [(match_operand 0 "pointer_operand" "rO")]
+ UNSPEC_INSN_WH64)
+ (clobber (mem:BLK (const_int 0)))]
+ ""
+ "wh64\t%r0"
+ [(set_attr "type" "X1")])
+
+
+;; Network intrinsics
+
+;; Note the "pseudo" text is handled specially by the
+;; asm_output_opcode routine. If the output is an empty string, the
+;; instruction would bypass the asm_output_opcode routine, bypassing
+;; the bundle handling code.
+(define_insn "tilegx_network_barrier"
+ [(unspec_volatile:SI [(const_int 0)] UNSPEC_NETWORK_BARRIER)]
+ ""
+ "pseudo"
+ [(set_attr "type" "nothing")
+ (set_attr "length" "0")])
+
+(define_insn "*netreg_receive"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,U,m")
+ (unspec_volatile:DI [(match_operand:DI 1 "netreg_operand" "i,i,i")
+ (reg:DI TILEGX_NETORDER_REG)]
+ UNSPEC_NETWORK_RECEIVE))
+ (clobber (reg:DI TILEGX_NETORDER_REG))]
+
+ ""
+ "@
+ move\t%0, %N1
+ st\t%0, %N1
+ st_add\t%I0, %N1, %i0"
+ [(set_attr "type" "*,Y2,X1")])
+
+(define_insn "*netreg_send"
+ [(unspec_volatile:DI
+ [(match_operand:DI 0 "netreg_operand" "i,i,i,i,i,i")
+ (match_operand:DI 1 "reg_or_cint_operand" "r,I,J,K,N,P")
+ (reg:DI TILEGX_NETORDER_REG)]
+ UNSPEC_NETWORK_SEND)
+ (clobber (reg:DI TILEGX_NETORDER_REG))]
+ ""
+ "@
+ move\t%N0, %r1
+ movei\t%N0, %1
+ moveli\t%N0, %1
+ shl16insli\t%N0, zero, %h1
+ v1addi\t%N0, zero, %j1
+ v2addi\t%N0, zero, %h1"
+ [(set_attr "type" "*,*,X01,X01,X01,X01")])
+
+(define_expand "tilegx_idn0_receive"
+ [(parallel
+ [(set (match_operand:DI 0 "register_operand" "")
+ (unspec_volatile:DI [(const_int TILEGX_NETREG_IDN0)
+ (reg:DI TILEGX_NETORDER_REG)]
+ UNSPEC_NETWORK_RECEIVE))
+ (clobber (reg:DI TILEGX_NETORDER_REG))])]
+ "")
+
+(define_expand "tilegx_idn1_receive"
+ [(parallel
+ [(set (match_operand:DI 0 "register_operand" "")
+ (unspec_volatile:DI [(const_int TILEGX_NETREG_IDN1)
+ (reg:DI TILEGX_NETORDER_REG)]
+ UNSPEC_NETWORK_RECEIVE))
+ (clobber (reg:DI TILEGX_NETORDER_REG))])]
+ "")
+
+(define_expand "tilegx_idn_send"
+ [(parallel
+ [(unspec_volatile:DI [(const_int TILEGX_NETREG_IDN0)
+ (match_operand:DI 0 "reg_or_cint_operand" "")
+ (reg:DI TILEGX_NETORDER_REG)]
+ UNSPEC_NETWORK_SEND)
+ (clobber (reg:DI TILEGX_NETORDER_REG))])]
+ "")
+
+(define_expand "tilegx_udn0_receive"
+ [(parallel
+ [(set (match_operand:DI 0 "register_operand" "")
+ (unspec_volatile:DI [(const_int TILEGX_NETREG_UDN0)
+ (reg:DI TILEGX_NETORDER_REG)]
+ UNSPEC_NETWORK_RECEIVE))
+ (clobber (reg:DI TILEGX_NETORDER_REG))])]
+ "")
+
+(define_expand "tilegx_udn1_receive"
+ [(parallel
+ [(set (match_operand:DI 0 "register_operand" "")
+ (unspec_volatile:DI [(const_int TILEGX_NETREG_UDN1)
+ (reg:DI TILEGX_NETORDER_REG)]
+ UNSPEC_NETWORK_RECEIVE))
+ (clobber (reg:DI TILEGX_NETORDER_REG))])]
+ "")
+
+(define_expand "tilegx_udn2_receive"
+ [(parallel
+ [(set (match_operand:DI 0 "register_operand" "")
+ (unspec_volatile:DI [(const_int TILEGX_NETREG_UDN2)
+ (reg:DI TILEGX_NETORDER_REG)]
+ UNSPEC_NETWORK_RECEIVE))
+ (clobber (reg:DI TILEGX_NETORDER_REG))])]
+ "")
+
+(define_expand "tilegx_udn3_receive"
+ [(parallel
+ [(set (match_operand:DI 0 "register_operand" "")
+ (unspec_volatile:DI [(const_int TILEGX_NETREG_UDN3)
+ (reg:DI TILEGX_NETORDER_REG)]
+ UNSPEC_NETWORK_RECEIVE))
+ (clobber (reg:DI TILEGX_NETORDER_REG))])]
+ "")
+
+(define_expand "tilegx_udn_send"
+ [(parallel
+ [(unspec_volatile:DI [(const_int TILEGX_NETREG_UDN0)
+ (match_operand:DI 0 "reg_or_cint_operand" "")
+ (reg:DI TILEGX_NETORDER_REG)]
+ UNSPEC_NETWORK_SEND)
+ (clobber (reg:DI TILEGX_NETORDER_REG))])]
+ "")
+
+(define_insn "*netreg_adddi_to_network"
+ [(unspec_volatile:DI
+ [(match_operand:DI 0 "netreg_operand" "i,i,i")
+ (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rO,rO,rO")
+ (match_operand:DI 2 "add_operand" "r,I,JT"))
+ (reg:DI TILEGX_NETORDER_REG)]
+ UNSPEC_NETWORK_SEND)
+ (clobber (reg:DI TILEGX_NETORDER_REG))]
+ ""
+ "@
+ add\t%N0, %r1, %2
+ addi\t%N0, %r1, %2
+ addli\t%N0, %r1, %H2"
+ [(set_attr "type" "*,*,X01")])
+
+(define_insn "*netreg_adddi_from_network"
+ [(set (match_operand:DI 0 "register_operand" "=r,r,r")
+ (plus:DI (unspec_volatile:DI
+ [(match_operand:DI 1 "netreg_operand" "%i,i,i")
+ (reg:DI TILEGX_NETORDER_REG)]
+ UNSPEC_NETWORK_RECEIVE)
+ (match_operand:DI 2 "add_operand" "rO,I,JT")))
+ (clobber (reg:DI TILEGX_NETORDER_REG))]
+ ""
+ "@
+ add\t%0, %N1, %r2
+ addi\t%0, %N1, %2
+ addli\t%0, %N1, %H2"
+ [(set_attr "type" "*,*,X01")])
+
+
+;;
+;; Stack protector instructions.
+;;
+
+(define_expand "stack_protect_set"
+ [(set (match_operand 0 "nonautoincmem_operand" "")
+ (match_operand 1 "nonautoincmem_operand" ""))]
+ ""
+{
+#ifdef TARGET_THREAD_SSP_OFFSET
+ rtx tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
+ rtx ssp_addr = gen_rtx_PLUS (Pmode, tp, GEN_INT (TARGET_THREAD_SSP_OFFSET));
+ rtx ssp = gen_reg_rtx (Pmode);
+
+ emit_insn (gen_rtx_SET (VOIDmode, ssp, ssp_addr));
+
+ operands[1] = gen_rtx_MEM (Pmode, ssp);
+#endif
+
+ if (TARGET_32BIT)
+ emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
+ else
+ emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
+
+ DONE;
+})
+
+(define_insn "stack_protect_setsi"
+ [(set (match_operand:SI 0 "nonautoincmem_operand" "=U")
+ (unspec:SI [(match_operand:SI 1 "nonautoincmem_operand" "U")]
+ UNSPEC_SP_SET))
+ (set (match_scratch:SI 2 "=&r") (const_int 0))]
+ ""
+ "ld4s\t%2, %1; { st4\t%0, %2; move\t%2, zero }"
+ [(set_attr "length" "16")
+ (set_attr "type" "cannot_bundle_3cycle")])
+
+(define_insn "stack_protect_setdi"
+ [(set (match_operand:DI 0 "nonautoincmem_operand" "=U")
+ (unspec:DI [(match_operand:DI 1 "nonautoincmem_operand" "U")]
+ UNSPEC_SP_SET))
+ (set (match_scratch:DI 2 "=&r") (const_int 0))]
+ ""
+ "ld\t%2, %1; { st\t%0, %2; move\t%2, zero }"
+ [(set_attr "length" "16")
+ (set_attr "type" "cannot_bundle_3cycle")])
+
+(define_expand "stack_protect_test"
+ [(match_operand 0 "nonautoincmem_operand" "")
+ (match_operand 1 "nonautoincmem_operand" "")
+ (match_operand 2 "" "")]
+ ""
+{
+ rtx compare_result;
+ rtx bcomp, loc_ref;
+
+#ifdef TARGET_THREAD_SSP_OFFSET
+ rtx tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
+ rtx ssp_addr = gen_rtx_PLUS (Pmode, tp, GEN_INT (TARGET_THREAD_SSP_OFFSET));
+ rtx ssp = gen_reg_rtx (Pmode);
+
+ emit_insn (gen_rtx_SET (VOIDmode, ssp, ssp_addr));
+
+ operands[1] = gen_rtx_MEM (Pmode, ssp);
+#endif
+
+ compare_result = gen_reg_rtx (Pmode);
+
+ if (TARGET_32BIT)
+ emit_insn (gen_stack_protect_testsi (compare_result, operands[0],
+ operands[1]));
+ else
+ emit_insn (gen_stack_protect_testdi (compare_result, operands[0],
+ operands[1]));
+
+ bcomp = gen_rtx_NE (SImode, compare_result, const0_rtx);
+
+ loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[2]);
+
+ emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
+ gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
+ loc_ref, pc_rtx)));
+
+ DONE;
+})
+
+(define_insn "stack_protect_testsi"
+ [(set (match_operand:SI 0 "register_operand" "=&r")
+ (unspec:SI [(match_operand:SI 1 "nonautoincmem_operand" "U")
+ (match_operand:SI 2 "nonautoincmem_operand" "U")]
+ UNSPEC_SP_TEST))
+ (set (match_scratch:SI 3 "=&r") (const_int 0))]
+ ""
+ "ld4s\t%0, %1; ld4s\t%3, %2; { cmpeq\t%0, %0, %3; move\t%3, zero }"
+ [(set_attr "length" "24")
+ (set_attr "type" "cannot_bundle_4cycle")])
+
+(define_insn "stack_protect_testdi"
+ [(set (match_operand:DI 0 "register_operand" "=&r")
+ (unspec:DI [(match_operand:DI 1 "nonautoincmem_operand" "U")
+ (match_operand:DI 2 "nonautoincmem_operand" "U")]
+ UNSPEC_SP_TEST))
+ (set (match_scratch:DI 3 "=&r") (const_int 0))]
+ ""
+ "ld\t%0, %1; ld\t%3, %2; { cmpeq\t%0, %0, %3; move\t%3, zero }"
+ [(set_attr "length" "24")
+ (set_attr "type" "cannot_bundle_4cycle")])
+
+(include "sync.md")