1 /* 2 * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package jdk.incubator.vector; 26 27 import jdk.internal.vm.annotation.ForceInline; 28 29 import java.util.Objects; 30 31 /*non-public*/ class VectorIntrinsics { 32 static final int VECTOR_ACCESS_OOB_CHECK = Integer.getInteger("jdk.incubator.vector.VECTOR_ACCESS_OOB_CHECK", 2); 33 34 @ForceInline 35 static void requireLength(int haveLength, int length) { 36 if (haveLength != length) { 37 throw requireLengthFailed(haveLength, length); 38 } 39 } 40 static IllegalArgumentException requireLengthFailed(int haveLength, int length) { 41 String msg = String.format("Length check failed: "+ 42 "length %d should have been %s", 43 haveLength, length); 44 return new IllegalArgumentException(msg); 45 } 46 47 @ForceInline 48 static int checkFromIndexSize(int ix, int vlen, int length) { 49 switch (VectorIntrinsics.VECTOR_ACCESS_OOB_CHECK) { 50 case 0: return ix; // no range check 51 case 1: return Objects.checkFromIndexSize(ix, vlen, length); 52 case 2: return Objects.checkIndex(ix, length - (vlen - 1)); 53 default: throw new InternalError(); 54 } 55 } 56 57 @ForceInline 58 static IntVector checkIndex(IntVector vix, int length) { 59 switch (VectorIntrinsics.VECTOR_ACCESS_OOB_CHECK) { 60 case 0: return vix; // no range check 61 case 1: // fall-through 62 case 2: 63 if (vix.compare(VectorOperators.LT, 0) 64 .or(vix.compare(VectorOperators.GE, length)) 65 .anyTrue()) { 66 throw checkIndexFailed(vix, length); 67 } 68 return vix; 69 default: throw new InternalError(); 70 } 71 } 72 73 private static 74 IndexOutOfBoundsException checkIndexFailed(IntVector vix, int length) { 75 String msg = String.format("Range check failed: vector %s out of bounds for length %d", vix, length); 76 return new IndexOutOfBoundsException(msg); 77 } 78 79 // If the index is not already a multiple of size, 80 // round it down to the next smaller multiple of size. 81 // It is an error if size is less than zero. 82 @ForceInline 83 static int roundDown(int index, int size) { 84 if ((size & (size - 1)) == 0) { 85 // Size is zero or a power of two, so we got this. 86 return index & ~(size - 1); 87 } else { 88 return roundDownNPOT(index, size); 89 } 90 } 91 private static int roundDownNPOT(int index, int size) { 92 if (index >= 0) { 93 return index - (index % size); 94 } else { 95 return index - Math.floorMod(index, Math.abs(size)); 96 } 97 } 98 @ForceInline 99 static int wrapToRange(int index, int size) { 100 if ((size & (size - 1)) == 0) { 101 // Size is zero or a power of two, so we got this. 102 return index & (size - 1); 103 } else { 104 return wrapToRangeNPOT(index, size); 105 } 106 } 107 private static int wrapToRangeNPOT(int index, int size) { 108 if (index >= 0) { 109 return (index % size); 110 } else { 111 return Math.floorMod(index, Math.abs(size)); 112 } 113 } 114 }