// Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. // Copyright (c) 2020, 2021, Arm Limited. All rights reserved. // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This code is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License version 2 only, as // published by the Free Software Foundation. // // This code 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 // version 2 for more details (a copy is included in the LICENSE file that // accompanied this code). // // You should have received a copy of the GNU General Public License version // 2 along with this work; if not, write to the Free Software Foundation, // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. // // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA // or visit www.oracle.com if you need additional information or have any // questions. // // // This file is automatically generated by running "m4 aarch64_neon_ad.m4". Do not edit ---- // AArch64 NEON Architecture Description File // ====================VECTOR INSTRUCTIONS================================== // ------------------------------ Load/store/reinterpret ----------------------- // Load Vector (16 bits) instruct loadV2(vecD dst, vmem2 mem) %{ predicate(n->as_LoadVector()->memory_size() == 2); match(Set dst (LoadVector mem)); ins_cost(4 * INSN_COST); format %{ "ldrh $dst,$mem\t# vector (16 bits)" %} ins_encode( aarch64_enc_ldrvH(dst, mem) ); ins_pipe(vload_reg_mem64); %} // Load Vector (32 bits) instruct loadV4(vecD dst, vmem4 mem) %{ predicate(n->as_LoadVector()->memory_size() == 4); match(Set dst (LoadVector mem)); ins_cost(4 * INSN_COST); format %{ "ldrs $dst,$mem\t# vector (32 bits)" %} ins_encode( aarch64_enc_ldrvS(dst, mem) ); ins_pipe(vload_reg_mem64); %} // Load Vector (64 bits) instruct loadV8(vecD dst, vmem8 mem) %{ predicate(n->as_LoadVector()->memory_size() == 8); match(Set dst (LoadVector mem)); ins_cost(4 * INSN_COST); format %{ "ldrd $dst,$mem\t# vector (64 bits)" %} ins_encode( aarch64_enc_ldrvD(dst, mem) ); ins_pipe(vload_reg_mem64); %} // Load Vector (128 bits) instruct loadV16(vecX dst, vmem16 mem) %{ predicate(UseSVE == 0 && n->as_LoadVector()->memory_size() == 16); match(Set dst (LoadVector mem)); ins_cost(4 * INSN_COST); format %{ "ldrq $dst,$mem\t# vector (128 bits)" %} ins_encode( aarch64_enc_ldrvQ(dst, mem) ); ins_pipe(vload_reg_mem128); %} // Store Vector (16 bits) instruct storeV2(vecD src, vmem2 mem) %{ predicate(n->as_StoreVector()->memory_size() == 2); match(Set mem (StoreVector mem src)); ins_cost(4 * INSN_COST); format %{ "strh $mem,$src\t# vector (16 bits)" %} ins_encode( aarch64_enc_strvH(src, mem) ); ins_pipe(vstore_reg_mem64); %} // Store Vector (32 bits) instruct storeV4(vecD src, vmem4 mem) %{ predicate(n->as_StoreVector()->memory_size() == 4); match(Set mem (StoreVector mem src)); ins_cost(4 * INSN_COST); format %{ "strs $mem,$src\t# vector (32 bits)" %} ins_encode( aarch64_enc_strvS(src, mem) ); ins_pipe(vstore_reg_mem64); %} // Store Vector (64 bits) instruct storeV8(vecD src, vmem8 mem) %{ predicate(n->as_StoreVector()->memory_size() == 8); match(Set mem (StoreVector mem src)); ins_cost(4 * INSN_COST); format %{ "strd $mem,$src\t# vector (64 bits)" %} ins_encode( aarch64_enc_strvD(src, mem) ); ins_pipe(vstore_reg_mem64); %} // Store Vector (128 bits) instruct storeV16(vecX src, vmem16 mem) %{ predicate(n->as_StoreVector()->memory_size() == 16); match(Set mem (StoreVector mem src)); ins_cost(4 * INSN_COST); format %{ "strq $mem,$src\t# vector (128 bits)" %} ins_encode( aarch64_enc_strvQ(src, mem) ); ins_pipe(vstore_reg_mem128); %} instruct reinterpretD(vecD dst) %{ predicate(n->bottom_type()->is_vect()->length_in_bytes() == 8 && n->in(1)->bottom_type()->is_vect()->length_in_bytes() == 8); match(Set dst (VectorReinterpret dst)); ins_cost(0); format %{ " # reinterpret $dst" %} ins_encode %{ // empty %} ins_pipe(pipe_class_empty); %} instruct reinterpretX(vecX dst) %{ predicate(n->bottom_type()->is_vect()->length_in_bytes() == 16 && n->in(1)->bottom_type()->is_vect()->length_in_bytes() == 16); match(Set dst (VectorReinterpret dst)); ins_cost(0); format %{ " # reinterpret $dst" %} ins_encode %{ // empty %} ins_pipe(pipe_class_empty); %} instruct reinterpretD2X(vecX dst, vecD src) %{ predicate(n->bottom_type()->is_vect()->length_in_bytes() == 16 && n->in(1)->bottom_type()->is_vect()->length_in_bytes() == 8); match(Set dst (VectorReinterpret src)); ins_cost(INSN_COST); format %{ " # reinterpret $dst,$src\t# D2X" %} ins_encode %{ // If registers are the same, no register move is required - the // upper 64 bits of 'src' are expected to have been initialized // to zero. if (as_FloatRegister($dst$$reg) != as_FloatRegister($src$$reg)) { __ orr(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); } %} ins_pipe(vlogical64); %} instruct reinterpretX2D(vecD dst, vecX src) %{ predicate(n->bottom_type()->is_vect()->length_in_bytes() == 8 && n->in(1)->bottom_type()->is_vect()->length_in_bytes() == 16); match(Set dst (VectorReinterpret src)); ins_cost(INSN_COST); format %{ " # reinterpret $dst,$src\t# X2D" %} ins_encode %{ // Resize the vector from 128-bits to 64-bits. The higher 64-bits of // the "dst" register must be cleared to zero. __ orr(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); %} ins_pipe(vlogical64); %} // ------------------------------ Vector cast ------------------------------- instruct vcvt4Bto4S(vecD dst, vecD src) %{ predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (VectorCastB2X src)); format %{ "sxtl $dst, T8H, $src, T8B\t# convert 4B to 4S vector" %} ins_encode %{ __ sxtl(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src$$reg), __ T8B); %} ins_pipe(pipe_class_default); %} instruct vcvt8Bto8S(vecX dst, vecD src) %{ predicate(n->as_Vector()->length() == 8 && n->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (VectorCastB2X src)); format %{ "sxtl $dst, T8H, $src, T8B\t# convert 8B to 8S vector" %} ins_encode %{ __ sxtl(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src$$reg), __ T8B); %} ins_pipe(pipe_class_default); %} instruct vcvt4Sto4B(vecD dst, vecD src) %{ predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (VectorCastS2X src)); format %{ "xtn $dst, T8B, $src, T8H\t# convert 4S to 4B vector" %} ins_encode %{ __ xtn(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg), __ T8H); %} ins_pipe(pipe_class_default); %} instruct vcvt8Sto8B(vecD dst, vecX src) %{ predicate(n->as_Vector()->length() == 8 && n->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (VectorCastS2X src)); format %{ "xtn $dst, T8B, $src, T8H\t# convert 8S to 8B vector" %} ins_encode %{ __ xtn(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg), __ T8H); %} ins_pipe(pipe_class_default); %} instruct vcvt4Sto4I(vecX dst, vecD src) %{ predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_INT); match(Set dst (VectorCastS2X src)); format %{ "sxtl $dst, T4S, $src, T4H\t# convert 4S to 4I vector" %} ins_encode %{ __ sxtl(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src$$reg), __ T4H); %} ins_pipe(pipe_class_default); %} instruct vcvt4Ito4S(vecD dst, vecX src) %{ predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (VectorCastI2X src)); format %{ "xtn $dst, T4H, $src, T4S\t# convert 4I to 4S vector" %} ins_encode %{ __ xtn(as_FloatRegister($dst$$reg), __ T4H, as_FloatRegister($src$$reg), __ T4S); %} ins_pipe(pipe_class_default); %} instruct vcvt2Ito2L(vecX dst, vecD src) %{ predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_LONG); match(Set dst (VectorCastI2X src)); format %{ "sxtl $dst, T2D, $src, T2S\t# convert 2I to 2L vector" %} ins_encode %{ __ sxtl(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src$$reg), __ T2S); %} ins_pipe(pipe_class_default); %} instruct vcvt2Lto2I(vecD dst, vecX src) %{ predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_INT); match(Set dst (VectorCastL2X src)); format %{ "xtn $dst, T2S, $src, T2D\t# convert 2L to 2I vector" %} ins_encode %{ __ xtn(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src$$reg), __ T2D); %} ins_pipe(pipe_class_default); %} instruct vcvt4Bto4I(vecX dst, vecD src) %{ predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_INT); match(Set dst (VectorCastB2X src)); format %{ "sxtl $dst, T8H, $src, T8B\n\t" "sxtl $dst, T4S, $dst, T4H\t# convert 4B to 4I vector" %} ins_encode %{ __ sxtl(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src$$reg), __ T8B); __ sxtl(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($dst$$reg), __ T4H); %} ins_pipe(pipe_slow); %} instruct vcvt4Ito4B(vecD dst, vecX src) %{ predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (VectorCastI2X src)); format %{ "xtn $dst, T4H, $src, T4S\n\t" "xtn $dst, T8B, $dst, T8H\t# convert 4I to 4B vector" %} ins_encode %{ __ xtn(as_FloatRegister($dst$$reg), __ T4H, as_FloatRegister($src$$reg), __ T4S); __ xtn(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($dst$$reg), __ T8H); %} ins_pipe(pipe_slow); %} instruct vcvt4Bto4F(vecX dst, vecD src) %{ predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); match(Set dst (VectorCastB2X src)); format %{ "sxtl $dst, T8H, $src, T8B\n\t" "sxtl $dst, T4S, $dst, T4H\n\t" "scvtfv T4S, $dst, $dst\t# convert 4B to 4F vector" %} ins_encode %{ __ sxtl(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src$$reg), __ T8B); __ sxtl(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($dst$$reg), __ T4H); __ scvtfv(__ T4S, as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg)); %} ins_pipe(pipe_slow); %} instruct vcvt4Sto4F(vecX dst, vecD src) %{ predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); match(Set dst (VectorCastS2X src)); format %{ "sxtl $dst, T4S, $src, T4H\n\t" "scvtfv T4S, $dst, $dst\t# convert 4S to 4F vector" %} ins_encode %{ __ sxtl(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src$$reg), __ T4H); __ scvtfv(__ T4S, as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg)); %} ins_pipe(pipe_slow); %} instruct vcvt2Ito2D(vecX dst, vecD src) %{ predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); match(Set dst (VectorCastI2X src)); format %{ "sxtl $dst, T2D, $src, T2S\n\t" "scvtfv T2D, $dst, $dst\t# convert 2I to 2D vector" %} ins_encode %{ __ sxtl(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src$$reg), __ T2S); __ scvtfv(__ T2D, as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg)); %} ins_pipe(pipe_slow); %} instruct vcvt2Ito2F(vecD dst, vecD src) %{ predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); match(Set dst (VectorCastI2X src)); format %{ "scvtfv T2S, $dst, $src\t# convert 2I to 2F vector" %} ins_encode %{ __ scvtfv(__ T2S, as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); %} ins_pipe(pipe_class_default); %} instruct vcvt4Ito4F(vecX dst, vecX src) %{ predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); match(Set dst (VectorCastI2X src)); format %{ "scvtfv T4S, $dst, $src\t# convert 4I to 4F vector" %} ins_encode %{ __ scvtfv(__ T4S, as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); %} ins_pipe(pipe_class_default); %} instruct vcvt2Lto2D(vecX dst, vecX src) %{ predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); match(Set dst (VectorCastL2X src)); format %{ "scvtfv T2D, $dst, $src\t# convert 2L to 2D vector" %} ins_encode %{ __ scvtfv(__ T2D, as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); %} ins_pipe(pipe_class_default); %} instruct vcvt2Fto2D(vecX dst, vecD src) %{ predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); match(Set dst (VectorCastF2X src)); format %{ "fcvtl $dst, T2D, $src, T2S\t# convert 2F to 2D vector" %} ins_encode %{ __ fcvtl(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src$$reg), __ T2S); %} ins_pipe(pipe_class_default); %} instruct vcvt2Dto2F(vecD dst, vecX src) %{ predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); match(Set dst (VectorCastD2X src)); format %{ "fcvtn $dst, T2S, $src, T2D\t# convert 2D to 2F vector" %} ins_encode %{ __ fcvtn(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src$$reg), __ T2D); %} ins_pipe(pipe_class_default); %} instruct vcvt2Lto2F(vecD dst, vecX src) %{ predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); match(Set dst (VectorCastL2X src)); format %{ "scvtfv T2D, $dst, $src\n\t" "fcvtn $dst, T2S, $dst, T2D\t# convert 2L to 2F vector" %} ins_encode %{ __ scvtfv(__ T2D, as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); __ fcvtn(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($dst$$reg), __ T2D); %} ins_pipe(pipe_slow); %} // ------------------------------ Reduction ------------------------------- instruct reduce_add8B(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, vecD tmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (AddReductionVI isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); format %{ "addv $tmp, T8B, $vsrc\n\t" "smov $dst, $tmp, B, 0\n\t" "addw $dst, $dst, $isrc\n\t" "sxtb $dst, $dst\t# add reduction8B" %} ins_encode %{ __ addv(as_FloatRegister($tmp$$reg), __ T8B, as_FloatRegister($vsrc$$reg)); __ smov($dst$$Register, as_FloatRegister($tmp$$reg), __ B, 0); __ addw($dst$$Register, $dst$$Register, $isrc$$Register); __ sxtb($dst$$Register, $dst$$Register); %} ins_pipe(pipe_slow); %} instruct reduce_add16B(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, vecX tmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (AddReductionVI isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); format %{ "addv $tmp, T16B, $vsrc\n\t" "smov $dst, $tmp, B, 0\n\t" "addw $dst, $dst, $isrc\n\t" "sxtb $dst, $dst\t# add reduction16B" %} ins_encode %{ __ addv(as_FloatRegister($tmp$$reg), __ T16B, as_FloatRegister($vsrc$$reg)); __ smov($dst$$Register, as_FloatRegister($tmp$$reg), __ B, 0); __ addw($dst$$Register, $dst$$Register, $isrc$$Register); __ sxtb($dst$$Register, $dst$$Register); %} ins_pipe(pipe_slow); %} instruct reduce_add4S(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, vecD tmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (AddReductionVI isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); format %{ "addv $tmp, T4H, $vsrc\n\t" "smov $dst, $tmp, H, 0\n\t" "addw $dst, $dst, $isrc\n\t" "sxth $dst, $dst\t# add reduction4S" %} ins_encode %{ __ addv(as_FloatRegister($tmp$$reg), __ T4H, as_FloatRegister($vsrc$$reg)); __ smov($dst$$Register, as_FloatRegister($tmp$$reg), __ H, 0); __ addw($dst$$Register, $dst$$Register, $isrc$$Register); __ sxth($dst$$Register, $dst$$Register); %} ins_pipe(pipe_slow); %} instruct reduce_add8S(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, vecX tmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (AddReductionVI isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); format %{ "addv $tmp, T8H, $vsrc\n\t" "smov $dst, $tmp, H, 0\n\t" "addw $dst, $dst, $isrc\n\t" "sxth $dst, $dst\t# add reduction8S" %} ins_encode %{ __ addv(as_FloatRegister($tmp$$reg), __ T8H, as_FloatRegister($vsrc$$reg)); __ smov($dst$$Register, as_FloatRegister($tmp$$reg), __ H, 0); __ addw($dst$$Register, $dst$$Register, $isrc$$Register); __ sxth($dst$$Register, $dst$$Register); %} ins_pipe(pipe_slow); %} instruct reduce_add2L(iRegLNoSp dst, iRegL isrc, vecX vsrc, vecX tmp) %{ match(Set dst (AddReductionVL isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); format %{ "addpd $tmp, $vsrc\n\t" "umov $dst, $tmp, D, 0\n\t" "add $dst, $isrc, $dst\t# add reduction2L" %} ins_encode %{ __ addpd(as_FloatRegister($tmp$$reg), as_FloatRegister($vsrc$$reg)); __ umov($dst$$Register, as_FloatRegister($tmp$$reg), __ D, 0); __ add($dst$$Register, $isrc$$Register, $dst$$Register); %} ins_pipe(pipe_slow); %} instruct reduce_mul8B(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, vecD vtmp1, vecD vtmp2, iRegINoSp itmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (MulReductionVI isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP vtmp1, TEMP vtmp2, TEMP itmp); format %{ "ins $vtmp1, S, $vsrc, 0, 1\n\t" "mulv $vtmp1, T8B, $vtmp1, $vsrc\n\t" "ins $vtmp2, H, $vtmp1, 0, 1\n\t" "mulv $vtmp2, T8B, $vtmp2, $vtmp1\n\t" "umov $itmp, $vtmp2, B, 0\n\t" "mulw $dst, $itmp, $isrc\n\t" "sxtb $dst, $dst\n\t" "umov $itmp, $vtmp2, B, 1\n\t" "mulw $dst, $itmp, $dst\n\t" "sxtb $dst, $dst\t# mul reduction8B" %} ins_encode %{ __ ins(as_FloatRegister($vtmp1$$reg), __ S, as_FloatRegister($vsrc$$reg), 0, 1); __ mulv(as_FloatRegister($vtmp1$$reg), __ T8B, as_FloatRegister($vtmp1$$reg), as_FloatRegister($vsrc$$reg)); __ ins(as_FloatRegister($vtmp2$$reg), __ H, as_FloatRegister($vtmp1$$reg), 0, 1); __ mulv(as_FloatRegister($vtmp2$$reg), __ T8B, as_FloatRegister($vtmp2$$reg), as_FloatRegister($vtmp1$$reg)); __ umov($itmp$$Register, as_FloatRegister($vtmp2$$reg), __ B, 0); __ mulw($dst$$Register, $itmp$$Register, $isrc$$Register); __ sxtb($dst$$Register, $dst$$Register); __ umov($itmp$$Register, as_FloatRegister($vtmp2$$reg), __ B, 1); __ mulw($dst$$Register, $itmp$$Register, $dst$$Register); __ sxtb($dst$$Register, $dst$$Register); %} ins_pipe(pipe_slow); %} instruct reduce_mul16B(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, vecX vtmp1, vecX vtmp2, iRegINoSp itmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (MulReductionVI isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP vtmp1, TEMP vtmp2, TEMP itmp); format %{ "ins $vtmp1, D, $vsrc, 0, 1\n\t" "mulv $vtmp1, T8B, $vtmp1, $vsrc\n\t" "ins $vtmp2, S, $vtmp1, 0, 1\n\t" "mulv $vtmp1, T8B, $vtmp2, $vtmp1\n\t" "ins $vtmp2, H, $vtmp1, 0, 1\n\t" "mulv $vtmp2, T8B, $vtmp2, $vtmp1\n\t" "umov $itmp, $vtmp2, B, 0\n\t" "mulw $dst, $itmp, $isrc\n\t" "sxtb $dst, $dst\n\t" "umov $itmp, $vtmp2, B, 1\n\t" "mulw $dst, $itmp, $dst\n\t" "sxtb $dst, $dst\t# mul reduction16B" %} ins_encode %{ __ ins(as_FloatRegister($vtmp1$$reg), __ D, as_FloatRegister($vsrc$$reg), 0, 1); __ mulv(as_FloatRegister($vtmp1$$reg), __ T8B, as_FloatRegister($vtmp1$$reg), as_FloatRegister($vsrc$$reg)); __ ins(as_FloatRegister($vtmp2$$reg), __ S, as_FloatRegister($vtmp1$$reg), 0, 1); __ mulv(as_FloatRegister($vtmp1$$reg), __ T8B, as_FloatRegister($vtmp2$$reg), as_FloatRegister($vtmp1$$reg)); __ ins(as_FloatRegister($vtmp2$$reg), __ H, as_FloatRegister($vtmp1$$reg), 0, 1); __ mulv(as_FloatRegister($vtmp2$$reg), __ T8B, as_FloatRegister($vtmp2$$reg), as_FloatRegister($vtmp1$$reg)); __ umov($itmp$$Register, as_FloatRegister($vtmp2$$reg), __ B, 0); __ mulw($dst$$Register, $itmp$$Register, $isrc$$Register); __ sxtb($dst$$Register, $dst$$Register); __ umov($itmp$$Register, as_FloatRegister($vtmp2$$reg), __ B, 1); __ mulw($dst$$Register, $itmp$$Register, $dst$$Register); __ sxtb($dst$$Register, $dst$$Register); %} ins_pipe(pipe_slow); %} instruct reduce_mul4S(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, vecD vtmp, iRegINoSp itmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (MulReductionVI isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP vtmp, TEMP itmp); format %{ "ins $vtmp, S, $vsrc, 0, 1\n\t" "mulv $vtmp, T4H, $vtmp, $vsrc\n\t" "umov $itmp, $vtmp, H, 0\n\t" "mulw $dst, $itmp, $isrc\n\t" "sxth $dst, $dst\n\t" "umov $itmp, $vtmp, H, 1\n\t" "mulw $dst, $itmp, $dst\n\t" "sxth $dst, $dst\t# mul reduction4S" %} ins_encode %{ __ ins(as_FloatRegister($vtmp$$reg), __ S, as_FloatRegister($vsrc$$reg), 0, 1); __ mulv(as_FloatRegister($vtmp$$reg), __ T4H, as_FloatRegister($vtmp$$reg), as_FloatRegister($vsrc$$reg)); __ umov($itmp$$Register, as_FloatRegister($vtmp$$reg), __ H, 0); __ mulw($dst$$Register, $itmp$$Register, $isrc$$Register); __ sxth($dst$$Register, $dst$$Register); __ umov($itmp$$Register, as_FloatRegister($vtmp$$reg), __ H, 1); __ mulw($dst$$Register, $itmp$$Register, $dst$$Register); __ sxth($dst$$Register, $dst$$Register); %} ins_pipe(pipe_slow); %} instruct reduce_mul8S(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, vecX vtmp1, vecX vtmp2, iRegINoSp itmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (MulReductionVI isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP vtmp1, TEMP vtmp2, TEMP itmp); format %{ "ins $vtmp1, D, $vsrc, 0, 1\n\t" "mulv $vtmp1, T4H, $vtmp1, $vsrc\n\t" "ins $vtmp2, S, $vtmp1, 0, 1\n\t" "mulv $vtmp2, T4H, $vtmp2, $vtmp1\n\t" "umov $itmp, $vtmp2, H, 0\n\t" "mulw $dst, $itmp, $isrc\n\t" "sxth $dst, $dst\n\t" "umov $itmp, $vtmp2, H, 1\n\t" "mulw $dst, $itmp, $dst\n\t" "sxth $dst, $dst\t# mul reduction8S" %} ins_encode %{ __ ins(as_FloatRegister($vtmp1$$reg), __ D, as_FloatRegister($vsrc$$reg), 0, 1); __ mulv(as_FloatRegister($vtmp1$$reg), __ T4H, as_FloatRegister($vtmp1$$reg), as_FloatRegister($vsrc$$reg)); __ ins(as_FloatRegister($vtmp2$$reg), __ S, as_FloatRegister($vtmp1$$reg), 0, 1); __ mulv(as_FloatRegister($vtmp2$$reg), __ T4H, as_FloatRegister($vtmp2$$reg), as_FloatRegister($vtmp1$$reg)); __ umov($itmp$$Register, as_FloatRegister($vtmp2$$reg), __ H, 0); __ mulw($dst$$Register, $itmp$$Register, $isrc$$Register); __ sxth($dst$$Register, $dst$$Register); __ umov($itmp$$Register, as_FloatRegister($vtmp2$$reg), __ H, 1); __ mulw($dst$$Register, $itmp$$Register, $dst$$Register); __ sxth($dst$$Register, $dst$$Register); %} ins_pipe(pipe_slow); %} instruct reduce_mul2L(iRegLNoSp dst, iRegL isrc, vecX vsrc, iRegLNoSp tmp) %{ match(Set dst (MulReductionVL isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); format %{ "umov $tmp, $vsrc, D, 0\n\t" "mul $dst, $isrc, $tmp\n\t" "umov $tmp, $vsrc, D, 1\n\t" "mul $dst, $dst, $tmp\t# mul reduction2L" %} ins_encode %{ __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ D, 0); __ mul($dst$$Register, $isrc$$Register, $tmp$$Register); __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ D, 1); __ mul($dst$$Register, $dst$$Register, $tmp$$Register); %} ins_pipe(pipe_slow); %} instruct reduce_max8B(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, vecD tmp, rFlagsReg cr) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (MaxReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp, KILL cr); format %{ "smaxv $tmp, T8B, $vsrc\n\t" "smov $dst, $tmp, B, 0\n\t" "cmpw $dst, $isrc\n\t" "cselw $dst, $dst, $isrc GT\t# max reduction8B" %} ins_encode %{ __ smaxv(as_FloatRegister($tmp$$reg), __ T8B, as_FloatRegister($vsrc$$reg)); __ smov(as_Register($dst$$reg), as_FloatRegister($tmp$$reg), __ B, 0); __ cmpw(as_Register($dst$$reg), as_Register($isrc$$reg)); __ cselw(as_Register($dst$$reg), as_Register($dst$$reg), as_Register($isrc$$reg), Assembler::GT); %} ins_pipe(pipe_slow); %} instruct reduce_max16B(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, vecX tmp, rFlagsReg cr) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (MaxReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp, KILL cr); format %{ "smaxv $tmp, T16B, $vsrc\n\t" "smov $dst, $tmp, B, 0\n\t" "cmpw $dst, $isrc\n\t" "cselw $dst, $dst, $isrc GT\t# max reduction16B" %} ins_encode %{ __ smaxv(as_FloatRegister($tmp$$reg), __ T16B, as_FloatRegister($vsrc$$reg)); __ smov(as_Register($dst$$reg), as_FloatRegister($tmp$$reg), __ B, 0); __ cmpw(as_Register($dst$$reg), as_Register($isrc$$reg)); __ cselw(as_Register($dst$$reg), as_Register($dst$$reg), as_Register($isrc$$reg), Assembler::GT); %} ins_pipe(pipe_slow); %} instruct reduce_max4S(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, vecD tmp, rFlagsReg cr) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (MaxReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp, KILL cr); format %{ "smaxv $tmp, T4H, $vsrc\n\t" "smov $dst, $tmp, H, 0\n\t" "cmpw $dst, $isrc\n\t" "cselw $dst, $dst, $isrc GT\t# max reduction4S" %} ins_encode %{ __ smaxv(as_FloatRegister($tmp$$reg), __ T4H, as_FloatRegister($vsrc$$reg)); __ smov(as_Register($dst$$reg), as_FloatRegister($tmp$$reg), __ H, 0); __ cmpw(as_Register($dst$$reg), as_Register($isrc$$reg)); __ cselw(as_Register($dst$$reg), as_Register($dst$$reg), as_Register($isrc$$reg), Assembler::GT); %} ins_pipe(pipe_slow); %} instruct reduce_max8S(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, vecX tmp, rFlagsReg cr) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (MaxReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp, KILL cr); format %{ "smaxv $tmp, T8H, $vsrc\n\t" "smov $dst, $tmp, H, 0\n\t" "cmpw $dst, $isrc\n\t" "cselw $dst, $dst, $isrc GT\t# max reduction8S" %} ins_encode %{ __ smaxv(as_FloatRegister($tmp$$reg), __ T8H, as_FloatRegister($vsrc$$reg)); __ smov(as_Register($dst$$reg), as_FloatRegister($tmp$$reg), __ H, 0); __ cmpw(as_Register($dst$$reg), as_Register($isrc$$reg)); __ cselw(as_Register($dst$$reg), as_Register($dst$$reg), as_Register($isrc$$reg), Assembler::GT); %} ins_pipe(pipe_slow); %} instruct reduce_max4I(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, vecX tmp, rFlagsReg cr) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT); match(Set dst (MaxReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp, KILL cr); format %{ "smaxv $tmp, T4S, $vsrc\n\t" "umov $dst, $tmp, S, 0\n\t" "cmpw $dst, $isrc\n\t" "cselw $dst, $dst, $isrc GT\t# max reduction4I" %} ins_encode %{ __ smaxv(as_FloatRegister($tmp$$reg), __ T4S, as_FloatRegister($vsrc$$reg)); __ umov(as_Register($dst$$reg), as_FloatRegister($tmp$$reg), __ S, 0); __ cmpw(as_Register($dst$$reg), as_Register($isrc$$reg)); __ cselw(as_Register($dst$$reg), as_Register($dst$$reg), as_Register($isrc$$reg), Assembler::GT); %} ins_pipe(pipe_slow); %} instruct reduce_min8B(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, vecD tmp, rFlagsReg cr) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (MinReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp, KILL cr); format %{ "sminv $tmp, T8B, $vsrc\n\t" "smov $dst, $tmp, B, 0\n\t" "cmpw $dst, $isrc\n\t" "cselw $dst, $dst, $isrc LT\t# min reduction8B" %} ins_encode %{ __ sminv(as_FloatRegister($tmp$$reg), __ T8B, as_FloatRegister($vsrc$$reg)); __ smov(as_Register($dst$$reg), as_FloatRegister($tmp$$reg), __ B, 0); __ cmpw(as_Register($dst$$reg), as_Register($isrc$$reg)); __ cselw(as_Register($dst$$reg), as_Register($dst$$reg), as_Register($isrc$$reg), Assembler::LT); %} ins_pipe(pipe_slow); %} instruct reduce_min16B(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, vecX tmp, rFlagsReg cr) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (MinReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp, KILL cr); format %{ "sminv $tmp, T16B, $vsrc\n\t" "smov $dst, $tmp, B, 0\n\t" "cmpw $dst, $isrc\n\t" "cselw $dst, $dst, $isrc LT\t# min reduction16B" %} ins_encode %{ __ sminv(as_FloatRegister($tmp$$reg), __ T16B, as_FloatRegister($vsrc$$reg)); __ smov(as_Register($dst$$reg), as_FloatRegister($tmp$$reg), __ B, 0); __ cmpw(as_Register($dst$$reg), as_Register($isrc$$reg)); __ cselw(as_Register($dst$$reg), as_Register($dst$$reg), as_Register($isrc$$reg), Assembler::LT); %} ins_pipe(pipe_slow); %} instruct reduce_min4S(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, vecD tmp, rFlagsReg cr) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (MinReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp, KILL cr); format %{ "sminv $tmp, T4H, $vsrc\n\t" "smov $dst, $tmp, H, 0\n\t" "cmpw $dst, $isrc\n\t" "cselw $dst, $dst, $isrc LT\t# min reduction4S" %} ins_encode %{ __ sminv(as_FloatRegister($tmp$$reg), __ T4H, as_FloatRegister($vsrc$$reg)); __ smov(as_Register($dst$$reg), as_FloatRegister($tmp$$reg), __ H, 0); __ cmpw(as_Register($dst$$reg), as_Register($isrc$$reg)); __ cselw(as_Register($dst$$reg), as_Register($dst$$reg), as_Register($isrc$$reg), Assembler::LT); %} ins_pipe(pipe_slow); %} instruct reduce_min8S(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, vecX tmp, rFlagsReg cr) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (MinReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp, KILL cr); format %{ "sminv $tmp, T8H, $vsrc\n\t" "smov $dst, $tmp, H, 0\n\t" "cmpw $dst, $isrc\n\t" "cselw $dst, $dst, $isrc LT\t# min reduction8S" %} ins_encode %{ __ sminv(as_FloatRegister($tmp$$reg), __ T8H, as_FloatRegister($vsrc$$reg)); __ smov(as_Register($dst$$reg), as_FloatRegister($tmp$$reg), __ H, 0); __ cmpw(as_Register($dst$$reg), as_Register($isrc$$reg)); __ cselw(as_Register($dst$$reg), as_Register($dst$$reg), as_Register($isrc$$reg), Assembler::LT); %} ins_pipe(pipe_slow); %} instruct reduce_min4I(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, vecX tmp, rFlagsReg cr) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT); match(Set dst (MinReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp, KILL cr); format %{ "sminv $tmp, T4S, $vsrc\n\t" "umov $dst, $tmp, S, 0\n\t" "cmpw $dst, $isrc\n\t" "cselw $dst, $dst, $isrc LT\t# min reduction4I" %} ins_encode %{ __ sminv(as_FloatRegister($tmp$$reg), __ T4S, as_FloatRegister($vsrc$$reg)); __ umov(as_Register($dst$$reg), as_FloatRegister($tmp$$reg), __ S, 0); __ cmpw(as_Register($dst$$reg), as_Register($isrc$$reg)); __ cselw(as_Register($dst$$reg), as_Register($dst$$reg), as_Register($isrc$$reg), Assembler::LT); %} ins_pipe(pipe_slow); %} instruct reduce_max2I(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, vecD tmp, rFlagsReg cr) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT); match(Set dst (MaxReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp, KILL cr); format %{ "smaxp $tmp, T2S, $vsrc, $vsrc\n\t" "umov $dst, $tmp, S, 0\n\t" "cmpw $dst, $isrc\n\t" "cselw $dst, $dst, $isrc GT\t# max reduction2I" %} ins_encode %{ __ smaxp(as_FloatRegister($tmp$$reg), __ T2S, as_FloatRegister($vsrc$$reg), as_FloatRegister($vsrc$$reg)); __ umov(as_Register($dst$$reg), as_FloatRegister($tmp$$reg), __ S, 0); __ cmpw(as_Register($dst$$reg), as_Register($isrc$$reg)); __ cselw(as_Register($dst$$reg), as_Register($dst$$reg), as_Register($isrc$$reg), Assembler::GT); %} ins_pipe(pipe_slow); %} instruct reduce_min2I(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, vecD tmp, rFlagsReg cr) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT); match(Set dst (MinReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp, KILL cr); format %{ "sminp $tmp, T2S, $vsrc, $vsrc\n\t" "umov $dst, $tmp, S, 0\n\t" "cmpw $dst, $isrc\n\t" "cselw $dst, $dst, $isrc LT\t# min reduction2I" %} ins_encode %{ __ sminp(as_FloatRegister($tmp$$reg), __ T2S, as_FloatRegister($vsrc$$reg), as_FloatRegister($vsrc$$reg)); __ umov(as_Register($dst$$reg), as_FloatRegister($tmp$$reg), __ S, 0); __ cmpw(as_Register($dst$$reg), as_Register($isrc$$reg)); __ cselw(as_Register($dst$$reg), as_Register($dst$$reg), as_Register($isrc$$reg), Assembler::LT); %} ins_pipe(pipe_slow); %} instruct reduce_max2L(iRegLNoSp dst, iRegL isrc, vecX vsrc, iRegLNoSp tmp, rFlagsReg cr) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG); match(Set dst (MaxReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp, KILL cr); format %{ "umov $tmp, $vsrc, D, 0\n\t" "cmp $isrc,$tmp\n\t" "csel $dst, $isrc, $tmp GT\n\t" "umov $tmp, $vsrc, D, 1\n\t" "cmp $dst, $tmp\n\t" "csel $dst, $dst, $tmp GT\t# max reduction2L" %} ins_encode %{ __ umov(as_Register($tmp$$reg), as_FloatRegister($vsrc$$reg), __ D, 0); __ cmp(as_Register($isrc$$reg), as_Register($tmp$$reg)); __ csel(as_Register($dst$$reg), as_Register($isrc$$reg), as_Register($tmp$$reg), Assembler::GT); __ umov(as_Register($tmp$$reg), as_FloatRegister($vsrc$$reg), __ D, 1); __ cmp(as_Register($dst$$reg), as_Register($tmp$$reg)); __ csel(as_Register($dst$$reg), as_Register($dst$$reg), as_Register($tmp$$reg), Assembler::GT); %} ins_pipe(pipe_slow); %} instruct reduce_min2L(iRegLNoSp dst, iRegL isrc, vecX vsrc, iRegLNoSp tmp, rFlagsReg cr) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG); match(Set dst (MinReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp, KILL cr); format %{ "umov $tmp, $vsrc, D, 0\n\t" "cmp $isrc,$tmp\n\t" "csel $dst, $isrc, $tmp LT\n\t" "umov $tmp, $vsrc, D, 1\n\t" "cmp $dst, $tmp\n\t" "csel $dst, $dst, $tmp LT\t# min reduction2L" %} ins_encode %{ __ umov(as_Register($tmp$$reg), as_FloatRegister($vsrc$$reg), __ D, 0); __ cmp(as_Register($isrc$$reg), as_Register($tmp$$reg)); __ csel(as_Register($dst$$reg), as_Register($isrc$$reg), as_Register($tmp$$reg), Assembler::LT); __ umov(as_Register($tmp$$reg), as_FloatRegister($vsrc$$reg), __ D, 1); __ cmp(as_Register($dst$$reg), as_Register($tmp$$reg)); __ csel(as_Register($dst$$reg), as_Register($dst$$reg), as_Register($tmp$$reg), Assembler::LT); %} ins_pipe(pipe_slow); %} instruct reduce_max2F(vRegF dst, vRegF fsrc, vecD vsrc) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); match(Set dst (MaxReductionV fsrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst); format %{ "fmaxp $dst, $vsrc, S\n\t" "fmaxs $dst, $dst, $fsrc\t# max reduction2F" %} ins_encode %{ __ fmaxp(as_FloatRegister($dst$$reg), as_FloatRegister($vsrc$$reg), __ S); __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg)); %} ins_pipe(pipe_class_default); %} instruct reduce_max4F(vRegF dst, vRegF fsrc, vecX vsrc) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); match(Set dst (MaxReductionV fsrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst); format %{ "fmaxv $dst, T4S, $vsrc\n\t" "fmaxs $dst, $dst, $fsrc\t# max reduction4F" %} ins_encode %{ __ fmaxv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($vsrc$$reg)); __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg)); %} ins_pipe(pipe_class_default); %} instruct reduce_max2D(vRegD dst, vRegD dsrc, vecX vsrc) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); match(Set dst (MaxReductionV dsrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst); format %{ "fmaxp $dst, $vsrc, D\n\t" "fmaxd $dst, $dst, $dsrc\t# max reduction2D" %} ins_encode %{ __ fmaxp(as_FloatRegister($dst$$reg), as_FloatRegister($vsrc$$reg), __ D); __ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($dsrc$$reg)); %} ins_pipe(pipe_class_default); %} instruct reduce_min2F(vRegF dst, vRegF fsrc, vecD vsrc) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); match(Set dst (MinReductionV fsrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst); format %{ "fminp $dst, $vsrc, S\n\t" "fmins $dst, $dst, $fsrc\t# min reduction2F" %} ins_encode %{ __ fminp(as_FloatRegister($dst$$reg), as_FloatRegister($vsrc$$reg), __ S); __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg)); %} ins_pipe(pipe_class_default); %} instruct reduce_min4F(vRegF dst, vRegF fsrc, vecX vsrc) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); match(Set dst (MinReductionV fsrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst); format %{ "fminv $dst, T4S, $vsrc\n\t" "fmins $dst, $dst, $fsrc\t# min reduction4F" %} ins_encode %{ __ fminv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($vsrc$$reg)); __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg)); %} ins_pipe(pipe_class_default); %} instruct reduce_min2D(vRegD dst, vRegD dsrc, vecX vsrc) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); match(Set dst (MinReductionV dsrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst); format %{ "fminp $dst, $vsrc, D\n\t" "fmind $dst, $dst, $dsrc\t# min reduction2D" %} ins_encode %{ __ fminp(as_FloatRegister($dst$$reg), as_FloatRegister($vsrc$$reg), __ D); __ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($dsrc$$reg)); %} ins_pipe(pipe_class_default); %} instruct reduce_and8B(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, iRegINoSp tmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (AndReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); format %{ "umov $tmp, $vsrc, S, 0\n\t" "umov $dst, $vsrc, S, 1\n\t" "andw $dst, $dst, $tmp\n\t" "andw $dst, $dst, $dst, LSR #16\n\t" "andw $dst, $dst, $dst, LSR #8\n\t" "andw $dst, $isrc, $dst\n\t" "sxtb $dst, $dst\t# and reduction8B" %} ins_encode %{ __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ S, 0); __ umov($dst$$Register, as_FloatRegister($vsrc$$reg), __ S, 1); __ andw($dst$$Register, $dst$$Register, $tmp$$Register); __ andw($dst$$Register, $dst$$Register, $dst$$Register, Assembler::LSR, 16); __ andw($dst$$Register, $dst$$Register, $dst$$Register, Assembler::LSR, 8); __ andw($dst$$Register, $isrc$$Register, $dst$$Register); __ sxtb($dst$$Register, $dst$$Register); %} ins_pipe(pipe_slow); %} instruct reduce_orr8B(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, iRegINoSp tmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (OrReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); format %{ "umov $tmp, $vsrc, S, 0\n\t" "umov $dst, $vsrc, S, 1\n\t" "orrw $dst, $dst, $tmp\n\t" "orrw $dst, $dst, $dst, LSR #16\n\t" "orrw $dst, $dst, $dst, LSR #8\n\t" "orrw $dst, $isrc, $dst\n\t" "sxtb $dst, $dst\t# orr reduction8B" %} ins_encode %{ __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ S, 0); __ umov($dst$$Register, as_FloatRegister($vsrc$$reg), __ S, 1); __ orrw($dst$$Register, $dst$$Register, $tmp$$Register); __ orrw($dst$$Register, $dst$$Register, $dst$$Register, Assembler::LSR, 16); __ orrw($dst$$Register, $dst$$Register, $dst$$Register, Assembler::LSR, 8); __ orrw($dst$$Register, $isrc$$Register, $dst$$Register); __ sxtb($dst$$Register, $dst$$Register); %} ins_pipe(pipe_slow); %} instruct reduce_eor8B(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, iRegINoSp tmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (XorReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); format %{ "umov $tmp, $vsrc, S, 0\n\t" "umov $dst, $vsrc, S, 1\n\t" "eorw $dst, $dst, $tmp\n\t" "eorw $dst, $dst, $dst, LSR #16\n\t" "eorw $dst, $dst, $dst, LSR #8\n\t" "eorw $dst, $isrc, $dst\n\t" "sxtb $dst, $dst\t# eor reduction8B" %} ins_encode %{ __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ S, 0); __ umov($dst$$Register, as_FloatRegister($vsrc$$reg), __ S, 1); __ eorw($dst$$Register, $dst$$Register, $tmp$$Register); __ eorw($dst$$Register, $dst$$Register, $dst$$Register, Assembler::LSR, 16); __ eorw($dst$$Register, $dst$$Register, $dst$$Register, Assembler::LSR, 8); __ eorw($dst$$Register, $isrc$$Register, $dst$$Register); __ sxtb($dst$$Register, $dst$$Register); %} ins_pipe(pipe_slow); %} instruct reduce_and16B(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, iRegINoSp tmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (AndReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); format %{ "umov $tmp, $vsrc, D, 0\n\t" "umov $dst, $vsrc, D, 1\n\t" "andr $dst, $dst, $tmp\n\t" "andr $dst, $dst, $dst, LSR #32\n\t" "andw $dst, $dst, $dst, LSR #16\n\t" "andw $dst, $dst, $dst, LSR #8\n\t" "andw $dst, $isrc, $dst\n\t" "sxtb $dst, $dst\t# and reduction16B" %} ins_encode %{ __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ D, 0); __ umov($dst$$Register, as_FloatRegister($vsrc$$reg), __ D, 1); __ andr($dst$$Register, $dst$$Register, $tmp$$Register); __ andr($dst$$Register, $dst$$Register, $dst$$Register, Assembler::LSR, 32); __ andw($dst$$Register, $dst$$Register, $dst$$Register, Assembler::LSR, 16); __ andw($dst$$Register, $dst$$Register, $dst$$Register, Assembler::LSR, 8); __ andw($dst$$Register, $isrc$$Register, $dst$$Register); __ sxtb($dst$$Register, $dst$$Register); %} ins_pipe(pipe_slow); %} instruct reduce_orr16B(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, iRegINoSp tmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (OrReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); format %{ "umov $tmp, $vsrc, D, 0\n\t" "umov $dst, $vsrc, D, 1\n\t" "orr $dst, $dst, $tmp\n\t" "orr $dst, $dst, $dst, LSR #32\n\t" "orrw $dst, $dst, $dst, LSR #16\n\t" "orrw $dst, $dst, $dst, LSR #8\n\t" "orrw $dst, $isrc, $dst\n\t" "sxtb $dst, $dst\t# orr reduction16B" %} ins_encode %{ __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ D, 0); __ umov($dst$$Register, as_FloatRegister($vsrc$$reg), __ D, 1); __ orr ($dst$$Register, $dst$$Register, $tmp$$Register); __ orr ($dst$$Register, $dst$$Register, $dst$$Register, Assembler::LSR, 32); __ orrw($dst$$Register, $dst$$Register, $dst$$Register, Assembler::LSR, 16); __ orrw($dst$$Register, $dst$$Register, $dst$$Register, Assembler::LSR, 8); __ orrw($dst$$Register, $isrc$$Register, $dst$$Register); __ sxtb($dst$$Register, $dst$$Register); %} ins_pipe(pipe_slow); %} instruct reduce_eor16B(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, iRegINoSp tmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (XorReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); format %{ "umov $tmp, $vsrc, D, 0\n\t" "umov $dst, $vsrc, D, 1\n\t" "eor $dst, $dst, $tmp\n\t" "eor $dst, $dst, $dst, LSR #32\n\t" "eorw $dst, $dst, $dst, LSR #16\n\t" "eorw $dst, $dst, $dst, LSR #8\n\t" "eorw $dst, $isrc, $dst\n\t" "sxtb $dst, $dst\t# eor reduction16B" %} ins_encode %{ __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ D, 0); __ umov($dst$$Register, as_FloatRegister($vsrc$$reg), __ D, 1); __ eor ($dst$$Register, $dst$$Register, $tmp$$Register); __ eor ($dst$$Register, $dst$$Register, $dst$$Register, Assembler::LSR, 32); __ eorw($dst$$Register, $dst$$Register, $dst$$Register, Assembler::LSR, 16); __ eorw($dst$$Register, $dst$$Register, $dst$$Register, Assembler::LSR, 8); __ eorw($dst$$Register, $isrc$$Register, $dst$$Register); __ sxtb($dst$$Register, $dst$$Register); %} ins_pipe(pipe_slow); %} instruct reduce_and4S(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, iRegINoSp tmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (AndReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); format %{ "umov $tmp, $vsrc, S, 0\n\t" "umov $dst, $vsrc, S, 1\n\t" "andw $dst, $dst, $tmp\n\t" "andw $dst, $dst, $dst, LSR #16\n\t" "andw $dst, $isrc, $dst\n\t" "sxth $dst, $dst\t# and reduction4S" %} ins_encode %{ __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ S, 0); __ umov($dst$$Register, as_FloatRegister($vsrc$$reg), __ S, 1); __ andw($dst$$Register, $dst$$Register, $tmp$$Register); __ andw($dst$$Register, $dst$$Register, $dst$$Register, Assembler::LSR, 16); __ andw($dst$$Register, $isrc$$Register, $dst$$Register); __ sxth($dst$$Register, $dst$$Register); %} ins_pipe(pipe_slow); %} instruct reduce_orr4S(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, iRegINoSp tmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (OrReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); format %{ "umov $tmp, $vsrc, S, 0\n\t" "umov $dst, $vsrc, S, 1\n\t" "orrw $dst, $dst, $tmp\n\t" "orrw $dst, $dst, $dst, LSR #16\n\t" "orrw $dst, $isrc, $dst\n\t" "sxth $dst, $dst\t# orr reduction4S" %} ins_encode %{ __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ S, 0); __ umov($dst$$Register, as_FloatRegister($vsrc$$reg), __ S, 1); __ orrw($dst$$Register, $dst$$Register, $tmp$$Register); __ orrw($dst$$Register, $dst$$Register, $dst$$Register, Assembler::LSR, 16); __ orrw($dst$$Register, $isrc$$Register, $dst$$Register); __ sxth($dst$$Register, $dst$$Register); %} ins_pipe(pipe_slow); %} instruct reduce_eor4S(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, iRegINoSp tmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (XorReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); format %{ "umov $tmp, $vsrc, S, 0\n\t" "umov $dst, $vsrc, S, 1\n\t" "eorw $dst, $dst, $tmp\n\t" "eorw $dst, $dst, $dst, LSR #16\n\t" "eorw $dst, $isrc, $dst\n\t" "sxth $dst, $dst\t# eor reduction4S" %} ins_encode %{ __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ S, 0); __ umov($dst$$Register, as_FloatRegister($vsrc$$reg), __ S, 1); __ eorw($dst$$Register, $dst$$Register, $tmp$$Register); __ eorw($dst$$Register, $dst$$Register, $dst$$Register, Assembler::LSR, 16); __ eorw($dst$$Register, $isrc$$Register, $dst$$Register); __ sxth($dst$$Register, $dst$$Register); %} ins_pipe(pipe_slow); %} instruct reduce_and8S(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, iRegINoSp tmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (AndReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); format %{ "umov $tmp, $vsrc, D, 0\n\t" "umov $dst, $vsrc, D, 1\n\t" "andr $dst, $dst, $tmp\n\t" "andr $dst, $dst, $dst, LSR #32\n\t" "andw $dst, $dst, $dst, LSR #16\n\t" "andw $dst, $isrc, $dst\n\t" "sxth $dst, $dst\t# and reduction8S" %} ins_encode %{ __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ D, 0); __ umov($dst$$Register, as_FloatRegister($vsrc$$reg), __ D, 1); __ andr($dst$$Register, $dst$$Register, $tmp$$Register); __ andr($dst$$Register, $dst$$Register, $dst$$Register, Assembler::LSR, 32); __ andw($dst$$Register, $dst$$Register, $dst$$Register, Assembler::LSR, 16); __ andw($dst$$Register, $isrc$$Register, $dst$$Register); __ sxth($dst$$Register, $dst$$Register); %} ins_pipe(pipe_slow); %} instruct reduce_orr8S(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, iRegINoSp tmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (OrReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); format %{ "umov $tmp, $vsrc, D, 0\n\t" "umov $dst, $vsrc, D, 1\n\t" "orr $dst, $dst, $tmp\n\t" "orr $dst, $dst, $dst, LSR #32\n\t" "orrw $dst, $dst, $dst, LSR #16\n\t" "orrw $dst, $isrc, $dst\n\t" "sxth $dst, $dst\t# orr reduction8S" %} ins_encode %{ __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ D, 0); __ umov($dst$$Register, as_FloatRegister($vsrc$$reg), __ D, 1); __ orr ($dst$$Register, $dst$$Register, $tmp$$Register); __ orr ($dst$$Register, $dst$$Register, $dst$$Register, Assembler::LSR, 32); __ orrw($dst$$Register, $dst$$Register, $dst$$Register, Assembler::LSR, 16); __ orrw($dst$$Register, $isrc$$Register, $dst$$Register); __ sxth($dst$$Register, $dst$$Register); %} ins_pipe(pipe_slow); %} instruct reduce_eor8S(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, iRegINoSp tmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (XorReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); format %{ "umov $tmp, $vsrc, D, 0\n\t" "umov $dst, $vsrc, D, 1\n\t" "eor $dst, $dst, $tmp\n\t" "eor $dst, $dst, $dst, LSR #32\n\t" "eorw $dst, $dst, $dst, LSR #16\n\t" "eorw $dst, $isrc, $dst\n\t" "sxth $dst, $dst\t# eor reduction8S" %} ins_encode %{ __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ D, 0); __ umov($dst$$Register, as_FloatRegister($vsrc$$reg), __ D, 1); __ eor ($dst$$Register, $dst$$Register, $tmp$$Register); __ eor ($dst$$Register, $dst$$Register, $dst$$Register, Assembler::LSR, 32); __ eorw($dst$$Register, $dst$$Register, $dst$$Register, Assembler::LSR, 16); __ eorw($dst$$Register, $isrc$$Register, $dst$$Register); __ sxth($dst$$Register, $dst$$Register); %} ins_pipe(pipe_slow); %} instruct reduce_and2I(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, iRegINoSp tmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT); match(Set dst (AndReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); format %{ "umov $tmp, $vsrc, S, 0\n\t" "andw $dst, $tmp, $isrc\n\t" "umov $tmp, $vsrc, S, 1\n\t" "andw $dst, $tmp, $dst\t# and reduction2I" %} ins_encode %{ __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ S, 0); __ andw($dst$$Register, $tmp$$Register, $isrc$$Register); __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ S, 1); __ andw($dst$$Register, $tmp$$Register, $dst$$Register); %} ins_pipe(pipe_slow); %} instruct reduce_orr2I(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, iRegINoSp tmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT); match(Set dst (OrReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); format %{ "umov $tmp, $vsrc, S, 0\n\t" "orrw $dst, $tmp, $isrc\n\t" "umov $tmp, $vsrc, S, 1\n\t" "orrw $dst, $tmp, $dst\t# orr reduction2I" %} ins_encode %{ __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ S, 0); __ orrw($dst$$Register, $tmp$$Register, $isrc$$Register); __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ S, 1); __ orrw($dst$$Register, $tmp$$Register, $dst$$Register); %} ins_pipe(pipe_slow); %} instruct reduce_eor2I(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, iRegINoSp tmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT); match(Set dst (XorReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); format %{ "umov $tmp, $vsrc, S, 0\n\t" "eorw $dst, $tmp, $isrc\n\t" "umov $tmp, $vsrc, S, 1\n\t" "eorw $dst, $tmp, $dst\t# eor reduction2I" %} ins_encode %{ __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ S, 0); __ eorw($dst$$Register, $tmp$$Register, $isrc$$Register); __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ S, 1); __ eorw($dst$$Register, $tmp$$Register, $dst$$Register); %} ins_pipe(pipe_slow); %} instruct reduce_and4I(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, iRegINoSp tmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT); match(Set dst (AndReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); format %{ "umov $tmp, $vsrc, D, 0\n\t" "umov $dst, $vsrc, D, 1\n\t" "andr $dst, $dst, $tmp\n\t" "andr $dst, $dst, $dst, LSR #32\n\t" "andw $dst, $isrc, $dst\t# and reduction4I" %} ins_encode %{ __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ D, 0); __ umov($dst$$Register, as_FloatRegister($vsrc$$reg), __ D, 1); __ andr($dst$$Register, $dst$$Register, $tmp$$Register); __ andr($dst$$Register, $dst$$Register, $dst$$Register, Assembler::LSR, 32); __ andw($dst$$Register, $isrc$$Register, $dst$$Register); %} ins_pipe(pipe_slow); %} instruct reduce_orr4I(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, iRegINoSp tmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT); match(Set dst (OrReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); format %{ "umov $tmp, $vsrc, D, 0\n\t" "umov $dst, $vsrc, D, 1\n\t" "orr $dst, $dst, $tmp\n\t" "orr $dst, $dst, $dst, LSR #32\n\t" "orrw $dst, $isrc, $dst\t# orr reduction4I" %} ins_encode %{ __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ D, 0); __ umov($dst$$Register, as_FloatRegister($vsrc$$reg), __ D, 1); __ orr ($dst$$Register, $dst$$Register, $tmp$$Register); __ orr ($dst$$Register, $dst$$Register, $dst$$Register, Assembler::LSR, 32); __ orrw($dst$$Register, $isrc$$Register, $dst$$Register); %} ins_pipe(pipe_slow); %} instruct reduce_eor4I(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, iRegINoSp tmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT); match(Set dst (XorReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); format %{ "umov $tmp, $vsrc, D, 0\n\t" "umov $dst, $vsrc, D, 1\n\t" "eor $dst, $dst, $tmp\n\t" "eor $dst, $dst, $dst, LSR #32\n\t" "eorw $dst, $isrc, $dst\t# eor reduction4I" %} ins_encode %{ __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ D, 0); __ umov($dst$$Register, as_FloatRegister($vsrc$$reg), __ D, 1); __ eor ($dst$$Register, $dst$$Register, $tmp$$Register); __ eor ($dst$$Register, $dst$$Register, $dst$$Register, Assembler::LSR, 32); __ eorw($dst$$Register, $isrc$$Register, $dst$$Register); %} ins_pipe(pipe_slow); %} instruct reduce_and2L(iRegLNoSp dst, iRegL isrc, vecX vsrc, iRegLNoSp tmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG); match(Set dst (AndReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); format %{ "umov $tmp, $vsrc, D, 0\n\t" "andr $dst, $isrc, $tmp\n\t" "umov $tmp, $vsrc, D, 1\n\t" "andr $dst, $dst, $tmp\t# and reduction2L" %} ins_encode %{ __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ D, 0); __ andr($dst$$Register, $isrc$$Register, $tmp$$Register); __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ D, 1); __ andr($dst$$Register, $dst$$Register, $tmp$$Register); %} ins_pipe(pipe_slow); %} instruct reduce_orr2L(iRegLNoSp dst, iRegL isrc, vecX vsrc, iRegLNoSp tmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG); match(Set dst (OrReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); format %{ "umov $tmp, $vsrc, D, 0\n\t" "orr $dst, $isrc, $tmp\n\t" "umov $tmp, $vsrc, D, 1\n\t" "orr $dst, $dst, $tmp\t# orr reduction2L" %} ins_encode %{ __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ D, 0); __ orr ($dst$$Register, $isrc$$Register, $tmp$$Register); __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ D, 1); __ orr ($dst$$Register, $dst$$Register, $tmp$$Register); %} ins_pipe(pipe_slow); %} instruct reduce_eor2L(iRegLNoSp dst, iRegL isrc, vecX vsrc, iRegLNoSp tmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG); match(Set dst (XorReductionV isrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); format %{ "umov $tmp, $vsrc, D, 0\n\t" "eor $dst, $isrc, $tmp\n\t" "umov $tmp, $vsrc, D, 1\n\t" "eor $dst, $dst, $tmp\t# eor reduction2L" %} ins_encode %{ __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ D, 0); __ eor ($dst$$Register, $isrc$$Register, $tmp$$Register); __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ D, 1); __ eor ($dst$$Register, $dst$$Register, $tmp$$Register); %} ins_pipe(pipe_slow); %} // ------------------------------ Vector insert --------------------------------- instruct insert8B(vecD dst, vecD src, iRegIorL2I val, immI idx) %{ predicate(n->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (VectorInsert (Binary src val) idx)); ins_cost(INSN_COST); format %{ "orr $dst, T8B, $src, $src\n\t" "mov $dst, T8B, $idx, $val\t# insert into vector(8B)" %} ins_encode %{ if (as_FloatRegister($dst$$reg) != as_FloatRegister($src$$reg)) { __ orr(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); } __ mov(as_FloatRegister($dst$$reg), __ T8B, $idx$$constant, $val$$Register); %} ins_pipe(pipe_slow); %} instruct insert16B(vecX dst, vecX src, iRegIorL2I val, immI idx) %{ predicate(n->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (VectorInsert (Binary src val) idx)); ins_cost(INSN_COST); format %{ "orr $dst, T16B, $src, $src\n\t" "mov $dst, T16B, $idx, $val\t# insert into vector(16B)" %} ins_encode %{ if (as_FloatRegister($dst$$reg) != as_FloatRegister($src$$reg)) { __ orr(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); } __ mov(as_FloatRegister($dst$$reg), __ T16B, $idx$$constant, $val$$Register); %} ins_pipe(pipe_slow); %} instruct insert4S(vecD dst, vecD src, iRegIorL2I val, immI idx) %{ predicate(n->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (VectorInsert (Binary src val) idx)); ins_cost(INSN_COST); format %{ "orr $dst, T8B, $src, $src\n\t" "mov $dst, T4H, $idx, $val\t# insert into vector(4S)" %} ins_encode %{ if (as_FloatRegister($dst$$reg) != as_FloatRegister($src$$reg)) { __ orr(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); } __ mov(as_FloatRegister($dst$$reg), __ T4H, $idx$$constant, $val$$Register); %} ins_pipe(pipe_slow); %} instruct insert8S(vecX dst, vecX src, iRegIorL2I val, immI idx) %{ predicate(n->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (VectorInsert (Binary src val) idx)); ins_cost(INSN_COST); format %{ "orr $dst, T16B, $src, $src\n\t" "mov $dst, T8H, $idx, $val\t# insert into vector(8S)" %} ins_encode %{ if (as_FloatRegister($dst$$reg) != as_FloatRegister($src$$reg)) { __ orr(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); } __ mov(as_FloatRegister($dst$$reg), __ T8H, $idx$$constant, $val$$Register); %} ins_pipe(pipe_slow); %} instruct insert2I(vecD dst, vecD src, iRegIorL2I val, immI idx) %{ predicate(n->bottom_type()->is_vect()->element_basic_type() == T_INT); match(Set dst (VectorInsert (Binary src val) idx)); ins_cost(INSN_COST); format %{ "orr $dst, T8B, $src, $src\n\t" "mov $dst, T2S, $idx, $val\t# insert into vector(2I)" %} ins_encode %{ if (as_FloatRegister($dst$$reg) != as_FloatRegister($src$$reg)) { __ orr(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); } __ mov(as_FloatRegister($dst$$reg), __ T2S, $idx$$constant, $val$$Register); %} ins_pipe(pipe_slow); %} instruct insert4I(vecX dst, vecX src, iRegIorL2I val, immI idx) %{ predicate(n->bottom_type()->is_vect()->element_basic_type() == T_INT); match(Set dst (VectorInsert (Binary src val) idx)); ins_cost(INSN_COST); format %{ "orr $dst, T16B, $src, $src\n\t" "mov $dst, T4S, $idx, $val\t# insert into vector(4I)" %} ins_encode %{ if (as_FloatRegister($dst$$reg) != as_FloatRegister($src$$reg)) { __ orr(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); } __ mov(as_FloatRegister($dst$$reg), __ T4S, $idx$$constant, $val$$Register); %} ins_pipe(pipe_slow); %} instruct insert2L(vecX dst, vecX src, iRegL val, immI idx) %{ predicate(n->bottom_type()->is_vect()->element_basic_type() == T_LONG); match(Set dst (VectorInsert (Binary src val) idx)); ins_cost(INSN_COST); format %{ "orr $dst, T16B, $src, $src\n\t" "mov $dst, T2D, $idx, $val\t# insert into vector(2L)" %} ins_encode %{ if (as_FloatRegister($dst$$reg) != as_FloatRegister($src$$reg)) { __ orr(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); } __ mov(as_FloatRegister($dst$$reg), __ T2D, $idx$$constant, $val$$Register); %} ins_pipe(pipe_slow); %} instruct insert2F(vecD dst, vecD src, vRegF val, immI idx) %{ predicate(n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); match(Set dst (VectorInsert (Binary src val) idx)); ins_cost(INSN_COST); effect(TEMP_DEF dst); format %{ "orr $dst, T8B, $src, $src\n\t" "ins $dst, S, $val, $idx, 0\t# insert into vector(2F)" %} ins_encode %{ __ orr(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); __ ins(as_FloatRegister($dst$$reg), __ S, as_FloatRegister($val$$reg), $idx$$constant, 0); %} ins_pipe(pipe_slow); %} instruct insert4F(vecX dst, vecX src, vRegF val, immI idx) %{ predicate(n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); match(Set dst (VectorInsert (Binary src val) idx)); ins_cost(INSN_COST); effect(TEMP_DEF dst); format %{ "orr $dst, T16B, $src, $src\n\t" "ins $dst, S, $val, $idx, 0\t# insert into vector(4F)" %} ins_encode %{ __ orr(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); __ ins(as_FloatRegister($dst$$reg), __ S, as_FloatRegister($val$$reg), $idx$$constant, 0); %} ins_pipe(pipe_slow); %} instruct insert2D(vecX dst, vecX src, vRegD val, immI idx) %{ predicate(n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); match(Set dst (VectorInsert (Binary src val) idx)); ins_cost(INSN_COST); effect(TEMP_DEF dst); format %{ "orr $dst, T16B, $src, $src\n\t" "ins $dst, D, $val, $idx, 0\t# insert into vector(2D)" %} ins_encode %{ __ orr(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); __ ins(as_FloatRegister($dst$$reg), __ D, as_FloatRegister($val$$reg), $idx$$constant, 0); %} ins_pipe(pipe_slow); %} // ------------------------------ Vector extract --------------------------------- instruct extract8B(iRegINoSp dst, vecD src, immI idx) %{ predicate(n->in(1)->bottom_type()->is_vect()->length() == 8); match(Set dst (ExtractB src idx)); ins_cost(INSN_COST); format %{ "smov $dst, $src, B, $idx\t# extract from vector(8B)" %} ins_encode %{ __ smov($dst$$Register, as_FloatRegister($src$$reg), __ B, $idx$$constant); %} ins_pipe(pipe_class_default); %} instruct extract16B(iRegINoSp dst, vecX src, immI idx) %{ predicate(n->in(1)->bottom_type()->is_vect()->length() == 16); match(Set dst (ExtractB src idx)); ins_cost(INSN_COST); format %{ "smov $dst, $src, B, $idx\t# extract from vector(16B)" %} ins_encode %{ __ smov($dst$$Register, as_FloatRegister($src$$reg), __ B, $idx$$constant); %} ins_pipe(pipe_class_default); %} instruct extract4S(iRegINoSp dst, vecD src, immI idx) %{ predicate(n->in(1)->bottom_type()->is_vect()->length() == 4); match(Set dst (ExtractS src idx)); ins_cost(INSN_COST); format %{ "smov $dst, $src, H, $idx\t# extract from vector(4S)" %} ins_encode %{ __ smov($dst$$Register, as_FloatRegister($src$$reg), __ H, $idx$$constant); %} ins_pipe(pipe_class_default); %} instruct extract8S(iRegINoSp dst, vecX src, immI idx) %{ predicate(n->in(1)->bottom_type()->is_vect()->length() == 8); match(Set dst (ExtractS src idx)); ins_cost(INSN_COST); format %{ "smov $dst, $src, H, $idx\t# extract from vector(8S)" %} ins_encode %{ __ smov($dst$$Register, as_FloatRegister($src$$reg), __ H, $idx$$constant); %} ins_pipe(pipe_class_default); %} instruct extract2I(iRegINoSp dst, vecD src, immI idx) %{ predicate(n->in(1)->bottom_type()->is_vect()->length() == 2); match(Set dst (ExtractI src idx)); ins_cost(INSN_COST); format %{ "umov $dst, $src, S, $idx\t# extract from vector(2I)" %} ins_encode %{ __ umov($dst$$Register, as_FloatRegister($src$$reg), __ S, $idx$$constant); %} ins_pipe(pipe_class_default); %} instruct extract4I(iRegINoSp dst, vecX src, immI idx) %{ predicate(n->in(1)->bottom_type()->is_vect()->length() == 4); match(Set dst (ExtractI src idx)); ins_cost(INSN_COST); format %{ "umov $dst, $src, S, $idx\t# extract from vector(4I)" %} ins_encode %{ __ umov($dst$$Register, as_FloatRegister($src$$reg), __ S, $idx$$constant); %} ins_pipe(pipe_class_default); %} instruct extract2L(iRegLNoSp dst, vecX src, immI idx) %{ predicate(n->in(1)->bottom_type()->is_vect()->length() == 2); match(Set dst (ExtractL src idx)); ins_cost(INSN_COST); format %{ "umov $dst, $src, D, $idx\t# extract from vector(2L)" %} ins_encode %{ __ umov($dst$$Register, as_FloatRegister($src$$reg), __ D, $idx$$constant); %} ins_pipe(pipe_class_default); %} instruct extract2F(vRegF dst, vecD src, immI idx) %{ predicate(n->in(1)->bottom_type()->is_vect()->length() == 2); match(Set dst (ExtractF src idx)); ins_cost(INSN_COST); format %{ "ins $dst, S, $src, 0, $idx\t# extract from vector(2F)" %} ins_encode %{ __ ins(as_FloatRegister($dst$$reg), __ S, as_FloatRegister($src$$reg), 0, $idx$$constant); %} ins_pipe(pipe_class_default); %} instruct extract4F(vRegF dst, vecX src, immI idx) %{ predicate(n->in(1)->bottom_type()->is_vect()->length() == 4); match(Set dst (ExtractF src idx)); ins_cost(INSN_COST); format %{ "ins $dst, S, $src, 0, $idx\t# extract from vector(4F)" %} ins_encode %{ __ ins(as_FloatRegister($dst$$reg), __ S, as_FloatRegister($src$$reg), 0, $idx$$constant); %} ins_pipe(pipe_class_default); %} instruct extract2D(vRegD dst, vecX src, immI idx) %{ predicate(n->in(1)->bottom_type()->is_vect()->length() == 2); match(Set dst (ExtractD src idx)); ins_cost(INSN_COST); format %{ "ins $dst, D, $src, 0, $idx\t# extract from vector(2D)" %} ins_encode %{ __ ins(as_FloatRegister($dst$$reg), __ D, as_FloatRegister($src$$reg), 0, $idx$$constant); %} ins_pipe(pipe_class_default); %} // ------------------------------ Vector comparison --------------------------------- instruct vcmpD(vecD dst, vecD src1, vecD src2, immI cond) %{ predicate(n->as_Vector()->length_in_bytes() == 8); match(Set dst (VectorMaskCmp (Binary src1 src2) cond)); format %{ "vcmpD $dst, $src1, $src2\t# vector compare " %} ins_cost(INSN_COST); ins_encode %{ BasicType bt = vector_element_basic_type(this); assert(type2aelembytes(bt) != 8, "not supported"); __ neon_compare(as_FloatRegister($dst$$reg), bt, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg), (int)$cond$$constant, /*isQ*/ false); %} ins_pipe(vdop64); %} instruct vcmpX(vecX dst, vecX src1, vecX src2, immI cond) %{ predicate(n->as_Vector()->length_in_bytes() == 16); match(Set dst (VectorMaskCmp (Binary src1 src2) cond)); format %{ "vcmpX $dst, $src1, $src2\t# vector compare " %} ins_cost(INSN_COST); ins_encode %{ BasicType bt = vector_element_basic_type(this); __ neon_compare(as_FloatRegister($dst$$reg), bt, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg), (int)$cond$$constant, /*isQ*/ true); %} ins_pipe(vdop128); %} // ------------------------------ Vector mul ----------------------------------- instruct vmul2L(vecX dst, vecX src1, vecX src2, iRegLNoSp tmp1, iRegLNoSp tmp2) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (MulVL src1 src2)); ins_cost(INSN_COST); effect(TEMP tmp1, TEMP tmp2); format %{ "umov $tmp1, $src1, D, 0\n\t" "umov $tmp2, $src2, D, 0\n\t" "mul $tmp2, $tmp2, $tmp1\n\t" "mov $dst, T2D, 0, $tmp2\t# insert into vector(2L)\n\t" "umov $tmp1, $src1, D, 1\n\t" "umov $tmp2, $src2, D, 1\n\t" "mul $tmp2, $tmp2, $tmp1\n\t" "mov $dst, T2D, 1, $tmp2\t# insert into vector(2L)\n\t" %} ins_encode %{ __ umov($tmp1$$Register, as_FloatRegister($src1$$reg), __ D, 0); __ umov($tmp2$$Register, as_FloatRegister($src2$$reg), __ D, 0); __ mul(as_Register($tmp2$$reg), as_Register($tmp2$$reg), as_Register($tmp1$$reg)); __ mov(as_FloatRegister($dst$$reg), __ T2D, 0, $tmp2$$Register); __ umov($tmp1$$Register, as_FloatRegister($src1$$reg), __ D, 1); __ umov($tmp2$$Register, as_FloatRegister($src2$$reg), __ D, 1); __ mul(as_Register($tmp2$$reg), as_Register($tmp2$$reg), as_Register($tmp1$$reg)); __ mov(as_FloatRegister($dst$$reg), __ T2D, 1, $tmp2$$Register); %} ins_pipe(pipe_slow); %} // --------------------------------- Vector not -------------------------------- instruct vnot2I(vecD dst, vecD src, immI_M1 m1) %{ predicate(n->as_Vector()->length_in_bytes() == 8); match(Set dst (XorV src (ReplicateB m1))); match(Set dst (XorV src (ReplicateS m1))); match(Set dst (XorV src (ReplicateI m1))); ins_cost(INSN_COST); format %{ "not $dst, T8B, $src\t# vector (8B)" %} ins_encode %{ __ notr(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg)); %} ins_pipe(pipe_class_default); %} instruct vnot4I(vecX dst, vecX src, immI_M1 m1) %{ predicate(n->as_Vector()->length_in_bytes() == 16); match(Set dst (XorV src (ReplicateB m1))); match(Set dst (XorV src (ReplicateS m1))); match(Set dst (XorV src (ReplicateI m1))); ins_cost(INSN_COST); format %{ "not $dst, T16B, $src\t# vector (16B)" %} ins_encode %{ __ notr(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg)); %} ins_pipe(pipe_class_default); %} instruct vnot2L(vecX dst, vecX src, immL_M1 m1) %{ predicate(n->as_Vector()->length_in_bytes() == 16); match(Set dst (XorV src (ReplicateL m1))); ins_cost(INSN_COST); format %{ "not $dst, T16B, $src\t# vector (16B)" %} ins_encode %{ __ notr(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg)); %} ins_pipe(pipe_class_default); %} // ------------------------------ Vector and_not ------------------------------- instruct vand_not2I(vecD dst, vecD src1, vecD src2, immI_M1 m1) %{ predicate(n->as_Vector()->length_in_bytes() == 8); match(Set dst (AndV src1 (XorV src2 (ReplicateB m1)))); match(Set dst (AndV src1 (XorV src2 (ReplicateS m1)))); match(Set dst (AndV src1 (XorV src2 (ReplicateI m1)))); ins_cost(INSN_COST); format %{ "bic $dst, T8B, $src1, $src2\t# vector (8B)" %} ins_encode %{ __ bic(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_class_default); %} instruct vand_not4I(vecX dst, vecX src1, vecX src2, immI_M1 m1) %{ predicate(n->as_Vector()->length_in_bytes() == 16); match(Set dst (AndV src1 (XorV src2 (ReplicateB m1)))); match(Set dst (AndV src1 (XorV src2 (ReplicateS m1)))); match(Set dst (AndV src1 (XorV src2 (ReplicateI m1)))); ins_cost(INSN_COST); format %{ "bic $dst, T16B, $src1, $src2\t# vector (16B)" %} ins_encode %{ __ bic(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_class_default); %} instruct vand_not2L(vecX dst, vecX src1, vecX src2, immL_M1 m1) %{ predicate(n->as_Vector()->length_in_bytes() == 16); match(Set dst (AndV src1 (XorV src2 (ReplicateL m1)))); ins_cost(INSN_COST); format %{ "bic $dst, T16B, $src1, $src2\t# vector (16B)" %} ins_encode %{ __ bic(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_class_default); %} // ------------------------------ Vector max/min ------------------------------- instruct vmax8B(vecD dst, vecD src1, vecD src2) %{ predicate((n->as_Vector()->length() == 4 || n->as_Vector()->length() == 8) && n->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (MaxV src1 src2)); ins_cost(INSN_COST); format %{ "maxv $dst, T8B, $src1, $src2\t# vector (8B)" %} ins_encode %{ __ maxv(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop64); %} instruct vmax16B(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 16 && n->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (MaxV src1 src2)); ins_cost(INSN_COST); format %{ "maxv $dst, T16B, $src1, $src2\t# vector (16B)" %} ins_encode %{ __ maxv(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop128); %} instruct vmax4S(vecD dst, vecD src1, vecD src2) %{ predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (MaxV src1 src2)); ins_cost(INSN_COST); format %{ "maxv $dst, T4H, $src1, $src2\t# vector (4S)" %} ins_encode %{ __ maxv(as_FloatRegister($dst$$reg), __ T4H, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop64); %} instruct vmax8S(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 8 && n->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (MaxV src1 src2)); ins_cost(INSN_COST); format %{ "maxv $dst, T8H, $src1, $src2\t# vector (8S)" %} ins_encode %{ __ maxv(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop128); %} instruct vmax2I(vecD dst, vecD src1, vecD src2) %{ predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_INT); match(Set dst (MaxV src1 src2)); ins_cost(INSN_COST); format %{ "maxv $dst, T2S, $src1, $src2\t# vector (2I)" %} ins_encode %{ __ maxv(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop64); %} instruct vmax4I(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_INT); match(Set dst (MaxV src1 src2)); ins_cost(INSN_COST); format %{ "maxv $dst, T4S, $src1, $src2\t# vector (4I)" %} ins_encode %{ __ maxv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop128); %} instruct vmin8B(vecD dst, vecD src1, vecD src2) %{ predicate((n->as_Vector()->length() == 4 || n->as_Vector()->length() == 8) && n->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (MinV src1 src2)); ins_cost(INSN_COST); format %{ "minv $dst, T8B, $src1, $src2\t# vector (8B)" %} ins_encode %{ __ minv(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop64); %} instruct vmin16B(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 16 && n->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (MinV src1 src2)); ins_cost(INSN_COST); format %{ "minv $dst, T16B, $src1, $src2\t# vector (16B)" %} ins_encode %{ __ minv(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop128); %} instruct vmin4S(vecD dst, vecD src1, vecD src2) %{ predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (MinV src1 src2)); ins_cost(INSN_COST); format %{ "minv $dst, T4H, $src1, $src2\t# vector (4S)" %} ins_encode %{ __ minv(as_FloatRegister($dst$$reg), __ T4H, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop64); %} instruct vmin8S(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 8 && n->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (MinV src1 src2)); ins_cost(INSN_COST); format %{ "minv $dst, T8H, $src1, $src2\t# vector (8S)" %} ins_encode %{ __ minv(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop128); %} instruct vmin2I(vecD dst, vecD src1, vecD src2) %{ predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_INT); match(Set dst (MinV src1 src2)); ins_cost(INSN_COST); format %{ "minv $dst, T2S, $src1, $src2\t# vector (2I)" %} ins_encode %{ __ minv(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop64); %} instruct vmin4I(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_INT); match(Set dst (MinV src1 src2)); ins_cost(INSN_COST); format %{ "minv $dst, T4S, $src1, $src2\t# vector (4I)" %} ins_encode %{ __ minv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop128); %} instruct vmax2L(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_LONG); match(Set dst (MaxV src1 src2)); ins_cost(INSN_COST); effect(TEMP dst); format %{ "cmgt $dst, T2D, $src1, $src2\t# vector (2L)\n\t" "bsl $dst, T16B, $src1, $src2\t# vector (16B)" %} ins_encode %{ __ cmgt(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); __ bsl(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop128); %} instruct vmin2L(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_LONG); match(Set dst (MinV src1 src2)); ins_cost(INSN_COST); effect(TEMP dst); format %{ "cmgt $dst, T2D, $src1, $src2\t# vector (2L)\n\t" "bsl $dst, T16B, $src2, $src1\t# vector (16B)" %} ins_encode %{ __ cmgt(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); __ bsl(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src2$$reg), as_FloatRegister($src1$$reg)); %} ins_pipe(vdop128); %} // --------------------------------- blend (bsl) ---------------------------- instruct vbsl8B(vecD dst, vecD src1, vecD src2) %{ predicate(n->as_Vector()->length_in_bytes() == 8); match(Set dst (VectorBlend (Binary src1 src2) dst)); ins_cost(INSN_COST); format %{ "bsl $dst, T8B, $src2, $src1\t# vector (8B)" %} ins_encode %{ __ bsl(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src2$$reg), as_FloatRegister($src1$$reg)); %} ins_pipe(vlogical64); %} instruct vbsl16B(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length_in_bytes() == 16); match(Set dst (VectorBlend (Binary src1 src2) dst)); ins_cost(INSN_COST); format %{ "bsl $dst, T16B, $src2, $src1\t# vector (16B)" %} ins_encode %{ __ bsl(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src2$$reg), as_FloatRegister($src1$$reg)); %} ins_pipe(vlogical128); %} // --------------------------------- Load/store Mask ---------------------------- instruct loadmask8B(vecD dst, vecD src ) %{ predicate(n->as_Vector()->length() == 8 && n->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (VectorLoadMask src )); ins_cost(INSN_COST); format %{ "negr $dst, T8B, $src\t# load mask (8B to 8B)" %} ins_encode %{ __ negr(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg)); %} ins_pipe(pipe_class_default); %} instruct loadmask16B(vecX dst, vecX src ) %{ predicate(n->as_Vector()->length() == 16 && n->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (VectorLoadMask src )); ins_cost(INSN_COST); format %{ "negr $dst, T16B, $src\t# load mask (16B to 16B)" %} ins_encode %{ __ negr(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg)); %} ins_pipe(pipe_class_default); %} instruct storemask8B(vecD dst, vecD src , immI_1 size) %{ predicate(n->as_Vector()->length() == 8); match(Set dst (VectorStoreMask src size)); ins_cost(INSN_COST); format %{ "negr $dst, T8B, $src\t# store mask (8B to 8B)" %} ins_encode %{ __ negr(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg)); %} ins_pipe(pipe_class_default); %} instruct storemask16B(vecX dst, vecX src , immI_1 size) %{ predicate(n->as_Vector()->length() == 16); match(Set dst (VectorStoreMask src size)); ins_cost(INSN_COST); format %{ "negr $dst, T16B, $src\t# store mask (16B to 16B)" %} ins_encode %{ __ negr(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg)); %} ins_pipe(pipe_class_default); %} instruct loadmask4S(vecD dst, vecD src ) %{ predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (VectorLoadMask src )); ins_cost(INSN_COST); format %{ "uxtl $dst, T8H, $src, T8B\n\t" "negr $dst, T8H, $dst\t# load mask (4B to 4H)" %} ins_encode %{ __ uxtl(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src$$reg), __ T8B); __ negr(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($dst$$reg)); %} ins_pipe(pipe_slow); %} instruct loadmask8S(vecX dst, vecD src ) %{ predicate(n->as_Vector()->length() == 8 && n->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (VectorLoadMask src )); ins_cost(INSN_COST); format %{ "uxtl $dst, T8H, $src, T8B\n\t" "negr $dst, T8H, $dst\t# load mask (8B to 8H)" %} ins_encode %{ __ uxtl(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src$$reg), __ T8B); __ negr(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($dst$$reg)); %} ins_pipe(pipe_slow); %} instruct storemask4S(vecD dst, vecD src , immI_2 size) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (VectorStoreMask src size)); ins_cost(INSN_COST); format %{ "xtn $dst, T8B, $src, T8H\n\t" "negr $dst, T8B, $dst\t# store mask (4H to 4B)" %} ins_encode %{ __ xtn(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg), __ T8H); __ negr(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($dst$$reg)); %} ins_pipe(pipe_slow); %} instruct storemask8S(vecD dst, vecX src , immI_2 size) %{ predicate(n->as_Vector()->length() == 8); match(Set dst (VectorStoreMask src size)); ins_cost(INSN_COST); format %{ "xtn $dst, T8B, $src, T8H\n\t" "negr $dst, T8B, $dst\t# store mask (8H to 8B)" %} ins_encode %{ __ xtn(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg), __ T8H); __ negr(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($dst$$reg)); %} ins_pipe(pipe_slow); %} instruct loadmask2I(vecD dst, vecD src ) %{ predicate(n->as_Vector()->length() == 2 && (n->bottom_type()->is_vect()->element_basic_type() == T_INT || n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT)); match(Set dst (VectorLoadMask src )); ins_cost(INSN_COST); format %{ "uxtl $dst, T8H, $src, T8B\t# 2B to 2H\n\t" "uxtl $dst, T4S, $dst, T4H\t# 2H to 2S\n\t" "negr $dst, T4S, $dst\t# load mask (2B to 2S)" %} ins_encode %{ __ uxtl(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src$$reg), __ T8B); __ uxtl(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($dst$$reg), __ T4H); __ negr(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($dst$$reg)); %} ins_pipe(pipe_slow); %} instruct loadmask4I(vecX dst, vecD src ) %{ predicate(n->as_Vector()->length() == 4 && (n->bottom_type()->is_vect()->element_basic_type() == T_INT || n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT)); match(Set dst (VectorLoadMask src )); ins_cost(INSN_COST); format %{ "uxtl $dst, T8H, $src, T8B\t# 4B to 4H\n\t" "uxtl $dst, T4S, $dst, T4H\t# 4H to 4S\n\t" "negr $dst, T4S, $dst\t# load mask (4B to 4S)" %} ins_encode %{ __ uxtl(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src$$reg), __ T8B); __ uxtl(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($dst$$reg), __ T4H); __ negr(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($dst$$reg)); %} ins_pipe(pipe_slow); %} instruct storemask2I(vecD dst, vecD src , immI_4 size) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (VectorStoreMask src size)); ins_cost(INSN_COST); format %{ "xtn $dst, T4H, $src, T4S\t# 2S to 2H\n\t" "xtn $dst, T8B, $dst, T8H\t# 2H to 2B\n\t" "negr $dst, T8B, $dst\t# store mask (2S to 2B)" %} ins_encode %{ __ xtn(as_FloatRegister($dst$$reg), __ T4H, as_FloatRegister($src$$reg), __ T4S); __ xtn(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($dst$$reg), __ T8H); __ negr(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($dst$$reg)); %} ins_pipe(pipe_slow); %} instruct storemask4I(vecD dst, vecX src , immI_4 size) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (VectorStoreMask src size)); ins_cost(INSN_COST); format %{ "xtn $dst, T4H, $src, T4S\t# 4S to 4H\n\t" "xtn $dst, T8B, $dst, T8H\t# 4H to 4B\n\t" "negr $dst, T8B, $dst\t# store mask (4S to 4B)" %} ins_encode %{ __ xtn(as_FloatRegister($dst$$reg), __ T4H, as_FloatRegister($src$$reg), __ T4S); __ xtn(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($dst$$reg), __ T8H); __ negr(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($dst$$reg)); %} ins_pipe(pipe_slow); %} instruct loadmask2L(vecX dst, vecD src) %{ predicate(n->as_Vector()->length() == 2 && (n->bottom_type()->is_vect()->element_basic_type() == T_LONG || n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE)); match(Set dst (VectorLoadMask src)); ins_cost(INSN_COST); format %{ "uxtl $dst, T8H, $src, T8B\t# 2B to 2S\n\t" "uxtl $dst, T4S, $dst, T4H\t# 2S to 2I\n\t" "uxtl $dst, T2D, $dst, T2S\t# 2I to 2L\n\t" "neg $dst, T2D, $dst\t# load mask (2B to 2L)" %} ins_encode %{ __ uxtl(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src$$reg), __ T8B); __ uxtl(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($dst$$reg), __ T4H); __ uxtl(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($dst$$reg), __ T2S); __ negr(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($dst$$reg)); %} ins_pipe(pipe_slow); %} instruct storemask2L(vecD dst, vecX src, immI_8 size) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (VectorStoreMask src size)); ins_cost(INSN_COST); format %{ "xtn $dst, T2S, $src, T2D\t# 2L to 2I\n\t" "xtn $dst, T4H, $dst, T4S\t# 2I to 2S\n\t" "xtn $dst, T8B, $dst, T8H\t# 2S to 2B\n\t" "neg $dst, T8B, $dst\t# store mask (2L to 2B)" %} ins_encode %{ __ xtn(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src$$reg), __ T2D); __ xtn(as_FloatRegister($dst$$reg), __ T4H, as_FloatRegister($dst$$reg), __ T4S); __ xtn(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($dst$$reg), __ T8H); __ negr(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($dst$$reg)); %} ins_pipe(pipe_slow); %} // vector mask cast instruct vmaskcastD(vecD dst) %{ predicate(n->bottom_type()->is_vect()->length_in_bytes() == 8 && n->in(1)->bottom_type()->is_vect()->length_in_bytes() == 8 && n->bottom_type()->is_vect()->length() == n->in(1)->bottom_type()->is_vect()->length()); match(Set dst (VectorMaskCast dst)); ins_cost(0); format %{ "vmaskcast $dst\t# empty" %} ins_encode %{ // empty %} ins_pipe(pipe_class_empty); %} instruct vmaskcastX(vecX dst) %{ predicate(n->bottom_type()->is_vect()->length_in_bytes() == 16 && n->in(1)->bottom_type()->is_vect()->length_in_bytes() == 16 && n->bottom_type()->is_vect()->length() == n->in(1)->bottom_type()->is_vect()->length()); match(Set dst (VectorMaskCast dst)); ins_cost(0); format %{ "vmaskcast $dst\t# empty" %} ins_encode %{ // empty %} ins_pipe(pipe_class_empty); %} //-------------------------------- LOAD_IOTA_INDICES---------------------------------- instruct loadcon8B(vecD dst, immI0 src) %{ predicate((n->as_Vector()->length() == 2 || n->as_Vector()->length() == 4 || n->as_Vector()->length() == 8) && n->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (VectorLoadConst src)); ins_cost(INSN_COST); format %{ "ldr $dst, CONSTANT_MEMORY\t# load iota indices" %} ins_encode %{ __ lea(rscratch1, ExternalAddress(StubRoutines::aarch64::vector_iota_indices())); __ ldrd(as_FloatRegister($dst$$reg), rscratch1); %} ins_pipe(pipe_class_memory); %} instruct loadcon16B(vecX dst, immI0 src) %{ predicate(n->as_Vector()->length() == 16 && n->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (VectorLoadConst src)); ins_cost(INSN_COST); format %{ "ldr $dst, CONSTANT_MEMORY\t# load iota indices" %} ins_encode %{ __ lea(rscratch1, ExternalAddress(StubRoutines::aarch64::vector_iota_indices())); __ ldrq(as_FloatRegister($dst$$reg), rscratch1); %} ins_pipe(pipe_class_memory); %} //-------------------------------- LOAD_SHUFFLE ---------------------------------- instruct loadshuffle8B(vecD dst, vecD src) %{ predicate(n->as_Vector()->length() == 8 && n->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (VectorLoadShuffle src)); ins_cost(INSN_COST); format %{ "mov $dst, T8B, $src\t# get 8B shuffle" %} ins_encode %{ __ orr(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); %} ins_pipe(pipe_class_default); %} instruct loadshuffle16B(vecX dst, vecX src) %{ predicate(n->as_Vector()->length() == 16 && n->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (VectorLoadShuffle src)); ins_cost(INSN_COST); format %{ "mov $dst, T16B, $src\t# get 16B shuffle" %} ins_encode %{ __ orr(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); %} ins_pipe(pipe_class_default); %} instruct loadshuffle4S(vecD dst, vecD src) %{ predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (VectorLoadShuffle src)); ins_cost(INSN_COST); format %{ "uxtl $dst, T8H, $src, T8B\t# 4B to 4H" %} ins_encode %{ __ uxtl(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src$$reg), __ T8B); %} ins_pipe(pipe_class_default); %} instruct loadshuffle8S(vecX dst, vecD src) %{ predicate(n->as_Vector()->length() == 8 && n->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (VectorLoadShuffle src)); ins_cost(INSN_COST); format %{ "uxtl $dst, T8H, $src, T8B\t# 8B to 8H" %} ins_encode %{ __ uxtl(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src$$reg), __ T8B); %} ins_pipe(pipe_class_default); %} instruct loadshuffle4I(vecX dst, vecD src) %{ predicate(n->as_Vector()->length() == 4 && (n->bottom_type()->is_vect()->element_basic_type() == T_INT || n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT)); match(Set dst (VectorLoadShuffle src)); ins_cost(INSN_COST); format %{ "uxtl $dst, T8H, $src, T8B\t# 4B to 4H \n\t" "uxtl $dst, T4S, $dst, T4H\t# 4H to 4S" %} ins_encode %{ __ uxtl(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src$$reg), __ T8B); __ uxtl(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($dst$$reg), __ T4H); %} ins_pipe(pipe_slow); %} //-------------------------------- Rearrange ------------------------------------- // Here is an example that rearranges a NEON vector with 4 ints: // Rearrange V1 int[a0, a1, a2, a3] to V2 int[a2, a3, a0, a1] // 1. Get the indices of V1 and store them as Vi byte[0, 1, 2, 3]. // 2. Convert Vi byte[0, 1, 2, 3] to the indices of V2 and also store them as Vi byte[2, 3, 0, 1]. // 3. Unsigned extend Long Vi from byte[2, 3, 0, 1] to int[2, 3, 0, 1]. // 4. Multiply Vi int[2, 3, 0, 1] with constant int[0x04040404, 0x04040404, 0x04040404, 0x04040404] // and get tbl base Vm int[0x08080808, 0x0c0c0c0c, 0x00000000, 0x04040404]. // 5. Add Vm with constant int[0x03020100, 0x03020100, 0x03020100, 0x03020100] // and get tbl index Vm int[0x0b0a0908, 0x0f0e0d0c, 0x03020100, 0x07060504] // 6. Use Vm as index register, and use V1 as table register. // Then get V2 as the result by tbl NEON instructions. // Notes: // Step 1 matches VectorLoadConst. // Step 3 matches VectorLoadShuffle. // Step 4, 5, 6 match VectorRearrange. // For VectorRearrange short/int, the reason why such complex calculation is // required is because NEON tbl supports bytes table only, so for short/int, we // need to lookup 2/4 bytes as a group. For VectorRearrange long, we use bsl // to implement rearrange. instruct rearrange8B(vecD dst, vecD src, vecD shuffle) %{ predicate(n->as_Vector()->length() == 8 && n->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (VectorRearrange src shuffle)); ins_cost(INSN_COST); effect(TEMP_DEF dst); format %{ "tbl $dst, T8B, {$dst}, $shuffle\t# rearrange 8B" %} ins_encode %{ __ tbl(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg), 1, as_FloatRegister($shuffle$$reg)); %} ins_pipe(pipe_slow); %} instruct rearrange16B(vecX dst, vecX src, vecX shuffle) %{ predicate(n->as_Vector()->length() == 16 && n->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (VectorRearrange src shuffle)); ins_cost(INSN_COST); effect(TEMP_DEF dst); format %{ "tbl $dst, T16B, {$dst}, $shuffle\t# rearrange 16B" %} ins_encode %{ __ tbl(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg), 1, as_FloatRegister($shuffle$$reg)); %} ins_pipe(pipe_slow); %} instruct rearrange4S(vecD dst, vecD src, vecD shuffle, vecD tmp0, vecD tmp1) %{ predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (VectorRearrange src shuffle)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp0, TEMP tmp1); format %{ "mov $tmp0, T8B, CONSTANT\t# constant 0x0202020202020202\n\t" "mov $tmp1, T4H, CONSTANT\t# constant 0x0100010001000100\n\t" "mulv $dst, T4H, T4H, $shuffle, $tmp0\n\t" "addv $dst, T8B, T8B, $dst, $tmp1\n\t" "tbl $dst, T8B, {$src}, 1, $dst\t# rearrange 4S" %} ins_encode %{ __ mov(as_FloatRegister($tmp0$$reg), __ T8B, 0x02); __ mov(as_FloatRegister($tmp1$$reg), __ T4H, 0x0100); __ mulv(as_FloatRegister($dst$$reg), __ T4H, as_FloatRegister($shuffle$$reg), as_FloatRegister($tmp0$$reg)); __ addv(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($dst$$reg), as_FloatRegister($tmp1$$reg)); __ tbl(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg), 1, as_FloatRegister($dst$$reg)); %} ins_pipe(pipe_slow); %} instruct rearrange8S(vecX dst, vecX src, vecX shuffle, vecX tmp0, vecX tmp1) %{ predicate(n->as_Vector()->length() == 8 && n->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (VectorRearrange src shuffle)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp0, TEMP tmp1); format %{ "mov $tmp0, T16B, CONSTANT\t# constant 0x0202020202020202\n\t" "mov $tmp1, T8H, CONSTANT\t# constant 0x0100010001000100\n\t" "mulv $dst, T8H, T8H, $shuffle, $tmp0\n\t" "addv $dst, T16B, T16B, $dst, $tmp1\n\t" "tbl $dst, T16B, {$src}, 1, $dst\t# rearrange 8S" %} ins_encode %{ __ mov(as_FloatRegister($tmp0$$reg), __ T16B, 0x02); __ mov(as_FloatRegister($tmp1$$reg), __ T8H, 0x0100); __ mulv(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($shuffle$$reg), as_FloatRegister($tmp0$$reg)); __ addv(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($dst$$reg), as_FloatRegister($tmp1$$reg)); __ tbl(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg), 1, as_FloatRegister($dst$$reg)); %} ins_pipe(pipe_slow); %} instruct rearrange4I(vecX dst, vecX src, vecX shuffle, vecX tmp0, vecX tmp1) %{ predicate(n->as_Vector()->length() == 4 && (n->bottom_type()->is_vect()->element_basic_type() == T_INT || n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT)); match(Set dst (VectorRearrange src shuffle)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp0, TEMP tmp1); format %{ "mov $tmp0, T16B, CONSTANT\t# constant 0x0404040404040404\n\t" "mov $tmp1, T4S, CONSTANT\t# constant 0x0302010003020100\n\t" "mulv $dst, T4S, $shuffle, $tmp0\n\t" "addv $dst, T16B, $dst, $tmp1\n\t" "tbl $dst, T16B, {$src}, 1, $dst\t# rearrange 4I" %} ins_encode %{ __ mov(as_FloatRegister($tmp0$$reg), __ T16B, 0x04); __ mov(as_FloatRegister($tmp1$$reg), __ T4S, 0x03020100); __ mulv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($shuffle$$reg), as_FloatRegister($tmp0$$reg)); __ addv(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($dst$$reg), as_FloatRegister($tmp1$$reg)); __ tbl(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg), 1, as_FloatRegister($dst$$reg)); %} ins_pipe(pipe_slow); %} //-------------------------------- Anytrue/alltrue ----------------------------- instruct anytrue_in_mask8B(iRegINoSp dst, vecD src1, vecD src2, vecD tmp, rFlagsReg cr) %{ predicate(static_cast(n)->get_predicate() == BoolTest::ne); match(Set dst (VectorTest src1 src2 )); ins_cost(INSN_COST); effect(TEMP tmp, KILL cr); format %{ "addv $tmp, T8B, $src1\n\t" "umov $dst, $tmp, B, 0\n\t" "cmp $dst, 0\n\t" "cset $dst\t# anytrue 8B" %} ins_encode %{ // No need to use src2. __ addv(as_FloatRegister($tmp$$reg), __ T8B, as_FloatRegister($src1$$reg)); __ umov($dst$$Register, as_FloatRegister($tmp$$reg), __ B, 0); __ cmpw($dst$$Register, zr); __ csetw($dst$$Register, Assembler::NE); %} ins_pipe(pipe_slow); %} instruct anytrue_in_mask16B(iRegINoSp dst, vecX src1, vecX src2, vecX tmp, rFlagsReg cr) %{ predicate(static_cast(n)->get_predicate() == BoolTest::ne); match(Set dst (VectorTest src1 src2 )); ins_cost(INSN_COST); effect(TEMP tmp, KILL cr); format %{ "addv $tmp, T16B, $src1\n\t" "umov $dst, $tmp, B, 0\n\t" "cmp $dst, 0\n\t" "cset $dst\t# anytrue 16B" %} ins_encode %{ // No need to use src2. __ addv(as_FloatRegister($tmp$$reg), __ T16B, as_FloatRegister($src1$$reg)); __ umov($dst$$Register, as_FloatRegister($tmp$$reg), __ B, 0); __ cmpw($dst$$Register, zr); __ csetw($dst$$Register, Assembler::NE); %} ins_pipe(pipe_slow); %} instruct alltrue_in_mask8B(iRegINoSp dst, vecD src1, vecD src2, vecD tmp, rFlagsReg cr) %{ predicate(static_cast(n)->get_predicate() == BoolTest::overflow); match(Set dst (VectorTest src1 src2 )); ins_cost(INSN_COST); effect(TEMP tmp, KILL cr); format %{ "uminv $tmp, T8B, $src1\n\t" "umov $dst, $tmp, B, 0\n\t" "cmp $dst, 0xff\n\t" "cset $dst\t# alltrue 8B" %} ins_encode %{ // No need to use src2. __ uminv(as_FloatRegister($tmp$$reg), __ T8B, as_FloatRegister($src1$$reg)); __ umov($dst$$Register, as_FloatRegister($tmp$$reg), __ B, 0); __ cmpw($dst$$Register, 0xff); __ csetw($dst$$Register, Assembler::EQ); %} ins_pipe(pipe_slow); %} instruct alltrue_in_mask16B(iRegINoSp dst, vecX src1, vecX src2, vecX tmp, rFlagsReg cr) %{ predicate(static_cast(n)->get_predicate() == BoolTest::overflow); match(Set dst (VectorTest src1 src2 )); ins_cost(INSN_COST); effect(TEMP tmp, KILL cr); format %{ "uminv $tmp, T16B, $src1\n\t" "umov $dst, $tmp, B, 0\n\t" "cmp $dst, 0xff\n\t" "cset $dst\t# alltrue 16B" %} ins_encode %{ // No need to use src2. __ uminv(as_FloatRegister($tmp$$reg), __ T16B, as_FloatRegister($src1$$reg)); __ umov($dst$$Register, as_FloatRegister($tmp$$reg), __ B, 0); __ cmpw($dst$$Register, 0xff); __ csetw($dst$$Register, Assembler::EQ); %} ins_pipe(pipe_slow); %} // --------------------------------- ABS -------------------------------------- instruct vabs8B(vecD dst, vecD src) %{ predicate(n->as_Vector()->length() == 4 || n->as_Vector()->length() == 8); match(Set dst (AbsVB src)); ins_cost(INSN_COST); format %{ "abs $dst, T8B, $src\t# vector (8B)" %} ins_encode %{ __ absr(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg)); %} ins_pipe(vlogical64); %} instruct vabs16B(vecX dst, vecX src) %{ predicate(n->as_Vector()->length() == 16); match(Set dst (AbsVB src)); ins_cost(INSN_COST); format %{ "abs $dst, T16B, $src\t# vector (16B)" %} ins_encode %{ __ absr(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg)); %} ins_pipe(vlogical128); %} instruct vabs4S(vecD dst, vecD src) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (AbsVS src)); ins_cost(INSN_COST); format %{ "abs $dst, T4H, $src\t# vector (4H)" %} ins_encode %{ __ absr(as_FloatRegister($dst$$reg), __ T4H, as_FloatRegister($src$$reg)); %} ins_pipe(vlogical64); %} instruct vabs8S(vecX dst, vecX src) %{ predicate(n->as_Vector()->length() == 8); match(Set dst (AbsVS src)); ins_cost(INSN_COST); format %{ "abs $dst, T8H, $src\t# vector (8H)" %} ins_encode %{ __ absr(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src$$reg)); %} ins_pipe(vlogical128); %} instruct vabs2I(vecD dst, vecD src) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (AbsVI src)); ins_cost(INSN_COST); format %{ "abs $dst, T2S, $src\t# vector (2S)" %} ins_encode %{ __ absr(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src$$reg)); %} ins_pipe(vlogical64); %} instruct vabs4I(vecX dst, vecX src) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (AbsVI src)); ins_cost(INSN_COST); format %{ "abs $dst, T4S, $src\t# vector (4S)" %} ins_encode %{ __ absr(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src$$reg)); %} ins_pipe(vlogical128); %} instruct vabs2L(vecX dst, vecX src) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (AbsVL src)); ins_cost(INSN_COST); format %{ "abs $dst, T2D, $src\t# vector (2D)" %} ins_encode %{ __ absr(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src$$reg)); %} ins_pipe(vlogical128); %} instruct vabs2F(vecD dst, vecD src) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (AbsVF src)); ins_cost(INSN_COST * 3); format %{ "fabs $dst, T2S, $src\t# vector (2S)" %} ins_encode %{ __ fabs(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src$$reg)); %} ins_pipe(vunop_fp64); %} instruct vabs4F(vecX dst, vecX src) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (AbsVF src)); ins_cost(INSN_COST * 3); format %{ "fabs $dst, T4S, $src\t# vector (4S)" %} ins_encode %{ __ fabs(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src$$reg)); %} ins_pipe(vunop_fp128); %} instruct vabs2D(vecX dst, vecX src) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (AbsVD src)); ins_cost(INSN_COST * 3); format %{ "fabs $dst, T2D, $src\t# vector (2D)" %} ins_encode %{ __ fabs(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src$$reg)); %} ins_pipe(vunop_fp128); %} // --------------------------------- FABS DIFF -------------------------------- instruct vabd2F(vecD dst, vecD src1, vecD src2) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (AbsVF (SubVF src1 src2))); ins_cost(INSN_COST * 3); format %{ "fabd $dst, T2S, $src1, $src2\t# vector (2S)" %} ins_encode %{ __ fabd(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vunop_fp64); %} instruct vabd4F(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (AbsVF (SubVF src1 src2))); ins_cost(INSN_COST * 3); format %{ "fabd $dst, T4S, $src1, $src2\t# vector (4S)" %} ins_encode %{ __ fabd(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vunop_fp128); %} instruct vabd2D(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (AbsVD (SubVD src1 src2))); ins_cost(INSN_COST * 3); format %{ "fabd $dst, T2D, $src1, $src2\t# vector (2D)" %} ins_encode %{ __ fabd(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vunop_fp128); %} instruct replicate8B(vecD dst, iRegIorL2I src) %{ predicate(n->as_Vector()->length() == 4 || n->as_Vector()->length() == 8); match(Set dst (ReplicateB src)); ins_cost(INSN_COST); format %{ "dup $dst, $src\t# vector (8B)" %} ins_encode %{ __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($src$$reg)); %} ins_pipe(vdup_reg_reg64); %} instruct replicate16B(vecX dst, iRegIorL2I src) %{ predicate(UseSVE == 0 && n->as_Vector()->length() == 16); match(Set dst (ReplicateB src)); ins_cost(INSN_COST); format %{ "dup $dst, $src\t# vector (16B)" %} ins_encode %{ __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($src$$reg)); %} ins_pipe(vdup_reg_reg128); %} instruct replicate8B_imm(vecD dst, immI con) %{ predicate(n->as_Vector()->length() == 4 || n->as_Vector()->length() == 8); match(Set dst (ReplicateB con)); ins_cost(INSN_COST); format %{ "movi $dst, $con\t# vector (8B)" %} ins_encode %{ __ mov(as_FloatRegister($dst$$reg), __ T8B, $con$$constant & 0xff); %} ins_pipe(vmovi_reg_imm64); %} instruct replicate16B_imm(vecX dst, immI con) %{ predicate(UseSVE == 0 && n->as_Vector()->length() == 16); match(Set dst (ReplicateB con)); ins_cost(INSN_COST); format %{ "movi $dst, $con\t# vector (16B)" %} ins_encode %{ __ mov(as_FloatRegister($dst$$reg), __ T16B, $con$$constant & 0xff); %} ins_pipe(vmovi_reg_imm128); %} instruct replicate4S(vecD dst, iRegIorL2I src) %{ predicate(n->as_Vector()->length() == 2 || n->as_Vector()->length() == 4); match(Set dst (ReplicateS src)); ins_cost(INSN_COST); format %{ "dup $dst, $src\t# vector (4S)" %} ins_encode %{ __ dup(as_FloatRegister($dst$$reg), __ T4H, as_Register($src$$reg)); %} ins_pipe(vdup_reg_reg64); %} instruct replicate8S(vecX dst, iRegIorL2I src) %{ predicate(UseSVE == 0 && n->as_Vector()->length() == 8); match(Set dst (ReplicateS src)); ins_cost(INSN_COST); format %{ "dup $dst, $src\t# vector (8S)" %} ins_encode %{ __ dup(as_FloatRegister($dst$$reg), __ T8H, as_Register($src$$reg)); %} ins_pipe(vdup_reg_reg128); %} instruct replicate4S_imm(vecD dst, immI con) %{ predicate(n->as_Vector()->length() == 2 || n->as_Vector()->length() == 4); match(Set dst (ReplicateS con)); ins_cost(INSN_COST); format %{ "movi $dst, $con\t# vector (4H)" %} ins_encode %{ __ mov(as_FloatRegister($dst$$reg), __ T4H, $con$$constant & 0xffff); %} ins_pipe(vmovi_reg_imm64); %} instruct replicate8S_imm(vecX dst, immI con) %{ predicate(UseSVE == 0 && n->as_Vector()->length() == 8); match(Set dst (ReplicateS con)); ins_cost(INSN_COST); format %{ "movi $dst, $con\t# vector (8H)" %} ins_encode %{ __ mov(as_FloatRegister($dst$$reg), __ T8H, $con$$constant & 0xffff); %} ins_pipe(vmovi_reg_imm128); %} instruct replicate2I(vecD dst, iRegIorL2I src) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (ReplicateI src)); ins_cost(INSN_COST); format %{ "dup $dst, $src\t# vector (2I)" %} ins_encode %{ __ dup(as_FloatRegister($dst$$reg), __ T2S, as_Register($src$$reg)); %} ins_pipe(vdup_reg_reg64); %} instruct replicate4I(vecX dst, iRegIorL2I src) %{ predicate(UseSVE == 0 && n->as_Vector()->length() == 4); match(Set dst (ReplicateI src)); ins_cost(INSN_COST); format %{ "dup $dst, $src\t# vector (4I)" %} ins_encode %{ __ dup(as_FloatRegister($dst$$reg), __ T4S, as_Register($src$$reg)); %} ins_pipe(vdup_reg_reg128); %} instruct replicate2I_imm(vecD dst, immI con) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (ReplicateI con)); ins_cost(INSN_COST); format %{ "movi $dst, $con\t# vector (2I)" %} ins_encode %{ __ mov(as_FloatRegister($dst$$reg), __ T2S, $con$$constant); %} ins_pipe(vmovi_reg_imm64); %} instruct replicate4I_imm(vecX dst, immI con) %{ predicate(UseSVE == 0 && n->as_Vector()->length() == 4); match(Set dst (ReplicateI con)); ins_cost(INSN_COST); format %{ "movi $dst, $con\t# vector (4I)" %} ins_encode %{ __ mov(as_FloatRegister($dst$$reg), __ T4S, $con$$constant); %} ins_pipe(vmovi_reg_imm128); %} instruct replicate2L(vecX dst, iRegL src) %{ predicate(UseSVE == 0 && n->as_Vector()->length() == 2); match(Set dst (ReplicateL src)); ins_cost(INSN_COST); format %{ "dup $dst, $src\t# vector (2L)" %} ins_encode %{ __ dup(as_FloatRegister($dst$$reg), __ T2D, as_Register($src$$reg)); %} ins_pipe(vdup_reg_reg128); %} instruct replicate2L_zero(vecX dst, immI0 zero) %{ predicate(UseSVE == 0 && n->as_Vector()->length() == 2); match(Set dst (ReplicateI zero)); ins_cost(INSN_COST); format %{ "movi $dst, $zero\t# vector (4I)" %} ins_encode %{ __ eor(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg)); %} ins_pipe(vmovi_reg_imm128); %} instruct replicate2F(vecD dst, vRegF src) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (ReplicateF src)); ins_cost(INSN_COST); format %{ "dup $dst, $src\t# vector (2F)" %} ins_encode %{ __ dup(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src$$reg)); %} ins_pipe(vdup_reg_freg64); %} instruct replicate4F(vecX dst, vRegF src) %{ predicate(UseSVE == 0 && n->as_Vector()->length() == 4); match(Set dst (ReplicateF src)); ins_cost(INSN_COST); format %{ "dup $dst, $src\t# vector (4F)" %} ins_encode %{ __ dup(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src$$reg)); %} ins_pipe(vdup_reg_freg128); %} instruct replicate2D(vecX dst, vRegD src) %{ predicate(UseSVE == 0 && n->as_Vector()->length() == 2); match(Set dst (ReplicateD src)); ins_cost(INSN_COST); format %{ "dup $dst, $src\t# vector (2D)" %} ins_encode %{ __ dup(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src$$reg)); %} ins_pipe(vdup_reg_dreg128); %} // ====================REDUCTION ARITHMETIC==================================== instruct reduce_add2I(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, vecD vtmp, iRegINoSp itmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT); match(Set dst (AddReductionVI isrc vsrc)); ins_cost(INSN_COST); effect(TEMP vtmp, TEMP itmp); format %{ "addpv $vtmp, T2S, $vsrc, $vsrc\n\t" "umov $itmp, $vtmp, S, 0\n\t" "addw $dst, $itmp, $isrc\t# add reduction2I" %} ins_encode %{ __ addpv(as_FloatRegister($vtmp$$reg), __ T2S, as_FloatRegister($vsrc$$reg), as_FloatRegister($vsrc$$reg)); __ umov($itmp$$Register, as_FloatRegister($vtmp$$reg), __ S, 0); __ addw($dst$$Register, $itmp$$Register, $isrc$$Register); %} ins_pipe(pipe_class_default); %} instruct reduce_add4I(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, vecX vtmp, iRegINoSp itmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT); match(Set dst (AddReductionVI isrc vsrc)); ins_cost(INSN_COST); effect(TEMP vtmp, TEMP itmp); format %{ "addv $vtmp, T4S, $vsrc\n\t" "umov $itmp, $vtmp, S, 0\n\t" "addw $dst, $itmp, $isrc\t# add reduction4I" %} ins_encode %{ __ addv(as_FloatRegister($vtmp$$reg), __ T4S, as_FloatRegister($vsrc$$reg)); __ umov($itmp$$Register, as_FloatRegister($vtmp$$reg), __ S, 0); __ addw($dst$$Register, $itmp$$Register, $isrc$$Register); %} ins_pipe(pipe_class_default); %} instruct reduce_mul2I(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, iRegINoSp tmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT); match(Set dst (MulReductionVI isrc vsrc)); ins_cost(INSN_COST); effect(TEMP tmp, TEMP dst); format %{ "umov $tmp, $vsrc, S, 0\n\t" "mul $dst, $tmp, $isrc\n\t" "umov $tmp, $vsrc, S, 1\n\t" "mul $dst, $tmp, $dst\t# mul reduction2I" %} ins_encode %{ __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ S, 0); __ mul($dst$$Register, $tmp$$Register, $isrc$$Register); __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ S, 1); __ mul($dst$$Register, $tmp$$Register, $dst$$Register); %} ins_pipe(pipe_class_default); %} instruct reduce_mul4I(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, vecX vtmp, iRegINoSp itmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT); match(Set dst (MulReductionVI isrc vsrc)); ins_cost(INSN_COST); effect(TEMP vtmp, TEMP itmp, TEMP dst); format %{ "ins $vtmp, D, $vsrc, 0, 1\n\t" "mulv $vtmp, T2S, $vtmp, $vsrc\n\t" "umov $itmp, $vtmp, S, 0\n\t" "mul $dst, $itmp, $isrc\n\t" "umov $itmp, $vtmp, S, 1\n\t" "mul $dst, $itmp, $dst\t# mul reduction4I" %} ins_encode %{ __ ins(as_FloatRegister($vtmp$$reg), __ D, as_FloatRegister($vsrc$$reg), 0, 1); __ mulv(as_FloatRegister($vtmp$$reg), __ T2S, as_FloatRegister($vtmp$$reg), as_FloatRegister($vsrc$$reg)); __ umov($itmp$$Register, as_FloatRegister($vtmp$$reg), __ S, 0); __ mul($dst$$Register, $itmp$$Register, $isrc$$Register); __ umov($itmp$$Register, as_FloatRegister($vtmp$$reg), __ S, 1); __ mul($dst$$Register, $itmp$$Register, $dst$$Register); %} ins_pipe(pipe_class_default); %} instruct reduce_add2F(vRegF dst, vRegF fsrc, vecD vsrc, vecD tmp) %{ match(Set dst (AddReductionVF fsrc vsrc)); ins_cost(INSN_COST); effect(TEMP tmp, TEMP dst); format %{ "fadds $dst, $fsrc, $vsrc\n\t" "ins $tmp, S, $vsrc, 0, 1\n\t" "fadds $dst, $dst, $tmp\t# add reduction2F" %} ins_encode %{ __ fadds(as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg), as_FloatRegister($vsrc$$reg)); __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($vsrc$$reg), 0, 1); __ fadds(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_class_default); %} instruct reduce_add4F(vRegF dst, vRegF fsrc, vecX vsrc, vecX tmp) %{ match(Set dst (AddReductionVF fsrc vsrc)); ins_cost(INSN_COST); effect(TEMP tmp, TEMP dst); format %{ "fadds $dst, $fsrc, $vsrc\n\t" "ins $tmp, S, $vsrc, 0, 1\n\t" "fadds $dst, $dst, $tmp\n\t" "ins $tmp, S, $vsrc, 0, 2\n\t" "fadds $dst, $dst, $tmp\n\t" "ins $tmp, S, $vsrc, 0, 3\n\t" "fadds $dst, $dst, $tmp\t# add reduction4F" %} ins_encode %{ __ fadds(as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg), as_FloatRegister($vsrc$$reg)); __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($vsrc$$reg), 0, 1); __ fadds(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($vsrc$$reg), 0, 2); __ fadds(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($vsrc$$reg), 0, 3); __ fadds(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_class_default); %} instruct reduce_mul2F(vRegF dst, vRegF fsrc, vecD vsrc, vecD tmp) %{ match(Set dst (MulReductionVF fsrc vsrc)); ins_cost(INSN_COST); effect(TEMP tmp, TEMP dst); format %{ "fmuls $dst, $fsrc, $vsrc\n\t" "ins $tmp, S, $vsrc, 0, 1\n\t" "fmuls $dst, $dst, $tmp\t# mul reduction2F" %} ins_encode %{ __ fmuls(as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg), as_FloatRegister($vsrc$$reg)); __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($vsrc$$reg), 0, 1); __ fmuls(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_class_default); %} instruct reduce_mul4F(vRegF dst, vRegF fsrc, vecX vsrc, vecX tmp) %{ match(Set dst (MulReductionVF fsrc vsrc)); ins_cost(INSN_COST); effect(TEMP tmp, TEMP dst); format %{ "fmuls $dst, $fsrc, $vsrc\n\t" "ins $tmp, S, $vsrc, 0, 1\n\t" "fmuls $dst, $dst, $tmp\n\t" "ins $tmp, S, $vsrc, 0, 2\n\t" "fmuls $dst, $dst, $tmp\n\t" "ins $tmp, S, $vsrc, 0, 3\n\t" "fmuls $dst, $dst, $tmp\t# mul reduction4F" %} ins_encode %{ __ fmuls(as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg), as_FloatRegister($vsrc$$reg)); __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($vsrc$$reg), 0, 1); __ fmuls(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($vsrc$$reg), 0, 2); __ fmuls(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($vsrc$$reg), 0, 3); __ fmuls(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_class_default); %} instruct reduce_add2D(vRegD dst, vRegD dsrc, vecX vsrc, vecX tmp) %{ match(Set dst (AddReductionVD dsrc vsrc)); ins_cost(INSN_COST); effect(TEMP tmp, TEMP dst); format %{ "faddd $dst, $dsrc, $vsrc\n\t" "ins $tmp, D, $vsrc, 0, 1\n\t" "faddd $dst, $dst, $tmp\t# add reduction2D" %} ins_encode %{ __ faddd(as_FloatRegister($dst$$reg), as_FloatRegister($dsrc$$reg), as_FloatRegister($vsrc$$reg)); __ ins(as_FloatRegister($tmp$$reg), __ D, as_FloatRegister($vsrc$$reg), 0, 1); __ faddd(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_class_default); %} instruct reduce_mul2D(vRegD dst, vRegD dsrc, vecX vsrc, vecX tmp) %{ match(Set dst (MulReductionVD dsrc vsrc)); ins_cost(INSN_COST); effect(TEMP tmp, TEMP dst); format %{ "fmuld $dst, $dsrc, $vsrc\n\t" "ins $tmp, D, $vsrc, 0, 1\n\t" "fmuld $dst, $dst, $tmp\t# mul reduction2D" %} ins_encode %{ __ fmuld(as_FloatRegister($dst$$reg), as_FloatRegister($dsrc$$reg), as_FloatRegister($vsrc$$reg)); __ ins(as_FloatRegister($tmp$$reg), __ D, as_FloatRegister($vsrc$$reg), 0, 1); __ fmuld(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_class_default); %} // ====================VECTOR ARITHMETIC======================================= // --------------------------------- ADD -------------------------------------- instruct vadd8B(vecD dst, vecD src1, vecD src2) %{ predicate(n->as_Vector()->length() == 4 || n->as_Vector()->length() == 8); match(Set dst (AddVB src1 src2)); ins_cost(INSN_COST); format %{ "addv $dst,$src1,$src2\t# vector (8B)" %} ins_encode %{ __ addv(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop64); %} instruct vadd16B(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 16); match(Set dst (AddVB src1 src2)); ins_cost(INSN_COST); format %{ "addv $dst,$src1,$src2\t# vector (16B)" %} ins_encode %{ __ addv(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop128); %} instruct vadd4S(vecD dst, vecD src1, vecD src2) %{ predicate(n->as_Vector()->length() == 2 || n->as_Vector()->length() == 4); match(Set dst (AddVS src1 src2)); ins_cost(INSN_COST); format %{ "addv $dst,$src1,$src2\t# vector (4H)" %} ins_encode %{ __ addv(as_FloatRegister($dst$$reg), __ T4H, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop64); %} instruct vadd8S(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 8); match(Set dst (AddVS src1 src2)); ins_cost(INSN_COST); format %{ "addv $dst,$src1,$src2\t# vector (8H)" %} ins_encode %{ __ addv(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop128); %} instruct vadd2I(vecD dst, vecD src1, vecD src2) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (AddVI src1 src2)); ins_cost(INSN_COST); format %{ "addv $dst,$src1,$src2\t# vector (2S)" %} ins_encode %{ __ addv(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop64); %} instruct vadd4I(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (AddVI src1 src2)); ins_cost(INSN_COST); format %{ "addv $dst,$src1,$src2\t# vector (4S)" %} ins_encode %{ __ addv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop128); %} instruct vadd2L(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (AddVL src1 src2)); ins_cost(INSN_COST); format %{ "addv $dst,$src1,$src2\t# vector (2L)" %} ins_encode %{ __ addv(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop128); %} instruct vadd2F(vecD dst, vecD src1, vecD src2) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (AddVF src1 src2)); ins_cost(INSN_COST); format %{ "fadd $dst,$src1,$src2\t# vector (2S)" %} ins_encode %{ __ fadd(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop_fp64); %} instruct vadd4F(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (AddVF src1 src2)); ins_cost(INSN_COST); format %{ "fadd $dst,$src1,$src2\t# vector (4S)" %} ins_encode %{ __ fadd(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop_fp128); %} instruct vadd2D(vecX dst, vecX src1, vecX src2) %{ match(Set dst (AddVD src1 src2)); ins_cost(INSN_COST); format %{ "fadd $dst,$src1,$src2\t# vector (2D)" %} ins_encode %{ __ fadd(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop_fp128); %} // --------------------------------- SUB -------------------------------------- instruct vsub8B(vecD dst, vecD src1, vecD src2) %{ predicate(n->as_Vector()->length() == 4 || n->as_Vector()->length() == 8); match(Set dst (SubVB src1 src2)); ins_cost(INSN_COST); format %{ "subv $dst,$src1,$src2\t# vector (8B)" %} ins_encode %{ __ subv(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop64); %} instruct vsub16B(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 16); match(Set dst (SubVB src1 src2)); ins_cost(INSN_COST); format %{ "subv $dst,$src1,$src2\t# vector (16B)" %} ins_encode %{ __ subv(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop128); %} instruct vsub4S(vecD dst, vecD src1, vecD src2) %{ predicate(n->as_Vector()->length() == 2 || n->as_Vector()->length() == 4); match(Set dst (SubVS src1 src2)); ins_cost(INSN_COST); format %{ "subv $dst,$src1,$src2\t# vector (4H)" %} ins_encode %{ __ subv(as_FloatRegister($dst$$reg), __ T4H, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop64); %} instruct vsub8S(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 8); match(Set dst (SubVS src1 src2)); ins_cost(INSN_COST); format %{ "subv $dst,$src1,$src2\t# vector (8H)" %} ins_encode %{ __ subv(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop128); %} instruct vsub2I(vecD dst, vecD src1, vecD src2) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (SubVI src1 src2)); ins_cost(INSN_COST); format %{ "subv $dst,$src1,$src2\t# vector (2S)" %} ins_encode %{ __ subv(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop64); %} instruct vsub4I(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (SubVI src1 src2)); ins_cost(INSN_COST); format %{ "subv $dst,$src1,$src2\t# vector (4S)" %} ins_encode %{ __ subv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop128); %} instruct vsub2L(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (SubVL src1 src2)); ins_cost(INSN_COST); format %{ "subv $dst,$src1,$src2\t# vector (2L)" %} ins_encode %{ __ subv(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop128); %} instruct vsub2F(vecD dst, vecD src1, vecD src2) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (SubVF src1 src2)); ins_cost(INSN_COST); format %{ "fsub $dst,$src1,$src2\t# vector (2S)" %} ins_encode %{ __ fsub(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop_fp64); %} instruct vsub4F(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (SubVF src1 src2)); ins_cost(INSN_COST); format %{ "fsub $dst,$src1,$src2\t# vector (4S)" %} ins_encode %{ __ fsub(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop_fp128); %} instruct vsub2D(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (SubVD src1 src2)); ins_cost(INSN_COST); format %{ "fsub $dst,$src1,$src2\t# vector (2D)" %} ins_encode %{ __ fsub(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop_fp128); %} // --------------------------------- MUL -------------------------------------- instruct vmul8B(vecD dst, vecD src1, vecD src2) %{ predicate(n->as_Vector()->length() == 4 || n->as_Vector()->length() == 8); match(Set dst (MulVB src1 src2)); ins_cost(INSN_COST); format %{ "mulv $dst,$src1,$src2\t# vector (8B)" %} ins_encode %{ __ mulv(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vmul64); %} instruct vmul16B(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 16); match(Set dst (MulVB src1 src2)); ins_cost(INSN_COST); format %{ "mulv $dst,$src1,$src2\t# vector (16B)" %} ins_encode %{ __ mulv(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vmul128); %} instruct vmul4S(vecD dst, vecD src1, vecD src2) %{ predicate(n->as_Vector()->length() == 2 || n->as_Vector()->length() == 4); match(Set dst (MulVS src1 src2)); ins_cost(INSN_COST); format %{ "mulv $dst,$src1,$src2\t# vector (4H)" %} ins_encode %{ __ mulv(as_FloatRegister($dst$$reg), __ T4H, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vmul64); %} instruct vmul8S(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 8); match(Set dst (MulVS src1 src2)); ins_cost(INSN_COST); format %{ "mulv $dst,$src1,$src2\t# vector (8H)" %} ins_encode %{ __ mulv(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vmul128); %} instruct vmul2I(vecD dst, vecD src1, vecD src2) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (MulVI src1 src2)); ins_cost(INSN_COST); format %{ "mulv $dst,$src1,$src2\t# vector (2S)" %} ins_encode %{ __ mulv(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vmul64); %} instruct vmul4I(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (MulVI src1 src2)); ins_cost(INSN_COST); format %{ "mulv $dst,$src1,$src2\t# vector (4S)" %} ins_encode %{ __ mulv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vmul128); %} instruct vmul2F(vecD dst, vecD src1, vecD src2) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (MulVF src1 src2)); ins_cost(INSN_COST); format %{ "fmul $dst,$src1,$src2\t# vector (2S)" %} ins_encode %{ __ fmul(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vmuldiv_fp64); %} instruct vmul4F(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (MulVF src1 src2)); ins_cost(INSN_COST); format %{ "fmul $dst,$src1,$src2\t# vector (4S)" %} ins_encode %{ __ fmul(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vmuldiv_fp128); %} instruct vmul2D(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (MulVD src1 src2)); ins_cost(INSN_COST); format %{ "fmul $dst,$src1,$src2\t# vector (2D)" %} ins_encode %{ __ fmul(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vmuldiv_fp128); %} // --------------------------------- MLA -------------------------------------- instruct vmla4S(vecD dst, vecD src1, vecD src2) %{ predicate(n->as_Vector()->length() == 2 || n->as_Vector()->length() == 4); match(Set dst (AddVS dst (MulVS src1 src2))); ins_cost(INSN_COST); format %{ "mlav $dst,$src1,$src2\t# vector (4H)" %} ins_encode %{ __ mlav(as_FloatRegister($dst$$reg), __ T4H, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vmla64); %} instruct vmla8S(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 8); match(Set dst (AddVS dst (MulVS src1 src2))); ins_cost(INSN_COST); format %{ "mlav $dst,$src1,$src2\t# vector (8H)" %} ins_encode %{ __ mlav(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vmla128); %} instruct vmla2I(vecD dst, vecD src1, vecD src2) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (AddVI dst (MulVI src1 src2))); ins_cost(INSN_COST); format %{ "mlav $dst,$src1,$src2\t# vector (2S)" %} ins_encode %{ __ mlav(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vmla64); %} instruct vmla4I(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (AddVI dst (MulVI src1 src2))); ins_cost(INSN_COST); format %{ "mlav $dst,$src1,$src2\t# vector (4S)" %} ins_encode %{ __ mlav(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vmla128); %} // dst + src1 * src2 instruct vmla2F(vecD dst, vecD src1, vecD src2) %{ predicate(UseFMA && n->as_Vector()->length() == 2); match(Set dst (FmaVF dst (Binary src1 src2))); ins_cost(INSN_COST); format %{ "fmla $dst,$src1,$src2\t# vector (2S)" %} ins_encode %{ __ fmla(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vmuldiv_fp64); %} // dst + src1 * src2 instruct vmla4F(vecX dst, vecX src1, vecX src2) %{ predicate(UseFMA && n->as_Vector()->length() == 4); match(Set dst (FmaVF dst (Binary src1 src2))); ins_cost(INSN_COST); format %{ "fmla $dst,$src1,$src2\t# vector (4S)" %} ins_encode %{ __ fmla(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vmuldiv_fp128); %} // dst + src1 * src2 instruct vmla2D(vecX dst, vecX src1, vecX src2) %{ predicate(UseFMA && n->as_Vector()->length() == 2); match(Set dst (FmaVD dst (Binary src1 src2))); ins_cost(INSN_COST); format %{ "fmla $dst,$src1,$src2\t# vector (2D)" %} ins_encode %{ __ fmla(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vmuldiv_fp128); %} // --------------------------------- MLS -------------------------------------- instruct vmls4S(vecD dst, vecD src1, vecD src2) %{ predicate(n->as_Vector()->length() == 2 || n->as_Vector()->length() == 4); match(Set dst (SubVS dst (MulVS src1 src2))); ins_cost(INSN_COST); format %{ "mlsv $dst,$src1,$src2\t# vector (4H)" %} ins_encode %{ __ mlsv(as_FloatRegister($dst$$reg), __ T4H, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vmla64); %} instruct vmls8S(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 8); match(Set dst (SubVS dst (MulVS src1 src2))); ins_cost(INSN_COST); format %{ "mlsv $dst,$src1,$src2\t# vector (8H)" %} ins_encode %{ __ mlsv(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vmla128); %} instruct vmls2I(vecD dst, vecD src1, vecD src2) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (SubVI dst (MulVI src1 src2))); ins_cost(INSN_COST); format %{ "mlsv $dst,$src1,$src2\t# vector (2S)" %} ins_encode %{ __ mlsv(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vmla64); %} instruct vmls4I(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (SubVI dst (MulVI src1 src2))); ins_cost(INSN_COST); format %{ "mlsv $dst,$src1,$src2\t# vector (4S)" %} ins_encode %{ __ mlsv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vmla128); %} // dst - src1 * src2 instruct vmls2F(vecD dst, vecD src1, vecD src2) %{ predicate(UseFMA && n->as_Vector()->length() == 2); match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); ins_cost(INSN_COST); format %{ "fmls $dst,$src1,$src2\t# vector (2S)" %} ins_encode %{ __ fmls(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vmuldiv_fp64); %} // dst - src1 * src2 instruct vmls4F(vecX dst, vecX src1, vecX src2) %{ predicate(UseFMA && n->as_Vector()->length() == 4); match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); ins_cost(INSN_COST); format %{ "fmls $dst,$src1,$src2\t# vector (4S)" %} ins_encode %{ __ fmls(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vmuldiv_fp128); %} // dst - src1 * src2 instruct vmls2D(vecX dst, vecX src1, vecX src2) %{ predicate(UseFMA && n->as_Vector()->length() == 2); match(Set dst (FmaVD dst (Binary (NegVD src1) src2))); match(Set dst (FmaVD dst (Binary src1 (NegVD src2)))); ins_cost(INSN_COST); format %{ "fmls $dst,$src1,$src2\t# vector (2D)" %} ins_encode %{ __ fmls(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vmuldiv_fp128); %} // --------------- Vector Multiply-Add Shorts into Integer -------------------- instruct vmuladdS2I(vecX dst, vecX src1, vecX src2, vecX tmp) %{ predicate(n->in(1)->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (MulAddVS2VI src1 src2)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); format %{ "smullv $tmp, $src1, $src2\t# vector (4H)\n\t" "smullv $dst, $src1, $src2\t# vector (8H)\n\t" "addpv $dst, $tmp, $dst\t# vector (4S)\n\t" %} ins_encode %{ __ smullv(as_FloatRegister($tmp$$reg), __ T4H, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); __ smullv(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); __ addpv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($tmp$$reg), as_FloatRegister($dst$$reg)); %} ins_pipe(vmuldiv_fp128); %} // --------------------------------- DIV -------------------------------------- instruct vdiv2F(vecD dst, vecD src1, vecD src2) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (DivVF src1 src2)); ins_cost(INSN_COST); format %{ "fdiv $dst,$src1,$src2\t# vector (2S)" %} ins_encode %{ __ fdiv(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vmuldiv_fp64); %} instruct vdiv4F(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (DivVF src1 src2)); ins_cost(INSN_COST); format %{ "fdiv $dst,$src1,$src2\t# vector (4S)" %} ins_encode %{ __ fdiv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vmuldiv_fp128); %} instruct vdiv2D(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (DivVD src1 src2)); ins_cost(INSN_COST); format %{ "fdiv $dst,$src1,$src2\t# vector (2D)" %} ins_encode %{ __ fdiv(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vmuldiv_fp128); %} // --------------------------------- SQRT ------------------------------------- instruct vsqrt2F(vecD dst, vecD src) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (SqrtVF src)); format %{ "fsqrt $dst, $src\t# vector (2F)" %} ins_encode %{ __ fsqrt(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src$$reg)); %} ins_pipe(vunop_fp64); %} instruct vsqrt4F(vecX dst, vecX src) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (SqrtVF src)); format %{ "fsqrt $dst, $src\t# vector (4F)" %} ins_encode %{ __ fsqrt(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src$$reg)); %} ins_pipe(vsqrt_fp128); %} instruct vsqrt2D(vecX dst, vecX src) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (SqrtVD src)); format %{ "fsqrt $dst, $src\t# vector (2D)" %} ins_encode %{ __ fsqrt(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src$$reg)); %} ins_pipe(vsqrt_fp128); %} // --------------------------------- NEG -------------------------------------- instruct vneg2F(vecD dst, vecD src) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (NegVF src)); ins_cost(INSN_COST * 3); format %{ "fneg $dst,$src\t# vector (2S)" %} ins_encode %{ __ fneg(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src$$reg)); %} ins_pipe(vunop_fp64); %} instruct vneg4F(vecX dst, vecX src) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (NegVF src)); ins_cost(INSN_COST * 3); format %{ "fneg $dst,$src\t# vector (4S)" %} ins_encode %{ __ fneg(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src$$reg)); %} ins_pipe(vunop_fp128); %} instruct vneg2D(vecX dst, vecX src) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (NegVD src)); ins_cost(INSN_COST * 3); format %{ "fneg $dst,$src\t# vector (2D)" %} ins_encode %{ __ fneg(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src$$reg)); %} ins_pipe(vunop_fp128); %} // --------------------------------- AND -------------------------------------- instruct vand8B(vecD dst, vecD src1, vecD src2) %{ predicate(n->as_Vector()->length_in_bytes() == 4 || n->as_Vector()->length_in_bytes() == 8); match(Set dst (AndV src1 src2)); ins_cost(INSN_COST); format %{ "and $dst,$src1,$src2\t# vector (8B)" %} ins_encode %{ __ andr(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vlogical64); %} instruct vand16B(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length_in_bytes() == 16); match(Set dst (AndV src1 src2)); ins_cost(INSN_COST); format %{ "and $dst,$src1,$src2\t# vector (16B)" %} ins_encode %{ __ andr(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vlogical128); %} // --------------------------------- OR --------------------------------------- instruct vor8B(vecD dst, vecD src1, vecD src2) %{ predicate(n->as_Vector()->length_in_bytes() == 4 || n->as_Vector()->length_in_bytes() == 8); match(Set dst (OrV src1 src2)); ins_cost(INSN_COST); format %{ "orr $dst,$src1,$src2\t# vector (8B)" %} ins_encode %{ __ orr(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vlogical64); %} instruct vor16B(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length_in_bytes() == 16); match(Set dst (OrV src1 src2)); ins_cost(INSN_COST); format %{ "orr $dst,$src1,$src2\t# vector (16B)" %} ins_encode %{ __ orr(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vlogical128); %} // --------------------------------- XOR -------------------------------------- instruct vxor8B(vecD dst, vecD src1, vecD src2) %{ predicate(n->as_Vector()->length_in_bytes() == 4 || n->as_Vector()->length_in_bytes() == 8); match(Set dst (XorV src1 src2)); ins_cost(INSN_COST); format %{ "xor $dst,$src1,$src2\t# vector (8B)" %} ins_encode %{ __ eor(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vlogical64); %} instruct vxor16B(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length_in_bytes() == 16); match(Set dst (XorV src1 src2)); ins_cost(INSN_COST); format %{ "xor $dst,$src1,$src2\t# vector (16B)" %} ins_encode %{ __ eor(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vlogical128); %} // ------------------------------ Shift --------------------------------------- instruct vshiftcnt8B(vecD dst, iRegIorL2I cnt) %{ predicate(n->as_Vector()->length_in_bytes() == 4 || n->as_Vector()->length_in_bytes() == 8); match(Set dst (LShiftCntV cnt)); match(Set dst (RShiftCntV cnt)); format %{ "dup $dst, $cnt\t# shift count vector (8B)" %} ins_encode %{ __ dup(as_FloatRegister($dst$$reg), __ T8B, as_Register($cnt$$reg)); %} ins_pipe(vdup_reg_reg64); %} instruct vshiftcnt16B(vecX dst, iRegIorL2I cnt) %{ predicate(n->as_Vector()->length_in_bytes() == 16); match(Set dst (LShiftCntV cnt)); match(Set dst (RShiftCntV cnt)); format %{ "dup $dst, $cnt\t# shift count vector (16B)" %} ins_encode %{ __ dup(as_FloatRegister($dst$$reg), __ T16B, as_Register($cnt$$reg)); %} ins_pipe(vdup_reg_reg128); %} instruct vsll8B(vecD dst, vecD src, vecD shift) %{ predicate(n->as_Vector()->length() == 4 || n->as_Vector()->length() == 8); match(Set dst (LShiftVB src shift)); ins_cost(INSN_COST); format %{ "sshl $dst,$src,$shift\t# vector (8B)" %} ins_encode %{ __ sshl(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg), as_FloatRegister($shift$$reg)); %} ins_pipe(vshift64); %} instruct vsll16B(vecX dst, vecX src, vecX shift) %{ predicate(n->as_Vector()->length() == 16); match(Set dst (LShiftVB src shift)); ins_cost(INSN_COST); format %{ "sshl $dst,$src,$shift\t# vector (16B)" %} ins_encode %{ __ sshl(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg), as_FloatRegister($shift$$reg)); %} ins_pipe(vshift128); %} // Right shifts with vector shift count on aarch64 SIMD are implemented // as left shift by negative shift count. // There are two cases for vector shift count. // // Case 1: The vector shift count is from replication. // | | // LoadVector RShiftCntV // | / // RShiftVI // Note: In inner loop, multiple neg instructions are used, which can be // moved to outer loop and merge into one neg instruction. // // Case 2: The vector shift count is from loading. // This case isn't supported by middle-end now. But it's supported by // panama/vectorIntrinsics(JEP 338: Vector API). // | | // LoadVector LoadVector // | / // RShiftVI // instruct vsra8B(vecD dst, vecD src, vecD shift, vecD tmp) %{ predicate(n->as_Vector()->length() == 4 || n->as_Vector()->length() == 8); match(Set dst (RShiftVB src shift)); ins_cost(INSN_COST); effect(TEMP tmp); format %{ "negr $tmp,$shift\t" "sshl $dst,$src,$tmp\t# vector (8B)" %} ins_encode %{ __ negr(as_FloatRegister($tmp$$reg), __ T8B, as_FloatRegister($shift$$reg)); __ sshl(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(vshift64); %} instruct vsra16B(vecX dst, vecX src, vecX shift, vecX tmp) %{ predicate(n->as_Vector()->length() == 16); match(Set dst (RShiftVB src shift)); ins_cost(INSN_COST); effect(TEMP tmp); format %{ "negr $tmp,$shift\t" "sshl $dst,$src,$tmp\t# vector (16B)" %} ins_encode %{ __ negr(as_FloatRegister($tmp$$reg), __ T16B, as_FloatRegister($shift$$reg)); __ sshl(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(vshift128); %} instruct vsrl8B(vecD dst, vecD src, vecD shift, vecD tmp) %{ predicate(n->as_Vector()->length() == 4 || n->as_Vector()->length() == 8); match(Set dst (URShiftVB src shift)); ins_cost(INSN_COST); effect(TEMP tmp); format %{ "negr $tmp,$shift\t" "ushl $dst,$src,$tmp\t# vector (8B)" %} ins_encode %{ __ negr(as_FloatRegister($tmp$$reg), __ T8B, as_FloatRegister($shift$$reg)); __ ushl(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(vshift64); %} instruct vsrl16B(vecX dst, vecX src, vecX shift, vecX tmp) %{ predicate(n->as_Vector()->length() == 16); match(Set dst (URShiftVB src shift)); ins_cost(INSN_COST); effect(TEMP tmp); format %{ "negr $tmp,$shift\t" "ushl $dst,$src,$tmp\t# vector (16B)" %} ins_encode %{ __ negr(as_FloatRegister($tmp$$reg), __ T16B, as_FloatRegister($shift$$reg)); __ ushl(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(vshift128); %} instruct vsll8B_imm(vecD dst, vecD src, immI shift) %{ predicate(n->as_Vector()->length() == 4 || n->as_Vector()->length() == 8); match(Set dst (LShiftVB src (LShiftCntV shift))); ins_cost(INSN_COST); format %{ "shl $dst, $src, $shift\t# vector (8B)" %} ins_encode %{ int sh = (int)$shift$$constant; if (sh >= 8) { __ eor(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); } else { __ shl(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg), sh); } %} ins_pipe(vshift64_imm); %} instruct vsll16B_imm(vecX dst, vecX src, immI shift) %{ predicate(n->as_Vector()->length() == 16); match(Set dst (LShiftVB src (LShiftCntV shift))); ins_cost(INSN_COST); format %{ "shl $dst, $src, $shift\t# vector (16B)" %} ins_encode %{ int sh = (int)$shift$$constant; if (sh >= 8) { __ eor(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); } else { __ shl(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg), sh); } %} ins_pipe(vshift128_imm); %} instruct vsra8B_imm(vecD dst, vecD src, immI shift) %{ predicate(n->as_Vector()->length() == 4 || n->as_Vector()->length() == 8); match(Set dst (RShiftVB src (RShiftCntV shift))); ins_cost(INSN_COST); format %{ "sshr $dst, $src, $shift\t# vector (8B)" %} ins_encode %{ int sh = (int)$shift$$constant; if (sh >= 8) sh = 7; __ sshr(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg), sh); %} ins_pipe(vshift64_imm); %} instruct vsra16B_imm(vecX dst, vecX src, immI shift) %{ predicate(n->as_Vector()->length() == 16); match(Set dst (RShiftVB src (RShiftCntV shift))); ins_cost(INSN_COST); format %{ "sshr $dst, $src, $shift\t# vector (16B)" %} ins_encode %{ int sh = (int)$shift$$constant; if (sh >= 8) sh = 7; __ sshr(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg), sh); %} ins_pipe(vshift128_imm); %} instruct vsrl8B_imm(vecD dst, vecD src, immI shift) %{ predicate(n->as_Vector()->length() == 4 || n->as_Vector()->length() == 8); match(Set dst (URShiftVB src (RShiftCntV shift))); ins_cost(INSN_COST); format %{ "ushr $dst, $src, $shift\t# vector (8B)" %} ins_encode %{ int sh = (int)$shift$$constant; if (sh >= 8) { __ eor(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); } else { __ ushr(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg), sh); } %} ins_pipe(vshift64_imm); %} instruct vsrl16B_imm(vecX dst, vecX src, immI shift) %{ predicate(n->as_Vector()->length() == 16); match(Set dst (URShiftVB src (RShiftCntV shift))); ins_cost(INSN_COST); format %{ "ushr $dst, $src, $shift\t# vector (16B)" %} ins_encode %{ int sh = (int)$shift$$constant; if (sh >= 8) { __ eor(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); } else { __ ushr(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg), sh); } %} ins_pipe(vshift128_imm); %} instruct vsll4S(vecD dst, vecD src, vecD shift) %{ predicate(n->as_Vector()->length() == 2 || n->as_Vector()->length() == 4); match(Set dst (LShiftVS src shift)); ins_cost(INSN_COST); format %{ "sshl $dst,$src,$shift\t# vector (4H)" %} ins_encode %{ __ sshl(as_FloatRegister($dst$$reg), __ T4H, as_FloatRegister($src$$reg), as_FloatRegister($shift$$reg)); %} ins_pipe(vshift64); %} instruct vsll8S(vecX dst, vecX src, vecX shift) %{ predicate(n->as_Vector()->length() == 8); match(Set dst (LShiftVS src shift)); ins_cost(INSN_COST); format %{ "sshl $dst,$src,$shift\t# vector (8H)" %} ins_encode %{ __ sshl(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src$$reg), as_FloatRegister($shift$$reg)); %} ins_pipe(vshift128); %} instruct vsra4S(vecD dst, vecD src, vecD shift, vecD tmp) %{ predicate(n->as_Vector()->length() == 2 || n->as_Vector()->length() == 4); match(Set dst (RShiftVS src shift)); ins_cost(INSN_COST); effect(TEMP tmp); format %{ "negr $tmp,$shift\t" "sshl $dst,$src,$tmp\t# vector (4H)" %} ins_encode %{ __ negr(as_FloatRegister($tmp$$reg), __ T8B, as_FloatRegister($shift$$reg)); __ sshl(as_FloatRegister($dst$$reg), __ T4H, as_FloatRegister($src$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(vshift64); %} instruct vsra8S(vecX dst, vecX src, vecX shift, vecX tmp) %{ predicate(n->as_Vector()->length() == 8); match(Set dst (RShiftVS src shift)); ins_cost(INSN_COST); effect(TEMP tmp); format %{ "negr $tmp,$shift\t" "sshl $dst,$src,$tmp\t# vector (8H)" %} ins_encode %{ __ negr(as_FloatRegister($tmp$$reg), __ T16B, as_FloatRegister($shift$$reg)); __ sshl(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(vshift128); %} instruct vsrl4S(vecD dst, vecD src, vecD shift, vecD tmp) %{ predicate(n->as_Vector()->length() == 2 || n->as_Vector()->length() == 4); match(Set dst (URShiftVS src shift)); ins_cost(INSN_COST); effect(TEMP tmp); format %{ "negr $tmp,$shift\t" "ushl $dst,$src,$tmp\t# vector (4H)" %} ins_encode %{ __ negr(as_FloatRegister($tmp$$reg), __ T8B, as_FloatRegister($shift$$reg)); __ ushl(as_FloatRegister($dst$$reg), __ T4H, as_FloatRegister($src$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(vshift64); %} instruct vsrl8S(vecX dst, vecX src, vecX shift, vecX tmp) %{ predicate(n->as_Vector()->length() == 8); match(Set dst (URShiftVS src shift)); ins_cost(INSN_COST); effect(TEMP tmp); format %{ "negr $tmp,$shift\t" "ushl $dst,$src,$tmp\t# vector (8H)" %} ins_encode %{ __ negr(as_FloatRegister($tmp$$reg), __ T16B, as_FloatRegister($shift$$reg)); __ ushl(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(vshift128); %} instruct vsll4S_imm(vecD dst, vecD src, immI shift) %{ predicate(n->as_Vector()->length() == 2 || n->as_Vector()->length() == 4); match(Set dst (LShiftVS src (LShiftCntV shift))); ins_cost(INSN_COST); format %{ "shl $dst, $src, $shift\t# vector (4H)" %} ins_encode %{ int sh = (int)$shift$$constant; if (sh >= 16) { __ eor(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); } else { __ shl(as_FloatRegister($dst$$reg), __ T4H, as_FloatRegister($src$$reg), sh); } %} ins_pipe(vshift64_imm); %} instruct vsll8S_imm(vecX dst, vecX src, immI shift) %{ predicate(n->as_Vector()->length() == 8); match(Set dst (LShiftVS src (LShiftCntV shift))); ins_cost(INSN_COST); format %{ "shl $dst, $src, $shift\t# vector (8H)" %} ins_encode %{ int sh = (int)$shift$$constant; if (sh >= 16) { __ eor(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); } else { __ shl(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src$$reg), sh); } %} ins_pipe(vshift128_imm); %} instruct vsra4S_imm(vecD dst, vecD src, immI shift) %{ predicate(n->as_Vector()->length() == 2 || n->as_Vector()->length() == 4); match(Set dst (RShiftVS src (RShiftCntV shift))); ins_cost(INSN_COST); format %{ "sshr $dst, $src, $shift\t# vector (4H)" %} ins_encode %{ int sh = (int)$shift$$constant; if (sh >= 16) sh = 15; __ sshr(as_FloatRegister($dst$$reg), __ T4H, as_FloatRegister($src$$reg), sh); %} ins_pipe(vshift64_imm); %} instruct vsra8S_imm(vecX dst, vecX src, immI shift) %{ predicate(n->as_Vector()->length() == 8); match(Set dst (RShiftVS src (RShiftCntV shift))); ins_cost(INSN_COST); format %{ "sshr $dst, $src, $shift\t# vector (8H)" %} ins_encode %{ int sh = (int)$shift$$constant; if (sh >= 16) sh = 15; __ sshr(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src$$reg), sh); %} ins_pipe(vshift128_imm); %} instruct vsrl4S_imm(vecD dst, vecD src, immI shift) %{ predicate(n->as_Vector()->length() == 2 || n->as_Vector()->length() == 4); match(Set dst (URShiftVS src (RShiftCntV shift))); ins_cost(INSN_COST); format %{ "ushr $dst, $src, $shift\t# vector (4H)" %} ins_encode %{ int sh = (int)$shift$$constant; if (sh >= 16) { __ eor(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); } else { __ ushr(as_FloatRegister($dst$$reg), __ T4H, as_FloatRegister($src$$reg), sh); } %} ins_pipe(vshift64_imm); %} instruct vsrl8S_imm(vecX dst, vecX src, immI shift) %{ predicate(n->as_Vector()->length() == 8); match(Set dst (URShiftVS src (RShiftCntV shift))); ins_cost(INSN_COST); format %{ "ushr $dst, $src, $shift\t# vector (8H)" %} ins_encode %{ int sh = (int)$shift$$constant; if (sh >= 16) { __ eor(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); } else { __ ushr(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src$$reg), sh); } %} ins_pipe(vshift128_imm); %} instruct vsll2I(vecD dst, vecD src, vecD shift) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (LShiftVI src shift)); ins_cost(INSN_COST); format %{ "sshl $dst,$src,$shift\t# vector (2S)" %} ins_encode %{ __ sshl(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src$$reg), as_FloatRegister($shift$$reg)); %} ins_pipe(vshift64); %} instruct vsll4I(vecX dst, vecX src, vecX shift) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (LShiftVI src shift)); ins_cost(INSN_COST); format %{ "sshl $dst,$src,$shift\t# vector (4S)" %} ins_encode %{ __ sshl(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src$$reg), as_FloatRegister($shift$$reg)); %} ins_pipe(vshift128); %} instruct vsra2I(vecD dst, vecD src, vecD shift, vecD tmp) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (RShiftVI src shift)); ins_cost(INSN_COST); effect(TEMP tmp); format %{ "negr $tmp,$shift\t" "sshl $dst,$src,$tmp\t# vector (2S)" %} ins_encode %{ __ negr(as_FloatRegister($tmp$$reg), __ T8B, as_FloatRegister($shift$$reg)); __ sshl(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(vshift64); %} instruct vsra4I(vecX dst, vecX src, vecX shift, vecX tmp) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (RShiftVI src shift)); ins_cost(INSN_COST); effect(TEMP tmp); format %{ "negr $tmp,$shift\t" "sshl $dst,$src,$tmp\t# vector (4S)" %} ins_encode %{ __ negr(as_FloatRegister($tmp$$reg), __ T16B, as_FloatRegister($shift$$reg)); __ sshl(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(vshift128); %} instruct vsrl2I(vecD dst, vecD src, vecD shift, vecD tmp) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (URShiftVI src shift)); ins_cost(INSN_COST); effect(TEMP tmp); format %{ "negr $tmp,$shift\t" "ushl $dst,$src,$tmp\t# vector (2S)" %} ins_encode %{ __ negr(as_FloatRegister($tmp$$reg), __ T8B, as_FloatRegister($shift$$reg)); __ ushl(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(vshift64); %} instruct vsrl4I(vecX dst, vecX src, vecX shift, vecX tmp) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (URShiftVI src shift)); ins_cost(INSN_COST); effect(TEMP tmp); format %{ "negr $tmp,$shift\t" "ushl $dst,$src,$tmp\t# vector (4S)" %} ins_encode %{ __ negr(as_FloatRegister($tmp$$reg), __ T16B, as_FloatRegister($shift$$reg)); __ ushl(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(vshift128); %} instruct vsll2I_imm(vecD dst, vecD src, immI shift) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (LShiftVI src (LShiftCntV shift))); ins_cost(INSN_COST); format %{ "shl $dst, $src, $shift\t# vector (2S)" %} ins_encode %{ __ shl(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src$$reg), (int)$shift$$constant); %} ins_pipe(vshift64_imm); %} instruct vsll4I_imm(vecX dst, vecX src, immI shift) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (LShiftVI src (LShiftCntV shift))); ins_cost(INSN_COST); format %{ "shl $dst, $src, $shift\t# vector (4S)" %} ins_encode %{ __ shl(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src$$reg), (int)$shift$$constant); %} ins_pipe(vshift128_imm); %} instruct vsra2I_imm(vecD dst, vecD src, immI shift) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (RShiftVI src (RShiftCntV shift))); ins_cost(INSN_COST); format %{ "sshr $dst, $src, $shift\t# vector (2S)" %} ins_encode %{ __ sshr(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src$$reg), (int)$shift$$constant); %} ins_pipe(vshift64_imm); %} instruct vsra4I_imm(vecX dst, vecX src, immI shift) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (RShiftVI src (RShiftCntV shift))); ins_cost(INSN_COST); format %{ "sshr $dst, $src, $shift\t# vector (4S)" %} ins_encode %{ __ sshr(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src$$reg), (int)$shift$$constant); %} ins_pipe(vshift128_imm); %} instruct vsrl2I_imm(vecD dst, vecD src, immI shift) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (URShiftVI src (RShiftCntV shift))); ins_cost(INSN_COST); format %{ "ushr $dst, $src, $shift\t# vector (2S)" %} ins_encode %{ __ ushr(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src$$reg), (int)$shift$$constant); %} ins_pipe(vshift64_imm); %} instruct vsrl4I_imm(vecX dst, vecX src, immI shift) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (URShiftVI src (RShiftCntV shift))); ins_cost(INSN_COST); format %{ "ushr $dst, $src, $shift\t# vector (4S)" %} ins_encode %{ __ ushr(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src$$reg), (int)$shift$$constant); %} ins_pipe(vshift128_imm); %} instruct vsll2L(vecX dst, vecX src, vecX shift) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (LShiftVL src shift)); ins_cost(INSN_COST); format %{ "sshl $dst,$src,$shift\t# vector (2D)" %} ins_encode %{ __ sshl(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src$$reg), as_FloatRegister($shift$$reg)); %} ins_pipe(vshift128); %} instruct vsra2L(vecX dst, vecX src, vecX shift, vecX tmp) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (RShiftVL src shift)); ins_cost(INSN_COST); effect(TEMP tmp); format %{ "negr $tmp,$shift\t" "sshl $dst,$src,$tmp\t# vector (2D)" %} ins_encode %{ __ negr(as_FloatRegister($tmp$$reg), __ T16B, as_FloatRegister($shift$$reg)); __ sshl(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(vshift128); %} instruct vsrl2L(vecX dst, vecX src, vecX shift, vecX tmp) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (URShiftVL src shift)); ins_cost(INSN_COST); effect(TEMP tmp); format %{ "negr $tmp,$shift\t" "ushl $dst,$src,$tmp\t# vector (2D)" %} ins_encode %{ __ negr(as_FloatRegister($tmp$$reg), __ T16B, as_FloatRegister($shift$$reg)); __ ushl(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(vshift128); %} instruct vsll2L_imm(vecX dst, vecX src, immI shift) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (LShiftVL src (LShiftCntV shift))); ins_cost(INSN_COST); format %{ "shl $dst, $src, $shift\t# vector (2D)" %} ins_encode %{ __ shl(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src$$reg), (int)$shift$$constant); %} ins_pipe(vshift128_imm); %} instruct vsra2L_imm(vecX dst, vecX src, immI shift) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (RShiftVL src (RShiftCntV shift))); ins_cost(INSN_COST); format %{ "sshr $dst, $src, $shift\t# vector (2D)" %} ins_encode %{ __ sshr(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src$$reg), (int)$shift$$constant); %} ins_pipe(vshift128_imm); %} instruct vsrl2L_imm(vecX dst, vecX src, immI shift) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (URShiftVL src (RShiftCntV shift))); ins_cost(INSN_COST); format %{ "ushr $dst, $src, $shift\t# vector (2D)" %} ins_encode %{ __ ushr(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src$$reg), (int)$shift$$constant); %} ins_pipe(vshift128_imm); %} instruct vsraa8B_imm(vecD dst, vecD src, immI shift) %{ predicate(n->as_Vector()->length() == 8); match(Set dst (AddVB dst (RShiftVB src (RShiftCntV shift)))); ins_cost(INSN_COST); format %{ "ssra $dst, $src, $shift\t# vector (8B)" %} ins_encode %{ int sh = (int)$shift$$constant; if (sh >= 8) sh = 7; __ ssra(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg), sh); %} ins_pipe(vshift64_imm); %} instruct vsraa16B_imm(vecX dst, vecX src, immI shift) %{ predicate(n->as_Vector()->length() == 16); match(Set dst (AddVB dst (RShiftVB src (RShiftCntV shift)))); ins_cost(INSN_COST); format %{ "ssra $dst, $src, $shift\t# vector (16B)" %} ins_encode %{ int sh = (int)$shift$$constant; if (sh >= 8) sh = 7; __ ssra(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg), sh); %} ins_pipe(vshift128_imm); %} instruct vsraa4S_imm(vecD dst, vecD src, immI shift) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (AddVS dst (RShiftVS src (RShiftCntV shift)))); ins_cost(INSN_COST); format %{ "ssra $dst, $src, $shift\t# vector (4H)" %} ins_encode %{ int sh = (int)$shift$$constant; if (sh >= 16) sh = 15; __ ssra(as_FloatRegister($dst$$reg), __ T4H, as_FloatRegister($src$$reg), sh); %} ins_pipe(vshift64_imm); %} instruct vsraa8S_imm(vecX dst, vecX src, immI shift) %{ predicate(n->as_Vector()->length() == 8); match(Set dst (AddVS dst (RShiftVS src (RShiftCntV shift)))); ins_cost(INSN_COST); format %{ "ssra $dst, $src, $shift\t# vector (8H)" %} ins_encode %{ int sh = (int)$shift$$constant; if (sh >= 16) sh = 15; __ ssra(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src$$reg), sh); %} ins_pipe(vshift128_imm); %} instruct vsraa2I_imm(vecD dst, vecD src, immI shift) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (AddVI dst (RShiftVI src (RShiftCntV shift)))); ins_cost(INSN_COST); format %{ "ssra $dst, $src, $shift\t# vector (2S)" %} ins_encode %{ __ ssra(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src$$reg), (int)$shift$$constant); %} ins_pipe(vshift64_imm); %} instruct vsraa4I_imm(vecX dst, vecX src, immI shift) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (AddVI dst (RShiftVI src (RShiftCntV shift)))); ins_cost(INSN_COST); format %{ "ssra $dst, $src, $shift\t# vector (4S)" %} ins_encode %{ __ ssra(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src$$reg), (int)$shift$$constant); %} ins_pipe(vshift128_imm); %} instruct vsraa2L_imm(vecX dst, vecX src, immI shift) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (AddVL dst (RShiftVL src (RShiftCntV shift)))); ins_cost(INSN_COST); format %{ "ssra $dst, $src, $shift\t# vector (2D)" %} ins_encode %{ __ ssra(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src$$reg), (int)$shift$$constant); %} ins_pipe(vshift128_imm); %} instruct vsrla8B_imm(vecD dst, vecD src, immI shift) %{ predicate(n->as_Vector()->length() == 8); match(Set dst (AddVB dst (URShiftVB src (RShiftCntV shift)))); ins_cost(INSN_COST); format %{ "usra $dst, $src, $shift\t# vector (8B)" %} ins_encode %{ int sh = (int)$shift$$constant; if (sh < 8) { __ usra(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg), sh); } %} ins_pipe(vshift64_imm); %} instruct vsrla16B_imm(vecX dst, vecX src, immI shift) %{ predicate(n->as_Vector()->length() == 16); match(Set dst (AddVB dst (URShiftVB src (RShiftCntV shift)))); ins_cost(INSN_COST); format %{ "usra $dst, $src, $shift\t# vector (16B)" %} ins_encode %{ int sh = (int)$shift$$constant; if (sh < 8) { __ usra(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg), sh); } %} ins_pipe(vshift128_imm); %} instruct vsrla4S_imm(vecD dst, vecD src, immI shift) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (AddVS dst (URShiftVS src (RShiftCntV shift)))); ins_cost(INSN_COST); format %{ "usra $dst, $src, $shift\t# vector (4H)" %} ins_encode %{ int sh = (int)$shift$$constant; if (sh < 16) { __ usra(as_FloatRegister($dst$$reg), __ T4H, as_FloatRegister($src$$reg), sh); } %} ins_pipe(vshift64_imm); %} instruct vsrla8S_imm(vecX dst, vecX src, immI shift) %{ predicate(n->as_Vector()->length() == 8); match(Set dst (AddVS dst (URShiftVS src (RShiftCntV shift)))); ins_cost(INSN_COST); format %{ "usra $dst, $src, $shift\t# vector (8H)" %} ins_encode %{ int sh = (int)$shift$$constant; if (sh < 16) { __ usra(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($src$$reg), sh); } %} ins_pipe(vshift128_imm); %} instruct vsrla2I_imm(vecD dst, vecD src, immI shift) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (AddVI dst (URShiftVI src (RShiftCntV shift)))); ins_cost(INSN_COST); format %{ "usra $dst, $src, $shift\t# vector (2S)" %} ins_encode %{ __ usra(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src$$reg), (int)$shift$$constant); %} ins_pipe(vshift64_imm); %} instruct vsrla4I_imm(vecX dst, vecX src, immI shift) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (AddVI dst (URShiftVI src (RShiftCntV shift)))); ins_cost(INSN_COST); format %{ "usra $dst, $src, $shift\t# vector (4S)" %} ins_encode %{ __ usra(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src$$reg), (int)$shift$$constant); %} ins_pipe(vshift128_imm); %} instruct vsrla2L_imm(vecX dst, vecX src, immI shift) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (AddVL dst (URShiftVL src (RShiftCntV shift)))); ins_cost(INSN_COST); format %{ "usra $dst, $src, $shift\t# vector (2D)" %} ins_encode %{ __ usra(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src$$reg), (int)$shift$$constant); %} ins_pipe(vshift128_imm); %} instruct vmax2F(vecD dst, vecD src1, vecD src2) %{ predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); match(Set dst (MaxV src1 src2)); ins_cost(INSN_COST); format %{ "fmax $dst,$src1,$src2\t# vector (2F)" %} ins_encode %{ __ fmax(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop_fp64); %} instruct vmax4F(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); match(Set dst (MaxV src1 src2)); ins_cost(INSN_COST); format %{ "fmax $dst,$src1,$src2\t# vector (4S)" %} ins_encode %{ __ fmax(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop_fp128); %} instruct vmax2D(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); match(Set dst (MaxV src1 src2)); ins_cost(INSN_COST); format %{ "fmax $dst,$src1,$src2\t# vector (2D)" %} ins_encode %{ __ fmax(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop_fp128); %} instruct vmin2F(vecD dst, vecD src1, vecD src2) %{ predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); match(Set dst (MinV src1 src2)); ins_cost(INSN_COST); format %{ "fmin $dst,$src1,$src2\t# vector (2F)" %} ins_encode %{ __ fmin(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop_fp64); %} instruct vmin4F(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); match(Set dst (MinV src1 src2)); ins_cost(INSN_COST); format %{ "fmin $dst,$src1,$src2\t# vector (4S)" %} ins_encode %{ __ fmin(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop_fp128); %} instruct vmin2D(vecX dst, vecX src1, vecX src2) %{ predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); match(Set dst (MinV src1 src2)); ins_cost(INSN_COST); format %{ "fmin $dst,$src1,$src2\t# vector (2D)" %} ins_encode %{ __ fmin(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(vdop_fp128); %} instruct vround2D_reg(vecX dst, vecX src, immI rmode) %{ predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); match(Set dst (RoundDoubleModeV src rmode)); format %{ "frint $dst, $src, $rmode" %} ins_encode %{ switch ($rmode$$constant) { case RoundDoubleModeNode::rmode_rint: __ frintn(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src$$reg)); break; case RoundDoubleModeNode::rmode_floor: __ frintm(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src$$reg)); break; case RoundDoubleModeNode::rmode_ceil: __ frintp(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src$$reg)); break; } %} ins_pipe(vdop_fp128); %} instruct vpopcount4I(vecX dst, vecX src) %{ predicate(UsePopCountInstruction && n->as_Vector()->length() == 4); match(Set dst (PopCountVI src)); format %{ "cnt $dst, $src\t# vector (16B)\n\t" "uaddlp $dst, $dst\t# vector (16B)\n\t" "uaddlp $dst, $dst\t# vector (8H)" %} ins_encode %{ __ cnt(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($src$$reg)); __ uaddlp(as_FloatRegister($dst$$reg), __ T16B, as_FloatRegister($dst$$reg)); __ uaddlp(as_FloatRegister($dst$$reg), __ T8H, as_FloatRegister($dst$$reg)); %} ins_pipe(pipe_class_default); %} instruct vpopcount2I(vecD dst, vecD src) %{ predicate(UsePopCountInstruction && n->as_Vector()->length() == 2); match(Set dst (PopCountVI src)); format %{ "cnt $dst, $src\t# vector (8B)\n\t" "uaddlp $dst, $dst\t# vector (8B)\n\t" "uaddlp $dst, $dst\t# vector (4H)" %} ins_encode %{ __ cnt(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($src$$reg)); __ uaddlp(as_FloatRegister($dst$$reg), __ T8B, as_FloatRegister($dst$$reg)); __ uaddlp(as_FloatRegister($dst$$reg), __ T4H, as_FloatRegister($dst$$reg)); %} ins_pipe(pipe_class_default); %}