changeset 17524:1aff5d45abaf

Add 64 bit implementations. Add hashCode test
author psandoz
date Tue, 26 Sep 2017 17:18:18 -0700
parents 1e7707244dd9
children 2737ffacb7c6
files src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte64Vector.java src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double64Vector.java src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float64Vector.java src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int64Vector.java src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long64Vector.java src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short64Vector.java src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Vector.java src/jdk.incubator.vector/share/classes/jdk/incubator/vector/gen-src.sh test/jdk/incubator/vector/VectorHash.java
diffstat 9 files changed, 2263 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte64Vector.java	Tue Sep 26 17:18:18 2017 -0700
@@ -0,0 +1,339 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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
+ * questions.
+ */
+package jdk.incubator.vector;
+
+import java.nio.ByteBuffer;
+
+@SuppressWarnings("cast")
+final class Byte64Vector extends ByteVector<Shapes.S64Bit> {
+    static final Byte64Species SPECIES = new Byte64Species();
+
+    static final Byte64Vector ZERO = new Byte64Vector();
+
+    byte[] vec;
+
+    Byte64Vector() {
+        vec = new byte[SPECIES.length()];
+    }
+
+    Byte64Vector(byte[] v) {
+        vec = v;
+    }
+
+
+    // Unary operator
+
+    @Override
+    Byte64Vector uOp(FUnOp f) {
+        byte[] res = new byte[length()];
+        for (int i = 0; i < length(); i++) {
+            res[i] = f.apply(i, vec[i]);
+        }
+        return new Byte64Vector(res);
+    }
+
+    @Override
+    Byte64Vector uOp(Mask<Byte, Shapes.S64Bit> m, FUnOp f) {
+        byte[] res = new byte[length()];
+        for (int i = 0; i < length(); i++) {
+            res[i] = m.getElement(i) ? f.apply(i, vec[i]) : vec[i];
+        }
+        return new Byte64Vector(res);
+    }
+
+    // Binary operator
+
+    @Override
+    Byte64Vector bOp(Vector<Byte, Shapes.S64Bit> o, FBinOp f) {
+        byte[] res = new byte[length()];
+        Byte64Vector v = (Byte64Vector) o;
+        for (int i = 0; i < length(); i++) {
+            res[i] = f.apply(i, vec[i], v.vec[i]);
+        }
+        return new Byte64Vector(res);
+    }
+
+    @Override
+    Byte64Vector bOp(Vector<Byte, Shapes.S64Bit> o, Mask<Byte, Shapes.S64Bit> m, FBinOp f) {
+        byte[] res = new byte[length()];
+        Byte64Vector v = (Byte64Vector) o;
+        for (int i = 0; i < length(); i++) {
+            res[i] = m.getElement(i) ? f.apply(i, vec[i], v.vec[i]) : vec[i];
+        }
+        return new Byte64Vector(res);
+    }
+
+    // Trinary operator
+
+    @Override
+    Byte64Vector tOp(Vector<Byte, Shapes.S64Bit> o1, Vector<Byte, Shapes.S64Bit> o2, FTriOp f) {
+        byte[] res = new byte[length()];
+        Byte64Vector v1 = (Byte64Vector) o1;
+        Byte64Vector v2 = (Byte64Vector) o2;
+        for (int i = 0; i < length(); i++) {
+            res[i] = f.apply(i, vec[i], v1.vec[i], v2.vec[i]);
+        }
+        return new Byte64Vector(res);
+    }
+
+    @Override
+    Byte64Vector tOp(Vector<Byte, Shapes.S64Bit> o1, Vector<Byte, Shapes.S64Bit> o2, Mask<Byte, Shapes.S64Bit> m, FTriOp f) {
+        byte[] res = new byte[length()];
+        Byte64Vector v1 = (Byte64Vector) o1;
+        Byte64Vector v2 = (Byte64Vector) o2;
+        for (int i = 0; i < length(); i++) {
+            res[i] = m.getElement(i) ? f.apply(i, vec[i], v1.vec[i], v2.vec[i]) : vec[i];
+        }
+        return new Byte64Vector(res);
+    }
+
+    @Override
+    byte rOp(byte v, FBinOp f) {
+        for (int i = 0; i < length(); i++) {
+            v = f.apply(i, v, vec[i]);
+        }
+        return v;
+    }
+
+    // Binary test
+
+    @Override
+    Mask<Byte, Shapes.S64Bit> bTest(Vector<Byte, Shapes.S64Bit> o, FBinTest f) {
+        Byte64Vector v = (Byte64Vector) o;
+        boolean[] bits = new boolean[length()];
+        for (int i = 0; i < length(); i++){
+            bits[i] = f.apply(i, vec[i], v.vec[i]);
+        }
+        return new GenericMask<>(this.species(), bits);
+    }
+
+    // Foreach
+
+    @Override
+    void forEach(FUnCon f) {
+        for (int i = 0; i < length(); i++) {
+            f.apply(i, vec[i]);
+        }
+    }
+
+    @Override
+    void forEach(Mask<Byte, Shapes.S64Bit> m, FUnCon f) {
+        forEach((i, a) -> {
+            if (m.getElement(i)) { f.apply(i, a); }
+        });
+    }
+
+
+
+    @Override
+    public Byte64Vector rotateEL(int j) {
+        byte[] res = new byte[length()];
+        for (int i = 0; i < length(); i++){
+            res[j+i % length()] = vec[i];
+        }
+        return new Byte64Vector(res);
+    }
+
+    @Override
+    public Byte64Vector rotateER(int j) {
+        byte[] res = new byte[length()];
+        for (int i = 0; i < length(); i++){
+            int z = i - j;
+            if(j < 0) {
+                res[length() + z] = vec[i];
+            } else {
+                res[z] = vec[i];
+            }
+        }
+        return new Byte64Vector(res);
+    }
+
+    @Override
+    public Byte64Vector shiftEL(int j) {
+        byte[] res = new byte[length()];
+        for (int i = 0; i < length()-j; i++) {
+            res[i + j] = vec[i];
+        }
+        return new Byte64Vector(res);
+    }
+
+    @Override
+    public Byte64Vector shiftER(int j) {
+        byte[] res = new byte[length()];
+        for (int i = 0; i < length()-j; i++){
+            res[i] = vec[j];
+        }
+        return new Byte64Vector(res);
+    }
+
+    @Override
+    public Byte64Vector shuffle(Vector<Byte, Shapes.S64Bit> o, Shuffle<Byte, Shapes.S64Bit> s) {
+        Byte64Vector v = (Byte64Vector) o;
+        return uOp((i, a) -> {
+            int e = s.getElement(i);
+            if(e > 0 && e < length()) {
+                //from this
+                return vec[e];
+            } else if(e < length() * 2) {
+                //from o
+                return v.vec[e - length()];
+            } else {
+                throw new ArrayIndexOutOfBoundsException("Bad reordering for shuffle");
+            }
+        });
+    }
+
+    @Override
+    public Byte64Vector swizzle(Shuffle<Byte, Shapes.S64Bit> s) {
+        return uOp((i, a) -> {
+            int e = s.getElement(i);
+            if(e > 0 && e < length()) {
+                return vec[e];
+            } else {
+                throw new ArrayIndexOutOfBoundsException("Bad reordering for shuffle");
+            }
+        });
+    }
+
+    @Override
+    public <F, Z extends Shape<Vector<?, ?>>> Vector<F, Z> cast(Class<F> type, Z shape) {
+        Vector.Species<F,Z> species = Vector.speciesInstance(type, shape);
+
+        // Whichever is larger
+        int blen = Math.max(species.bitSize(), bitSize()) / Byte.SIZE;
+        ByteBuffer bb = ByteBuffer.allocate(blen);
+
+        int limit = Math.min(species.length(), length());
+
+        if (type == Byte.class) {
+            for (int i = 0; i < limit; i++){
+                bb.put(i, (byte) vec[i]);
+            }
+        } else if (type == Short.class) {
+            for (int i = 0; i < limit; i++){
+                bb.asShortBuffer().put(i, (short) vec[i]);
+            }
+        } else if (type == Integer.class) {
+            for (int i = 0; i < limit; i++){
+                bb.asIntBuffer().put(i, (int) vec[i]);
+            }
+        } else if (type == Long.class){
+            for (int i = 0; i < limit; i++){
+                bb.asLongBuffer().put(i, (long) vec[i]);
+            }
+        } else if (type == Float.class){
+            for (int i = 0; i < limit; i++){
+                bb.asFloatBuffer().put(i, (float) vec[i]);
+            }
+        } else if (type == Double.class){
+            for (int i = 0; i < limit; i++){
+                bb.asDoubleBuffer().put(i, (double) vec[i]);
+            }
+        } else {
+            throw new UnsupportedOperationException("Bad lane type for casting.");
+        }
+
+        return species.fromByteBuffer(bb);
+    }
+
+    // Accessors
+
+    @Override
+    public byte get(int i) {
+        return vec[i];
+    }
+
+    @Override
+    public Byte64Vector with(int i, byte e) {
+        byte[] res = vec.clone();
+        res[i] = e;
+        return new Byte64Vector(res);
+    }
+
+    // Species
+
+    @Override
+    public Byte64Species species() {
+        return SPECIES;
+    }
+
+    static final class Byte64Species extends ByteSpecies<Shapes.S64Bit> {
+        static final int BIT_SIZE = Shapes.S_64_BIT.bitSize();
+
+        static final int LENGTH = BIT_SIZE / Byte.SIZE;
+
+        @Override
+        public int bitSize() {
+            return BIT_SIZE;
+        }
+
+        @Override
+        public int length() {
+            return LENGTH;
+        }
+
+        @Override
+        public Class<Byte> elementType() {
+            return Byte.class;
+        }
+
+        @Override
+        public int elementSize() {
+            return Byte.SIZE;
+        }
+
+        @Override
+        public Shapes.S64Bit shape() {
+            return Shapes.S_64_BIT;
+        }
+
+        @Override
+        Byte64Vector op(FOp f) {
+            byte[] res = new byte[length()];
+            for (int i = 0; i < length(); i++) {
+                res[i] = f.apply(i);
+            }
+            return new Byte64Vector(res);
+        }
+
+        @Override
+        Byte64Vector op(Mask<Byte, Shapes.S64Bit> m, FOp f) {
+            byte[] res = new byte[length()];
+            for (int i = 0; i < length(); i++) {
+                if (m.getElement(i)) {
+                    res[i] = f.apply(i);
+                }
+            }
+            return new Byte64Vector(res);
+        }
+
+        // Factories
+
+        @Override
+        public Byte64Vector zero() {
+            return ZERO;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double64Vector.java	Tue Sep 26 17:18:18 2017 -0700
@@ -0,0 +1,346 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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
+ * questions.
+ */
+package jdk.incubator.vector;
+
+import java.nio.ByteBuffer;
+
+@SuppressWarnings("cast")
+final class Double64Vector extends DoubleVector<Shapes.S64Bit> {
+    static final Double64Species SPECIES = new Double64Species();
+
+    static final Double64Vector ZERO = new Double64Vector();
+
+    double[] vec;
+
+    Double64Vector() {
+        vec = new double[SPECIES.length()];
+    }
+
+    Double64Vector(double[] v) {
+        vec = v;
+    }
+
+
+    // Unary operator
+
+    @Override
+    Double64Vector uOp(FUnOp f) {
+        double[] res = new double[length()];
+        for (int i = 0; i < length(); i++) {
+            res[i] = f.apply(i, vec[i]);
+        }
+        return new Double64Vector(res);
+    }
+
+    @Override
+    Double64Vector uOp(Mask<Double, Shapes.S64Bit> m, FUnOp f) {
+        double[] res = new double[length()];
+        for (int i = 0; i < length(); i++) {
+            res[i] = m.getElement(i) ? f.apply(i, vec[i]) : vec[i];
+        }
+        return new Double64Vector(res);
+    }
+
+    // Binary operator
+
+    @Override
+    Double64Vector bOp(Vector<Double, Shapes.S64Bit> o, FBinOp f) {
+        double[] res = new double[length()];
+        Double64Vector v = (Double64Vector) o;
+        for (int i = 0; i < length(); i++) {
+            res[i] = f.apply(i, vec[i], v.vec[i]);
+        }
+        return new Double64Vector(res);
+    }
+
+    @Override
+    Double64Vector bOp(Vector<Double, Shapes.S64Bit> o, Mask<Double, Shapes.S64Bit> m, FBinOp f) {
+        double[] res = new double[length()];
+        Double64Vector v = (Double64Vector) o;
+        for (int i = 0; i < length(); i++) {
+            res[i] = m.getElement(i) ? f.apply(i, vec[i], v.vec[i]) : vec[i];
+        }
+        return new Double64Vector(res);
+    }
+
+    // Trinary operator
+
+    @Override
+    Double64Vector tOp(Vector<Double, Shapes.S64Bit> o1, Vector<Double, Shapes.S64Bit> o2, FTriOp f) {
+        double[] res = new double[length()];
+        Double64Vector v1 = (Double64Vector) o1;
+        Double64Vector v2 = (Double64Vector) o2;
+        for (int i = 0; i < length(); i++) {
+            res[i] = f.apply(i, vec[i], v1.vec[i], v2.vec[i]);
+        }
+        return new Double64Vector(res);
+    }
+
+    @Override
+    Double64Vector tOp(Vector<Double, Shapes.S64Bit> o1, Vector<Double, Shapes.S64Bit> o2, Mask<Double, Shapes.S64Bit> m, FTriOp f) {
+        double[] res = new double[length()];
+        Double64Vector v1 = (Double64Vector) o1;
+        Double64Vector v2 = (Double64Vector) o2;
+        for (int i = 0; i < length(); i++) {
+            res[i] = m.getElement(i) ? f.apply(i, vec[i], v1.vec[i], v2.vec[i]) : vec[i];
+        }
+        return new Double64Vector(res);
+    }
+
+    @Override
+    double rOp(double v, FBinOp f) {
+        for (int i = 0; i < length(); i++) {
+            v = f.apply(i, v, vec[i]);
+        }
+        return v;
+    }
+
+    // Binary test
+
+    @Override
+    Mask<Double, Shapes.S64Bit> bTest(Vector<Double, Shapes.S64Bit> o, FBinTest f) {
+        Double64Vector v = (Double64Vector) o;
+        boolean[] bits = new boolean[length()];
+        for (int i = 0; i < length(); i++){
+            bits[i] = f.apply(i, vec[i], v.vec[i]);
+        }
+        return new GenericMask<>(this.species(), bits);
+    }
+
+    // Foreach
+
+    @Override
+    void forEach(FUnCon f) {
+        for (int i = 0; i < length(); i++) {
+            f.apply(i, vec[i]);
+        }
+    }
+
+    @Override
+    void forEach(Mask<Double, Shapes.S64Bit> m, FUnCon f) {
+        forEach((i, a) -> {
+            if (m.getElement(i)) { f.apply(i, a); }
+        });
+    }
+
+    Long64Vector toBits() {
+        long[] res = new long[this.species().length()];
+        for(int i = 0; i < this.species().length(); i++){
+            res[i] = Double.doubleToLongBits(vec[i]);
+        }
+        return new Long64Vector(res);
+    }
+
+
+    @Override
+    public Double64Vector rotateEL(int j) {
+        double[] res = new double[length()];
+        for (int i = 0; i < length(); i++){
+            res[j+i % length()] = vec[i];
+        }
+        return new Double64Vector(res);
+    }
+
+    @Override
+    public Double64Vector rotateER(int j) {
+        double[] res = new double[length()];
+        for (int i = 0; i < length(); i++){
+            int z = i - j;
+            if(j < 0) {
+                res[length() + z] = vec[i];
+            } else {
+                res[z] = vec[i];
+            }
+        }
+        return new Double64Vector(res);
+    }
+
+    @Override
+    public Double64Vector shiftEL(int j) {
+        double[] res = new double[length()];
+        for (int i = 0; i < length()-j; i++) {
+            res[i + j] = vec[i];
+        }
+        return new Double64Vector(res);
+    }
+
+    @Override
+    public Double64Vector shiftER(int j) {
+        double[] res = new double[length()];
+        for (int i = 0; i < length()-j; i++){
+            res[i] = vec[j];
+        }
+        return new Double64Vector(res);
+    }
+
+    @Override
+    public Double64Vector shuffle(Vector<Double, Shapes.S64Bit> o, Shuffle<Double, Shapes.S64Bit> s) {
+        Double64Vector v = (Double64Vector) o;
+        return uOp((i, a) -> {
+            int e = s.getElement(i);
+            if(e > 0 && e < length()) {
+                //from this
+                return vec[e];
+            } else if(e < length() * 2) {
+                //from o
+                return v.vec[e - length()];
+            } else {
+                throw new ArrayIndexOutOfBoundsException("Bad reordering for shuffle");
+            }
+        });
+    }
+
+    @Override
+    public Double64Vector swizzle(Shuffle<Double, Shapes.S64Bit> s) {
+        return uOp((i, a) -> {
+            int e = s.getElement(i);
+            if(e > 0 && e < length()) {
+                return vec[e];
+            } else {
+                throw new ArrayIndexOutOfBoundsException("Bad reordering for shuffle");
+            }
+        });
+    }
+
+    @Override
+    public <F, Z extends Shape<Vector<?, ?>>> Vector<F, Z> cast(Class<F> type, Z shape) {
+        Vector.Species<F,Z> species = Vector.speciesInstance(type, shape);
+
+        // Whichever is larger
+        int blen = Math.max(species.bitSize(), bitSize()) / Byte.SIZE;
+        ByteBuffer bb = ByteBuffer.allocate(blen);
+
+        int limit = Math.min(species.length(), length());
+
+        if (type == Byte.class) {
+            for (int i = 0; i < limit; i++){
+                bb.put(i, (byte) vec[i]);
+            }
+        } else if (type == Short.class) {
+            for (int i = 0; i < limit; i++){
+                bb.asShortBuffer().put(i, (short) vec[i]);
+            }
+        } else if (type == Integer.class) {
+            for (int i = 0; i < limit; i++){
+                bb.asIntBuffer().put(i, (int) vec[i]);
+            }
+        } else if (type == Long.class){
+            for (int i = 0; i < limit; i++){
+                bb.asLongBuffer().put(i, (long) vec[i]);
+            }
+        } else if (type == Float.class){
+            for (int i = 0; i < limit; i++){
+                bb.asFloatBuffer().put(i, (float) vec[i]);
+            }
+        } else if (type == Double.class){
+            for (int i = 0; i < limit; i++){
+                bb.asDoubleBuffer().put(i, (double) vec[i]);
+            }
+        } else {
+            throw new UnsupportedOperationException("Bad lane type for casting.");
+        }
+
+        return species.fromByteBuffer(bb);
+    }
+
+    // Accessors
+
+    @Override
+    public double get(int i) {
+        return vec[i];
+    }
+
+    @Override
+    public Double64Vector with(int i, double e) {
+        double[] res = vec.clone();
+        res[i] = e;
+        return new Double64Vector(res);
+    }
+
+    // Species
+
+    @Override
+    public Double64Species species() {
+        return SPECIES;
+    }
+
+    static final class Double64Species extends DoubleSpecies<Shapes.S64Bit> {
+        static final int BIT_SIZE = Shapes.S_64_BIT.bitSize();
+
+        static final int LENGTH = BIT_SIZE / Double.SIZE;
+
+        @Override
+        public int bitSize() {
+            return BIT_SIZE;
+        }
+
+        @Override
+        public int length() {
+            return LENGTH;
+        }
+
+        @Override
+        public Class<Double> elementType() {
+            return Double.class;
+        }
+
+        @Override
+        public int elementSize() {
+            return Double.SIZE;
+        }
+
+        @Override
+        public Shapes.S64Bit shape() {
+            return Shapes.S_64_BIT;
+        }
+
+        @Override
+        Double64Vector op(FOp f) {
+            double[] res = new double[length()];
+            for (int i = 0; i < length(); i++) {
+                res[i] = f.apply(i);
+            }
+            return new Double64Vector(res);
+        }
+
+        @Override
+        Double64Vector op(Mask<Double, Shapes.S64Bit> m, FOp f) {
+            double[] res = new double[length()];
+            for (int i = 0; i < length(); i++) {
+                if (m.getElement(i)) {
+                    res[i] = f.apply(i);
+                }
+            }
+            return new Double64Vector(res);
+        }
+
+        // Factories
+
+        @Override
+        public Double64Vector zero() {
+            return ZERO;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float64Vector.java	Tue Sep 26 17:18:18 2017 -0700
@@ -0,0 +1,346 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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
+ * questions.
+ */
+package jdk.incubator.vector;
+
+import java.nio.ByteBuffer;
+
+@SuppressWarnings("cast")
+final class Float64Vector extends FloatVector<Shapes.S64Bit> {
+    static final Float64Species SPECIES = new Float64Species();
+
+    static final Float64Vector ZERO = new Float64Vector();
+
+    float[] vec;
+
+    Float64Vector() {
+        vec = new float[SPECIES.length()];
+    }
+
+    Float64Vector(float[] v) {
+        vec = v;
+    }
+
+
+    // Unary operator
+
+    @Override
+    Float64Vector uOp(FUnOp f) {
+        float[] res = new float[length()];
+        for (int i = 0; i < length(); i++) {
+            res[i] = f.apply(i, vec[i]);
+        }
+        return new Float64Vector(res);
+    }
+
+    @Override
+    Float64Vector uOp(Mask<Float, Shapes.S64Bit> m, FUnOp f) {
+        float[] res = new float[length()];
+        for (int i = 0; i < length(); i++) {
+            res[i] = m.getElement(i) ? f.apply(i, vec[i]) : vec[i];
+        }
+        return new Float64Vector(res);
+    }
+
+    // Binary operator
+
+    @Override
+    Float64Vector bOp(Vector<Float, Shapes.S64Bit> o, FBinOp f) {
+        float[] res = new float[length()];
+        Float64Vector v = (Float64Vector) o;
+        for (int i = 0; i < length(); i++) {
+            res[i] = f.apply(i, vec[i], v.vec[i]);
+        }
+        return new Float64Vector(res);
+    }
+
+    @Override
+    Float64Vector bOp(Vector<Float, Shapes.S64Bit> o, Mask<Float, Shapes.S64Bit> m, FBinOp f) {
+        float[] res = new float[length()];
+        Float64Vector v = (Float64Vector) o;
+        for (int i = 0; i < length(); i++) {
+            res[i] = m.getElement(i) ? f.apply(i, vec[i], v.vec[i]) : vec[i];
+        }
+        return new Float64Vector(res);
+    }
+
+    // Trinary operator
+
+    @Override
+    Float64Vector tOp(Vector<Float, Shapes.S64Bit> o1, Vector<Float, Shapes.S64Bit> o2, FTriOp f) {
+        float[] res = new float[length()];
+        Float64Vector v1 = (Float64Vector) o1;
+        Float64Vector v2 = (Float64Vector) o2;
+        for (int i = 0; i < length(); i++) {
+            res[i] = f.apply(i, vec[i], v1.vec[i], v2.vec[i]);
+        }
+        return new Float64Vector(res);
+    }
+
+    @Override
+    Float64Vector tOp(Vector<Float, Shapes.S64Bit> o1, Vector<Float, Shapes.S64Bit> o2, Mask<Float, Shapes.S64Bit> m, FTriOp f) {
+        float[] res = new float[length()];
+        Float64Vector v1 = (Float64Vector) o1;
+        Float64Vector v2 = (Float64Vector) o2;
+        for (int i = 0; i < length(); i++) {
+            res[i] = m.getElement(i) ? f.apply(i, vec[i], v1.vec[i], v2.vec[i]) : vec[i];
+        }
+        return new Float64Vector(res);
+    }
+
+    @Override
+    float rOp(float v, FBinOp f) {
+        for (int i = 0; i < length(); i++) {
+            v = f.apply(i, v, vec[i]);
+        }
+        return v;
+    }
+
+    // Binary test
+
+    @Override
+    Mask<Float, Shapes.S64Bit> bTest(Vector<Float, Shapes.S64Bit> o, FBinTest f) {
+        Float64Vector v = (Float64Vector) o;
+        boolean[] bits = new boolean[length()];
+        for (int i = 0; i < length(); i++){
+            bits[i] = f.apply(i, vec[i], v.vec[i]);
+        }
+        return new GenericMask<>(this.species(), bits);
+    }
+
+    // Foreach
+
+    @Override
+    void forEach(FUnCon f) {
+        for (int i = 0; i < length(); i++) {
+            f.apply(i, vec[i]);
+        }
+    }
+
+    @Override
+    void forEach(Mask<Float, Shapes.S64Bit> m, FUnCon f) {
+        forEach((i, a) -> {
+            if (m.getElement(i)) { f.apply(i, a); }
+        });
+    }
+
+    Int64Vector toBits() {
+        int[] res = new int[this.species().length()];
+        for(int i = 0; i < this.species().length(); i++){
+            res[i] = Float.floatToIntBits(vec[i]);
+        }
+        return new Int64Vector(res);
+    }
+
+
+    @Override
+    public Float64Vector rotateEL(int j) {
+        float[] res = new float[length()];
+        for (int i = 0; i < length(); i++){
+            res[j+i % length()] = vec[i];
+        }
+        return new Float64Vector(res);
+    }
+
+    @Override
+    public Float64Vector rotateER(int j) {
+        float[] res = new float[length()];
+        for (int i = 0; i < length(); i++){
+            int z = i - j;
+            if(j < 0) {
+                res[length() + z] = vec[i];
+            } else {
+                res[z] = vec[i];
+            }
+        }
+        return new Float64Vector(res);
+    }
+
+    @Override
+    public Float64Vector shiftEL(int j) {
+        float[] res = new float[length()];
+        for (int i = 0; i < length()-j; i++) {
+            res[i + j] = vec[i];
+        }
+        return new Float64Vector(res);
+    }
+
+    @Override
+    public Float64Vector shiftER(int j) {
+        float[] res = new float[length()];
+        for (int i = 0; i < length()-j; i++){
+            res[i] = vec[j];
+        }
+        return new Float64Vector(res);
+    }
+
+    @Override
+    public Float64Vector shuffle(Vector<Float, Shapes.S64Bit> o, Shuffle<Float, Shapes.S64Bit> s) {
+        Float64Vector v = (Float64Vector) o;
+        return uOp((i, a) -> {
+            int e = s.getElement(i);
+            if(e > 0 && e < length()) {
+                //from this
+                return vec[e];
+            } else if(e < length() * 2) {
+                //from o
+                return v.vec[e - length()];
+            } else {
+                throw new ArrayIndexOutOfBoundsException("Bad reordering for shuffle");
+            }
+        });
+    }
+
+    @Override
+    public Float64Vector swizzle(Shuffle<Float, Shapes.S64Bit> s) {
+        return uOp((i, a) -> {
+            int e = s.getElement(i);
+            if(e > 0 && e < length()) {
+                return vec[e];
+            } else {
+                throw new ArrayIndexOutOfBoundsException("Bad reordering for shuffle");
+            }
+        });
+    }
+
+    @Override
+    public <F, Z extends Shape<Vector<?, ?>>> Vector<F, Z> cast(Class<F> type, Z shape) {
+        Vector.Species<F,Z> species = Vector.speciesInstance(type, shape);
+
+        // Whichever is larger
+        int blen = Math.max(species.bitSize(), bitSize()) / Byte.SIZE;
+        ByteBuffer bb = ByteBuffer.allocate(blen);
+
+        int limit = Math.min(species.length(), length());
+
+        if (type == Byte.class) {
+            for (int i = 0; i < limit; i++){
+                bb.put(i, (byte) vec[i]);
+            }
+        } else if (type == Short.class) {
+            for (int i = 0; i < limit; i++){
+                bb.asShortBuffer().put(i, (short) vec[i]);
+            }
+        } else if (type == Integer.class) {
+            for (int i = 0; i < limit; i++){
+                bb.asIntBuffer().put(i, (int) vec[i]);
+            }
+        } else if (type == Long.class){
+            for (int i = 0; i < limit; i++){
+                bb.asLongBuffer().put(i, (long) vec[i]);
+            }
+        } else if (type == Float.class){
+            for (int i = 0; i < limit; i++){
+                bb.asFloatBuffer().put(i, (float) vec[i]);
+            }
+        } else if (type == Double.class){
+            for (int i = 0; i < limit; i++){
+                bb.asDoubleBuffer().put(i, (double) vec[i]);
+            }
+        } else {
+            throw new UnsupportedOperationException("Bad lane type for casting.");
+        }
+
+        return species.fromByteBuffer(bb);
+    }
+
+    // Accessors
+
+    @Override
+    public float get(int i) {
+        return vec[i];
+    }
+
+    @Override
+    public Float64Vector with(int i, float e) {
+        float[] res = vec.clone();
+        res[i] = e;
+        return new Float64Vector(res);
+    }
+
+    // Species
+
+    @Override
+    public Float64Species species() {
+        return SPECIES;
+    }
+
+    static final class Float64Species extends FloatSpecies<Shapes.S64Bit> {
+        static final int BIT_SIZE = Shapes.S_64_BIT.bitSize();
+
+        static final int LENGTH = BIT_SIZE / Float.SIZE;
+
+        @Override
+        public int bitSize() {
+            return BIT_SIZE;
+        }
+
+        @Override
+        public int length() {
+            return LENGTH;
+        }
+
+        @Override
+        public Class<Float> elementType() {
+            return Float.class;
+        }
+
+        @Override
+        public int elementSize() {
+            return Float.SIZE;
+        }
+
+        @Override
+        public Shapes.S64Bit shape() {
+            return Shapes.S_64_BIT;
+        }
+
+        @Override
+        Float64Vector op(FOp f) {
+            float[] res = new float[length()];
+            for (int i = 0; i < length(); i++) {
+                res[i] = f.apply(i);
+            }
+            return new Float64Vector(res);
+        }
+
+        @Override
+        Float64Vector op(Mask<Float, Shapes.S64Bit> m, FOp f) {
+            float[] res = new float[length()];
+            for (int i = 0; i < length(); i++) {
+                if (m.getElement(i)) {
+                    res[i] = f.apply(i);
+                }
+            }
+            return new Float64Vector(res);
+        }
+
+        // Factories
+
+        @Override
+        public Float64Vector zero() {
+            return ZERO;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int64Vector.java	Tue Sep 26 17:18:18 2017 -0700
@@ -0,0 +1,346 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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
+ * questions.
+ */
+package jdk.incubator.vector;
+
+import java.nio.ByteBuffer;
+
+@SuppressWarnings("cast")
+final class Int64Vector extends IntVector<Shapes.S64Bit> {
+    static final Int64Species SPECIES = new Int64Species();
+
+    static final Int64Vector ZERO = new Int64Vector();
+
+    int[] vec;
+
+    Int64Vector() {
+        vec = new int[SPECIES.length()];
+    }
+
+    Int64Vector(int[] v) {
+        vec = v;
+    }
+
+
+    // Unary operator
+
+    @Override
+    Int64Vector uOp(FUnOp f) {
+        int[] res = new int[length()];
+        for (int i = 0; i < length(); i++) {
+            res[i] = f.apply(i, vec[i]);
+        }
+        return new Int64Vector(res);
+    }
+
+    @Override
+    Int64Vector uOp(Mask<Integer, Shapes.S64Bit> m, FUnOp f) {
+        int[] res = new int[length()];
+        for (int i = 0; i < length(); i++) {
+            res[i] = m.getElement(i) ? f.apply(i, vec[i]) : vec[i];
+        }
+        return new Int64Vector(res);
+    }
+
+    // Binary operator
+
+    @Override
+    Int64Vector bOp(Vector<Integer, Shapes.S64Bit> o, FBinOp f) {
+        int[] res = new int[length()];
+        Int64Vector v = (Int64Vector) o;
+        for (int i = 0; i < length(); i++) {
+            res[i] = f.apply(i, vec[i], v.vec[i]);
+        }
+        return new Int64Vector(res);
+    }
+
+    @Override
+    Int64Vector bOp(Vector<Integer, Shapes.S64Bit> o, Mask<Integer, Shapes.S64Bit> m, FBinOp f) {
+        int[] res = new int[length()];
+        Int64Vector v = (Int64Vector) o;
+        for (int i = 0; i < length(); i++) {
+            res[i] = m.getElement(i) ? f.apply(i, vec[i], v.vec[i]) : vec[i];
+        }
+        return new Int64Vector(res);
+    }
+
+    // Trinary operator
+
+    @Override
+    Int64Vector tOp(Vector<Integer, Shapes.S64Bit> o1, Vector<Integer, Shapes.S64Bit> o2, FTriOp f) {
+        int[] res = new int[length()];
+        Int64Vector v1 = (Int64Vector) o1;
+        Int64Vector v2 = (Int64Vector) o2;
+        for (int i = 0; i < length(); i++) {
+            res[i] = f.apply(i, vec[i], v1.vec[i], v2.vec[i]);
+        }
+        return new Int64Vector(res);
+    }
+
+    @Override
+    Int64Vector tOp(Vector<Integer, Shapes.S64Bit> o1, Vector<Integer, Shapes.S64Bit> o2, Mask<Integer, Shapes.S64Bit> m, FTriOp f) {
+        int[] res = new int[length()];
+        Int64Vector v1 = (Int64Vector) o1;
+        Int64Vector v2 = (Int64Vector) o2;
+        for (int i = 0; i < length(); i++) {
+            res[i] = m.getElement(i) ? f.apply(i, vec[i], v1.vec[i], v2.vec[i]) : vec[i];
+        }
+        return new Int64Vector(res);
+    }
+
+    @Override
+    int rOp(int v, FBinOp f) {
+        for (int i = 0; i < length(); i++) {
+            v = f.apply(i, v, vec[i]);
+        }
+        return v;
+    }
+
+    // Binary test
+
+    @Override
+    Mask<Integer, Shapes.S64Bit> bTest(Vector<Integer, Shapes.S64Bit> o, FBinTest f) {
+        Int64Vector v = (Int64Vector) o;
+        boolean[] bits = new boolean[length()];
+        for (int i = 0; i < length(); i++){
+            bits[i] = f.apply(i, vec[i], v.vec[i]);
+        }
+        return new GenericMask<>(this.species(), bits);
+    }
+
+    // Foreach
+
+    @Override
+    void forEach(FUnCon f) {
+        for (int i = 0; i < length(); i++) {
+            f.apply(i, vec[i]);
+        }
+    }
+
+    @Override
+    void forEach(Mask<Integer, Shapes.S64Bit> m, FUnCon f) {
+        forEach((i, a) -> {
+            if (m.getElement(i)) { f.apply(i, a); }
+        });
+    }
+
+
+    Float64Vector toFP() {
+        float[] res = new float[this.species().length()];
+        for(int i = 0; i < this.species().length(); i++){
+            res[i] = Float.intBitsToFloat(vec[i]);
+        }
+        return new Float64Vector(res);
+    }
+
+    @Override
+    public Int64Vector rotateEL(int j) {
+        int[] res = new int[length()];
+        for (int i = 0; i < length(); i++){
+            res[j+i % length()] = vec[i];
+        }
+        return new Int64Vector(res);
+    }
+
+    @Override
+    public Int64Vector rotateER(int j) {
+        int[] res = new int[length()];
+        for (int i = 0; i < length(); i++){
+            int z = i - j;
+            if(j < 0) {
+                res[length() + z] = vec[i];
+            } else {
+                res[z] = vec[i];
+            }
+        }
+        return new Int64Vector(res);
+    }
+
+    @Override
+    public Int64Vector shiftEL(int j) {
+        int[] res = new int[length()];
+        for (int i = 0; i < length()-j; i++) {
+            res[i + j] = vec[i];
+        }
+        return new Int64Vector(res);
+    }
+
+    @Override
+    public Int64Vector shiftER(int j) {
+        int[] res = new int[length()];
+        for (int i = 0; i < length()-j; i++){
+            res[i] = vec[j];
+        }
+        return new Int64Vector(res);
+    }
+
+    @Override
+    public Int64Vector shuffle(Vector<Integer, Shapes.S64Bit> o, Shuffle<Integer, Shapes.S64Bit> s) {
+        Int64Vector v = (Int64Vector) o;
+        return uOp((i, a) -> {
+            int e = s.getElement(i);
+            if(e > 0 && e < length()) {
+                //from this
+                return vec[e];
+            } else if(e < length() * 2) {
+                //from o
+                return v.vec[e - length()];
+            } else {
+                throw new ArrayIndexOutOfBoundsException("Bad reordering for shuffle");
+            }
+        });
+    }
+
+    @Override
+    public Int64Vector swizzle(Shuffle<Integer, Shapes.S64Bit> s) {
+        return uOp((i, a) -> {
+            int e = s.getElement(i);
+            if(e > 0 && e < length()) {
+                return vec[e];
+            } else {
+                throw new ArrayIndexOutOfBoundsException("Bad reordering for shuffle");
+            }
+        });
+    }
+
+    @Override
+    public <F, Z extends Shape<Vector<?, ?>>> Vector<F, Z> cast(Class<F> type, Z shape) {
+        Vector.Species<F,Z> species = Vector.speciesInstance(type, shape);
+
+        // Whichever is larger
+        int blen = Math.max(species.bitSize(), bitSize()) / Byte.SIZE;
+        ByteBuffer bb = ByteBuffer.allocate(blen);
+
+        int limit = Math.min(species.length(), length());
+
+        if (type == Byte.class) {
+            for (int i = 0; i < limit; i++){
+                bb.put(i, (byte) vec[i]);
+            }
+        } else if (type == Short.class) {
+            for (int i = 0; i < limit; i++){
+                bb.asShortBuffer().put(i, (short) vec[i]);
+            }
+        } else if (type == Integer.class) {
+            for (int i = 0; i < limit; i++){
+                bb.asIntBuffer().put(i, (int) vec[i]);
+            }
+        } else if (type == Long.class){
+            for (int i = 0; i < limit; i++){
+                bb.asLongBuffer().put(i, (long) vec[i]);
+            }
+        } else if (type == Float.class){
+            for (int i = 0; i < limit; i++){
+                bb.asFloatBuffer().put(i, (float) vec[i]);
+            }
+        } else if (type == Double.class){
+            for (int i = 0; i < limit; i++){
+                bb.asDoubleBuffer().put(i, (double) vec[i]);
+            }
+        } else {
+            throw new UnsupportedOperationException("Bad lane type for casting.");
+        }
+
+        return species.fromByteBuffer(bb);
+    }
+
+    // Accessors
+
+    @Override
+    public int get(int i) {
+        return vec[i];
+    }
+
+    @Override
+    public Int64Vector with(int i, int e) {
+        int[] res = vec.clone();
+        res[i] = e;
+        return new Int64Vector(res);
+    }
+
+    // Species
+
+    @Override
+    public Int64Species species() {
+        return SPECIES;
+    }
+
+    static final class Int64Species extends IntSpecies<Shapes.S64Bit> {
+        static final int BIT_SIZE = Shapes.S_64_BIT.bitSize();
+
+        static final int LENGTH = BIT_SIZE / Integer.SIZE;
+
+        @Override
+        public int bitSize() {
+            return BIT_SIZE;
+        }
+
+        @Override
+        public int length() {
+            return LENGTH;
+        }
+
+        @Override
+        public Class<Integer> elementType() {
+            return Integer.class;
+        }
+
+        @Override
+        public int elementSize() {
+            return Integer.SIZE;
+        }
+
+        @Override
+        public Shapes.S64Bit shape() {
+            return Shapes.S_64_BIT;
+        }
+
+        @Override
+        Int64Vector op(FOp f) {
+            int[] res = new int[length()];
+            for (int i = 0; i < length(); i++) {
+                res[i] = f.apply(i);
+            }
+            return new Int64Vector(res);
+        }
+
+        @Override
+        Int64Vector op(Mask<Integer, Shapes.S64Bit> m, FOp f) {
+            int[] res = new int[length()];
+            for (int i = 0; i < length(); i++) {
+                if (m.getElement(i)) {
+                    res[i] = f.apply(i);
+                }
+            }
+            return new Int64Vector(res);
+        }
+
+        // Factories
+
+        @Override
+        public Int64Vector zero() {
+            return ZERO;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long64Vector.java	Tue Sep 26 17:18:18 2017 -0700
@@ -0,0 +1,346 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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
+ * questions.
+ */
+package jdk.incubator.vector;
+
+import java.nio.ByteBuffer;
+
+@SuppressWarnings("cast")
+final class Long64Vector extends LongVector<Shapes.S64Bit> {
+    static final Long64Species SPECIES = new Long64Species();
+
+    static final Long64Vector ZERO = new Long64Vector();
+
+    long[] vec;
+
+    Long64Vector() {
+        vec = new long[SPECIES.length()];
+    }
+
+    Long64Vector(long[] v) {
+        vec = v;
+    }
+
+
+    // Unary operator
+
+    @Override
+    Long64Vector uOp(FUnOp f) {
+        long[] res = new long[length()];
+        for (int i = 0; i < length(); i++) {
+            res[i] = f.apply(i, vec[i]);
+        }
+        return new Long64Vector(res);
+    }
+
+    @Override
+    Long64Vector uOp(Mask<Long, Shapes.S64Bit> m, FUnOp f) {
+        long[] res = new long[length()];
+        for (int i = 0; i < length(); i++) {
+            res[i] = m.getElement(i) ? f.apply(i, vec[i]) : vec[i];
+        }
+        return new Long64Vector(res);
+    }
+
+    // Binary operator
+
+    @Override
+    Long64Vector bOp(Vector<Long, Shapes.S64Bit> o, FBinOp f) {
+        long[] res = new long[length()];
+        Long64Vector v = (Long64Vector) o;
+        for (int i = 0; i < length(); i++) {
+            res[i] = f.apply(i, vec[i], v.vec[i]);
+        }
+        return new Long64Vector(res);
+    }
+
+    @Override
+    Long64Vector bOp(Vector<Long, Shapes.S64Bit> o, Mask<Long, Shapes.S64Bit> m, FBinOp f) {
+        long[] res = new long[length()];
+        Long64Vector v = (Long64Vector) o;
+        for (int i = 0; i < length(); i++) {
+            res[i] = m.getElement(i) ? f.apply(i, vec[i], v.vec[i]) : vec[i];
+        }
+        return new Long64Vector(res);
+    }
+
+    // Trinary operator
+
+    @Override
+    Long64Vector tOp(Vector<Long, Shapes.S64Bit> o1, Vector<Long, Shapes.S64Bit> o2, FTriOp f) {
+        long[] res = new long[length()];
+        Long64Vector v1 = (Long64Vector) o1;
+        Long64Vector v2 = (Long64Vector) o2;
+        for (int i = 0; i < length(); i++) {
+            res[i] = f.apply(i, vec[i], v1.vec[i], v2.vec[i]);
+        }
+        return new Long64Vector(res);
+    }
+
+    @Override
+    Long64Vector tOp(Vector<Long, Shapes.S64Bit> o1, Vector<Long, Shapes.S64Bit> o2, Mask<Long, Shapes.S64Bit> m, FTriOp f) {
+        long[] res = new long[length()];
+        Long64Vector v1 = (Long64Vector) o1;
+        Long64Vector v2 = (Long64Vector) o2;
+        for (int i = 0; i < length(); i++) {
+            res[i] = m.getElement(i) ? f.apply(i, vec[i], v1.vec[i], v2.vec[i]) : vec[i];
+        }
+        return new Long64Vector(res);
+    }
+
+    @Override
+    long rOp(long v, FBinOp f) {
+        for (int i = 0; i < length(); i++) {
+            v = f.apply(i, v, vec[i]);
+        }
+        return v;
+    }
+
+    // Binary test
+
+    @Override
+    Mask<Long, Shapes.S64Bit> bTest(Vector<Long, Shapes.S64Bit> o, FBinTest f) {
+        Long64Vector v = (Long64Vector) o;
+        boolean[] bits = new boolean[length()];
+        for (int i = 0; i < length(); i++){
+            bits[i] = f.apply(i, vec[i], v.vec[i]);
+        }
+        return new GenericMask<>(this.species(), bits);
+    }
+
+    // Foreach
+
+    @Override
+    void forEach(FUnCon f) {
+        for (int i = 0; i < length(); i++) {
+            f.apply(i, vec[i]);
+        }
+    }
+
+    @Override
+    void forEach(Mask<Long, Shapes.S64Bit> m, FUnCon f) {
+        forEach((i, a) -> {
+            if (m.getElement(i)) { f.apply(i, a); }
+        });
+    }
+
+
+    Double64Vector toFP() {
+        double[] res = new double[this.species().length()];
+        for(int i = 0; i < this.species().length(); i++){
+            res[i] = Double.longBitsToDouble(vec[i]);
+        }
+        return new Double64Vector(res);
+    }
+
+    @Override
+    public Long64Vector rotateEL(int j) {
+        long[] res = new long[length()];
+        for (int i = 0; i < length(); i++){
+            res[j+i % length()] = vec[i];
+        }
+        return new Long64Vector(res);
+    }
+
+    @Override
+    public Long64Vector rotateER(int j) {
+        long[] res = new long[length()];
+        for (int i = 0; i < length(); i++){
+            int z = i - j;
+            if(j < 0) {
+                res[length() + z] = vec[i];
+            } else {
+                res[z] = vec[i];
+            }
+        }
+        return new Long64Vector(res);
+    }
+
+    @Override
+    public Long64Vector shiftEL(int j) {
+        long[] res = new long[length()];
+        for (int i = 0; i < length()-j; i++) {
+            res[i + j] = vec[i];
+        }
+        return new Long64Vector(res);
+    }
+
+    @Override
+    public Long64Vector shiftER(int j) {
+        long[] res = new long[length()];
+        for (int i = 0; i < length()-j; i++){
+            res[i] = vec[j];
+        }
+        return new Long64Vector(res);
+    }
+
+    @Override
+    public Long64Vector shuffle(Vector<Long, Shapes.S64Bit> o, Shuffle<Long, Shapes.S64Bit> s) {
+        Long64Vector v = (Long64Vector) o;
+        return uOp((i, a) -> {
+            int e = s.getElement(i);
+            if(e > 0 && e < length()) {
+                //from this
+                return vec[e];
+            } else if(e < length() * 2) {
+                //from o
+                return v.vec[e - length()];
+            } else {
+                throw new ArrayIndexOutOfBoundsException("Bad reordering for shuffle");
+            }
+        });
+    }
+
+    @Override
+    public Long64Vector swizzle(Shuffle<Long, Shapes.S64Bit> s) {
+        return uOp((i, a) -> {
+            int e = s.getElement(i);
+            if(e > 0 && e < length()) {
+                return vec[e];
+            } else {
+                throw new ArrayIndexOutOfBoundsException("Bad reordering for shuffle");
+            }
+        });
+    }
+
+    @Override
+    public <F, Z extends Shape<Vector<?, ?>>> Vector<F, Z> cast(Class<F> type, Z shape) {
+        Vector.Species<F,Z> species = Vector.speciesInstance(type, shape);
+
+        // Whichever is larger
+        int blen = Math.max(species.bitSize(), bitSize()) / Byte.SIZE;
+        ByteBuffer bb = ByteBuffer.allocate(blen);
+
+        int limit = Math.min(species.length(), length());
+
+        if (type == Byte.class) {
+            for (int i = 0; i < limit; i++){
+                bb.put(i, (byte) vec[i]);
+            }
+        } else if (type == Short.class) {
+            for (int i = 0; i < limit; i++){
+                bb.asShortBuffer().put(i, (short) vec[i]);
+            }
+        } else if (type == Integer.class) {
+            for (int i = 0; i < limit; i++){
+                bb.asIntBuffer().put(i, (int) vec[i]);
+            }
+        } else if (type == Long.class){
+            for (int i = 0; i < limit; i++){
+                bb.asLongBuffer().put(i, (long) vec[i]);
+            }
+        } else if (type == Float.class){
+            for (int i = 0; i < limit; i++){
+                bb.asFloatBuffer().put(i, (float) vec[i]);
+            }
+        } else if (type == Double.class){
+            for (int i = 0; i < limit; i++){
+                bb.asDoubleBuffer().put(i, (double) vec[i]);
+            }
+        } else {
+            throw new UnsupportedOperationException("Bad lane type for casting.");
+        }
+
+        return species.fromByteBuffer(bb);
+    }
+
+    // Accessors
+
+    @Override
+    public long get(int i) {
+        return vec[i];
+    }
+
+    @Override
+    public Long64Vector with(int i, long e) {
+        long[] res = vec.clone();
+        res[i] = e;
+        return new Long64Vector(res);
+    }
+
+    // Species
+
+    @Override
+    public Long64Species species() {
+        return SPECIES;
+    }
+
+    static final class Long64Species extends LongSpecies<Shapes.S64Bit> {
+        static final int BIT_SIZE = Shapes.S_64_BIT.bitSize();
+
+        static final int LENGTH = BIT_SIZE / Long.SIZE;
+
+        @Override
+        public int bitSize() {
+            return BIT_SIZE;
+        }
+
+        @Override
+        public int length() {
+            return LENGTH;
+        }
+
+        @Override
+        public Class<Long> elementType() {
+            return Long.class;
+        }
+
+        @Override
+        public int elementSize() {
+            return Long.SIZE;
+        }
+
+        @Override
+        public Shapes.S64Bit shape() {
+            return Shapes.S_64_BIT;
+        }
+
+        @Override
+        Long64Vector op(FOp f) {
+            long[] res = new long[length()];
+            for (int i = 0; i < length(); i++) {
+                res[i] = f.apply(i);
+            }
+            return new Long64Vector(res);
+        }
+
+        @Override
+        Long64Vector op(Mask<Long, Shapes.S64Bit> m, FOp f) {
+            long[] res = new long[length()];
+            for (int i = 0; i < length(); i++) {
+                if (m.getElement(i)) {
+                    res[i] = f.apply(i);
+                }
+            }
+            return new Long64Vector(res);
+        }
+
+        // Factories
+
+        @Override
+        public Long64Vector zero() {
+            return ZERO;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short64Vector.java	Tue Sep 26 17:18:18 2017 -0700
@@ -0,0 +1,339 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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
+ * questions.
+ */
+package jdk.incubator.vector;
+
+import java.nio.ByteBuffer;
+
+@SuppressWarnings("cast")
+final class Short64Vector extends ShortVector<Shapes.S64Bit> {
+    static final Short64Species SPECIES = new Short64Species();
+
+    static final Short64Vector ZERO = new Short64Vector();
+
+    short[] vec;
+
+    Short64Vector() {
+        vec = new short[SPECIES.length()];
+    }
+
+    Short64Vector(short[] v) {
+        vec = v;
+    }
+
+
+    // Unary operator
+
+    @Override
+    Short64Vector uOp(FUnOp f) {
+        short[] res = new short[length()];
+        for (int i = 0; i < length(); i++) {
+            res[i] = f.apply(i, vec[i]);
+        }
+        return new Short64Vector(res);
+    }
+
+    @Override
+    Short64Vector uOp(Mask<Short, Shapes.S64Bit> m, FUnOp f) {
+        short[] res = new short[length()];
+        for (int i = 0; i < length(); i++) {
+            res[i] = m.getElement(i) ? f.apply(i, vec[i]) : vec[i];
+        }
+        return new Short64Vector(res);
+    }
+
+    // Binary operator
+
+    @Override
+    Short64Vector bOp(Vector<Short, Shapes.S64Bit> o, FBinOp f) {
+        short[] res = new short[length()];
+        Short64Vector v = (Short64Vector) o;
+        for (int i = 0; i < length(); i++) {
+            res[i] = f.apply(i, vec[i], v.vec[i]);
+        }
+        return new Short64Vector(res);
+    }
+
+    @Override
+    Short64Vector bOp(Vector<Short, Shapes.S64Bit> o, Mask<Short, Shapes.S64Bit> m, FBinOp f) {
+        short[] res = new short[length()];
+        Short64Vector v = (Short64Vector) o;
+        for (int i = 0; i < length(); i++) {
+            res[i] = m.getElement(i) ? f.apply(i, vec[i], v.vec[i]) : vec[i];
+        }
+        return new Short64Vector(res);
+    }
+
+    // Trinary operator
+
+    @Override
+    Short64Vector tOp(Vector<Short, Shapes.S64Bit> o1, Vector<Short, Shapes.S64Bit> o2, FTriOp f) {
+        short[] res = new short[length()];
+        Short64Vector v1 = (Short64Vector) o1;
+        Short64Vector v2 = (Short64Vector) o2;
+        for (int i = 0; i < length(); i++) {
+            res[i] = f.apply(i, vec[i], v1.vec[i], v2.vec[i]);
+        }
+        return new Short64Vector(res);
+    }
+
+    @Override
+    Short64Vector tOp(Vector<Short, Shapes.S64Bit> o1, Vector<Short, Shapes.S64Bit> o2, Mask<Short, Shapes.S64Bit> m, FTriOp f) {
+        short[] res = new short[length()];
+        Short64Vector v1 = (Short64Vector) o1;
+        Short64Vector v2 = (Short64Vector) o2;
+        for (int i = 0; i < length(); i++) {
+            res[i] = m.getElement(i) ? f.apply(i, vec[i], v1.vec[i], v2.vec[i]) : vec[i];
+        }
+        return new Short64Vector(res);
+    }
+
+    @Override
+    short rOp(short v, FBinOp f) {
+        for (int i = 0; i < length(); i++) {
+            v = f.apply(i, v, vec[i]);
+        }
+        return v;
+    }
+
+    // Binary test
+
+    @Override
+    Mask<Short, Shapes.S64Bit> bTest(Vector<Short, Shapes.S64Bit> o, FBinTest f) {
+        Short64Vector v = (Short64Vector) o;
+        boolean[] bits = new boolean[length()];
+        for (int i = 0; i < length(); i++){
+            bits[i] = f.apply(i, vec[i], v.vec[i]);
+        }
+        return new GenericMask<>(this.species(), bits);
+    }
+
+    // Foreach
+
+    @Override
+    void forEach(FUnCon f) {
+        for (int i = 0; i < length(); i++) {
+            f.apply(i, vec[i]);
+        }
+    }
+
+    @Override
+    void forEach(Mask<Short, Shapes.S64Bit> m, FUnCon f) {
+        forEach((i, a) -> {
+            if (m.getElement(i)) { f.apply(i, a); }
+        });
+    }
+
+
+
+    @Override
+    public Short64Vector rotateEL(int j) {
+        short[] res = new short[length()];
+        for (int i = 0; i < length(); i++){
+            res[j+i % length()] = vec[i];
+        }
+        return new Short64Vector(res);
+    }
+
+    @Override
+    public Short64Vector rotateER(int j) {
+        short[] res = new short[length()];
+        for (int i = 0; i < length(); i++){
+            int z = i - j;
+            if(j < 0) {
+                res[length() + z] = vec[i];
+            } else {
+                res[z] = vec[i];
+            }
+        }
+        return new Short64Vector(res);
+    }
+
+    @Override
+    public Short64Vector shiftEL(int j) {
+        short[] res = new short[length()];
+        for (int i = 0; i < length()-j; i++) {
+            res[i + j] = vec[i];
+        }
+        return new Short64Vector(res);
+    }
+
+    @Override
+    public Short64Vector shiftER(int j) {
+        short[] res = new short[length()];
+        for (int i = 0; i < length()-j; i++){
+            res[i] = vec[j];
+        }
+        return new Short64Vector(res);
+    }
+
+    @Override
+    public Short64Vector shuffle(Vector<Short, Shapes.S64Bit> o, Shuffle<Short, Shapes.S64Bit> s) {
+        Short64Vector v = (Short64Vector) o;
+        return uOp((i, a) -> {
+            int e = s.getElement(i);
+            if(e > 0 && e < length()) {
+                //from this
+                return vec[e];
+            } else if(e < length() * 2) {
+                //from o
+                return v.vec[e - length()];
+            } else {
+                throw new ArrayIndexOutOfBoundsException("Bad reordering for shuffle");
+            }
+        });
+    }
+
+    @Override
+    public Short64Vector swizzle(Shuffle<Short, Shapes.S64Bit> s) {
+        return uOp((i, a) -> {
+            int e = s.getElement(i);
+            if(e > 0 && e < length()) {
+                return vec[e];
+            } else {
+                throw new ArrayIndexOutOfBoundsException("Bad reordering for shuffle");
+            }
+        });
+    }
+
+    @Override
+    public <F, Z extends Shape<Vector<?, ?>>> Vector<F, Z> cast(Class<F> type, Z shape) {
+        Vector.Species<F,Z> species = Vector.speciesInstance(type, shape);
+
+        // Whichever is larger
+        int blen = Math.max(species.bitSize(), bitSize()) / Byte.SIZE;
+        ByteBuffer bb = ByteBuffer.allocate(blen);
+
+        int limit = Math.min(species.length(), length());
+
+        if (type == Byte.class) {
+            for (int i = 0; i < limit; i++){
+                bb.put(i, (byte) vec[i]);
+            }
+        } else if (type == Short.class) {
+            for (int i = 0; i < limit; i++){
+                bb.asShortBuffer().put(i, (short) vec[i]);
+            }
+        } else if (type == Integer.class) {
+            for (int i = 0; i < limit; i++){
+                bb.asIntBuffer().put(i, (int) vec[i]);
+            }
+        } else if (type == Long.class){
+            for (int i = 0; i < limit; i++){
+                bb.asLongBuffer().put(i, (long) vec[i]);
+            }
+        } else if (type == Float.class){
+            for (int i = 0; i < limit; i++){
+                bb.asFloatBuffer().put(i, (float) vec[i]);
+            }
+        } else if (type == Double.class){
+            for (int i = 0; i < limit; i++){
+                bb.asDoubleBuffer().put(i, (double) vec[i]);
+            }
+        } else {
+            throw new UnsupportedOperationException("Bad lane type for casting.");
+        }
+
+        return species.fromByteBuffer(bb);
+    }
+
+    // Accessors
+
+    @Override
+    public short get(int i) {
+        return vec[i];
+    }
+
+    @Override
+    public Short64Vector with(int i, short e) {
+        short[] res = vec.clone();
+        res[i] = e;
+        return new Short64Vector(res);
+    }
+
+    // Species
+
+    @Override
+    public Short64Species species() {
+        return SPECIES;
+    }
+
+    static final class Short64Species extends ShortSpecies<Shapes.S64Bit> {
+        static final int BIT_SIZE = Shapes.S_64_BIT.bitSize();
+
+        static final int LENGTH = BIT_SIZE / Short.SIZE;
+
+        @Override
+        public int bitSize() {
+            return BIT_SIZE;
+        }
+
+        @Override
+        public int length() {
+            return LENGTH;
+        }
+
+        @Override
+        public Class<Short> elementType() {
+            return Short.class;
+        }
+
+        @Override
+        public int elementSize() {
+            return Short.SIZE;
+        }
+
+        @Override
+        public Shapes.S64Bit shape() {
+            return Shapes.S_64_BIT;
+        }
+
+        @Override
+        Short64Vector op(FOp f) {
+            short[] res = new short[length()];
+            for (int i = 0; i < length(); i++) {
+                res[i] = f.apply(i);
+            }
+            return new Short64Vector(res);
+        }
+
+        @Override
+        Short64Vector op(Mask<Short, Shapes.S64Bit> m, FOp f) {
+            short[] res = new short[length()];
+            for (int i = 0; i < length(); i++) {
+                if (m.getElement(i)) {
+                    res[i] = f.apply(i);
+                }
+            }
+            return new Short64Vector(res);
+        }
+
+        // Factories
+
+        @Override
+        public Short64Vector zero() {
+            return ZERO;
+        }
+    }
+}
--- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Vector.java	Tue Sep 26 11:10:38 2017 -0700
+++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Vector.java	Tue Sep 26 17:18:18 2017 -0700
@@ -253,7 +253,9 @@
 
         //Float
         if (c == Float.class) {
-            if (s == Shapes.S_128_BIT)
+            if (s == Shapes.S_64_BIT)
+                res = (Vector.Species<E, S>) Float64Vector.SPECIES;
+            else if (s == Shapes.S_128_BIT)
                 res = (Vector.Species<E, S>) Float128Vector.SPECIES;
             else if (s == Shapes.S_256_BIT)
                 res = (Vector.Species<E, S>) Float256Vector.SPECIES;
@@ -262,7 +264,9 @@
             //Double
         }
         else if (c == Double.class) {
-            if (s == Shapes.S_128_BIT)
+            if (s == Shapes.S_64_BIT)
+                res = (Vector.Species<E, S>) Double64Vector.SPECIES;
+            else if (s == Shapes.S_128_BIT)
                 res = (Vector.Species<E, S>) Double128Vector.SPECIES;
             else if (s == Shapes.S_256_BIT)
                 res = (Vector.Species<E, S>) Double256Vector.SPECIES;
@@ -271,7 +275,9 @@
             //Byte
         }
         else if (c == Byte.class) {
-            if (s == Shapes.S_128_BIT)
+            if (s == Shapes.S_64_BIT)
+                res = (Vector.Species<E, S>) Byte64Vector.SPECIES;
+            else if (s == Shapes.S_128_BIT)
                 res = (Vector.Species<E, S>) Byte128Vector.SPECIES;
             else if (s == Shapes.S_256_BIT)
                 res = (Vector.Species<E, S>) Byte256Vector.SPECIES;
@@ -280,7 +286,9 @@
             //Short
         }
         else if (c == Short.class) {
-            if (s == Shapes.S_128_BIT)
+            if (s == Shapes.S_64_BIT)
+                res = (Vector.Species<E, S>) Short64Vector.SPECIES;
+            else if (s == Shapes.S_128_BIT)
                 res = (Vector.Species<E, S>) Short128Vector.SPECIES;
             else if (s == Shapes.S_256_BIT)
                 res = (Vector.Species<E, S>) Short256Vector.SPECIES;
@@ -289,7 +297,9 @@
             //Int
         }
         else if (c == Integer.class) {
-            if (s == Shapes.S_128_BIT)
+            if (s == Shapes.S_64_BIT)
+                res = (Vector.Species<E, S>) Int64Vector.SPECIES;
+            else if (s == Shapes.S_128_BIT)
                 res = (Vector.Species<E, S>) Int128Vector.SPECIES;
             else if (s == Shapes.S_256_BIT)
                 res = (Vector.Species<E, S>) Int256Vector.SPECIES;
@@ -298,7 +308,9 @@
             //Long
         }
         else if (c == Long.class) {
-            if (s == Shapes.S_128_BIT)
+            if (s == Shapes.S_64_BIT)
+                res = (Vector.Species<E, S>) Long64Vector.SPECIES;
+            else if (s == Shapes.S_128_BIT)
                 res = (Vector.Species<E, S>) Long128Vector.SPECIES;
             else if (s == Shapes.S_256_BIT)
                 res = (Vector.Species<E, S>) Long256Vector.SPECIES;
--- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/gen-src.sh	Tue Sep 26 11:10:38 2017 -0700
+++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/gen-src.sh	Tue Sep 26 17:18:18 2017 -0700
@@ -74,17 +74,17 @@
     > $abstractvectortype.java
 
 
-  for bits in 128 256 512
+  for bits in 64 128 256 512
   do
     vectortype=${typeprefix}${Type}${bits}Vector
     bitsvectortype=${typeprefix}${Bitstype}${bits}Vector
     fpvectortype=${typeprefix}${Fptype}${bits}Vector
     shape=S${bits}Bit
     Shape=S_${bits}_BIT
-    args="$args -Dbits=$bits -Dvectortype=$vectortype -Dbitsvectortype=$bitsvectortype -Dfpvectortype=$fpvectortype -Dshape=$shape -DShape=$Shape"
+    bitargs="$args -Dbits=$bits -Dvectortype=$vectortype -Dbitsvectortype=$bitsvectortype -Dfpvectortype=$fpvectortype -Dshape=$shape -DShape=$Shape"
 
-    echo $args
-    java $SPP -nel $args \
+    echo $bitargs
+    java $SPP -nel $bitargs \
       < X-VectorBits.java.template \
       > $vectortype.java
   done
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/incubator/vector/VectorHash.java	Tue Sep 26 17:18:18 2017 -0700
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. 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.
+ */
+
+/**
+ * @test
+ * @modules jdk.incubator.vector
+ */
+
+import jdk.incubator.vector.ByteVector;
+import jdk.incubator.vector.IntVector;
+import jdk.incubator.vector.Shapes;
+import jdk.incubator.vector.Vector;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Properties;
+
+public class VectorHash {
+
+    public static void main(String[] args) {
+        String s = "hello world!";
+        byte[] b = s.getBytes(StandardCharsets.UTF_8);
+
+        Properties p = System.getProperties();
+        p.forEach((k, v) -> {
+            byte[] bk = k.toString().getBytes(StandardCharsets.UTF_8);
+            byte[] bv = v.toString().getBytes(StandardCharsets.UTF_8);
+            assertHashCode(bk);
+            assertHashCode(bv);
+        });
+    }
+
+    static void assertHashCode(byte[] b) {
+        int expected = Arrays.hashCode(b);
+        assertEquals(hashCodeUnrollExplicit(b), expected);
+        assertEquals(hashCodeUnrollConstants(b), expected);
+        assertEquals(hashCodeVector64(b), expected);
+        assertEquals(hashCodeVector128(b), expected);
+    }
+
+    static void assertEquals(Object a, Object b) {
+        if (!a.equals(b)) throw new AssertionError();
+    }
+
+    static int hashCodeUnrollExplicit(byte[] a) {
+        if (a == null)
+            return 0;
+
+        int h = 1;
+        int i = 0;
+        for (; i < (a.length & ~(8 - 1)); i += 8) {
+            h = h * 31 * 31 * 31 * 31 * 31 * 31 * 31 * 31 +
+                a[i + 0] * 31 * 31 * 31 * 31 * 31 * 31 * 31 +
+                a[i + 1] * 31 * 31 * 31 * 31 * 31 * 31 +
+                a[i + 2] * 31 * 31 * 31 * 31 * 31 +
+                a[i + 3] * 31 * 31 * 31 * 31 +
+                a[i + 4] * 31 * 31 * 31 +
+                a[i + 5] * 31 * 31 +
+                a[i + 6] * 31 +
+                a[i + 7];
+        }
+
+        for (; i < a.length; i++) {
+            h = 31 * h + a[i];
+        }
+        return h;
+    }
+
+    static int hashCodeUnrollConstants(byte[] a) {
+        if (a == null)
+            return 0;
+
+        int h = 1;
+        int i = 0;
+        for (; i < (a.length & ~(8 - 1)); i += 8) {
+            h = h * COEFF_31_TO_8 +
+                a[i + 0] * H_COEFF_8.get(0) +
+                a[i + 1] * H_COEFF_8.get(1) +
+                a[i + 2] * H_COEFF_8.get(2) +
+                a[i + 3] * H_COEFF_8.get(3) +
+                a[i + 4] * H_COEFF_8.get(4) +
+                a[i + 5] * H_COEFF_8.get(5) +
+                a[i + 6] * H_COEFF_8.get(6) +
+                a[i + 7] * H_COEFF_8.get(7);
+        }
+
+        for (; i < a.length; i++) {
+            h = 31 * h + a[i];
+        }
+        return h;
+    }
+
+    static int hashCodeVector64(byte[] a) {
+        int h = 1;
+        int i = 0;
+        for (; i < (a.length & ~(BYTE_64_SPECIES.length() - 1)); i += BYTE_64_SPECIES.length()) {
+            ByteVector<Shapes.S64Bit> b = BYTE_64_SPECIES.fromArray(a, i);
+            IntVector<Shapes.S256Bit> x = (IntVector<Shapes.S256Bit>) b.cast(Integer.class, Shapes.S_256_BIT);
+            h = h * COEFF_31_TO_8 + x.mul(H_COEFF_8).sumAll();
+        }
+
+        for (; i < a.length; i++) {
+            h = 31 * h + a[i];
+        }
+        return h;
+    }
+
+    static int hashCodeVector128(byte[] a) {
+        int h = 1;
+        int i = 0;
+        for (; i < (a.length & ~(BYTE_128_SPECIES.length() - 1)); i += BYTE_128_SPECIES.length()) {
+            ByteVector<Shapes.S128Bit> b = BYTE_128_SPECIES.fromArray(a, i);
+            IntVector<Shapes.S512Bit> x = (IntVector<Shapes.S512Bit>) b.cast(Integer.class, Shapes.S_512_BIT);
+            h = h * COEFF_31_TO_16 + x.mul(H_COEFF_16).sumAll();
+        }
+
+        for (; i < a.length; i++) {
+            h = 31 * h + a[i];
+        }
+        return h;
+    }
+
+    static final ByteVector.ByteSpecies<Shapes.S128Bit> BYTE_128_SPECIES = (ByteVector.ByteSpecies<Shapes.S128Bit>)
+            Vector.speciesInstance(Byte.class, Shapes.S_128_BIT);
+    static final int COEFF_31_TO_16;
+    static final IntVector<Shapes.S512Bit> H_COEFF_16;
+
+    static final ByteVector.ByteSpecies<Shapes.S64Bit> BYTE_64_SPECIES = (ByteVector.ByteSpecies<Shapes.S64Bit>)
+            Vector.speciesInstance(Byte.class, Shapes.S_64_BIT);
+    static final int COEFF_31_TO_8;
+    static final IntVector<Shapes.S256Bit> H_COEFF_8;
+
+    static {
+        IntVector.IntSpecies<Shapes.S256Bit> int256Species = (IntVector.IntSpecies<Shapes.S256Bit>)
+                Vector.speciesInstance(Integer.class, Shapes.S_256_BIT);
+
+        int[] a = new int[int256Species.length()];
+        a[a.length - 1] = 1;
+        for (int i = 1; i < a.length; i++) {
+            a[a.length - 1 - i] = a[a.length - 1 - i + 1] * 31;
+        }
+
+        COEFF_31_TO_8 = a[0] * 31;
+        H_COEFF_8 = int256Species.fromArray(a, 0);
+
+
+        IntVector.IntSpecies<Shapes.S512Bit> int512Species = (IntVector.IntSpecies<Shapes.S512Bit>)
+                Vector.speciesInstance(Integer.class, Shapes.S_512_BIT);
+
+        a = new int[int512Species.length()];
+        a[a.length - 1] = 1;
+        for (int i = 1; i < a.length; i++) {
+            a[a.length - 1 - i] = a[a.length - 1 - i + 1] * 31;
+        }
+
+        COEFF_31_TO_16 = a[0] * 31;
+        H_COEFF_16 = int512Species.fromArray(a, 0);
+    }
+}