URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [config/] [tilepro/] [tilepro.md] - Rev 758
Go to most recent revision | Compare with Previous | Blame | View Log
;; Machine description for Tilera TILEPro chip for GCC.
;; Copyright (C) 2011, 2012
;; 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_ADDLIS 1)
(UNSPEC_INSN_AULI 2)
(UNSPEC_INSN_AVGB_U 3)
(UNSPEC_INSN_AVGH 4)
(UNSPEC_INSN_BITX 5)
(UNSPEC_INSN_CRC32_32 6)
(UNSPEC_INSN_CRC32_8 7)
(UNSPEC_INSN_DRAIN 8)
(UNSPEC_INSN_DTLBPR 9)
(UNSPEC_INSN_DWORD_ALIGN 10)
(UNSPEC_INSN_FINV 11)
(UNSPEC_INSN_FLUSH 12)
(UNSPEC_INSN_FNOP 13)
(UNSPEC_INSN_ICOH 14)
(UNSPEC_INSN_ILL 15)
(UNSPEC_INSN_INFO 16)
(UNSPEC_INSN_INFOL 17)
(UNSPEC_INSN_INV 18)
(UNSPEC_INSN_LNK 19)
(UNSPEC_INSN_MFSPR 20)
(UNSPEC_INSN_MNZB 21)
(UNSPEC_INSN_MNZH 22)
(UNSPEC_INSN_MOVELIS 23)
(UNSPEC_INSN_MTSPR 24)
(UNSPEC_INSN_MZB 25)
(UNSPEC_INSN_MZH 26)
(UNSPEC_INSN_NAP 27)
(UNSPEC_INSN_PACKBS_U 28)
(UNSPEC_INSN_PACKHB 29)
(UNSPEC_INSN_PACKHS 30)
(UNSPEC_INSN_PACKLB 31)
(UNSPEC_INSN_PREFETCH_L1 32)
(UNSPEC_INSN_TBLIDXB0 33)
(UNSPEC_INSN_TBLIDXB1 34)
(UNSPEC_INSN_TBLIDXB2 35)
(UNSPEC_INSN_TBLIDXB3 36)
(UNSPEC_INSN_WH64 37)
;; 2 cycles
(UNSPEC_INSN_ADIFFB_U 100)
(UNSPEC_INSN_ADIFFH 101)
(UNSPEC_INSN_MULHHA_SS 102)
(UNSPEC_INSN_MULHHA_SU 103)
(UNSPEC_INSN_MULHHA_UU 104)
(UNSPEC_INSN_MULHHSA_UU 105)
(UNSPEC_INSN_MULHH_SS 106)
(UNSPEC_INSN_MULHH_SU 107)
(UNSPEC_INSN_MULHH_UU 108)
(UNSPEC_INSN_MULHLA_SS 109)
(UNSPEC_INSN_MULHLA_SU 110)
(UNSPEC_INSN_MULHLA_US 111)
(UNSPEC_INSN_MULHLA_UU 112)
(UNSPEC_INSN_MULHLSA_UU 113)
(UNSPEC_INSN_MULHL_SS 114)
(UNSPEC_INSN_MULHL_SU 115)
(UNSPEC_INSN_MULHL_US 116)
(UNSPEC_INSN_MULHL_UU 117)
(UNSPEC_INSN_MULLLA_SS 118)
(UNSPEC_INSN_MULLLA_SU 119)
(UNSPEC_INSN_MULLLA_UU 120)
(UNSPEC_INSN_MULLLSA_UU 121)
(UNSPEC_INSN_MULLL_SU 122)
(UNSPEC_INSN_MULLL_SS 123)
(UNSPEC_INSN_MULLL_UU 124)
(UNSPEC_INSN_SADAB_U 125)
(UNSPEC_INSN_SADAH 126)
(UNSPEC_INSN_SADAH_U 127)
(UNSPEC_INSN_SADB_U 128)
(UNSPEC_INSN_SADH 129)
(UNSPEC_INSN_SADH_U 130)
;;
;; The following are special insns.
;;
;; Blockage
(UNSPEC_BLOCKAGE 200)
;; Latency specifying loads.
(UNSPEC_LATENCY_L2 201)
(UNSPEC_LATENCY_MISS 202)
;; Lnk and its label
(UNSPEC_LNK_AND_LABEL 203)
;; Memory fence
(UNSPEC_MF 204)
;; A pseudo-op that prevents network operations from being ordered.
(UNSPEC_NETWORK_BARRIER 205)
;; Operations that access network registers.
(UNSPEC_NETWORK_RECEIVE 206)
(UNSPEC_NETWORK_SEND 207)
;; Stack protector operations
(UNSPEC_SP_SET 208)
(UNSPEC_SP_TEST 209)
;; A call to __tls_get_addr
(UNSPEC_TLS_GD_CALL 210)
;; An opaque TLS "add" operation for TLS general dynamic model
;; access.
(UNSPEC_TLS_GD_ADD 211)
;; An opaque TLS "load" operation for TLS initial exec model access.
(UNSPEC_TLS_IE_LOAD 212)
;;
;; The following are operands.
;;
(UNSPEC_PCREL_SYM 300)
(UNSPEC_GOT16_SYM 301)
(UNSPEC_GOT32_SYM 302)
(UNSPEC_TLS_GD 303)
(UNSPEC_TLS_IE 304)
(UNSPEC_TLS_LE 305)
])
;; Mark the last instruction of various latencies, used to
;; determine the rtx costs of unspec insns.
(define_constants [
(TILEPRO_LAST_LATENCY_1_INSN 99)
(TILEPRO_LAST_LATENCY_2_INSN 199)
(TILEPRO_LAST_LATENCY_INSN 299)
])
;; Constants for network registers.
(define_constants [
(TILEPRO_NETREG_IDN0 0)
(TILEPRO_NETREG_IDN1 1)
(TILEPRO_NETREG_SN 2)
(TILEPRO_NETREG_UDN0 3)
(TILEPRO_NETREG_UDN1 4)
(TILEPRO_NETREG_UDN2 5)
(TILEPRO_NETREG_UDN3 6)
])
;; Constants for special purpose registers.
(define_constants [
(TILEPRO_NETORDER_REG 66)])
;; Operand and operator predicates and constraints
(include "predicates.md")
(include "constraints.md")
(include "tilepro-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_miss,X01,Y0,Y0_2cycle,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 iterators.
(define_mode_iterator I48MODE [SI DI])
(define_mode_iterator I12MODE [QI HI])
(define_code_iterator binop_u5bit [ashift ashiftrt lshiftrt rotate])
(define_code_iterator binop_with_imm
[ashift lshiftrt ashiftrt rotate eq lt and ior xor])
(define_code_iterator unop [bswap clz ctz popcount])
(define_mode_attr load [(QI "lb") (HI "lh") (SI "lw")])
(define_mode_attr store [(QI "sb") (HI "sh") (SI "sw")])
;; <optab> expands to the name of the optab for a particular code.
(define_code_attr optab [(ashift "ashl")
(ashiftrt "ashr")
(lshiftrt "lshr")
(eq "seq")
(ne "sne")
(lt "slt")
(ltu "sltu")
(le "sle")
(leu "sleu")
(minus "sub")
(plus "add")
(rotate "rotl")
(smax "smax")
(smin "smin")
(umax "umax")
(umin "umin")
(ss_minus "sssub")
(ss_plus "ssadd")
(us_minus "ussub")
(us_plus "usadd")
(and "and")
(ior "ior")
(xor "xor")
(bswap "bswap")
(clz "clz")
(ctz "ctz")
(popcount "popcount")])
;; <insn> expands to the name of the insn that implements a particular
;; code.
(define_code_attr insn [(ashift "shl")
(ashiftrt "sra")
(lshiftrt "shr")
(eq "seq")
(ne "sne")
(lt "slt")
(ltu "slt")
(le "slte")
(leu "slte")
(minus "sub")
(plus "add")
(rotate "rl")
(smax "max")
(smin "min")
(umax "max")
(umin "min")
(ss_minus "sub")
(ss_plus "add")
(us_minus "sub")
(us_plus "add")
(and "and")
(ior "or")
(xor "xor")
(bswap "bytex")
(clz "clz")
(ctz "ctz")
(popcount "pcnt")])
;; <u> expands to the suffix of the insn that implements a particular
;; code.
(define_code_attr u [(ashift "")
(ashiftrt "")
(lshiftrt "")
(eq "")
(ne "")
(lt "")
(ltu "_u")
(le "")
(leu "_u")
(minus "")
(plus "")
(rotate "")
(smax "")
(smin "")
(umax "_u")
(umin "_u")
(ss_minus "s")
(ss_plus "s")
(us_minus "s_u")
(us_plus "s_u")
(and "")
(ior "")
(xor "")])
;; <comm> indicates whether a particular code is commutative, using
;; the "%" commutative opterator constraint.
(define_code_attr comm [(ashift "")
(ashiftrt "")
(lshiftrt "")
(eq "%")
(ne "%")
(lt "")
(ltu "")
(le "")
(leu "")
(minus "")
(plus "%")
(rotate "")
(smax "%")
(umax "%")
(smin "%")
(umin "%")
(ss_plus "%")
(us_plus "%")
(ss_minus "")
(us_minus "")
(and "%")
(ior "%")
(xor "%")])
(define_mode_iterator VEC [V4QI V2HI])
;; 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_plus ne le leu minus us_minus])
;; Code iterator for all 2-byte vector ops without immediate variants.
(define_code_iterator v2op [ss_plus ne le leu minus ss_minus])
;; 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 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 "pack")
(ss_truncate "pack")])
;; <pack_u> expands to the suffix of the insn that implements a
;; particular vector packing code.
(define_code_attr pack_u [(truncate "")
(us_truncate "s_u")
(ss_truncate "s")])
;;
;; The basic data move insns.
;;
(define_expand "movqi"
[(set (match_operand:QI 0 "nonimmediate_operand" "")
(match_operand:QI 1 "nonautoinc_operand" ""))]
""
{
if (tilepro_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
lb_u\t%0, %1
lbadd_u\t%0, %I1, %i1
sb\t%0, %r1
sbadd\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 (tilepro_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,J,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, %1
lh_u\t%0, %1
lhadd_u\t%0, %I1, %i1
sh\t%0, %r1
shadd\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 (tilepro_expand_mov (SImode, operands))
DONE;
})
(define_insn "*movsi_high_insn"
[(set (match_operand:SI 0 "register_operand" "=r")
(high:SI (match_operand:SI 1 "symbolic_operand" "in")))]
""
"auli\t%0, zero, ha16(%1)"
[(set_attr "type" "X01")])
(define_insn "*movsi_insn"
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,r,r,U,m")
(match_operand:SI 1 "move_operand" "r,I,J,K,N,P,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, %1
auli\t%0, zero, %h1
addib\t%0, zero, %j1
addih\t%0, zero, %h1
lw\t%0, %1
lwadd\t%0, %I1, %i1
sw\t%0, %r1
swadd\t%I0, %r1, %i0"
[(set_attr "type" "*,*,X01,X01,X01,X01,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"))]
""
"mm\t%r0, %r1, %r0, 0, 7"
[(set_attr "type" "X01")])
(define_insn "movstricthi"
[(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
(match_operand:HI 1 "reg_or_0_operand" "rO"))]
""
"mm\t%r0, %r1, %r0, 0, 15"
[(set_attr "type" "X01")])
(define_expand "movmisalign<mode>"
[(set (match_operand:VEC 0 "nonautoincmem_nonimmediate_operand" "")
(match_operand:VEC 1 "nonautoincmem_general_operand" ""))]
""
{
tilepro_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
lw\t%0, %1
lwadd\t%0, %I1, %i1
sw\t%0, %r1
swadd\t%I0, %r1, %i0"
[(set_attr "type" "*,Y2_2cycle,X1_2cycle,Y2,X1")])
(define_expand "mov<mode>"
[(set (match_operand:VEC 0 "nonimmediate_operand" "")
(match_operand:VEC 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], <MODE>mode)
&& operands[1] != const0_rtx
&& (register_operand (operands[0], <MODE>mode)
|| (!reload_in_progress && !reload_completed)))
{
emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
gen_lowpart (SImode, operands[1])));
DONE;
}
})
(define_insn "*mov<mode>"
[(set (match_operand:VEC 0 "nonimmediate_operand" "=r,r,r,U,m")
(match_operand:VEC 1 "general_operand" "rO,U,m,rO,rO"))]
""
"@
move\t%0, %r1
lw\t%0, %1
lwadd\t%0, %I1, %i1
sw\t%0, %r1
swadd\t%I0, %r1, %i0"
[(set_attr "type" "*,Y2_2cycle,X1_2cycle,Y2,X1")])
;;
;; Bit-field extracts
;;
(define_expand "extv"
[(set (match_operand:SI 0 "register_operand" "")
(sign_extract:SI
(match_operand:QI 1 "nonautoincmem_operand" "")
(match_operand:SI 2 "immediate_operand" "")
(match_operand:SI 3 "immediate_operand" "")))]
""
{
HOST_WIDE_INT bit_offset, bit_width;
HOST_WIDE_INT first_byte_offset, last_byte_offset;
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 4 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 > 3)
FAIL;
tilepro_expand_unaligned_load (operands[0], operands[1],
bit_width, bit_offset, 1);
DONE;
})
(define_expand "extzv"
[(set (match_operand:SI 0 "register_operand" "")
(zero_extract:SI
(match_operand:QI 1 "nonautoincmem_operand" "")
(match_operand:SI 2 "immediate_operand" "")
(match_operand:SI 3 "immediate_operand" "")))]
""
{
HOST_WIDE_INT bit_offset, bit_width;
HOST_WIDE_INT first_byte_offset, last_byte_offset;
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 4 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 > 3)
FAIL;
tilepro_expand_unaligned_load (operands[0], operands[1],
bit_width, bit_offset, 0);
DONE;
})
;;
;; Arithmetic ops
;;
(define_insn "*s123a_insn"
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 2 "cint_248_operand" "I"))
(match_operand:SI 3 "reg_or_0_operand" "rO")))]
""
"s%t2a\t%0, %r1, %r3")
(define_expand "addsi3"
[(set (match_operand:SI 0 "register_operand" "")
(plus:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "reg_or_cint_operand" "")))]
""
"
if (tilepro_expand_addsi (operands[0], operands[1], operands[2]))
DONE;
")
(define_insn "*addsi_high_insn"
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI
(match_operand:SI 1 "reg_or_0_operand" "%rO")
(high:SI (match_operand:SI 2 "const_symbolic_operand" "T"))))]
""
"auli\t%0, %r1, %H2"
[(set_attr "type" "X01")])
(define_insn "*addsi_lo_sum_insn"
[(set (match_operand:SI 0 "register_operand" "=r")
(lo_sum:SI
(match_operand:SI 1 "reg_or_0_operand" "%rO")
(match_operand:SI 2 "const_symbolic_operand" "T")))]
""
"addli\t%0, %r1, %L2"
[(set_attr "type" "X01")])
(define_insn "*addsi3_insn"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
(plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO,rO,rO")
(match_operand:SI 2 "add_operand" "r,I,J,K")))]
""
"@
add\t%0, %r1, %r2
addi\t%0, %r1, %2
addli\t%0, %r1, %2
auli\t%0, %r1, %h2"
[(set_attr "type" "*,*,X01,X01")])
(define_insn "subsi3"
[(set (match_operand:SI 0 "register_operand" "=r")
(minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 2 "reg_or_0_operand" "rO")))]
""
"sub\t%0, %r1, %r2")
(define_insn "negsi2"
[(set (match_operand:SI 0 "register_operand" "=r")
(neg:SI (match_operand:SI 1 "reg_or_0_operand" "rO")))]
""
"sub\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")))]
""
"adds\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")))]
""
"subs\t%0, %r1, %r2"
[(set_attr "type" "X01")])
;;
;; Shifts
;;
;; ashift, ashiftrt, lshiftrt, rotate.
(define_insn "<optab>si3"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(binop_u5bit:SI (match_operand:SI 1 "reg_or_0_operand" "rO,rO")
(match_operand:SI 2 "reg_or_u5bit_operand" "I,rO")))]
""
"@
<insn>i\t%0, %r1, %2
<insn>\t%0, %r1, %r2")
;;
;; Compares
;;
(define_expand "cstore<mode>4"
[(set (match_operand:SI 0 "register_operand" "")
(match_operator:SI 1 "ordered_comparison_operator"
[(match_operand:I48MODE 2 "reg_or_cint_operand" "")
(match_operand:I48MODE 3 "reg_or_cint_operand" "")]))]
""
{ if (!tilepro_emit_setcc (operands, <MODE>mode)) FAIL; else DONE; })
(define_insn "insn_seq"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(eq:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO")
(match_operand:SI 2 "reg_or_cint_operand" "I,rO")))]
""
"@
seqi\t%0, %r1, %2
seq\t%0, %r1, %r2")
(define_insn "insn_sne"
[(set (match_operand:SI 0 "register_operand" "=r")
(ne:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 2 "reg_or_cint_operand" "rO")))]
""
"sne\t%0, %r1, %r2")
(define_insn "insn_slt"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(lt:SI (match_operand:SI 1 "reg_or_0_operand" "rO,rO")
(match_operand:SI 2 "reg_or_cint_operand" "I,rO")))]
""
"@
slti\t%0, %r1, %2
slt\t%0, %r1, %r2")
(define_insn "insn_slte"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(le:SI (match_operand:SI 1 "reg_or_0_operand" "rO,rO")
(match_operand:SI 2 "reg_or_cint_operand" "L,rO")))]
""
"@
slti\t%0, %r1, %P2
slte\t%0, %r1, %r2")
(define_insn "insn_slt_u"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(ltu:SI (match_operand:SI 1 "reg_or_0_operand" "rO,rO")
(match_operand:SI 2 "reg_or_cint_operand" "I,rO")))]
""
"@
slti_u\t%0, %r1, %2
slt_u\t%0, %r1, %r2")
(define_insn "insn_slte_u"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(leu:SI (match_operand:SI 1 "reg_or_0_operand" "rO,rO")
(match_operand:SI 2 "reg_or_cint_operand" "Q,rO")))]
""
"@
slti_u\t%0, %r1, %P2
slte_u\t%0, %r1, %r2")
;;
;; Logical ops
;;
(define_insn "andsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
(and:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO,rO")
(match_operand:SI 2 "and_operand" "I,M,rO")))]
""
"@
andi\t%0, %r1, %2
mm\t%0, %r1, zero, %M2
and\t%0, %r1, %r2"
[(set_attr "type" "*,X01,*")])
(define_insn "iorsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(ior:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO")
(match_operand:SI 2 "reg_or_s8bit_operand" "I,rO")))]
""
"@
ori\t%0, %r1, %2
or\t%0, %r1, %r2")
(define_insn "xorsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(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")])
;; bswap, clz, ctz, popcount
(define_insn "<optab>si2"
[(set (match_operand:SI 0 "register_operand" "=r")
(unop:SI (match_operand:SI 1 "reg_or_0_operand" "rO")))]
""
"<insn>\t%0, %r1"
[(set_attr "type" "Y0")])
(define_expand "ctzdi2"
[(set (match_operand:DI 0 "register_operand" "")
(ctz:DI (match_operand:DI 1 "reg_or_0_operand" "")))]
""
{
rtx lo, hi, ctz_lo, ctz_hi, ctz_hi_plus_32, result;
split_di (&operands[1], 1, &lo, &hi);
lo = force_reg (SImode, lo);
hi = force_reg (SImode, hi);
ctz_lo = gen_reg_rtx (SImode);
emit_insn (gen_ctzsi2 (ctz_lo, lo));
ctz_hi = gen_reg_rtx (SImode);
emit_insn (gen_ctzsi2 (ctz_hi, hi));
ctz_hi_plus_32 = gen_reg_rtx (SImode);
emit_insn (gen_addsi3 (ctz_hi_plus_32, ctz_hi, GEN_INT (32)));
result = gen_reg_rtx (SImode);
emit_insn (gen_insn_mvz (result, ctz_lo, lo, ctz_hi_plus_32));
emit_move_insn (operands[0], convert_to_mode (DImode, result, 1));
DONE;
})
(define_expand "clzdi2"
[(set (match_operand:DI 0 "register_operand" "")
(clz:DI (match_operand:DI 1 "reg_or_0_operand" "")))]
""
{
rtx lo, hi, clz_lo, clz_hi, clz_lo_plus_32, result;
split_di (&operands[1], 1, &lo, &hi);
lo = force_reg (SImode, lo);
hi = force_reg (SImode, hi);
clz_lo = gen_reg_rtx (SImode);
emit_insn (gen_clzsi2 (clz_lo, lo));
clz_hi = gen_reg_rtx (SImode);
emit_insn (gen_clzsi2 (clz_hi, hi));
clz_lo_plus_32 = gen_reg_rtx (SImode);
emit_insn (gen_addsi3 (clz_lo_plus_32, clz_lo, GEN_INT (32)));
result = gen_reg_rtx (SImode);
emit_insn (gen_insn_mvz (result, clz_hi, hi, clz_lo_plus_32));
emit_move_insn (operands[0], convert_to_mode (DImode, result, 1));
DONE;
})
(define_expand "ffsdi2"
[(set (match_operand:DI 0 "register_operand" "")
(ffs:DI (match_operand:DI 1 "reg_or_0_operand" "")))]
""
{
rtx lo, hi, ctz_lo, ctz_hi, ctz_hi_plus_32, ctz, ctz_plus_1,ctz_cond;
rtx result;
split_di (&operands[1], 1, &lo, &hi);
lo = force_reg (SImode, lo);
hi = force_reg (SImode, hi);
ctz_lo = gen_reg_rtx (SImode);
emit_insn (gen_ctzsi2 (ctz_lo, lo));
ctz_hi = gen_reg_rtx (SImode);
emit_insn (gen_ctzsi2 (ctz_hi, hi));
ctz_hi_plus_32 = gen_reg_rtx (SImode);
emit_insn (gen_addsi3 (ctz_hi_plus_32, ctz_hi, GEN_INT (32)));
ctz = gen_reg_rtx (SImode);
emit_insn (gen_insn_mvz (ctz, ctz_lo, lo, ctz_hi_plus_32));
ctz_plus_1 = gen_reg_rtx (SImode);
emit_insn (gen_addsi3 (ctz_plus_1, ctz, GEN_INT (1)));
ctz_cond = gen_reg_rtx (SImode);
emit_insn (gen_iorsi3 (ctz_cond, lo, hi));
result = gen_reg_rtx (SImode);
emit_insn (gen_insn_mvz (result, ctz_plus_1, ctz_cond, const0_rtx));
emit_move_insn (operands[0], convert_to_mode (DImode, result, 1));
DONE;
})
(define_expand "popcountdi2"
[(set (match_operand:DI 0 "register_operand" "")
(popcount:DI (match_operand:DI 1 "nonmemory_operand" "")))]
""
{
rtx lo, hi, popcount_lo, popcount_hi, result;
split_di (&operands[1], 1, &lo, &hi);
lo = force_reg (SImode, lo);
hi = force_reg (SImode, hi);
popcount_lo = gen_reg_rtx (SImode);
emit_insn (gen_popcountsi2 (popcount_lo, lo));
popcount_hi = gen_reg_rtx (SImode);
emit_insn (gen_popcountsi2 (popcount_hi, hi));
result = gen_reg_rtx (SImode);
emit_insn (gen_addsi3 (result, popcount_lo, popcount_hi));
emit_move_insn (operands[0], convert_to_mode (DImode, result, 1));
DONE;
})
(define_expand "paritysi2"
[(set (match_operand:SI 0 "register_operand" "")
(parity:SI (match_operand:SI 1 "reg_or_0_operand" "")))]
""
{
operands[2] = gen_reg_rtx (SImode);
emit_insn (gen_popcountsi2 (operands[2], operands[1]));
emit_insn (gen_andsi3 (operands[0], operands[2], const1_rtx));
DONE;
})
(define_expand "paritydi2"
[(set (match_operand:DI 0 "register_operand" "")
(parity:DI (match_operand:DI 1 "nonmemory_operand" "")))]
""
{
rtx lo, hi, xor_lohi, result;
split_di (&operands[1], 1, &lo, &hi);
lo = force_reg (SImode, lo);
hi = force_reg (SImode, hi);
xor_lohi = gen_reg_rtx (SImode);
emit_insn (gen_xorsi3 (xor_lohi, lo, hi));
result = gen_reg_rtx (SImode);
emit_insn (gen_paritysi2 (result, xor_lohi));
emit_move_insn (operands[0], convert_to_mode (DImode, result, 1));
DONE;
})
(define_insn "one_cmplsi2"
[(set (match_operand:SI 0 "register_operand" "=r")
(not:SI (match_operand:SI 1 "reg_or_0_operand" "rO")))]
""
"nor\t%0, %r1, zero")
;;
;; Conditional moves.
;;
(define_expand "movsicc"
[(set (match_operand:SI 0 "register_operand" "")
(if_then_else:SI (match_operand 1 "comparison_operator" "")
(match_operand:SI 2 "reg_or_0_operand" "")
(match_operand:SI 3 "reg_or_0_operand" "")))]
""
{ operands[1] = tilepro_emit_conditional_move (operands[1]); })
(define_insn "movcc_insn"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
(if_then_else:SI
(match_operator 4 "eqne_operator"
[(match_operand:SI 1 "reg_or_0_operand" "rO,rO,rO,rO")
(const_int 0)])
(match_operand:SI 2 "reg_or_0_operand" "rO,O,rO,0")
(match_operand:SI 3 "reg_or_0_operand" "O,rO,0,rO")))]
""
"@
m%c4\t%0, %r1, %r2
m%C4\t%0, %r1, %r3
mv%c4\t%0, %r1, %r2
mv%C4\t%0, %r1, %r3"
[(set_attr "type" "*,*,Y0,Y0")])
(define_expand "insn_mz"
[(set (match_operand:SI 0 "register_operand" "")
(if_then_else:SI
(eq (match_operand:SI 1 "reg_or_0_operand" "")
(const_int 0))
(match_operand:SI 2 "reg_or_0_operand" "")
(const_int 0)))])
(define_expand "insn_mnz"
[(set (match_operand:SI 0 "register_operand" "")
(if_then_else:SI
(ne (match_operand:SI 1 "reg_or_0_operand" "")
(const_int 0))
(match_operand:SI 2 "reg_or_0_operand" "")
(const_int 0)))])
(define_expand "insn_mvz"
[(set (match_operand:SI 0 "register_operand" "")
(if_then_else:SI
(eq (match_operand:SI 2 "reg_or_0_operand" "")
(const_int 0))
(match_operand:SI 3 "reg_or_0_operand" "")
(match_operand:SI 1 "reg_or_0_operand" "")))])
(define_expand "insn_mvnz"
[(set (match_operand:SI 0 "register_operand" "")
(if_then_else:SI
(ne (match_operand:SI 2 "reg_or_0_operand" "")
(const_int 0))
(match_operand:SI 3 "reg_or_0_operand" "")
(match_operand:SI 1 "reg_or_0_operand" "")))])
;;
;; Conversions
;;
(define_insn "zero_extendqisi2"
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
(zero_extend:SI (match_operand:QI 1 "move_operand" "rO,U,m")))]
""
"@
mm\t%0, %r1, zero, 0, 7
lb_u\t%0, %1
lbadd_u\t%0, %I1, %i1"
[(set_attr "type" "X01,Y2_2cycle,X1_2cycle")])
(define_insn "zero_extendhisi2"
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
(zero_extend:SI (match_operand:HI 1 "move_operand" "rO,U,m")))]
""
"@
mm\t%0, %r1, zero, 0, 15
lh_u\t%0, %1
lhadd_u\t%0, %I1, %i1"
[(set_attr "type" "X01,Y2_2cycle,X1_2cycle")])
(define_expand "extendhisi2"
[(set (match_operand:SI 0 "register_operand" "")
(sign_extend:SI (match_operand:HI 1 "move_operand" "")))]
""
{
if (!memory_operand (operands[1], HImode))
{
operands[1] = gen_lowpart (SImode, operands[1]);
operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
emit_move_insn (operands[2], gen_rtx_ASHIFT (SImode, operands[1],
GEN_INT (16)));
emit_move_insn (operands[0], gen_rtx_ASHIFTRT (SImode, operands[2],
GEN_INT (16)));
DONE;
}
})
(define_insn "*lh"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(sign_extend:SI (match_operand:HI 1 "memory_operand" "U,m")))]
""
"@
lh\t%0, %1
lhadd\t%0, %I1, %i1"
[(set_attr "type" "Y2_2cycle,X1_2cycle")])
(define_expand "extendqisi2"
[(set (match_operand:SI 0 "register_operand" "")
(sign_extend:SI (match_operand:QI 1 "move_operand" "")))]
""
{
if (!memory_operand (operands[1], QImode))
{
operands[1] = gen_lowpart (SImode, operands[1]);
operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
emit_move_insn (operands[2], gen_rtx_ASHIFT (SImode, operands[1],
GEN_INT (24)));
emit_move_insn (operands[0], gen_rtx_ASHIFTRT (SImode, operands[2],
GEN_INT (24)));
DONE;
}
})
(define_insn "*lb"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(sign_extend:SI (match_operand:QI 1 "memory_operand" "U,m")))]
""
"@
lb\t%0, %1
lbadd\t%0, %I1, %i1"
[(set_attr "type" "Y2_2cycle,X1_2cycle")])
;;
;; insv patterns
;;
(define_expand "insv"
[(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "u5bit_cint_operand" "")
(match_operand:SI 2 "u5bit_cint_operand" ""))
(match_operand:SI 3 "reg_or_cint_operand" ""))]
""
{
tilepro_expand_insv (operands);
DONE;
})
(define_insn "*insv_tblidxb0"
[(set (zero_extract:SI
(match_operand:SI 0 "register_operand" "+r")
(const_int 8)
(const_int 2))
(match_operand:SI 1 "register_operand" "rO"))]
""
"tblidxb0\t%0, %r1"
[(set_attr "type" "Y0")])
(define_insn "*insv_tblidxb1"
[(set (zero_extract:SI
(match_operand:SI 0 "register_operand" "+r")
(const_int 8)
(const_int 2))
(zero_extract:SI
(const_int 8)
(const_int 8)
(match_operand:SI 1 "register_operand" "rO")))]
""
"tblidxb1\t%0, %r1"
[(set_attr "type" "Y0")])
(define_insn "*insv_tblidxb2"
[(set (zero_extract:SI
(match_operand:SI 0 "register_operand" "+r")
(const_int 8)
(const_int 2))
(zero_extract:SI
(const_int 8)
(const_int 16)
(match_operand:SI 1 "register_operand" "rO")))]
""
"tblidxb2\t%0, %r1"
[(set_attr "type" "Y0")])
(define_insn "*insv_tblidxb3"
[(set (zero_extract:SI
(match_operand:SI 0 "register_operand" "+r")
(const_int 8)
(const_int 2))
(zero_extract:SI
(const_int 8)
(const_int 24)
(match_operand:SI 1 "register_operand" "rO")))]
""
"tblidxb3\t%0, %r1"
[(set_attr "type" "Y0")])
(define_insn "*insv_mm1"
[(set (zero_extract:SI
(match_operand:SI 0 "register_operand" "+r")
(match_operand:SI 1 "u5bit_cint_operand" "n")
(const_int 0))
(match_operand:SI 2 "register_operand" "rO"))]
""
"mm\t%0, %r2, %0, 0, %1-1"
[(set_attr "type" "X01")])
(define_insn "*insv_mm2"
[(set (zero_extract:SI
(match_operand:SI 0 "register_operand" "+r")
(match_operand:SI 1 "u5bit_cint_operand" "n")
(match_operand:SI 2 "u5bit_cint_operand" "n"))
(zero_extract:SI
(match_operand:SI 3 "register_operand" "rO")
(match_dup 1)
(match_dup 2)))]
""
"mm\t%0, %r3, %0, %2, %2+%1-1"
[(set_attr "type" "X01")])
;;
;; Multiplies
;;
(define_expand "mulsi3"
[(set (match_operand:SI 0 "register_operand" "=r")
(mult:SI (zero_extend:SI
(subreg:HI (match_operand:SI 1 "nonmemory_operand" "") 0))
(zero_extend:SI
(subreg:HI (match_operand:SI 2 "nonmemory_operand" "") 0))))
(set (match_dup 0)
(unspec:SI [(match_dup 0) (match_dup 1) (match_dup 2)]
UNSPEC_INSN_MULHLSA_UU))
(set (match_dup 0)
(unspec:SI [(match_dup 0) (match_dup 2) (match_dup 1)]
UNSPEC_INSN_MULHLSA_UU))]
""
{
operands[1] = force_reg (SImode, operands[1]);
operands[1] = make_safe_from (operands[1], operands[0]);
if (tilepro_expand_mulsi (operands[0], operands[1], operands[2]))
DONE;
else
{
operands[2] = force_reg (SImode, operands[2]);
operands[2] = make_safe_from (operands[2], operands[0]);
}
})
(define_insn "mulhisi3"
[(set (match_operand:SI 0 "register_operand" "=r")
(mult:SI (sign_extend:SI
(match_operand:HI 1 "reg_or_0_operand" "rO"))
(sign_extend:SI
(match_operand:HI 2 "reg_or_0_operand" "rO"))))]
""
"mulll_ss\t%0, %r1, %r2"
[(set_attr "type" "Y0_2cycle")])
(define_insn "umulhisi3"
[(set (match_operand:SI 0 "register_operand" "=r")
(mult:SI (zero_extend:SI
(match_operand:HI 1 "reg_or_0_operand" "rO"))
(zero_extend:SI
(match_operand:HI 2 "reg_or_0_operand" "rO"))))]
""
"mulll_uu\t%0, %r1, %r2"
[(set_attr "type" "Y0_2cycle")])
(define_insn "usmulhisi3"
[(set (match_operand:SI 0 "register_operand" "=r")
(mult:SI (zero_extend:SI
(match_operand:HI 1 "reg_or_0_operand" "rO"))
(sign_extend:SI
(match_operand:HI 2 "reg_or_0_operand" "rO"))))]
""
"mulll_su\t%0, %r2, %r1"
[(set_attr "type" "X0_2cycle")])
(define_insn "maddhisi4"
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI
(mult:SI (sign_extend:SI
(match_operand:HI 1 "reg_or_0_operand" "rO"))
(sign_extend:SI
(match_operand:HI 2 "reg_or_0_operand" "rO")))
(match_operand:SI 3 "register_operand" "0")))]
""
"mullla_ss\t%0, %r1, %r2"
[(set_attr "type" "Y0_2cycle")])
(define_insn "umaddhisi4"
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI
(mult:SI (zero_extend:SI
(match_operand:HI 1 "reg_or_0_operand" "rO"))
(zero_extend:SI
(match_operand:HI 2 "reg_or_0_operand" "rO")))
(match_operand:SI 3 "register_operand" "0")))]
""
"mullla_uu\t%0, %r1, %r2"
[(set_attr "type" "Y0_2cycle")])
(define_insn "mulqihi3"
[(set (match_operand:HI 0 "register_operand" "=r")
(mult:HI (sign_extend:HI
(match_operand:QI 1 "reg_or_0_operand" "rO"))
(sign_extend:HI
(match_operand:QI 2 "reg_or_0_operand" "rO"))))]
""
"mulll_ss\t%0, %r1, %r2"
[(set_attr "type" "Y0_2cycle")])
(define_insn "umulqihi3"
[(set (match_operand:HI 0 "register_operand" "=r")
(mult:HI (zero_extend:HI
(match_operand:QI 1 "reg_or_0_operand" "rO"))
(zero_extend:HI
(match_operand:QI 2 "reg_or_0_operand" "rO"))))]
""
"mulll_uu\t%0, %r1, %r2"
[(set_attr "type" "Y0_2cycle")])
(define_expand "smulsi3_highpart"
[(set (match_operand:SI 0 "register_operand" "")
(truncate:SI
(ashiftrt:DI
(mult:DI (sign_extend:DI (match_operand:SI 1 "reg_or_0_operand" ""))
(sign_extend:DI (match_operand:SI 2 "reg_or_0_operand" "")))
(const_int 32))))]
""
{
tilepro_expand_smulsi3_highpart (operands[0], operands[1], operands[2]);
DONE;
})
(define_expand "umulsi3_highpart"
[(set (match_operand:SI 0 "register_operand" "")
(truncate:SI
(lshiftrt:DI
(mult:DI (zero_extend:DI (match_operand:SI 1 "reg_or_0_operand" ""))
(zero_extend:DI (match_operand:SI 2 "reg_or_0_operand" "")))
(const_int 32))))]
""
{
tilepro_expand_umulsi3_highpart (operands[0], operands[1], operands[2]);
DONE;
})
;;
;; 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
""
{
if (optimize > 0)
{
rtx s0;
rtx bcomp;
rtx loc_ref;
/* only do inner loop */
if (INTVAL (operands[3]) > 1)
FAIL;
/* only deal with loop counters in SImode */
if (GET_MODE (operands[0]) != SImode)
FAIL;
s0 = operands [0];
emit_move_insn (s0, gen_rtx_PLUS (SImode, s0, GEN_INT (-1)));
bcomp = gen_rtx_NE(SImode, 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)]
""
{
tilepro_expand_prologue ();
DONE;
})
(define_expand "epilogue"
[(const_int 0)]
""
{
tilepro_expand_epilogue (false);
DONE;
})
(define_expand "sibcall_epilogue"
[(const_int 0)]
""
{
tilepro_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)))]
""
"tilepro_allocate_stack (operands[0], operands[1]); DONE;")
;;
;; Branches
;;
(define_expand "call"
[(parallel [(call (match_operand:SI 0 "call_operand" "")
(match_operand 1 "" ""))
(use (reg:SI 54))
(clobber (reg:SI 55))])]
""
"")
(define_insn "*call_insn"
[(call (mem:SI (match_operand:SI 0 "call_address_operand" "rO,i"))
(match_operand 1 "" ""))
(use (reg:SI 54))
(clobber (reg:SI 55))]
""
"@
jalr\t%r0
jal\t%p0"
[(set_attr "type" "X1,X1")])
(define_expand "call_value"
[(parallel [(set (match_operand 0 "register_operand" "")
(call (match_operand:SI 1 "call_operand" "")
(match_operand 2 "" "")))
(use (reg:SI 54))
(clobber (reg:SI 55))])]
"")
(define_insn "*call_value_insn"
[(set (match_operand 0 "register_operand" "=r,r")
(call (mem:SI (match_operand:SI 1 "call_address_operand" "rO,i"))
(match_operand 2 "" "")))
(use (reg:SI 54))
(clobber (reg:SI 55))]
""
"@
jalr\t%r1
jal\t%p1"
[(set_attr "type" "X1,X1")])
(define_expand "sibcall"
[(parallel [(call (match_operand:SI 0 "call_operand" "")
(match_operand 1 "" ""))
(use (reg:SI 54))])]
""
"")
(define_insn "*sibcall_insn"
[(call (mem:SI (match_operand:SI 0 "call_address_operand" "rO,i"))
(match_operand 1 "" ""))
(use (reg:SI 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:SI 1 "call_operand" "")
(match_operand:SI 2 "" "")))
(use (reg:SI 54))])]
""
"")
(define_insn "*sibcall_value"
[(set (match_operand 0 "" "")
(call (mem:SI (match_operand:SI 1 "call_address_operand" "rO,i"))
(match_operand:SI 2 "" "")))
(use (reg:SI 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:SI 0 "register_operand" "rO"))]
""
"jr\t%r0"
[(set_attr "type" "X1")])
(define_expand "return"
[(parallel
[(return)
(use (reg:SI 55))])]
"tilepro_can_use_return_insn_p ()"
"")
(define_insn "_return"
[(return)
(use (reg:SI 55))]
"reload_completed"
"jrp\tlr"
[(set_attr "type" "X1")])
(define_expand "tablejump"
[(set (pc) (match_operand:SI 0 "register_operand" ""))
(use (label_ref (match_operand 1 "" "")))]
""
{
tilepro_expand_tablejump (operands[0], operands[1]);
DONE;
})
(define_insn "tablejump_aux"
[(set (pc) (match_operand:SI 0 "register_operand" "r"))
(use (label_ref (match_operand 1 "" "")))]
""
"jr\t%0"
[(set_attr "type" "X1")])
;; 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: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,J")))
(clobber (mem:BLK (scratch)))]
""
"@
add\t%0, %1, %2
addi\t%0, %1, %2
addli\t%0, %1, %2"
[(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"
[(set (match_operand:SI 0 "register_operand" "=r")
(match_operand:SI 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 "cbranchsi4"
[(set (pc)
(if_then_else (match_operator 0 "ordered_comparison_operator"
[(match_operand:SI 1 "reg_or_cint_operand")
(match_operand:SI 2 "reg_or_cint_operand")])
(label_ref (match_operand 3 ""))
(pc)))]
""
{ tilepro_emit_conditional_branch (operands, SImode); DONE; })
(define_expand "cbranchdi4"
[(set (pc)
(if_then_else (match_operator 0 "ordered_comparison_operator"
[(match_operand:DI 1 "reg_or_cint_operand")
(match_operand:DI 2 "reg_or_cint_operand")])
(label_ref (match_operand 3 ""))
(pc)))]
""
{ tilepro_emit_conditional_branch (operands, DImode); DONE; })
(define_insn "*bcc_normal"
[(set (pc)
(if_then_else
(match_operator 1 "signed_comparison_operator"
[(match_operand:SI 2 "reg_or_0_operand" "rO")
(const_int 0)])
(label_ref (match_operand 0 "" ""))
(pc)))]
""
{ return tilepro_output_cbranch (insn, operands, false); }
[(set_attr "type" "X1_branch")])
(define_insn "*bcc_reverse"
[(set (pc)
(if_then_else
(match_operator 1 "signed_comparison_operator"
[(match_operand:SI 2 "reg_or_0_operand" "rO")
(const_int 0)])
(pc)
(label_ref (match_operand 0 "" ""))))]
""
{ return tilepro_output_cbranch (insn, operands, true); }
[(set_attr "type" "X1_branch")])
;; FIXME: the straight forward versions which do not include the
;; subreg:QI does not match for some unknown reason.
(define_insn "*bbs_normal"
[(set (pc)
(if_then_else
(ne (zero_extract:SI (subreg:QI
(match_operand:SI 1 "reg_or_0_operand" "rO") 0)
(const_int 1)
(const_int 0))
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
{ return tilepro_output_cbranch_with_opcode (insn, operands, "bbs", "bbns",
1, 0); }
[(set_attr "type" "X1_branch")])
(define_insn "*bbc_normal"
[(set (pc)
(if_then_else
(eq (zero_extract:SI (subreg:QI
(match_operand:SI 1 "reg_or_0_operand" "rO") 0)
(const_int 1)
(const_int 0))
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
{ return tilepro_output_cbranch_with_opcode (insn, operands, "bbns", "bbs",
1, 0); }
[(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:SI 0 "address_operand" "rO")
(match_operand:SI 1 "const_int_operand" "")
(match_operand:SI 2 "const_int_operand" ""))]
""
"prefetch\t%r0"
[(set_attr "type" "Y2")])
;;
;; 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 "tilepro_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:SI 0 "nonimmediate_operand" "=r,U,m")
(unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i,i,i")
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_RECEIVE))
(clobber (reg:SI TILEPRO_NETORDER_REG))]
""
"@
move\t%0, %N1
sw\t%0, %N1
swadd\t%I0, %N1, %i0"
[(set_attr "type" "*,Y2,X1")])
(define_insn "*netreg_send"
[(unspec_volatile:SI
[(match_operand:SI 0 "netreg_operand" "i,i,i,i,i,i")
(match_operand:SI 1 "reg_or_cint_operand" "rO,I,J,K,N,P")
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_SEND)
(clobber (reg:SI TILEPRO_NETORDER_REG))]
""
"@
move\t%N0, %r1
movei\t%N0, %1
moveli\t%N0, %1
auli\t%N0, zero, %h1
addib\t%N0, zero, %j1
addih\t%N0, zero, %h1"
[(set_attr "type" "*,*,X01,X01,X01,X01")])
(define_insn "*netreg_copy"
[(unspec_volatile:SI
[(match_operand:SI 0 "netreg_operand" "i")
(unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_RECEIVE)
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_SEND)
(clobber (reg:SI TILEPRO_NETORDER_REG))
(clobber (reg:SI TILEPRO_NETORDER_REG))]
""
"move %N0, %N1")
(define_expand "tilepro_idn0_receive"
[(parallel
[(set (match_operand:SI 0 "register_operand" "")
(unspec_volatile:SI [(const_int TILEPRO_NETREG_IDN0)
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_RECEIVE))
(clobber (reg:SI TILEPRO_NETORDER_REG))])]
"")
(define_expand "tilepro_idn1_receive"
[(parallel
[(set (match_operand:SI 0 "register_operand" "")
(unspec_volatile:SI [(const_int TILEPRO_NETREG_IDN1)
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_RECEIVE))
(clobber (reg:SI TILEPRO_NETORDER_REG))])]
"")
(define_expand "tilepro_idn_send"
[(parallel
[(unspec_volatile:SI [(const_int TILEPRO_NETREG_IDN0)
(match_operand:SI 0 "reg_or_cint_operand" "")
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_SEND)
(clobber (reg:SI TILEPRO_NETORDER_REG))])]
"")
(define_expand "tilepro_sn_receive"
[(parallel
[(set (match_operand:SI 0 "register_operand" "")
(unspec_volatile:SI [(const_int TILEPRO_NETREG_SN)
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_RECEIVE))
(clobber (reg:SI TILEPRO_NETORDER_REG))])]
"")
(define_expand "tilepro_sn_send"
[(parallel
[(unspec_volatile:SI [(const_int TILEPRO_NETREG_SN)
(match_operand:SI 0 "reg_or_cint_operand" "")
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_SEND)
(clobber (reg:SI TILEPRO_NETORDER_REG))])]
"")
(define_expand "tilepro_udn0_receive"
[(parallel
[(set (match_operand:SI 0 "register_operand" "")
(unspec_volatile:SI [(const_int TILEPRO_NETREG_UDN0)
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_RECEIVE))
(clobber (reg:SI TILEPRO_NETORDER_REG))])]
"")
(define_expand "tilepro_udn1_receive"
[(parallel
[(set (match_operand:SI 0 "register_operand" "")
(unspec_volatile:SI [(const_int TILEPRO_NETREG_UDN1)
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_RECEIVE))
(clobber (reg:SI TILEPRO_NETORDER_REG))])]
"")
(define_expand "tilepro_udn2_receive"
[(parallel
[(set (match_operand:SI 0 "register_operand" "")
(unspec_volatile:SI [(const_int TILEPRO_NETREG_UDN2)
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_RECEIVE))
(clobber (reg:SI TILEPRO_NETORDER_REG))])]
"")
(define_expand "tilepro_udn3_receive"
[(parallel
[(set (match_operand:SI 0 "register_operand" "")
(unspec_volatile:SI [(const_int TILEPRO_NETREG_UDN3)
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_RECEIVE))
(clobber (reg:SI TILEPRO_NETORDER_REG))])]
"")
(define_expand "tilepro_udn_send"
[(parallel
[(unspec_volatile:SI [(const_int TILEPRO_NETREG_UDN0)
(match_operand:SI 0 "reg_or_cint_operand" "")
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_SEND)
(clobber (reg:SI TILEPRO_NETORDER_REG))])]
"")
(define_insn "*netreg_add_to_network"
[(unspec_volatile:SI
[(match_operand:SI 0 "netreg_operand" "i,i,i,i")
(plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rO,rO,rO,rO")
(match_operand:SI 2 "add_operand" "r,I,J,K"))
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_SEND)
(clobber (reg:SI TILEPRO_NETORDER_REG))]
""
"@
add\t%N0, %r1, %2
addi\t%N0, %r1, %2
addli\t%N0, %r1, %2
auli\t%N0, %r1, %h2"
[(set_attr "type" "*,*,X01,X01")])
(define_insn "*netreg_add_from_network"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
(plus:SI
(unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i,i,i,i")
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_RECEIVE)
(match_operand:SI 2 "add_operand" "rO,I,J,K")))
(clobber (reg:SI TILEPRO_NETORDER_REG))]
""
"@
add\t%0, %N1, %r2
addi\t%0, %N1, %2
addli\t%0, %N1, %2
auli\t%0, %N1, %h2"
[(set_attr "type" "*,*,X01,X01")])
(define_insn "*netreg_add_from_to_network"
[(unspec_volatile:SI
[(match_operand:SI 0 "netreg_operand" "i,i,i,i")
(plus:SI
(unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i,i,i,i")
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_RECEIVE)
(match_operand:SI 2 "add_operand" "rO,I,J,K"))
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_SEND)
(clobber (reg:SI TILEPRO_NETORDER_REG))
(clobber (reg:SI TILEPRO_NETORDER_REG))]
""
"@
add\t%N0, %N1, %r2
addi\t%N0, %N1, %2
addli\t%N0, %N1, %2
auli\t%N0, %N1, %h2"
[(set_attr "type" "*,*,X01,X01")])
(define_code_iterator netreg_binop
[minus])
(define_insn "*netreg_binop_to_network"
[(unspec_volatile:SI
[(match_operand:SI 0 "netreg_operand" "i")
(netreg_binop:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 2 "reg_or_0_operand" "rO"))
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_SEND)
(clobber (reg:SI TILEPRO_NETORDER_REG))]
""
"<insn>\t%N0, %r1, %r2")
(define_insn "*netreg_binop_from_network0"
[(set (match_operand:SI 0 "register_operand" "=r")
(netreg_binop:SI
(unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_RECEIVE)
(match_operand:SI 2 "reg_or_0_operand" "rO")))
(clobber (reg:SI TILEPRO_NETORDER_REG))]
""
"<insn>\t%0, %N1, %r2")
(define_insn "*netreg_binop_from_network1"
[(set (match_operand:SI 0 "register_operand" "=r")
(netreg_binop:SI
(match_operand:SI 1 "reg_or_0_operand" "rO")
(unspec_volatile:SI [(match_operand:SI 2 "netreg_operand" "i")
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_RECEIVE)))
(clobber (reg:SI TILEPRO_NETORDER_REG))]
""
"<insn>\t%0, %r1, %N2")
(define_insn "*netreg_binop_from_to_network0"
[(unspec_volatile:SI
[(match_operand:SI 0 "netreg_operand" "i")
(netreg_binop:SI
(unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_RECEIVE)
(match_operand:SI 2 "reg_or_0_operand" "rO"))
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_SEND)
(clobber (reg:SI TILEPRO_NETORDER_REG))
(clobber (reg:SI TILEPRO_NETORDER_REG))]
""
"<insn>\t%N0, %N1, %r2")
(define_insn "*netreg_binop_from_to_network1"
[(unspec_volatile:SI
[(match_operand:SI 0 "netreg_operand" "i")
(netreg_binop:SI
(match_operand:SI 1 "reg_or_0_operand" "rO")
(unspec_volatile:SI [(match_operand:SI 2 "netreg_operand" "i")
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_RECEIVE))
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_SEND)
(clobber (reg:SI TILEPRO_NETORDER_REG))
(clobber (reg:SI TILEPRO_NETORDER_REG))]
""
"<insn>\t%N0, %r1, %N2")
(define_insn "*netreg_binop_to_network"
[(unspec_volatile:SI
[(match_operand:SI 0 "netreg_operand" "i,i")
(binop_with_imm:SI (match_operand:SI 1 "reg_or_0_operand" "rO,rO")
(match_operand:SI 2 "reg_or_cint_operand" "I,rO"))
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_SEND)
(clobber (reg:SI TILEPRO_NETORDER_REG))]
""
"@
<insn>i<u>\t%N0, %r1, %2
<insn><u>\t%N0, %r1, %r2")
(define_insn "*netreg_binop_from_network"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(binop_with_imm:SI
(unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i,i")
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_RECEIVE)
(match_operand:SI 2 "reg_or_cint_operand" "I,rO")))
(clobber (reg:SI TILEPRO_NETORDER_REG))]
""
"@
<insn>i<u>\t%0, %N1, %2
<insn><u>\t%0, %N1, %r2")
(define_insn "*netreg_binop_from_to_network"
[(unspec_volatile:SI
[(match_operand:SI 0 "netreg_operand" "i,i")
(binop_with_imm:SI
(unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i,i")
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_RECEIVE)
(match_operand:SI 2 "reg_or_cint_operand" "I,rO"))
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_SEND)
(clobber (reg:SI TILEPRO_NETORDER_REG))
(clobber (reg:SI TILEPRO_NETORDER_REG))]
""
"@
<insn>i<u>\t%N0, %N1, %2
<insn><u>\t%N0, %N1, %r2")
(define_insn "*netreg_unop_to_network"
[(unspec_volatile:SI [(match_operand:SI 0 "netreg_operand" "i")
(unop:SI (match_operand:SI 1 "reg_or_0_operand" "rO"))
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_SEND)
(clobber (reg:SI TILEPRO_NETORDER_REG))]
""
"<insn>\t%N0, %r1"
[(set_attr "type" "Y0")])
(define_insn "*netreg_unop_from_network"
[(set (match_operand:SI 0 "register_operand" "=r")
(unop:SI
(unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_RECEIVE)))
(clobber (reg:SI TILEPRO_NETORDER_REG))]
""
"<insn>\t%0, %N1"
[(set_attr "type" "Y0")])
(define_insn "*netreg_unop_from_to_network"
[(unspec_volatile:SI
[(match_operand:SI 0 "netreg_operand" "i")
(unop:SI
(unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_RECEIVE))
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_SEND)
(clobber (reg:SI TILEPRO_NETORDER_REG))
(clobber (reg:SI TILEPRO_NETORDER_REG))]
""
"<insn>\t%N0, %N1"
[(set_attr "type" "Y0")])
(define_insn "*netreg_sadh_u_from_network0"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI
[(unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_RECEIVE)
(match_operand:SI 2 "reg_or_0_operand" "rO")]
UNSPEC_INSN_SADH_U))
(clobber (reg:SI TILEPRO_NETORDER_REG))]
""
"sadh_u\t%0, %N1, %r2"
[(set_attr "type" "X0_2cycle")])
(define_insn "*netreg_sadh_u_from_network1"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI
[(match_operand:SI 1 "reg_or_0_operand" "rO")
(unspec_volatile:SI [(match_operand:SI 2 "netreg_operand" "i")
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_RECEIVE)]
UNSPEC_INSN_SADH_U))
(clobber (reg:SI TILEPRO_NETORDER_REG))]
""
"sadh_u\t%0, %r1, %N2"
[(set_attr "type" "X0_2cycle")])
(define_insn "*netreg_sadah_u_from_network0"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI
[(match_operand:SI 1 "reg_or_0_operand" "0")
(unspec_volatile:SI [(match_operand:SI 2 "netreg_operand" "i")
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_RECEIVE)
(match_operand:SI 3 "reg_or_0_operand" "rO")]
UNSPEC_INSN_SADAH_U))
(clobber (reg:SI TILEPRO_NETORDER_REG))]
""
"sadah_u\t%0, %N2, %r3"
[(set_attr "type" "X0_2cycle")])
(define_insn "*netreg_sadah_u_from_network1"
[(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")
(unspec_volatile:SI [(match_operand:SI 3 "netreg_operand" "i")
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_RECEIVE)]
UNSPEC_INSN_SADAH_U))
(clobber (reg:SI TILEPRO_NETORDER_REG))]
""
"sadah_u\t%0, %r2, %N3"
[(set_attr "type" "X0_2cycle")])
(define_code_iterator mm_combiner [ior xor plus])
;; This doesn't seem to match -- too complex for 'combine'?
;;
;; (define_insn "*netreg_mm_to_network"
;; [(unspec_volatile:SI
;; [(match_operand:SI 0 "netreg_operand" "i")
;; (mm_combiner:SI
;; (and:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
;; (match_operand:SI 3 "const_int_operand" "n"))
;; (and:SI (match_operand:SI 2 "reg_or_0_operand" "rO")
;; (match_operand:SI 4 "const_int_operand" "n")))]
;; UNSPEC_NETWORK_SEND)]
;; "tilepro_bitfield_operand_p (INTVAL (operands[3]), NULL, NULL)
;; && INTVAL (operands[3]) == ~INTVAL (operands[4])"
;; "mm\t%N0, %r1, %r2, %M3"
;; [(set_attr "type" "X01")])
;; FIXME: the straight forward versions which do not include the
;; subreg:QI does not match for some unknown reason.
(define_insn "*netreg_bbs_normal"
[(set (pc)
(if_then_else
(ne (zero_extract:SI
(subreg:QI
(unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_RECEIVE) 0)
(const_int 1)
(const_int 0))
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))
(clobber (reg:SI TILEPRO_NETORDER_REG))]
""
{ return tilepro_output_cbranch_with_opcode (insn, operands, "bbs", "bbns",
1, 1); }
[(set_attr "type" "X1_branch")])
(define_insn "*netreg_bbc_normal"
[(set (pc)
(if_then_else
(eq (zero_extract:SI
(subreg:QI
(unspec_volatile:SI [(match_operand:SI 1 "netreg_operand" "i")
(reg:SI TILEPRO_NETORDER_REG)]
UNSPEC_NETWORK_RECEIVE) 0)
(const_int 1)
(const_int 0))
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))
(clobber (reg:SI TILEPRO_NETORDER_REG))]
""
{ return tilepro_output_cbranch_with_opcode (insn, operands, "bbns", "bbns",
1, 1); }
[(set_attr "type" "X1_branch")])
;;
;; "__insn" Intrinsics (some expand directly to normal patterns above).
;;
(define_insn "insn_addlis"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec_volatile:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 2 "s16bit_cint_operand" "i")]
UNSPEC_INSN_ADDLIS))]
""
"addlis\t%0, %r1, %2"
[(set_attr "type" "X01")])
(define_insn "insn_auli"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 2 "s16bit_cint_operand" "i")]
UNSPEC_INSN_AULI))]
""
"auli\t%0, %r1, %2"
[(set_attr "type" "X01")])
(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:SI 0 "reg_or_0_operand" "rO")]
UNSPEC_INSN_ICOH)]
""
"icoh\t%r0"
[(set_attr "type" "X1")])
(define_insn "insn_info"
[(unspec_volatile:VOID [(match_operand:SI 0 "s8bit_cint_operand" "i")]
UNSPEC_INSN_INFO)]
""
"info\t%0")
(define_insn "insn_infol"
[(unspec_volatile:VOID [(match_operand:SI 0 "s16bit_cint_operand" "i")]
UNSPEC_INSN_INFOL)]
""
"infol\t%0"
[(set_attr "type" "X01")])
;; loads
(define_expand "insn_<load>"
[(set (match_operand:SI 0 "register_operand" "")
(sign_extend:SI
(mem:I12MODE (match_operand:SI 1 "address_operand" ""))))]
"")
(define_expand "insn_<load>_u"
[(set (match_operand:SI 0 "register_operand" "")
(zero_extend:SI
(mem:I12MODE (match_operand:SI 1 "address_operand" ""))))]
"")
(define_insn "insn_<load>add"
[(set (match_operand:SI 1 "register_operand" "=r")
(plus:SI (match_operand:SI 3 "register_operand" "1")
(match_operand:SI 2 "s8bit_cint_operand" "i")))
(set (match_operand:SI 0 "register_operand" "=r")
(sign_extend:SI (mem:I12MODE (match_dup 3))))]
""
"<load>add\t%0, %1, %2"
[(set_attr "type" "X1_2cycle")])
(define_insn "insn_<load>add_u"
[(set (match_operand:SI 1 "register_operand" "=r")
(plus:SI (match_operand:SI 3 "register_operand" "1")
(match_operand:SI 2 "s8bit_cint_operand" "i")))
(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI (mem:I12MODE (match_dup 3))))]
""
"<load>add_u\t%0, %1, %2"
[(set_attr "type" "X1_2cycle")])
(define_expand "insn_lw"
[(set (match_operand:SI 0 "register_operand" "")
(mem:SI (match_operand:SI 1 "address_operand" "")))]
"")
(define_insn "insn_lwadd"
[(set (match_operand:SI 1 "register_operand" "=r")
(plus:SI (match_operand:SI 3 "register_operand" "1")
(match_operand:SI 2 "s8bit_cint_operand" "i")))
(set (match_operand:SI 0 "register_operand" "=r")
(mem:SI (match_dup 3)))]
""
"lwadd\t%0, %1, %2"
[(set_attr "type" "X1_2cycle")])
(define_insn "insn_lwadd_na"
[(set (match_operand:SI 1 "register_operand" "=r")
(plus:SI (match_operand:SI 3 "register_operand" "1")
(match_operand:SI 2 "s8bit_cint_operand" "i")))
(set (match_operand:SI 0 "register_operand" "=r")
(mem:SI (and:SI (match_dup 3) (const_int -4))))]
""
"lwadd_na\t%0, %1, %2"
[(set_attr "type" "X1_2cycle")])
(define_insn "insn_lw_na"
[(set (match_operand:SI 0 "register_operand" "=r")
(mem:SI (and:SI (match_operand:SI 1 "address_operand" "rO")
(const_int -4))))]
""
"lw_na\t%0, %r1"
[(set_attr "type" "X1_2cycle")])
;; L2 hits
(define_insn "insn_<load>_L2"
[(set (match_operand:SI 0 "register_operand" "=r")
(sign_extend:SI
(unspec:I12MODE
[(mem:I12MODE (match_operand:SI 1 "address_operand" "rO"))]
UNSPEC_LATENCY_L2)))]
""
"<load>\t%0, %r1"
[(set_attr "type" "Y2_L2")])
(define_insn "insn_<load>_u_L2"
[(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI
(unspec:I12MODE
[(mem:I12MODE (match_operand:SI 1 "address_operand" "rO"))]
UNSPEC_LATENCY_L2)))]
""
"<load>_u\t%0, %r1"
[(set_attr "type" "Y2_L2")])
(define_insn "insn_<load>add_L2"
[(set (match_operand:SI 1 "register_operand" "=r")
(plus:SI (match_operand:SI 3 "register_operand" "1")
(match_operand:SI 2 "s8bit_cint_operand" "i")))
(set (match_operand:SI 0 "register_operand" "=r")
(sign_extend:SI (unspec:I12MODE [(mem:I12MODE (match_dup 3))]
UNSPEC_LATENCY_L2)))]
""
"<load>add\t%0, %1, %2"
[(set_attr "type" "X1_L2")])
(define_insn "insn_<load>add_u_L2"
[(set (match_operand:SI 1 "register_operand" "=r")
(plus:SI (match_operand:SI 3 "register_operand" "1")
(match_operand:SI 2 "s8bit_cint_operand" "i")))
(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI (unspec:I12MODE [(mem:I12MODE (match_dup 3))]
UNSPEC_LATENCY_L2)))]
""
"<load>add_u\t%0, %1, %2"
[(set_attr "type" "X1_L2")])
(define_insn "insn_lwadd_L2"
[(set (match_operand:SI 1 "register_operand" "=r")
(plus:SI (match_operand:SI 3 "register_operand" "1")
(match_operand:SI 2 "s8bit_cint_operand" "i")))
(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(mem:SI (match_dup 3))] UNSPEC_LATENCY_L2))]
""
"lwadd\t%0, %1, %2"
[(set_attr "type" "X1_L2")])
(define_insn "insn_lwadd_na_L2"
[(set (match_operand:SI 1 "register_operand" "=r")
(plus:SI (match_operand:SI 3 "register_operand" "1")
(match_operand:SI 2 "s8bit_cint_operand" "i")))
(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(mem:SI (and:SI (match_dup 3) (const_int -4)))]
UNSPEC_LATENCY_L2))]
""
"lwadd_na\t%0, %1, %2"
[(set_attr "type" "X1_L2")])
(define_insn "insn_lw_na_L2"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(mem:SI (and:SI (match_operand:SI 1 "address_operand" "rO")
(const_int -4)))]
UNSPEC_LATENCY_L2))]
""
"lw_na\t%0, %r1"
[(set_attr "type" "X1_L2")])
(define_insn "insn_lw_L2"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(mem:SI (match_operand:SI 1 "address_operand" "rO"))]
UNSPEC_LATENCY_L2))]
""
"lw\t%0, %r1"
[(set_attr "type" "Y2_L2")])
;; L2 miss
(define_insn "insn_<load>_miss"
[(set (match_operand:SI 0 "register_operand" "=r")
(sign_extend:SI
(unspec:I12MODE
[(mem:I12MODE (match_operand:SI 1 "address_operand" "rO"))]
UNSPEC_LATENCY_MISS)))]
""
"<load>\t%0, %r1"
[(set_attr "type" "Y2_miss")])
(define_insn "insn_<load>_u_miss"
[(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI
(unspec:I12MODE
[(mem:I12MODE (match_operand:SI 1 "address_operand" "rO"))]
UNSPEC_LATENCY_MISS)))]
""
"<load>_u\t%0, %r1"
[(set_attr "type" "Y2_miss")])
(define_insn "insn_<load>add_miss"
[(set (match_operand:SI 1 "register_operand" "=r")
(plus:SI (match_operand:SI 3 "register_operand" "1")
(match_operand:SI 2 "s8bit_cint_operand" "i")))
(set (match_operand:SI 0 "register_operand" "=r")
(sign_extend:SI (unspec:I12MODE [(mem:I12MODE (match_dup 3))]
UNSPEC_LATENCY_MISS)))]
""
"<load>add\t%0, %1, %2"
[(set_attr "type" "X1_miss")])
(define_insn "insn_<load>add_u_miss"
[(set (match_operand:SI 1 "register_operand" "=r")
(plus:SI (match_operand:SI 3 "register_operand" "1")
(match_operand:SI 2 "s8bit_cint_operand" "i")))
(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI (unspec:I12MODE [(mem:I12MODE (match_dup 3))]
UNSPEC_LATENCY_MISS)))]
""
"<load>add_u\t%0, %1, %2"
[(set_attr "type" "X1_miss")])
(define_insn "insn_lwadd_miss"
[(set (match_operand:SI 1 "register_operand" "=r")
(plus:SI (match_operand:SI 3 "register_operand" "1")
(match_operand:SI 2 "s8bit_cint_operand" "i")))
(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(mem:SI (match_dup 3))] UNSPEC_LATENCY_MISS))]
""
"lwadd\t%0, %1, %2"
[(set_attr "type" "X1_miss")])
(define_insn "insn_lwadd_na_miss"
[(set (match_operand:SI 1 "register_operand" "=r")
(plus:SI (match_operand:SI 3 "register_operand" "1")
(match_operand:SI 2 "s8bit_cint_operand" "i")))
(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(mem:SI (and:SI (match_dup 3) (const_int -4)))]
UNSPEC_LATENCY_MISS))]
""
"lwadd_na\t%0, %1, %2"
[(set_attr "type" "X1_miss")])
(define_insn "insn_lw_na_miss"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(mem:SI (and:SI (match_operand:SI 1 "address_operand" "rO")
(const_int -4)))]
UNSPEC_LATENCY_MISS))]
""
"lw_na\t%0, %r1"
[(set_attr "type" "X1_miss")])
(define_insn "insn_lw_miss"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(mem:SI (match_operand:SI 1 "address_operand" "rO"))]
UNSPEC_LATENCY_MISS))]
""
"lw\t%0, %r1"
[(set_attr "type" "Y2_miss")])
;; end loads
(define_insn "insn_mfspr"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec_volatile:SI [(match_operand:SI 1 "u15bit_cint_operand" "i")]
UNSPEC_INSN_MFSPR))
(clobber (mem:BLK (const_int 0)))]
""
"mfspr\t%0, %1"
[(set_attr "type" "X1")])
(define_insn "*mm"
[(set (match_operand:SI 0 "register_operand" "=r")
(mm_combiner:SI
(and:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 3 "const_int_operand" "n"))
(and:SI (match_operand:SI 2 "reg_or_0_operand" "rO")
(match_operand:SI 4 "const_int_operand" "n"))))]
"tilepro_bitfield_operand_p (INTVAL (operands[3]), NULL, NULL)
&& INTVAL (operands[3]) == ~INTVAL (operands[4])"
"mm\t%0, %r1, %r2, %M3"
[(set_attr "type" "X01")])
(define_expand "insn_mm"
[(set (match_operand:SI 0 "register_operand" "")
(ior:SI
(and:SI (match_operand:SI 1 "reg_or_cint_operand" "")
(match_operand:SI 3 "u5bit_cint_operand" ""))
(and:SI (match_operand:SI 2 "reg_or_cint_operand" "")
(match_operand:SI 4 "u5bit_cint_operand" ""))))]
""
{
int first, last, i;
HOST_WIDE_INT mask;
first = INTVAL (operands[3]) & 31;
last = INTVAL (operands[4]) & 31;
if (((last + 1) & 31) == first)
{
/* Handle pathological case of a mask that includes only the
first operand. The reordering code below can't handle this. */
emit_move_insn (operands[0], operands[1]);
DONE;
}
/* Canonicalize order by putting constant second, if any. */
if (CONST_INT_P (operands[1]))
{
int tmp_first;
rtx tmp = operands[1];
operands[1] = operands[2];
operands[2] = tmp;
/* Invert the bit range. */
tmp_first = first;
first = (last + 1) & 31;
last = (tmp_first - 1) & 31;
}
/* Convert the first/last bit range into a bit mask. */
mask = 0;
for (i = first; ; i = (i + 1) & 31)
{
mask |= ((HOST_WIDE_INT)1) << i;
if (i == last)
break;
}
mask = trunc_int_for_mode (mask, SImode);
operands[1] = force_reg (SImode, operands[1]);
operands[3] = GEN_INT (mask);
operands[4] = GEN_INT (~mask);
if (CONST_INT_P (operands[2]))
{
HOST_WIDE_INT inserted_bits = INTVAL (operands[2]) & ~mask;
if (inserted_bits == 0)
{
/* All inserted bits are zero. Use a bitwise AND. */
emit_insn (gen_andsi3 (operands[0], operands[1], operands[3]));
DONE;
}
else if (inserted_bits == ~mask)
{
/* All inserted bits are ones. Use a bitwise IOR if we can. */
if (satisfies_constraint_I (operands[4]))
{
emit_insn (gen_iorsi3 (operands[0], operands[1], operands[4]));
DONE;
}
/* Canonicalize to inserting -1 when setting all masked bits
to 1, to facilitate CSE. */
inserted_bits = -1;
}
/* Sign extend the inserted bits to make them easier to materialize
in a register, but only if the inserted bits (~mask) do not already
include the high bits. */
if ((~mask & 0x80000000) == 0)
{
int shift = sizeof (HOST_WIDE_INT) * 8 - first;
inserted_bits = (inserted_bits << shift) >> shift;
}
operands[2] = GEN_INT (inserted_bits);
}
operands[2] = force_reg (SImode, operands[2]);
})
(define_insn "insn_movelis"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec_volatile:SI [(match_operand:SI 1 "s16bit_cint_operand" "i")]
UNSPEC_INSN_MOVELIS))]
""
"movelis\t%0, %1"
[(set_attr "type" "X01")])
(define_insn "insn_mtspr"
[(unspec_volatile:SI [(match_operand:SI 0 "u15bit_cint_operand" "i")
(match_operand:SI 1 "reg_or_0_operand" "rO")]
UNSPEC_INSN_MTSPR)
(clobber (mem:BLK (const_int 0)))]
""
"mtspr\t%0, %r1"
[(set_attr "type" "X1")])
(define_expand "insn_prefetch"
[(prefetch (match_operand:SI 0 "address_operand" "")
(const_int 0)
(const_int 2))])
(define_expand "insn_prefetch_L1"
[(use (match_operand:SI 0 "address_operand" ""))]
""
{
/* Generate a volatile byte load to a dummy register. */
rtx mem = gen_rtx_MEM (QImode, operands[0]);
MEM_VOLATILE_P (mem) = 1;
emit_insn (gen_zero_extendqisi2 (gen_reg_rtx (SImode), mem));
DONE;
})
(define_expand "insn_s1a"
[(set (match_operand:SI 0 "register_operand" "")
(plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "")
(const_int 2))
(match_operand:SI 2 "reg_or_0_operand" "")))]
"")
(define_expand "insn_s2a"
[(set (match_operand:SI 0 "register_operand" "")
(plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "")
(const_int 4))
(match_operand:SI 2 "reg_or_0_operand" "")))]
"")
(define_expand "insn_s3a"
[(set (match_operand:SI 0 "register_operand" "")
(plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "")
(const_int 8))
(match_operand:SI 2 "reg_or_0_operand" "")))]
"")
(define_expand "insn_<store>"
[(set (mem:I12MODE (match_operand:SI 0 "address_operand" ""))
(match_operand:SI 1 "reg_or_0_operand" ""))]
""
{
operands[1] = simplify_gen_subreg (<MODE>mode, operands[1], SImode, 0);
})
(define_expand "insn_sw"
[(set (mem:SI (match_operand:SI 0 "address_operand" ""))
(match_operand:SI 1 "reg_or_0_operand" ""))]
"")
(define_expand "insn_<store>add"
[(parallel
[(set (match_operand:SI 0 "register_operand" "")
(plus:SI (match_operand:SI 3 "register_operand" "")
(match_operand:SI 2 "s8bit_cint_operand" "")))
(set (mem:I12MODE (match_dup 3))
(match_operand:SI 1 "reg_or_0_operand" ""))])]
""
{
operands[1] = simplify_gen_subreg (<MODE>mode, operands[1], SImode, 0);
})
(define_insn "*insn_<store>add"
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (match_operand:SI 3 "register_operand" "0")
(match_operand:SI 2 "s8bit_cint_operand" "i")))
(set (mem:I12MODE (match_dup 3))
(match_operand:I12MODE 1 "reg_or_0_operand" "rO"))]
""
"<store>add\t%0, %r1, %2"
[(set_attr "type" "X1")])
(define_insn "insn_swadd"
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (match_operand:SI 3 "register_operand" "0")
(match_operand:SI 2 "s8bit_cint_operand" "i")))
(set (mem:SI (match_dup 3))
(match_operand:SI 1 "reg_or_0_operand" "rO"))]
""
"swadd\t%0, %r1, %2"
[(set_attr "type" "X1")])
(define_insn "insn_wh64"
[(unspec_volatile:VOID [(match_operand:SI 0 "reg_or_0_operand" "rO")]
UNSPEC_INSN_WH64)
(clobber (mem:BLK (const_int 0)))]
""
"wh64\t%r0"
[(set_attr "type" "X1")])
(define_insn "insn_tns"
[(set (match_operand:SI 0 "register_operand" "=r")
(mem:SI (match_operand:SI 1 "reg_or_0_operand" "rO")))
(set (mem:SI (match_dup 1)) (const_int 1))]
""
"tns\t%0, %1"
[(set_attr "type" "X1")])
;; insn_addb
;; insn_addib
;; insn_maxb_u
;; insn_maxib_u
;; insn_minb_u
;; insn_minib_u
;; insn_seqb
;; insn_seqib
;; insn_sltb
;; insn_sltib
;; insn_sltb_u
;; insn_sltib_u
(define_insn "<optab>v4qi3"
[(set (match_operand:V4QI 0 "register_operand" "=r,r")
(v1op_immed:V4QI
(match_operand:V4QI 1 "reg_or_0_operand" "<comm>rO,rO")
(match_operand:V4QI 2 "reg_or_v4s8bit_operand" "W,rO")))]
""
"@
<insn>ib<u>\t%0, %r1, %j2
<insn>b<u>\t%0, %r1, %r2"
[(set_attr "type" "X01,X01")])
(define_expand "insn_<insn>b<u>"
[(set (match_operand:SI 0 "register_operand" "")
(v1op_immed:V4QI
(match_operand:SI 1 "reg_or_0_operand" "")
(match_operand:SI 2 "reg_or_0_operand" "")))]
""
{
tilepro_expand_builtin_vector_binop (gen_<optab>v4qi3, V4QImode, operands[0],
V4QImode, operands[1], operands[2], true);
DONE;
})
(define_expand "insn_<insn>ib<u>"
[(set (match_operand:SI 0 "register_operand" "")
(v1op_immed:V4QI
(match_operand:SI 1 "reg_or_0_operand" "")
(match_operand:SI 2 "s8bit_cint_operand" "")))]
""
{
/* Tile out immediate and expand to general case. */
rtx n = tilepro_simd_int (operands[2], QImode);
tilepro_expand_builtin_vector_binop (gen_<optab>v4qi3, V4QImode, operands[0],
V4QImode, operands[1], n, true);
DONE;
})
;; insn_shlb
;; insn_shlib
;; insn_shrb
;; insn_shrib
;; insn_srab
;; insn_sraib
(define_insn "<optab>v4qi3"
[(set (match_operand:V4QI 0 "register_operand" "=r,r")
(any_shift:V4QI
(match_operand:V4QI 1 "reg_or_0_operand" "rO,rO")
(match_operand:SI 2 "reg_or_u5bit_operand" "I,rO")))]
""
"@
<insn>ib<u>\t%0, %r1, %2
<insn>b<u>\t%0, %r1, %r2"
[(set_attr "type" "X01,X01")])
(define_expand "insn_<insn>b<u>"
[(set (match_operand:SI 0 "register_operand" "")
(any_shift:V4QI
(match_operand:SI 1 "reg_or_0_operand" "")
(match_operand:SI 2 "reg_or_u5bit_operand" "")))]
""
{
tilepro_expand_builtin_vector_binop (gen_<optab>v4qi3, V4QImode, operands[0],
V4QImode, operands[1], operands[2], false);
DONE;
})
;; insn_addh
;; insn_addih
;; insn_maxh
;; insn_maxih
;; insn_minh
;; insn_minih
;; insn_seqh
;; insn_seqih
;; insn_slth
;; insn_sltih
;; insn_slth_u
;; insn_sltih_u
(define_insn "<optab>v2hi3"
[(set (match_operand:V2HI 0 "register_operand" "=r,r")
(v2op_immed:V2HI
(match_operand:V2HI 1 "reg_or_0_operand" "<comm>rO,rO")
(match_operand:V2HI 2 "reg_or_v2s8bit_operand" "Y,rO")))]
""
"@
<insn>ih<u>\t%0, %r1, %j2
<insn>h<u>\t%0, %r1, %r2"
[(set_attr "type" "X01,X01")])
(define_expand "insn_<insn>h<u>"
[(set (match_operand:SI 0 "register_operand" "")
(v2op_immed:V2HI
(match_operand:SI 1 "reg_or_0_operand" "")
(match_operand:SI 2 "reg_or_0_operand" "")))]
""
{
tilepro_expand_builtin_vector_binop (gen_<optab>v2hi3, V2HImode, operands[0],
V2HImode, operands[1], operands[2], true);
DONE;
})
(define_expand "insn_<insn>ih<u>"
[(set (match_operand:SI 0 "register_operand" "")
(v2op_immed:V2HI
(match_operand:SI 1 "reg_or_0_operand" "")
(match_operand:SI 2 "s8bit_cint_operand" "")))]
""
{
/* Tile out immediate and expand to general case. */
rtx n = tilepro_simd_int (operands[2], HImode);
tilepro_expand_builtin_vector_binop (gen_<optab>v2hi3, V2HImode, operands[0],
V2HImode, operands[1], n, true);
DONE;
})
;; insn_shlh
;; insn_shlih
;; insn_shrh
;; insn_shrih
;; insn_srah
;; insn_sraih
(define_insn "<optab>v2hi3"
[(set (match_operand:V2HI 0 "register_operand" "=r,r")
(any_shift:V2HI
(match_operand:V2HI 1 "reg_or_0_operand" "rO,rO")
(match_operand:SI 2 "reg_or_u5bit_operand" "I,rO")))]
""
"@
<insn>ih<u>\t%0, %r1, %2
<insn>h<u>\t%0, %r1, %r2"
[(set_attr "type" "X01,X01")])
(define_expand "insn_<insn>h<u>"
[(set (match_operand:SI 0 "register_operand" "")
(any_shift:V2HI
(match_operand:SI 1 "reg_or_0_operand" "")
(match_operand:SI 2 "reg_or_0_operand" "")))]
""
{
tilepro_expand_builtin_vector_binop (gen_<optab>v2hi3, V2HImode, operands[0],
V2HImode, operands[1], operands[2], false);
DONE;
})
;; insn_addbs_u
;; insn_subbs_u
;; insn_subb
;; insn_slteb
;; insn_slteb_u
;; insn_sneb
(define_insn "<optab>v4qi3"
[(set (match_operand:V4QI 0 "register_operand" "=r")
(v1op:V4QI
(match_operand:V4QI 1 "reg_or_0_operand" "<comm>rO")
(match_operand:V4QI 2 "reg_or_0_operand" "rO")))]
""
"<insn>b<u>\t%0, %r1, %r2"
[(set_attr "type" "X01")])
(define_expand "insn_<insn>b<u>"
[(set (match_operand:SI 0 "register_operand" "")
(v1op:V4QI
(match_operand:SI 1 "reg_or_0_operand" "")
(match_operand:SI 2 "reg_or_0_operand" "")))]
""
{
tilepro_expand_builtin_vector_binop (gen_<optab>v4qi3, V4QImode, operands[0],
V4QImode, operands[1], operands[2], true);
DONE;
})
;; insn_addhs
;; insn_subhs
;; insn_subh
;; insn_slteh
;; insn_slteh_u
;; insn_sneh
(define_insn "<optab>v2hi3"
[(set (match_operand:V2HI 0 "register_operand" "=r")
(v2op:V2HI
(match_operand:V2HI 1 "reg_or_0_operand" "<comm>rO")
(match_operand:V2HI 2 "reg_or_0_operand" "rO")))]
""
"<insn>h<u>\t%0, %r1, %r2"
[(set_attr "type" "X01")])
(define_expand "insn_<insn>h<u>"
[(set (match_operand:SI 0 "register_operand" "")
(v2op:V2HI
(match_operand:SI 1 "reg_or_0_operand" "")
(match_operand:SI 2 "reg_or_0_operand" "")))]
""
{
tilepro_expand_builtin_vector_binop (gen_<optab>v2hi3, V2HImode, operands[0],
V2HImode, operands[1], operands[2], true);
DONE;
})
;; insn_inthb
;; Byte ordering of these vectors is endian dependent. We concat
;; right-to-left for little endian. We concat and interleave in the
;; opposite way gcc's vector patterns work, so we need to reverse the
;; order of source operands.
;; {B3,B2,B1,B0} {A3,A2,A1,A0}
;; => {A3,A2,A1,A0,B3,B2,B1,B0}
;; => {A3,B3,A2,B2}
(define_insn "vec_interleave_highv4qi"
[(set (match_operand:V4QI 0 "register_operand" "=r")
(vec_select:V4QI
(vec_concat:V8QI (match_operand:V4QI 1 "reg_or_0_operand" "rO")
(match_operand:V4QI 2 "reg_or_0_operand" "rO"))
(parallel [(const_int 2) (const_int 6)
(const_int 3) (const_int 7)])))]
""
"inthb\t%0, %r2, %r1"
[(set_attr "type" "X01")])
(define_expand "insn_inthb"
[(match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "reg_or_0_operand" "")
(match_operand:SI 2 "reg_or_0_operand" "")]
""
{
/* Our instruction interleaves opposite of the way vec_interleave
works, so we need to reverse the source operands. */
tilepro_expand_builtin_vector_binop (gen_vec_interleave_highv4qi, V4QImode,
operands[0], V4QImode, operands[2],
operands[1], true);
DONE;
})
;; insn_intlb
;; {B3,B2,B1,B0} {A3,A2,A1,A0}
;; => {A3,A2,A1,A0,B3,B2,B1,B0}
;; => {A1,B1,A0,B0}
(define_insn "vec_interleave_lowv4qi"
[(set (match_operand:V4QI 0 "register_operand" "=r")
(vec_select:V4QI
(vec_concat:V8QI (match_operand:V4QI 1 "reg_or_0_operand" "rO")
(match_operand:V4QI 2 "reg_or_0_operand" "rO"))
(parallel [(const_int 0) (const_int 4)
(const_int 1) (const_int 5)])))]
""
"intlb\t%0, %r2, %r1"
[(set_attr "type" "X01")])
(define_expand "insn_intlb"
[(match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "reg_or_0_operand" "")
(match_operand:SI 2 "reg_or_0_operand" "")]
""
{
/* Our instruction interleaves opposite of the way vec_interleave
works, so we need to reverse the source operands. */
tilepro_expand_builtin_vector_binop (gen_vec_interleave_lowv4qi, V4QImode,
operands[0], V4QImode, operands[2],
operands[1], true);
DONE;
})
;; insn_inthh
;; {B1,B0} {A1,A0}
;; => {A1,A0,B1,B0}
;; => {A1,B1}
(define_insn "vec_interleave_highv2hi"
[(set (match_operand:V2HI 0 "register_operand" "=r")
(vec_select:V2HI
(vec_concat:V4HI (match_operand:V2HI 1 "reg_or_0_operand" "rO")
(match_operand:V2HI 2 "reg_or_0_operand" "rO"))
(parallel [(const_int 1) (const_int 3)])))]
""
"inthh\t%0, %r2, %r1"
[(set_attr "type" "X01")])
(define_expand "insn_inthh"
[(match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "reg_or_0_operand" "")
(match_operand:SI 2 "reg_or_0_operand" "")]
""
{
/* Our instruction interleaves opposite of the way vec_interleave
works, so we need to reverse the source operands. */
tilepro_expand_builtin_vector_binop (gen_vec_interleave_highv2hi, V2HImode,
operands[0], V2HImode, operands[2],
operands[1], true);
DONE;
})
;; insn_intlh
;; {B1,B0} {A1,A0}
;; => {A1,A0,B1,B0}
;; => {A0,B0}
(define_insn "vec_interleave_lowv2hi"
[(set (match_operand:V2HI 0 "register_operand" "=r")
(vec_select:V2HI
(vec_concat:V4HI (match_operand:V2HI 1 "reg_or_0_operand" "rO")
(match_operand:V2HI 2 "reg_or_0_operand" "rO"))
(parallel [(const_int 0) (const_int 2)])))]
""
"intlh\t%0, %r2, %r1"
[(set_attr "type" "X01")])
(define_expand "insn_intlh"
[(match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "reg_or_0_operand" "")
(match_operand:SI 2 "reg_or_0_operand" "")]
""
{
/* Our instruction interleaves opposite of the way vec_interleave
works, so we need to reverse the source operands. */
tilepro_expand_builtin_vector_binop (gen_vec_interleave_lowv2hi, V2HImode,
operands[0], V2HImode, operands[2],
operands[1], true);
DONE;
})
;; insn_packbs_u
;; insn_packlb
;; {B1,B0} {A1,A0}
;; => {A1,A0,B1,B0}
(define_insn "vec_pack_<pack_optab>_v2hi"
[(set (match_operand:V4QI 0 "register_operand" "=r")
(vec_concat:V4QI
(v2pack:V2QI (match_operand:V2HI 1 "reg_or_0_operand" "rO"))
(v2pack:V2QI (match_operand:V2HI 2 "reg_or_0_operand" "rO"))))]
""
"<pack_insn>b<pack_u>\t%0, %r2, %r1"
[(set_attr "type" "X01")])
(define_expand "insn_<pack_insn>b<pack_u>"
[(set (match_operand:SI 0 "register_operand" "")
(vec_concat:V4QI
(v2pack:V2QI (match_operand:SI 1 "reg_or_0_operand" ""))
(v2pack:V2QI (match_operand:SI 2 "reg_or_0_operand" ""))))]
""
{
/* Our instruction concats opposite of the way vec_pack works, so we
need to reverse the source operands. */
tilepro_expand_builtin_vector_binop (gen_vec_pack_<pack_optab>_v2hi,
V4QImode, operands[0],
V2HImode, operands[2], operands[1], true);
DONE;
})
;; insn_packhb
;; {B1,B0} {A1,A0}
;; => {A1,A0,B1,B0}
(define_insn "vec_pack_hipart_v2hi"
[(set (match_operand:V4QI 0 "register_operand" "=r")
(vec_concat:V4QI
(truncate:V2QI
(ashiftrt:V2HI (match_operand:V2HI 1 "reg_or_0_operand" "rO")
(const_int 8)))
(truncate:V2QI
(ashiftrt:V2HI (match_operand:V2HI 2 "reg_or_0_operand" "rO")
(const_int 8)))))]
""
"packhb\t%0, %r2, %r1"
[(set_attr "type" "X01")])
(define_expand "insn_packhb"
[(set (match_operand:SI 0 "register_operand" "")
(vec_concat:V4QI
(truncate:V2QI
(ashiftrt:V2HI (match_operand:SI 2 "reg_or_0_operand" "")
(const_int 8)))
(truncate:V2QI
(ashiftrt:V2HI (match_operand:SI 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. */
tilepro_expand_builtin_vector_binop (gen_vec_pack_hipart_v2hi,
V4QImode, operands[0],
V2HImode, operands[2], operands[1], true);
DONE;
})
;; insn_packhs
;; {B0} {A0}
;; => {A0,B0}
(define_insn "vec_pack_ssat_si"
[(set (match_operand:V2HI 0 "register_operand" "=r")
(vec_concat:V2HI
(ss_truncate:HI (match_operand:SI 1 "reg_or_0_operand" "rO"))
(ss_truncate:HI (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
""
"packhs\t%0, %r2, %r1"
[(set_attr "type" "X01")])
(define_expand "insn_packhs"
[(set (match_operand:SI 0 "register_operand" "")
(vec_concat:V2HI
(ss_truncate:HI (match_operand:SI 2 "reg_or_0_operand" ""))
(ss_truncate:HI (match_operand:SI 1 "reg_or_0_operand" ""))))]
""
{
/* Our instruction concats opposite of the way vec_pack works, so we
need to reverse the source operands. */
tilepro_expand_builtin_vector_binop (gen_vec_pack_ssat_si,
V2HImode, operands[0],
SImode, operands[2], operands[1], true);
DONE;
})
;; Rest of the intrinsics
(define_insn "insn_adiffb_u"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 2 "reg_or_0_operand" "rO")]
UNSPEC_INSN_ADIFFB_U))]
""
"adiffb_u\t%0, %r1, %r2"
[(set_attr "type" "X0_2cycle")])
(define_insn "insn_adiffh"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 2 "reg_or_0_operand" "rO")]
UNSPEC_INSN_ADIFFH))]
""
"adiffh\t%0, %r1, %r2"
[(set_attr "type" "X0_2cycle")])
(define_insn "insn_avgb_u"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 2 "reg_or_0_operand" "rO")]
UNSPEC_INSN_AVGB_U))]
""
"avgb_u\t%0, %r1, %r2"
[(set_attr "type" "X0")])
(define_insn "insn_avgh"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 2 "reg_or_0_operand" "rO")]
UNSPEC_INSN_AVGH))]
""
"avgh\t%0, %r1, %r2"
[(set_attr "type" "X0")])
(define_insn "insn_bitx"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")]
UNSPEC_INSN_BITX))]
""
"bitx\t%0, %r1"
[(set_attr "type" "Y0")])
(define_insn "insn_crc32_32"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 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:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 2 "reg_or_0_operand" "rO")]
UNSPEC_INSN_CRC32_8))]
""
"crc32_8\t%0, %r1, %r2"
[(set_attr "type" "X0")])
(define_insn "insn_dtlbpr"
[(unspec_volatile:VOID [(match_operand:SI 0 "reg_or_0_operand" "rO")]
UNSPEC_INSN_DTLBPR)]
""
"dtlbpr\t%r0"
[(set_attr "type" "X1")])
(define_insn "insn_dword_align"
[(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_DWORD_ALIGN))]
""
"dword_align\t%0, %r2, %r3"
[(set_attr "type" "X0")])
(define_insn "insn_finv"
[(unspec_volatile:VOID [(match_operand:SI 0 "reg_or_0_operand" "rO")]
UNSPEC_INSN_FINV)]
""
"finv\t%r0"
[(set_attr "type" "X1")])
(define_insn "insn_flush"
[(unspec_volatile:VOID [(match_operand:SI 0 "reg_or_0_operand" "rO")]
UNSPEC_INSN_FLUSH)]
""
"flush\t%r0"
[(set_attr "type" "X1")])
(define_insn "insn_fnop"
[(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_FNOP)]
""
"fnop")
(define_insn "insn_ill"
[(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_ILL)]
""
"ill"
[(set_attr "type" "cannot_bundle")])
(define_insn "insn_inv"
[(unspec_volatile:VOID [(match_operand:SI 0 "reg_or_0_operand" "rO")]
UNSPEC_INSN_INV)]
""
"inv\t%r0"
[(set_attr "type" "X1")])
(define_insn "insn_lnk"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(const_int 0)] UNSPEC_INSN_LNK))]
""
"lnk\t%0"
[(set_attr "type" "X1")])
(define_insn "insn_mnzb"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 2 "reg_or_0_operand" "rO")]
UNSPEC_INSN_MNZB))]
""
"mnzb\t%0, %r1, %r2"
[(set_attr "type" "X01")])
(define_insn "insn_mnzh"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 2 "reg_or_0_operand" "rO")]
UNSPEC_INSN_MNZH))]
""
"mnzh\t%0, %r1, %r2"
[(set_attr "type" "X01")])
(define_insn "insn_mulhh_ss"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 2 "reg_or_0_operand" "rO")]
UNSPEC_INSN_MULHH_SS))]
""
"mulhh_ss\t%0, %r1, %r2"
[(set_attr "type" "Y0_2cycle")])
(define_insn "insn_mulhh_su"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 2 "reg_or_0_operand" "rO")]
UNSPEC_INSN_MULHH_SU))]
""
"mulhh_su\t%0, %r1, %r2"
[(set_attr "type" "X0_2cycle")])
(define_insn "insn_mulhh_uu"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 2 "reg_or_0_operand" "rO")]
UNSPEC_INSN_MULHH_UU))]
""
"mulhh_uu\t%0, %r1, %r2"
[(set_attr "type" "Y0_2cycle")])
(define_insn "insn_mulhha_ss"
[(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_MULHHA_SS))]
""
"mulhha_ss\t%0, %r2, %r3"
[(set_attr "type" "Y0_2cycle")])
(define_insn "insn_mulhha_su"
[(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_MULHHA_SU))]
""
"mulhha_su\t%0, %r2, %r3"
[(set_attr "type" "X0_2cycle")])
(define_insn "insn_mulhha_uu"
[(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_MULHHA_UU))]
""
"mulhha_uu\t%0, %r2, %r3"
[(set_attr "type" "Y0_2cycle")])
(define_insn "insn_mulhhsa_uu"
[(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_MULHHSA_UU))]
""
"mulhhsa_uu\t%0, %r2, %r3"
[(set_attr "type" "X0_2cycle")])
(define_insn "insn_mulhl_ss"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 2 "reg_or_0_operand" "rO")]
UNSPEC_INSN_MULHL_SS))]
""
"mulhl_ss\t%0, %r1, %r2"
[(set_attr "type" "X0_2cycle")])
(define_insn "insn_mulhl_su"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 2 "reg_or_0_operand" "rO")]
UNSPEC_INSN_MULHL_SU))]
""
"mulhl_su\t%0, %r1, %r2"
[(set_attr "type" "X0_2cycle")])
(define_insn "insn_mulhl_us"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 2 "reg_or_0_operand" "rO")]
UNSPEC_INSN_MULHL_US))]
""
"mulhl_us\t%0, %r1, %r2"
[(set_attr "type" "X0_2cycle")])
(define_insn "insn_mulhl_uu"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 2 "reg_or_0_operand" "rO")]
UNSPEC_INSN_MULHL_UU))]
""
"mulhl_uu\t%0, %r1, %r2"
[(set_attr "type" "X0_2cycle")])
(define_insn "insn_mulhla_ss"
[(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_MULHLA_SS))]
""
"mulhla_ss\t%0, %r2, %r3"
[(set_attr "type" "X0_2cycle")])
(define_insn "insn_mulhla_su"
[(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_MULHLA_SU))]
""
"mulhla_su\t%0, %r2, %r3"
[(set_attr "type" "X0_2cycle")])
(define_insn "insn_mulhla_us"
[(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_MULHLA_US))]
""
"mulhla_us\t%0, %r2, %r3"
[(set_attr "type" "X0_2cycle")])
(define_insn "insn_mulhla_uu"
[(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_MULHLA_UU))]
""
"mulhla_uu\t%0, %r2, %r3"
[(set_attr "type" "X0_2cycle")])
(define_insn "insn_mulhlsa_uu"
[(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_MULHLSA_UU))]
""
"mulhlsa_uu\t%0, %r2, %r3"
[(set_attr "type" "Y0_2cycle")])
(define_insn "insn_mulll_ss"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 2 "reg_or_0_operand" "rO")]
UNSPEC_INSN_MULLL_SS))]
""
"mulll_ss\t%0, %r1, %r2"
[(set_attr "type" "Y0_2cycle")])
(define_insn "insn_mulll_su"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 2 "reg_or_0_operand" "rO")]
UNSPEC_INSN_MULLL_SU))]
""
"mulll_su\t%0, %r1, %r2"
[(set_attr "type" "X0_2cycle")])
(define_insn "insn_mulll_uu"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 2 "reg_or_0_operand" "rO")]
UNSPEC_INSN_MULLL_UU))]
""
"mulll_uu\t%0, %r1, %r2"
[(set_attr "type" "Y0_2cycle")])
(define_insn "insn_mullla_ss"
[(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_MULLLA_SS))]
""
"mullla_ss\t%0, %r2, %r3"
[(set_attr "type" "Y0_2cycle")])
(define_insn "insn_mullla_su"
[(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_MULLLA_SU))]
""
"mullla_su\t%0, %r2, %r3"
[(set_attr "type" "X0_2cycle")])
(define_insn "insn_mullla_uu"
[(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_MULLLA_UU))]
""
"mullla_uu\t%0, %r2, %r3"
[(set_attr "type" "Y0_2cycle")])
(define_insn "insn_mulllsa_uu"
[(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_MULLLSA_UU))]
""
"mulllsa_uu\t%0, %r2, %r3"
[(set_attr "type" "X0_2cycle")])
(define_insn "insn_mzb"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 2 "reg_or_0_operand" "rO")]
UNSPEC_INSN_MZB))]
""
"mzb\t%0, %r1, %r2"
[(set_attr "type" "X01")])
(define_insn "insn_mzh"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 2 "reg_or_0_operand" "rO")]
UNSPEC_INSN_MZH))]
""
"mzh\t%0, %r1, %r2"
[(set_attr "type" "X01")])
(define_insn "insn_nap"
[(unspec_volatile:VOID [(const_int 0)] UNSPEC_INSN_NAP)]
""
"nap"
[(set_attr "type" "cannot_bundle")])
(define_insn "insn_nor"
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (not:SI (match_operand:SI 1 "reg_or_0_operand" "rO"))
(not:SI (match_operand:SI 2 "reg_or_0_operand" "rO"))))]
""
"nor\t%0, %r1, %r2")
(define_insn "insn_sadab_u"
[(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_SADAB_U))]
""
"sadab_u\t%0, %r2, %r3"
[(set_attr "type" "X0_2cycle")])
(define_insn "insn_sadah"
[(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_SADAH))]
""
"sadah\t%0, %r2, %r3"
[(set_attr "type" "X0_2cycle")])
(define_insn "insn_sadah_u"
[(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_SADAH_U))]
""
"sadah_u\t%0, %r2, %r3"
[(set_attr "type" "X0_2cycle")])
(define_insn "insn_sadb_u"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 2 "reg_or_0_operand" "rO")]
UNSPEC_INSN_SADB_U))]
""
"sadb_u\t%0, %r1, %r2"
[(set_attr "type" "X0_2cycle")])
(define_insn "insn_sadh"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 2 "reg_or_0_operand" "rO")]
UNSPEC_INSN_SADH))]
""
"sadh\t%0, %r1, %r2"
[(set_attr "type" "X0_2cycle")])
(define_insn "insn_sadh_u"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "rO")
(match_operand:SI 2 "reg_or_0_operand" "rO")]
UNSPEC_INSN_SADH_U))]
""
"sadh_u\t%0, %r1, %r2"
[(set_attr "type" "X0_2cycle")])
(define_insn "insn_tblidxb0"
[(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")]
UNSPEC_INSN_TBLIDXB0))]
""
"tblidxb0\t%0, %r2"
[(set_attr "type" "Y0")])
(define_insn "insn_tblidxb1"
[(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")]
UNSPEC_INSN_TBLIDXB1))]
""
"tblidxb1\t%0, %r2"
[(set_attr "type" "Y0")])
(define_insn "insn_tblidxb2"
[(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")]
UNSPEC_INSN_TBLIDXB2))]
""
"tblidxb2\t%0, %r2"
[(set_attr "type" "Y0")])
(define_insn "insn_tblidxb3"
[(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")]
UNSPEC_INSN_TBLIDXB3))]
""
"tblidxb3\t%0, %r2"
[(set_attr "type" "Y0")])
;;
;; 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"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec_volatile:SI [(match_operand:SI 1 "symbolic_operand" "")]
UNSPEC_LNK_AND_LABEL))]
""
"%1 = . + 8\n\tlnk\t%0"
[(set_attr "type" "X1")])
(define_expand "addli_pcrel"
[(set (match_operand:SI 0 "register_operand" "")
(lo_sum:SI
(match_operand:SI 1 "register_operand" "")
(const:SI
(unspec:SI [(match_operand:SI 2 "symbolic_operand" "")
(match_operand:SI 3 "symbolic_operand" "")]
UNSPEC_PCREL_SYM))))]
"flag_pic")
(define_expand "auli_pcrel"
[(set (match_operand:SI 0 "register_operand" "")
(plus:SI
(match_operand:SI 1 "reg_or_0_operand" "")
(high:SI
(const:SI
(unspec:SI [(match_operand:SI 2 "symbolic_operand" "")
(match_operand:SI 3 "symbolic_operand" "")]
UNSPEC_PCREL_SYM)))))]
"flag_pic")
(define_expand "add_got16"
[(set (match_operand:SI 0 "register_operand" "")
(lo_sum:SI
(match_operand:SI 1 "reg_or_0_operand" "")
(const:SI (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")]
UNSPEC_GOT16_SYM))))]
"flag_pic == 1")
(define_expand "addhi_got32"
[(set (match_operand:SI 0 "register_operand" "")
(plus:SI
(match_operand:SI 1 "reg_or_0_operand" "")
(high:SI
(const:SI (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")]
UNSPEC_GOT32_SYM)))))]
"flag_pic == 2")
(define_expand "addlo_got32"
[(set (match_operand:SI 0 "register_operand" "")
(lo_sum:SI
(match_operand:SI 1 "reg_or_0_operand" "")
(const:SI (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")]
UNSPEC_GOT32_SYM))))]
"flag_pic == 2")
;;
;; TLS
;;
(define_expand "tls_gd_addhi"
[(set (match_operand:SI 0 "register_operand" "")
(plus:SI
(match_operand:SI 1 "reg_or_0_operand" "")
(high:SI
(const:SI (unspec:SI [(match_operand 2 "tls_symbolic_operand" "")]
UNSPEC_TLS_GD)))))]
"HAVE_AS_TLS")
(define_expand "tls_gd_addlo"
[(set (match_operand:SI 0 "register_operand" "")
(lo_sum:SI
(match_operand:SI 1 "reg_or_0_operand" "")
(const:SI (unspec:SI [(match_operand 2 "tls_symbolic_operand" "")]
UNSPEC_TLS_GD))))]
"HAVE_AS_TLS")
(define_expand "tls_gd_call"
[(parallel
[(set (reg:SI 0)
(unspec:SI [(match_operand:SI 0 "tls_symbolic_operand" "")
(reg:SI 0)]
UNSPEC_TLS_GD_CALL))
(clobber (reg:SI 25))
(clobber (reg:SI 26))
(clobber (reg:SI 27))
(clobber (reg:SI 28))
(clobber (reg:SI 29))
(clobber (reg:SI 55))])]
""
{
cfun->machine->calls_tls_get_addr = true;
})
(define_insn "*tls_gd_call"
[(set (reg:SI 0)
(unspec:SI [(match_operand:SI 0 "tls_symbolic_operand" "")
(reg:SI 0)]
UNSPEC_TLS_GD_CALL))
(clobber (reg:SI 25))
(clobber (reg:SI 26))
(clobber (reg:SI 27))
(clobber (reg:SI 28))
(clobber (reg:SI 29))
(clobber (reg:SI 55))]
""
"jal\ttls_gd_call(%0)"
[(set_attr "type" "X1")])
(define_insn "tls_gd_add"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "tls_symbolic_operand" "")]
UNSPEC_TLS_GD_ADD))]
"HAVE_AS_TLS"
"addi\t%0, %1, tls_gd_add(%2)")
(define_insn "tls_ie_load"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "tls_symbolic_operand" "")]
UNSPEC_TLS_IE_LOAD))]
"HAVE_AS_TLS"
"lw_tls\t%0, %1, tls_ie_load(%2)"
[(set_attr "type" "X1_2cycle")])
(define_expand "tls_ie_addhi"
[(set (match_operand:SI 0 "register_operand" "")
(plus:SI
(match_operand:SI 1 "register_operand" "")
(high:SI
(const:SI (unspec:SI [(match_operand 2 "tls_ie_symbolic_operand" "")]
UNSPEC_TLS_IE)))))]
"HAVE_AS_TLS")
(define_expand "tls_ie_addlo"
[(set (match_operand:SI 0 "register_operand" "")
(lo_sum:SI
(match_operand:SI 1 "register_operand" "")
(const:SI (unspec:SI [(match_operand 2 "tls_ie_symbolic_operand" "")]
UNSPEC_TLS_IE))))]
"HAVE_AS_TLS")
(define_expand "tls_le_addhi"
[(set (match_operand:SI 0 "register_operand" "")
(plus:SI
(match_operand:SI 1 "register_operand" "")
(high:SI
(const:SI (unspec:SI [(match_operand 2 "tls_le_symbolic_operand" "")]
UNSPEC_TLS_LE)))))]
"HAVE_AS_TLS")
(define_expand "tls_le_addlo"
[(set (match_operand:SI 0 "register_operand" "")
(lo_sum:SI
(match_operand:SI 1 "register_operand" "")
(const:SI (unspec:SI [(match_operand 2 "tls_le_symbolic_operand" "")]
UNSPEC_TLS_LE))))]
"HAVE_AS_TLS")
;;
;; 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
emit_insn (gen_stack_protect_setsi (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))]
""
"lw\t%2, %1; { sw\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 (SImode);
emit_insn (gen_stack_protect_testsi (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))]
""
"lw\t%0, %1; lw\t%3, %2; { seq\t%0, %0, %3; move\t%3, zero }"
[(set_attr "length" "24")
(set_attr "type" "cannot_bundle_4cycle")])
Go to most recent revision | Compare with Previous | Blame | View Log