mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
8266317: Vector API enhancements
Co-authored-by: Paul Sandoz <psandoz@openjdk.org> Co-authored-by: Sandhya Viswanathan <sviswanathan@openjdk.org> Reviewed-by: jbhateja, vlivanov
This commit is contained in:
parent
eb385c0de2
commit
5982cfc856
121 changed files with 9631 additions and 736 deletions
|
@ -834,6 +834,14 @@ final class Byte128Vector extends ByteVector {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
ByteVector fromBooleanArray0(boolean[] a, int offset) {
|
||||
return super.fromBooleanArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
|
@ -866,6 +866,14 @@ final class Byte256Vector extends ByteVector {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
ByteVector fromBooleanArray0(boolean[] a, int offset) {
|
||||
return super.fromBooleanArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
|
@ -930,6 +930,14 @@ final class Byte512Vector extends ByteVector {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
ByteVector fromBooleanArray0(boolean[] a, int offset) {
|
||||
return super.fromBooleanArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
|
@ -818,6 +818,14 @@ final class Byte64Vector extends ByteVector {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
ByteVector fromBooleanArray0(boolean[] a, int offset) {
|
||||
return super.fromBooleanArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
|
@ -804,6 +804,14 @@ final class ByteMaxVector extends ByteVector {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
ByteVector fromBooleanArray0(boolean[] a, int offset) {
|
||||
return super.fromBooleanArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
|
@ -379,20 +379,6 @@ public abstract class ByteVector extends AbstractVector<Byte> {
|
|||
return maskFactory(bits);
|
||||
}
|
||||
|
||||
/*package-private*/
|
||||
@ForceInline
|
||||
static boolean doBinTest(int cond, byte a, byte b) {
|
||||
switch (cond) {
|
||||
case BT_eq: return a == b;
|
||||
case BT_ne: return a != b;
|
||||
case BT_lt: return a < b;
|
||||
case BT_le: return a <= b;
|
||||
case BT_gt: return a > b;
|
||||
case BT_ge: return a >= b;
|
||||
}
|
||||
throw new AssertionError(Integer.toHexString(cond));
|
||||
}
|
||||
|
||||
/*package-private*/
|
||||
@Override
|
||||
abstract ByteSpecies vspecies();
|
||||
|
@ -1767,17 +1753,20 @@ public abstract class ByteVector extends AbstractVector<Byte> {
|
|||
}
|
||||
|
||||
@ForceInline
|
||||
private static
|
||||
boolean compareWithOp(int cond, byte a, byte b) {
|
||||
switch (cond) {
|
||||
case BT_eq: return a == b;
|
||||
case BT_ne: return a != b;
|
||||
case BT_lt: return a < b;
|
||||
case BT_le: return a <= b;
|
||||
case BT_gt: return a > b;
|
||||
case BT_ge: return a >= b;
|
||||
}
|
||||
throw new AssertionError();
|
||||
private static boolean compareWithOp(int cond, byte a, byte b) {
|
||||
return switch (cond) {
|
||||
case BT_eq -> a == b;
|
||||
case BT_ne -> a != b;
|
||||
case BT_lt -> a < b;
|
||||
case BT_le -> a <= b;
|
||||
case BT_gt -> a > b;
|
||||
case BT_ge -> a >= b;
|
||||
case BT_ult -> Byte.compareUnsigned(a, b) < 0;
|
||||
case BT_ule -> Byte.compareUnsigned(a, b) <= 0;
|
||||
case BT_ugt -> Byte.compareUnsigned(a, b) > 0;
|
||||
case BT_uge -> Byte.compareUnsigned(a, b) >= 0;
|
||||
default -> throw new AssertionError();
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2835,6 +2824,165 @@ public abstract class ByteVector extends AbstractVector<Byte> {
|
|||
return vsp.vOp(m, n -> a[offset + indexMap[mapOffset + n]]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Loads a vector from an array of type {@code boolean[]}
|
||||
* starting at an offset.
|
||||
* For each vector lane, where {@code N} is the vector lane index, the
|
||||
* array element at index {@code offset + N}
|
||||
* is first converted to a {@code byte} value and then
|
||||
* placed into the resulting vector at lane index {@code N}.
|
||||
* <p>
|
||||
* A {@code boolean} value is converted to a {@code byte} value by applying the
|
||||
* expression {@code (byte) (b ? 1 : 0)}, where {@code b} is the {@code boolean} value.
|
||||
*
|
||||
* @param species species of desired vector
|
||||
* @param a the array
|
||||
* @param offset the offset into the array
|
||||
* @return the vector loaded from an array
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code offset+N < 0} or {@code offset+N >= a.length}
|
||||
* for any lane {@code N} in the vector
|
||||
*/
|
||||
@ForceInline
|
||||
public static
|
||||
ByteVector fromBooleanArray(VectorSpecies<Byte> species,
|
||||
boolean[] a, int offset) {
|
||||
offset = checkFromIndexSize(offset, species.length(), a.length);
|
||||
ByteSpecies vsp = (ByteSpecies) species;
|
||||
return vsp.dummyVector().fromBooleanArray0(a, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a vector from an array of type {@code boolean[]}
|
||||
* starting at an offset and using a mask.
|
||||
* Lanes where the mask is unset are filled with the default
|
||||
* value of {@code byte} (zero).
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
* if the mask lane at index {@code N} is set then the array element at
|
||||
* index {@code offset + N}
|
||||
* is first converted to a {@code byte} value and then
|
||||
* placed into the resulting vector at lane index
|
||||
* {@code N}, otherwise the default element value is placed into the
|
||||
* resulting vector at lane index {@code N}.
|
||||
* <p>
|
||||
* A {@code boolean} value is converted to a {@code byte} value by applying the
|
||||
* expression {@code (byte) (b ? 1 : 0)}, where {@code b} is the {@code boolean} value.
|
||||
*
|
||||
* @param species species of desired vector
|
||||
* @param a the array
|
||||
* @param offset the offset into the array
|
||||
* @param m the mask controlling lane selection
|
||||
* @return the vector loaded from an array
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code offset+N < 0} or {@code offset+N >= a.length}
|
||||
* for any lane {@code N} in the vector
|
||||
* where the mask is set
|
||||
*/
|
||||
@ForceInline
|
||||
public static
|
||||
ByteVector fromBooleanArray(VectorSpecies<Byte> species,
|
||||
boolean[] a, int offset,
|
||||
VectorMask<Byte> m) {
|
||||
ByteSpecies vsp = (ByteSpecies) species;
|
||||
if (offset >= 0 && offset <= (a.length - species.length())) {
|
||||
ByteVector zero = vsp.zero();
|
||||
return zero.blend(zero.fromBooleanArray0(a, offset), m);
|
||||
}
|
||||
|
||||
// FIXME: optimize
|
||||
checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
|
||||
return vsp.vOp(m, i -> (byte) (a[offset + i] ? 1 : 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gathers a new vector composed of elements from an array of type
|
||||
* {@code boolean[]},
|
||||
* using indexes obtained by adding a fixed {@code offset} to a
|
||||
* series of secondary offsets from an <em>index map</em>.
|
||||
* The index map is a contiguous sequence of {@code VLENGTH}
|
||||
* elements in a second array of {@code int}s, starting at a given
|
||||
* {@code mapOffset}.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
* the lane is loaded from the expression
|
||||
* {@code (byte) (a[f(N)] ? 1 : 0)}, where {@code f(N)} is the
|
||||
* index mapping expression
|
||||
* {@code offset + indexMap[mapOffset + N]]}.
|
||||
*
|
||||
* @param species species of desired vector
|
||||
* @param a the array
|
||||
* @param offset the offset into the array, may be negative if relative
|
||||
* indexes in the index map compensate to produce a value within the
|
||||
* array bounds
|
||||
* @param indexMap the index map
|
||||
* @param mapOffset the offset into the index map
|
||||
* @return the vector loaded from the indexed elements of the array
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code mapOffset+N < 0}
|
||||
* or if {@code mapOffset+N >= indexMap.length},
|
||||
* or if {@code f(N)=offset+indexMap[mapOffset+N]}
|
||||
* is an invalid index into {@code a},
|
||||
* for any lane {@code N} in the vector
|
||||
* @see ByteVector#toIntArray()
|
||||
*/
|
||||
@ForceInline
|
||||
public static
|
||||
ByteVector fromBooleanArray(VectorSpecies<Byte> species,
|
||||
boolean[] a, int offset,
|
||||
int[] indexMap, int mapOffset) {
|
||||
// FIXME: optimize
|
||||
ByteSpecies vsp = (ByteSpecies) species;
|
||||
return vsp.vOp(n -> (byte) (a[offset + indexMap[mapOffset + n]] ? 1 : 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gathers a new vector composed of elements from an array of type
|
||||
* {@code boolean[]},
|
||||
* under the control of a mask, and
|
||||
* using indexes obtained by adding a fixed {@code offset} to a
|
||||
* series of secondary offsets from an <em>index map</em>.
|
||||
* The index map is a contiguous sequence of {@code VLENGTH}
|
||||
* elements in a second array of {@code int}s, starting at a given
|
||||
* {@code mapOffset}.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
* if the lane is set in the mask,
|
||||
* the lane is loaded from the expression
|
||||
* {@code (byte) (a[f(N)] ? 1 : 0)}, where {@code f(N)} is the
|
||||
* index mapping expression
|
||||
* {@code offset + indexMap[mapOffset + N]]}.
|
||||
* Unset lanes in the resulting vector are set to zero.
|
||||
*
|
||||
* @param species species of desired vector
|
||||
* @param a the array
|
||||
* @param offset the offset into the array, may be negative if relative
|
||||
* indexes in the index map compensate to produce a value within the
|
||||
* array bounds
|
||||
* @param indexMap the index map
|
||||
* @param mapOffset the offset into the index map
|
||||
* @param m the mask controlling lane selection
|
||||
* @return the vector loaded from the indexed elements of the array
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code mapOffset+N < 0}
|
||||
* or if {@code mapOffset+N >= indexMap.length},
|
||||
* or if {@code f(N)=offset+indexMap[mapOffset+N]}
|
||||
* is an invalid index into {@code a},
|
||||
* for any lane {@code N} in the vector
|
||||
* where the mask is set
|
||||
* @see ByteVector#toIntArray()
|
||||
*/
|
||||
@ForceInline
|
||||
public static
|
||||
ByteVector fromBooleanArray(VectorSpecies<Byte> species,
|
||||
boolean[] a, int offset,
|
||||
int[] indexMap, int mapOffset,
|
||||
VectorMask<Byte> m) {
|
||||
// FIXME: optimize
|
||||
ByteSpecies vsp = (ByteSpecies) species;
|
||||
return vsp.vOp(m, n -> (byte) (a[offset + indexMap[mapOffset + n]] ? 1 : 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a vector from a {@linkplain ByteBuffer byte buffer}
|
||||
* starting at an offset into the byte buffer.
|
||||
|
@ -2961,7 +3109,7 @@ public abstract class ByteVector extends AbstractVector<Byte> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Stores this vector into an array of {@code byte}
|
||||
* Stores this vector into an array of type {@code byte[]}
|
||||
* starting at offset and using a mask.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
|
@ -3077,6 +3225,174 @@ public abstract class ByteVector extends AbstractVector<Byte> {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Stores this vector into an array of type {@code boolean[]}
|
||||
* starting at an offset.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
* the lane element at index {@code N}
|
||||
* is first converted to a {@code boolean} value and then
|
||||
* stored into the array element {@code a[offset+N]}.
|
||||
* <p>
|
||||
* A {@code byte} value is converted to a {@code boolean} value by applying the
|
||||
* expression {@code (b & 1) != 0} where {@code b} is the byte value.
|
||||
*
|
||||
* @param a the array
|
||||
* @param offset the offset into the array
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code offset+N < 0} or {@code offset+N >= a.length}
|
||||
* for any lane {@code N} in the vector
|
||||
*/
|
||||
@ForceInline
|
||||
public final
|
||||
void intoBooleanArray(boolean[] a, int offset) {
|
||||
offset = checkFromIndexSize(offset, length(), a.length);
|
||||
ByteSpecies vsp = vspecies();
|
||||
ByteVector normalized = this.and((byte) 1);
|
||||
VectorSupport.store(
|
||||
vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
|
||||
a, booleanArrayAddress(a, offset),
|
||||
normalized,
|
||||
a, offset,
|
||||
(arr, off, v)
|
||||
-> v.stOp(arr, off,
|
||||
(arr_, off_, i, e) -> arr_[off_ + i] = (e & 1) != 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores this vector into an array of type {@code boolean[]}
|
||||
* starting at offset and using a mask.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
* the lane element at index {@code N}
|
||||
* is first converted to a {@code boolean} value and then
|
||||
* stored into the array element {@code a[offset+N]}.
|
||||
* If the mask lane at {@code N} is unset then the corresponding
|
||||
* array element {@code a[offset+N]} is left unchanged.
|
||||
* <p>
|
||||
* A {@code byte} value is converted to a {@code boolean} value by applying the
|
||||
* expression {@code (b & 1) != 0} where {@code b} is the byte value.
|
||||
* <p>
|
||||
* Array range checking is done for lanes where the mask is set.
|
||||
* Lanes where the mask is unset are not stored and do not need
|
||||
* to correspond to legitimate elements of {@code a}.
|
||||
* That is, unset lanes may correspond to array indexes less than
|
||||
* zero or beyond the end of the array.
|
||||
*
|
||||
* @param a the array
|
||||
* @param offset the offset into the array
|
||||
* @param m the mask controlling lane storage
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code offset+N < 0} or {@code offset+N >= a.length}
|
||||
* for any lane {@code N} in the vector
|
||||
* where the mask is set
|
||||
*/
|
||||
@ForceInline
|
||||
public final
|
||||
void intoBooleanArray(boolean[] a, int offset,
|
||||
VectorMask<Byte> m) {
|
||||
if (m.allTrue()) {
|
||||
intoBooleanArray(a, offset);
|
||||
} else {
|
||||
// FIXME: optimize
|
||||
ByteSpecies vsp = vspecies();
|
||||
checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
|
||||
stOp(a, offset, m, (arr, off, i, e) -> arr[off+i] = (e & 1) != 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scatters this vector into an array of type {@code boolean[]}
|
||||
* using indexes obtained by adding a fixed {@code offset} to a
|
||||
* series of secondary offsets from an <em>index map</em>.
|
||||
* The index map is a contiguous sequence of {@code VLENGTH}
|
||||
* elements in a second array of {@code int}s, starting at a given
|
||||
* {@code mapOffset}.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
* the lane element at index {@code N}
|
||||
* is first converted to a {@code boolean} value and then
|
||||
* stored into the array
|
||||
* element {@code a[f(N)]}, where {@code f(N)} is the
|
||||
* index mapping expression
|
||||
* {@code offset + indexMap[mapOffset + N]]}.
|
||||
* <p>
|
||||
* A {@code byte} value is converted to a {@code boolean} value by applying the
|
||||
* expression {@code (b & 1) != 0} where {@code b} is the byte value.
|
||||
*
|
||||
* @param a the array
|
||||
* @param offset an offset to combine with the index map offsets
|
||||
* @param indexMap the index map
|
||||
* @param mapOffset the offset into the index map
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code mapOffset+N < 0}
|
||||
* or if {@code mapOffset+N >= indexMap.length},
|
||||
* or if {@code f(N)=offset+indexMap[mapOffset+N]}
|
||||
* is an invalid index into {@code a},
|
||||
* for any lane {@code N} in the vector
|
||||
* @see ByteVector#toIntArray()
|
||||
*/
|
||||
@ForceInline
|
||||
public final
|
||||
void intoBooleanArray(boolean[] a, int offset,
|
||||
int[] indexMap, int mapOffset) {
|
||||
// FIXME: optimize
|
||||
stOp(a, offset,
|
||||
(arr, off, i, e) -> {
|
||||
int j = indexMap[mapOffset + i];
|
||||
arr[off + j] = (e & 1) != 0;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Scatters this vector into an array of type {@code boolean[]},
|
||||
* under the control of a mask, and
|
||||
* using indexes obtained by adding a fixed {@code offset} to a
|
||||
* series of secondary offsets from an <em>index map</em>.
|
||||
* The index map is a contiguous sequence of {@code VLENGTH}
|
||||
* elements in a second array of {@code int}s, starting at a given
|
||||
* {@code mapOffset}.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
* if the mask lane at index {@code N} is set then
|
||||
* the lane element at index {@code N}
|
||||
* is first converted to a {@code boolean} value and then
|
||||
* stored into the array
|
||||
* element {@code a[f(N)]}, where {@code f(N)} is the
|
||||
* index mapping expression
|
||||
* {@code offset + indexMap[mapOffset + N]]}.
|
||||
* <p>
|
||||
* A {@code byte} value is converted to a {@code boolean} value by applying the
|
||||
* expression {@code (b & 1) != 0} where {@code b} is the byte value.
|
||||
*
|
||||
* @param a the array
|
||||
* @param offset an offset to combine with the index map offsets
|
||||
* @param indexMap the index map
|
||||
* @param mapOffset the offset into the index map
|
||||
* @param m the mask
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code mapOffset+N < 0}
|
||||
* or if {@code mapOffset+N >= indexMap.length},
|
||||
* or if {@code f(N)=offset+indexMap[mapOffset+N]}
|
||||
* is an invalid index into {@code a},
|
||||
* for any lane {@code N} in the vector
|
||||
* where the mask is set
|
||||
* @see ByteVector#toIntArray()
|
||||
*/
|
||||
@ForceInline
|
||||
public final
|
||||
void intoBooleanArray(boolean[] a, int offset,
|
||||
int[] indexMap, int mapOffset,
|
||||
VectorMask<Byte> m) {
|
||||
// FIXME: optimize
|
||||
stOp(a, offset, m,
|
||||
(arr, off, i, e) -> {
|
||||
int j = indexMap[mapOffset + i];
|
||||
arr[off + j] = (e & 1) != 0;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc} <!--workaround-->
|
||||
*/
|
||||
|
@ -3183,6 +3499,22 @@ public abstract class ByteVector extends AbstractVector<Byte> {
|
|||
(arr_, off_, i) -> arr_[off_ + i]));
|
||||
}
|
||||
|
||||
|
||||
/*package-private*/
|
||||
abstract
|
||||
ByteVector fromBooleanArray0(boolean[] a, int offset);
|
||||
@ForceInline
|
||||
final
|
||||
ByteVector fromBooleanArray0Template(boolean[] a, int offset) {
|
||||
ByteSpecies vsp = vspecies();
|
||||
return VectorSupport.load(
|
||||
vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
|
||||
a, booleanArrayAddress(a, offset),
|
||||
a, offset, vsp,
|
||||
(arr, off, s) -> s.ldOp(arr, off,
|
||||
(arr_, off_, i) -> (byte) (arr_[off_ + i] ? 1 : 0)));
|
||||
}
|
||||
|
||||
@Override
|
||||
abstract
|
||||
ByteVector fromByteArray0(byte[] a, int offset);
|
||||
|
@ -3313,6 +3645,17 @@ public abstract class ByteVector extends AbstractVector<Byte> {
|
|||
return ARRAY_BASE + (((long)index) << ARRAY_SHIFT);
|
||||
}
|
||||
|
||||
|
||||
static final int ARRAY_BOOLEAN_SHIFT =
|
||||
31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_BOOLEAN_INDEX_SCALE);
|
||||
static final long ARRAY_BOOLEAN_BASE =
|
||||
Unsafe.ARRAY_BOOLEAN_BASE_OFFSET;
|
||||
|
||||
@ForceInline
|
||||
static long booleanArrayAddress(boolean[] a, int index) {
|
||||
return ARRAY_BOOLEAN_BASE + (((long)index) << ARRAY_BOOLEAN_SHIFT);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static long byteArrayAddress(byte[] a, int index) {
|
||||
return Unsafe.ARRAY_BYTE_BASE_OFFSET + index;
|
||||
|
|
|
@ -802,6 +802,8 @@ final class Double128Vector extends DoubleVector {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
|
@ -806,6 +806,8 @@ final class Double256Vector extends DoubleVector {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
|
@ -814,6 +814,8 @@ final class Double512Vector extends DoubleVector {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
|
@ -800,6 +800,8 @@ final class Double64Vector extends DoubleVector {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
|
@ -799,6 +799,8 @@ final class DoubleMaxVector extends DoubleVector {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
|
@ -379,20 +379,6 @@ public abstract class DoubleVector extends AbstractVector<Double> {
|
|||
return maskFactory(bits);
|
||||
}
|
||||
|
||||
/*package-private*/
|
||||
@ForceInline
|
||||
static boolean doBinTest(int cond, double a, double b) {
|
||||
switch (cond) {
|
||||
case BT_eq: return a == b;
|
||||
case BT_ne: return a != b;
|
||||
case BT_lt: return a < b;
|
||||
case BT_le: return a <= b;
|
||||
case BT_gt: return a > b;
|
||||
case BT_ge: return a >= b;
|
||||
}
|
||||
throw new AssertionError(Integer.toHexString(cond));
|
||||
}
|
||||
|
||||
/*package-private*/
|
||||
@Override
|
||||
abstract DoubleSpecies vspecies();
|
||||
|
@ -1680,17 +1666,16 @@ public abstract class DoubleVector extends AbstractVector<Double> {
|
|||
}
|
||||
|
||||
@ForceInline
|
||||
private static
|
||||
boolean compareWithOp(int cond, double a, double b) {
|
||||
switch (cond) {
|
||||
case BT_eq: return a == b;
|
||||
case BT_ne: return a != b;
|
||||
case BT_lt: return a < b;
|
||||
case BT_le: return a <= b;
|
||||
case BT_gt: return a > b;
|
||||
case BT_ge: return a >= b;
|
||||
}
|
||||
throw new AssertionError();
|
||||
private static boolean compareWithOp(int cond, double a, double b) {
|
||||
return switch (cond) {
|
||||
case BT_eq -> a == b;
|
||||
case BT_ne -> a != b;
|
||||
case BT_lt -> a < b;
|
||||
case BT_le -> a <= b;
|
||||
case BT_gt -> a > b;
|
||||
case BT_ge -> a >= b;
|
||||
default -> throw new AssertionError();
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2742,6 +2727,8 @@ public abstract class DoubleVector extends AbstractVector<Double> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Loads a vector from a {@linkplain ByteBuffer byte buffer}
|
||||
* starting at an offset into the byte buffer.
|
||||
|
@ -2874,7 +2861,7 @@ public abstract class DoubleVector extends AbstractVector<Double> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Stores this vector into an array of {@code double}
|
||||
* Stores this vector into an array of type {@code double[]}
|
||||
* starting at offset and using a mask.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
|
@ -3031,6 +3018,8 @@ public abstract class DoubleVector extends AbstractVector<Double> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc} <!--workaround-->
|
||||
*/
|
||||
|
@ -3137,6 +3126,8 @@ public abstract class DoubleVector extends AbstractVector<Double> {
|
|||
(arr_, off_, i) -> arr_[off_ + i]));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
abstract
|
||||
DoubleVector fromByteArray0(byte[] a, int offset);
|
||||
|
@ -3272,6 +3263,8 @@ public abstract class DoubleVector extends AbstractVector<Double> {
|
|||
return ARRAY_BASE + (((long)index) << ARRAY_SHIFT);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ForceInline
|
||||
static long byteArrayAddress(byte[] a, int index) {
|
||||
return Unsafe.ARRAY_BYTE_BASE_OFFSET + index;
|
||||
|
|
|
@ -806,6 +806,8 @@ final class Float128Vector extends FloatVector {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
|
@ -814,6 +814,8 @@ final class Float256Vector extends FloatVector {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
|
@ -830,6 +830,8 @@ final class Float512Vector extends FloatVector {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
|
@ -802,6 +802,8 @@ final class Float64Vector extends FloatVector {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
|
@ -799,6 +799,8 @@ final class FloatMaxVector extends FloatVector {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
|
@ -379,20 +379,6 @@ public abstract class FloatVector extends AbstractVector<Float> {
|
|||
return maskFactory(bits);
|
||||
}
|
||||
|
||||
/*package-private*/
|
||||
@ForceInline
|
||||
static boolean doBinTest(int cond, float a, float b) {
|
||||
switch (cond) {
|
||||
case BT_eq: return a == b;
|
||||
case BT_ne: return a != b;
|
||||
case BT_lt: return a < b;
|
||||
case BT_le: return a <= b;
|
||||
case BT_gt: return a > b;
|
||||
case BT_ge: return a >= b;
|
||||
}
|
||||
throw new AssertionError(Integer.toHexString(cond));
|
||||
}
|
||||
|
||||
/*package-private*/
|
||||
@Override
|
||||
abstract FloatSpecies vspecies();
|
||||
|
@ -1692,17 +1678,16 @@ public abstract class FloatVector extends AbstractVector<Float> {
|
|||
}
|
||||
|
||||
@ForceInline
|
||||
private static
|
||||
boolean compareWithOp(int cond, float a, float b) {
|
||||
switch (cond) {
|
||||
case BT_eq: return a == b;
|
||||
case BT_ne: return a != b;
|
||||
case BT_lt: return a < b;
|
||||
case BT_le: return a <= b;
|
||||
case BT_gt: return a > b;
|
||||
case BT_ge: return a >= b;
|
||||
}
|
||||
throw new AssertionError();
|
||||
private static boolean compareWithOp(int cond, float a, float b) {
|
||||
return switch (cond) {
|
||||
case BT_eq -> a == b;
|
||||
case BT_ne -> a != b;
|
||||
case BT_lt -> a < b;
|
||||
case BT_le -> a <= b;
|
||||
case BT_gt -> a > b;
|
||||
case BT_ge -> a >= b;
|
||||
default -> throw new AssertionError();
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2748,6 +2733,8 @@ public abstract class FloatVector extends AbstractVector<Float> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Loads a vector from a {@linkplain ByteBuffer byte buffer}
|
||||
* starting at an offset into the byte buffer.
|
||||
|
@ -2880,7 +2867,7 @@ public abstract class FloatVector extends AbstractVector<Float> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Stores this vector into an array of {@code float}
|
||||
* Stores this vector into an array of type {@code float[]}
|
||||
* starting at offset and using a mask.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
|
@ -3018,6 +3005,8 @@ public abstract class FloatVector extends AbstractVector<Float> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc} <!--workaround-->
|
||||
*/
|
||||
|
@ -3124,6 +3113,8 @@ public abstract class FloatVector extends AbstractVector<Float> {
|
|||
(arr_, off_, i) -> arr_[off_ + i]));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
abstract
|
||||
FloatVector fromByteArray0(byte[] a, int offset);
|
||||
|
@ -3259,6 +3250,8 @@ public abstract class FloatVector extends AbstractVector<Float> {
|
|||
return ARRAY_BASE + (((long)index) << ARRAY_SHIFT);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ForceInline
|
||||
static long byteArrayAddress(byte[] a, int index) {
|
||||
return Unsafe.ARRAY_BYTE_BASE_OFFSET + index;
|
||||
|
|
|
@ -810,6 +810,8 @@ final class Int128Vector extends IntVector {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
|
@ -818,6 +818,8 @@ final class Int256Vector extends IntVector {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
|
@ -834,6 +834,8 @@ final class Int512Vector extends IntVector {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
|
@ -806,6 +806,8 @@ final class Int64Vector extends IntVector {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
|
@ -815,6 +815,8 @@ final class IntMaxVector extends IntVector {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
|
@ -379,20 +379,6 @@ public abstract class IntVector extends AbstractVector<Integer> {
|
|||
return maskFactory(bits);
|
||||
}
|
||||
|
||||
/*package-private*/
|
||||
@ForceInline
|
||||
static boolean doBinTest(int cond, int a, int b) {
|
||||
switch (cond) {
|
||||
case BT_eq: return a == b;
|
||||
case BT_ne: return a != b;
|
||||
case BT_lt: return a < b;
|
||||
case BT_le: return a <= b;
|
||||
case BT_gt: return a > b;
|
||||
case BT_ge: return a >= b;
|
||||
}
|
||||
throw new AssertionError(Integer.toHexString(cond));
|
||||
}
|
||||
|
||||
/*package-private*/
|
||||
@Override
|
||||
abstract IntSpecies vspecies();
|
||||
|
@ -1766,17 +1752,20 @@ public abstract class IntVector extends AbstractVector<Integer> {
|
|||
}
|
||||
|
||||
@ForceInline
|
||||
private static
|
||||
boolean compareWithOp(int cond, int a, int b) {
|
||||
switch (cond) {
|
||||
case BT_eq: return a == b;
|
||||
case BT_ne: return a != b;
|
||||
case BT_lt: return a < b;
|
||||
case BT_le: return a <= b;
|
||||
case BT_gt: return a > b;
|
||||
case BT_ge: return a >= b;
|
||||
}
|
||||
throw new AssertionError();
|
||||
private static boolean compareWithOp(int cond, int a, int b) {
|
||||
return switch (cond) {
|
||||
case BT_eq -> a == b;
|
||||
case BT_ne -> a != b;
|
||||
case BT_lt -> a < b;
|
||||
case BT_le -> a <= b;
|
||||
case BT_gt -> a > b;
|
||||
case BT_ge -> a >= b;
|
||||
case BT_ult -> Integer.compareUnsigned(a, b) < 0;
|
||||
case BT_ule -> Integer.compareUnsigned(a, b) <= 0;
|
||||
case BT_ugt -> Integer.compareUnsigned(a, b) > 0;
|
||||
case BT_uge -> Integer.compareUnsigned(a, b) >= 0;
|
||||
default -> throw new AssertionError();
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2851,6 +2840,8 @@ public abstract class IntVector extends AbstractVector<Integer> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Loads a vector from a {@linkplain ByteBuffer byte buffer}
|
||||
* starting at an offset into the byte buffer.
|
||||
|
@ -2983,7 +2974,7 @@ public abstract class IntVector extends AbstractVector<Integer> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Stores this vector into an array of {@code int}
|
||||
* Stores this vector into an array of type {@code int[]}
|
||||
* starting at offset and using a mask.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
|
@ -3121,6 +3112,8 @@ public abstract class IntVector extends AbstractVector<Integer> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc} <!--workaround-->
|
||||
*/
|
||||
|
@ -3227,6 +3220,8 @@ public abstract class IntVector extends AbstractVector<Integer> {
|
|||
(arr_, off_, i) -> arr_[off_ + i]));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
abstract
|
||||
IntVector fromByteArray0(byte[] a, int offset);
|
||||
|
@ -3362,6 +3357,8 @@ public abstract class IntVector extends AbstractVector<Integer> {
|
|||
return ARRAY_BASE + (((long)index) << ARRAY_SHIFT);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ForceInline
|
||||
static long byteArrayAddress(byte[] a, int index) {
|
||||
return Unsafe.ARRAY_BYTE_BASE_OFFSET + index;
|
||||
|
|
|
@ -796,6 +796,8 @@ final class Long128Vector extends LongVector {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
|
@ -800,6 +800,8 @@ final class Long256Vector extends LongVector {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
|
@ -808,6 +808,8 @@ final class Long512Vector extends LongVector {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
|
@ -794,6 +794,8 @@ final class Long64Vector extends LongVector {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
|
@ -794,6 +794,8 @@ final class LongMaxVector extends LongVector {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
|
@ -379,20 +379,6 @@ public abstract class LongVector extends AbstractVector<Long> {
|
|||
return maskFactory(bits);
|
||||
}
|
||||
|
||||
/*package-private*/
|
||||
@ForceInline
|
||||
static boolean doBinTest(int cond, long a, long b) {
|
||||
switch (cond) {
|
||||
case BT_eq: return a == b;
|
||||
case BT_ne: return a != b;
|
||||
case BT_lt: return a < b;
|
||||
case BT_le: return a <= b;
|
||||
case BT_gt: return a > b;
|
||||
case BT_ge: return a >= b;
|
||||
}
|
||||
throw new AssertionError(Integer.toHexString(cond));
|
||||
}
|
||||
|
||||
/*package-private*/
|
||||
@Override
|
||||
abstract LongSpecies vspecies();
|
||||
|
@ -1684,17 +1670,20 @@ public abstract class LongVector extends AbstractVector<Long> {
|
|||
}
|
||||
|
||||
@ForceInline
|
||||
private static
|
||||
boolean compareWithOp(int cond, long a, long b) {
|
||||
switch (cond) {
|
||||
case BT_eq: return a == b;
|
||||
case BT_ne: return a != b;
|
||||
case BT_lt: return a < b;
|
||||
case BT_le: return a <= b;
|
||||
case BT_gt: return a > b;
|
||||
case BT_ge: return a >= b;
|
||||
}
|
||||
throw new AssertionError();
|
||||
private static boolean compareWithOp(int cond, long a, long b) {
|
||||
return switch (cond) {
|
||||
case BT_eq -> a == b;
|
||||
case BT_ne -> a != b;
|
||||
case BT_lt -> a < b;
|
||||
case BT_le -> a <= b;
|
||||
case BT_gt -> a > b;
|
||||
case BT_ge -> a >= b;
|
||||
case BT_ult -> Long.compareUnsigned(a, b) < 0;
|
||||
case BT_ule -> Long.compareUnsigned(a, b) <= 0;
|
||||
case BT_ugt -> Long.compareUnsigned(a, b) > 0;
|
||||
case BT_uge -> Long.compareUnsigned(a, b) >= 0;
|
||||
default -> throw new AssertionError();
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2735,6 +2724,8 @@ public abstract class LongVector extends AbstractVector<Long> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Loads a vector from a {@linkplain ByteBuffer byte buffer}
|
||||
* starting at an offset into the byte buffer.
|
||||
|
@ -2867,7 +2858,7 @@ public abstract class LongVector extends AbstractVector<Long> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Stores this vector into an array of {@code long}
|
||||
* Stores this vector into an array of type {@code long[]}
|
||||
* starting at offset and using a mask.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
|
@ -3024,6 +3015,8 @@ public abstract class LongVector extends AbstractVector<Long> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc} <!--workaround-->
|
||||
*/
|
||||
|
@ -3130,6 +3123,8 @@ public abstract class LongVector extends AbstractVector<Long> {
|
|||
(arr_, off_, i) -> arr_[off_ + i]));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
abstract
|
||||
LongVector fromByteArray0(byte[] a, int offset);
|
||||
|
@ -3265,6 +3260,8 @@ public abstract class LongVector extends AbstractVector<Long> {
|
|||
return ARRAY_BASE + (((long)index) << ARRAY_SHIFT);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ForceInline
|
||||
static long byteArrayAddress(byte[] a, int index) {
|
||||
return Unsafe.ARRAY_BYTE_BASE_OFFSET + index;
|
||||
|
|
|
@ -818,6 +818,14 @@ final class Short128Vector extends ShortVector {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
ShortVector fromCharArray0(char[] a, int offset) {
|
||||
return super.fromCharArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
|
@ -834,6 +834,14 @@ final class Short256Vector extends ShortVector {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
ShortVector fromCharArray0(char[] a, int offset) {
|
||||
return super.fromCharArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
|
@ -866,6 +866,14 @@ final class Short512Vector extends ShortVector {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
ShortVector fromCharArray0(char[] a, int offset) {
|
||||
return super.fromCharArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
|
@ -810,6 +810,14 @@ final class Short64Vector extends ShortVector {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
ShortVector fromCharArray0(char[] a, int offset) {
|
||||
return super.fromCharArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
|
@ -804,6 +804,14 @@ final class ShortMaxVector extends ShortVector {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
ShortVector fromCharArray0(char[] a, int offset) {
|
||||
return super.fromCharArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
|
@ -379,20 +379,6 @@ public abstract class ShortVector extends AbstractVector<Short> {
|
|||
return maskFactory(bits);
|
||||
}
|
||||
|
||||
/*package-private*/
|
||||
@ForceInline
|
||||
static boolean doBinTest(int cond, short a, short b) {
|
||||
switch (cond) {
|
||||
case BT_eq: return a == b;
|
||||
case BT_ne: return a != b;
|
||||
case BT_lt: return a < b;
|
||||
case BT_le: return a <= b;
|
||||
case BT_gt: return a > b;
|
||||
case BT_ge: return a >= b;
|
||||
}
|
||||
throw new AssertionError(Integer.toHexString(cond));
|
||||
}
|
||||
|
||||
/*package-private*/
|
||||
@Override
|
||||
abstract ShortSpecies vspecies();
|
||||
|
@ -1767,17 +1753,20 @@ public abstract class ShortVector extends AbstractVector<Short> {
|
|||
}
|
||||
|
||||
@ForceInline
|
||||
private static
|
||||
boolean compareWithOp(int cond, short a, short b) {
|
||||
switch (cond) {
|
||||
case BT_eq: return a == b;
|
||||
case BT_ne: return a != b;
|
||||
case BT_lt: return a < b;
|
||||
case BT_le: return a <= b;
|
||||
case BT_gt: return a > b;
|
||||
case BT_ge: return a >= b;
|
||||
}
|
||||
throw new AssertionError();
|
||||
private static boolean compareWithOp(int cond, short a, short b) {
|
||||
return switch (cond) {
|
||||
case BT_eq -> a == b;
|
||||
case BT_ne -> a != b;
|
||||
case BT_lt -> a < b;
|
||||
case BT_le -> a <= b;
|
||||
case BT_gt -> a > b;
|
||||
case BT_ge -> a >= b;
|
||||
case BT_ult -> Short.compareUnsigned(a, b) < 0;
|
||||
case BT_ule -> Short.compareUnsigned(a, b) <= 0;
|
||||
case BT_ugt -> Short.compareUnsigned(a, b) > 0;
|
||||
case BT_uge -> Short.compareUnsigned(a, b) >= 0;
|
||||
default -> throw new AssertionError();
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2835,6 +2824,159 @@ public abstract class ShortVector extends AbstractVector<Short> {
|
|||
return vsp.vOp(m, n -> a[offset + indexMap[mapOffset + n]]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a vector from an array of type {@code char[]}
|
||||
* starting at an offset.
|
||||
* For each vector lane, where {@code N} is the vector lane index, the
|
||||
* array element at index {@code offset + N}
|
||||
* is first cast to a {@code short} value and then
|
||||
* placed into the resulting vector at lane index {@code N}.
|
||||
*
|
||||
* @param species species of desired vector
|
||||
* @param a the array
|
||||
* @param offset the offset into the array
|
||||
* @return the vector loaded from an array
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code offset+N < 0} or {@code offset+N >= a.length}
|
||||
* for any lane {@code N} in the vector
|
||||
*/
|
||||
@ForceInline
|
||||
public static
|
||||
ShortVector fromCharArray(VectorSpecies<Short> species,
|
||||
char[] a, int offset) {
|
||||
offset = checkFromIndexSize(offset, species.length(), a.length);
|
||||
ShortSpecies vsp = (ShortSpecies) species;
|
||||
return vsp.dummyVector().fromCharArray0(a, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a vector from an array of type {@code char[]}
|
||||
* starting at an offset and using a mask.
|
||||
* Lanes where the mask is unset are filled with the default
|
||||
* value of {@code short} (zero).
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
* if the mask lane at index {@code N} is set then the array element at
|
||||
* index {@code offset + N}
|
||||
* is first cast to a {@code short} value and then
|
||||
* placed into the resulting vector at lane index
|
||||
* {@code N}, otherwise the default element value is placed into the
|
||||
* resulting vector at lane index {@code N}.
|
||||
*
|
||||
* @param species species of desired vector
|
||||
* @param a the array
|
||||
* @param offset the offset into the array
|
||||
* @param m the mask controlling lane selection
|
||||
* @return the vector loaded from an array
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code offset+N < 0} or {@code offset+N >= a.length}
|
||||
* for any lane {@code N} in the vector
|
||||
* where the mask is set
|
||||
*/
|
||||
@ForceInline
|
||||
public static
|
||||
ShortVector fromCharArray(VectorSpecies<Short> species,
|
||||
char[] a, int offset,
|
||||
VectorMask<Short> m) {
|
||||
ShortSpecies vsp = (ShortSpecies) species;
|
||||
if (offset >= 0 && offset <= (a.length - species.length())) {
|
||||
ShortVector zero = vsp.zero();
|
||||
return zero.blend(zero.fromCharArray0(a, offset), m);
|
||||
}
|
||||
|
||||
// FIXME: optimize
|
||||
checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
|
||||
return vsp.vOp(m, i -> (short) a[offset + i]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gathers a new vector composed of elements from an array of type
|
||||
* {@code char[]},
|
||||
* using indexes obtained by adding a fixed {@code offset} to a
|
||||
* series of secondary offsets from an <em>index map</em>.
|
||||
* The index map is a contiguous sequence of {@code VLENGTH}
|
||||
* elements in a second array of {@code int}s, starting at a given
|
||||
* {@code mapOffset}.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
* the lane is loaded from the expression
|
||||
* {@code (short) a[f(N)]}, where {@code f(N)} is the
|
||||
* index mapping expression
|
||||
* {@code offset + indexMap[mapOffset + N]]}.
|
||||
*
|
||||
* @param species species of desired vector
|
||||
* @param a the array
|
||||
* @param offset the offset into the array, may be negative if relative
|
||||
* indexes in the index map compensate to produce a value within the
|
||||
* array bounds
|
||||
* @param indexMap the index map
|
||||
* @param mapOffset the offset into the index map
|
||||
* @return the vector loaded from the indexed elements of the array
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code mapOffset+N < 0}
|
||||
* or if {@code mapOffset+N >= indexMap.length},
|
||||
* or if {@code f(N)=offset+indexMap[mapOffset+N]}
|
||||
* is an invalid index into {@code a},
|
||||
* for any lane {@code N} in the vector
|
||||
* @see ShortVector#toIntArray()
|
||||
*/
|
||||
@ForceInline
|
||||
public static
|
||||
ShortVector fromCharArray(VectorSpecies<Short> species,
|
||||
char[] a, int offset,
|
||||
int[] indexMap, int mapOffset) {
|
||||
// FIXME: optimize
|
||||
ShortSpecies vsp = (ShortSpecies) species;
|
||||
return vsp.vOp(n -> (short) a[offset + indexMap[mapOffset + n]]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gathers a new vector composed of elements from an array of type
|
||||
* {@code char[]},
|
||||
* under the control of a mask, and
|
||||
* using indexes obtained by adding a fixed {@code offset} to a
|
||||
* series of secondary offsets from an <em>index map</em>.
|
||||
* The index map is a contiguous sequence of {@code VLENGTH}
|
||||
* elements in a second array of {@code int}s, starting at a given
|
||||
* {@code mapOffset}.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
* if the lane is set in the mask,
|
||||
* the lane is loaded from the expression
|
||||
* {@code (short) a[f(N)]}, where {@code f(N)} is the
|
||||
* index mapping expression
|
||||
* {@code offset + indexMap[mapOffset + N]]}.
|
||||
* Unset lanes in the resulting vector are set to zero.
|
||||
*
|
||||
* @param species species of desired vector
|
||||
* @param a the array
|
||||
* @param offset the offset into the array, may be negative if relative
|
||||
* indexes in the index map compensate to produce a value within the
|
||||
* array bounds
|
||||
* @param indexMap the index map
|
||||
* @param mapOffset the offset into the index map
|
||||
* @param m the mask controlling lane selection
|
||||
* @return the vector loaded from the indexed elements of the array
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code mapOffset+N < 0}
|
||||
* or if {@code mapOffset+N >= indexMap.length},
|
||||
* or if {@code f(N)=offset+indexMap[mapOffset+N]}
|
||||
* is an invalid index into {@code a},
|
||||
* for any lane {@code N} in the vector
|
||||
* where the mask is set
|
||||
* @see ShortVector#toIntArray()
|
||||
*/
|
||||
@ForceInline
|
||||
public static
|
||||
ShortVector fromCharArray(VectorSpecies<Short> species,
|
||||
char[] a, int offset,
|
||||
int[] indexMap, int mapOffset,
|
||||
VectorMask<Short> m) {
|
||||
// FIXME: optimize
|
||||
ShortSpecies vsp = (ShortSpecies) species;
|
||||
return vsp.vOp(m, n -> (short) a[offset + indexMap[mapOffset + n]]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Loads a vector from a {@linkplain ByteBuffer byte buffer}
|
||||
* starting at an offset into the byte buffer.
|
||||
|
@ -2967,7 +3109,7 @@ public abstract class ShortVector extends AbstractVector<Short> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Stores this vector into an array of {@code short}
|
||||
* Stores this vector into an array of type {@code short[]}
|
||||
* starting at offset and using a mask.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
|
@ -3083,6 +3225,161 @@ public abstract class ShortVector extends AbstractVector<Short> {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores this vector into an array of type {@code char[]}
|
||||
* starting at an offset.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
* the lane element at index {@code N}
|
||||
* is first cast to a {@code char} value and then
|
||||
* stored into the array element {@code a[offset+N]}.
|
||||
*
|
||||
* @param a the array, of type {@code char[]}
|
||||
* @param offset the offset into the array
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code offset+N < 0} or {@code offset+N >= a.length}
|
||||
* for any lane {@code N} in the vector
|
||||
*/
|
||||
@ForceInline
|
||||
public final
|
||||
void intoCharArray(char[] a, int offset) {
|
||||
offset = checkFromIndexSize(offset, length(), a.length);
|
||||
ShortSpecies vsp = vspecies();
|
||||
VectorSupport.store(
|
||||
vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
|
||||
a, charArrayAddress(a, offset),
|
||||
this,
|
||||
a, offset,
|
||||
(arr, off, v)
|
||||
-> v.stOp(arr, off,
|
||||
(arr_, off_, i, e) -> arr_[off_ + i] = (char) e));
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores this vector into an array of type {@code char[]}
|
||||
* starting at offset and using a mask.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
* the lane element at index {@code N}
|
||||
* is first cast to a {@code char} value and then
|
||||
* stored into the array element {@code a[offset+N]}.
|
||||
* If the mask lane at {@code N} is unset then the corresponding
|
||||
* array element {@code a[offset+N]} is left unchanged.
|
||||
* <p>
|
||||
* Array range checking is done for lanes where the mask is set.
|
||||
* Lanes where the mask is unset are not stored and do not need
|
||||
* to correspond to legitimate elements of {@code a}.
|
||||
* That is, unset lanes may correspond to array indexes less than
|
||||
* zero or beyond the end of the array.
|
||||
*
|
||||
* @param a the array, of type {@code char[]}
|
||||
* @param offset the offset into the array
|
||||
* @param m the mask controlling lane storage
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code offset+N < 0} or {@code offset+N >= a.length}
|
||||
* for any lane {@code N} in the vector
|
||||
* where the mask is set
|
||||
*/
|
||||
@ForceInline
|
||||
public final
|
||||
void intoCharArray(char[] a, int offset,
|
||||
VectorMask<Short> m) {
|
||||
if (m.allTrue()) {
|
||||
intoCharArray(a, offset);
|
||||
} else {
|
||||
// FIXME: optimize
|
||||
ShortSpecies vsp = vspecies();
|
||||
checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
|
||||
stOp(a, offset, m, (arr, off, i, v) -> arr[off+i] = (char) v);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scatters this vector into an array of type {@code char[]}
|
||||
* using indexes obtained by adding a fixed {@code offset} to a
|
||||
* series of secondary offsets from an <em>index map</em>.
|
||||
* The index map is a contiguous sequence of {@code VLENGTH}
|
||||
* elements in a second array of {@code int}s, starting at a given
|
||||
* {@code mapOffset}.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
* the lane element at index {@code N}
|
||||
* is first cast to a {@code char} value and then
|
||||
* stored into the array
|
||||
* element {@code a[f(N)]}, where {@code f(N)} is the
|
||||
* index mapping expression
|
||||
* {@code offset + indexMap[mapOffset + N]]}.
|
||||
*
|
||||
* @param a the array
|
||||
* @param offset an offset to combine with the index map offsets
|
||||
* @param indexMap the index map
|
||||
* @param mapOffset the offset into the index map
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code mapOffset+N < 0}
|
||||
* or if {@code mapOffset+N >= indexMap.length},
|
||||
* or if {@code f(N)=offset+indexMap[mapOffset+N]}
|
||||
* is an invalid index into {@code a},
|
||||
* for any lane {@code N} in the vector
|
||||
* @see ShortVector#toIntArray()
|
||||
*/
|
||||
@ForceInline
|
||||
public final
|
||||
void intoCharArray(char[] a, int offset,
|
||||
int[] indexMap, int mapOffset) {
|
||||
// FIXME: optimize
|
||||
stOp(a, offset,
|
||||
(arr, off, i, e) -> {
|
||||
int j = indexMap[mapOffset + i];
|
||||
arr[off + j] = (char) e;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Scatters this vector into an array of type {@code char[]},
|
||||
* under the control of a mask, and
|
||||
* using indexes obtained by adding a fixed {@code offset} to a
|
||||
* series of secondary offsets from an <em>index map</em>.
|
||||
* The index map is a contiguous sequence of {@code VLENGTH}
|
||||
* elements in a second array of {@code int}s, starting at a given
|
||||
* {@code mapOffset}.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
* if the mask lane at index {@code N} is set then
|
||||
* the lane element at index {@code N}
|
||||
* is first cast to a {@code char} value and then
|
||||
* stored into the array
|
||||
* element {@code a[f(N)]}, where {@code f(N)} is the
|
||||
* index mapping expression
|
||||
* {@code offset + indexMap[mapOffset + N]]}.
|
||||
*
|
||||
* @param a the array
|
||||
* @param offset an offset to combine with the index map offsets
|
||||
* @param indexMap the index map
|
||||
* @param mapOffset the offset into the index map
|
||||
* @param m the mask
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code mapOffset+N < 0}
|
||||
* or if {@code mapOffset+N >= indexMap.length},
|
||||
* or if {@code f(N)=offset+indexMap[mapOffset+N]}
|
||||
* is an invalid index into {@code a},
|
||||
* for any lane {@code N} in the vector
|
||||
* where the mask is set
|
||||
* @see ShortVector#toIntArray()
|
||||
*/
|
||||
@ForceInline
|
||||
public final
|
||||
void intoCharArray(char[] a, int offset,
|
||||
int[] indexMap, int mapOffset,
|
||||
VectorMask<Short> m) {
|
||||
// FIXME: optimize
|
||||
stOp(a, offset, m,
|
||||
(arr, off, i, e) -> {
|
||||
int j = indexMap[mapOffset + i];
|
||||
arr[off + j] = (char) e;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc} <!--workaround-->
|
||||
*/
|
||||
|
@ -3189,6 +3486,22 @@ public abstract class ShortVector extends AbstractVector<Short> {
|
|||
(arr_, off_, i) -> arr_[off_ + i]));
|
||||
}
|
||||
|
||||
/*package-private*/
|
||||
abstract
|
||||
ShortVector fromCharArray0(char[] a, int offset);
|
||||
@ForceInline
|
||||
final
|
||||
ShortVector fromCharArray0Template(char[] a, int offset) {
|
||||
ShortSpecies vsp = vspecies();
|
||||
return VectorSupport.load(
|
||||
vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
|
||||
a, charArrayAddress(a, offset),
|
||||
a, offset, vsp,
|
||||
(arr, off, s) -> s.ldOp(arr, off,
|
||||
(arr_, off_, i) -> (short) arr_[off_ + i]));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
abstract
|
||||
ShortVector fromByteArray0(byte[] a, int offset);
|
||||
|
@ -3324,6 +3637,17 @@ public abstract class ShortVector extends AbstractVector<Short> {
|
|||
return ARRAY_BASE + (((long)index) << ARRAY_SHIFT);
|
||||
}
|
||||
|
||||
static final int ARRAY_CHAR_SHIFT =
|
||||
31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_CHAR_INDEX_SCALE);
|
||||
static final long ARRAY_CHAR_BASE =
|
||||
Unsafe.ARRAY_CHAR_BASE_OFFSET;
|
||||
|
||||
@ForceInline
|
||||
static long charArrayAddress(char[] a, int index) {
|
||||
return ARRAY_CHAR_BASE + (((long)index) << ARRAY_CHAR_SHIFT);
|
||||
}
|
||||
|
||||
|
||||
@ForceInline
|
||||
static long byteArrayAddress(byte[] a, int index) {
|
||||
return Unsafe.ARRAY_BYTE_BASE_OFFSET + index;
|
||||
|
|
|
@ -240,13 +240,13 @@ import java.util.Arrays;
|
|||
* each distinct lane of the input vector. If there are additional
|
||||
* vector arguments of the same type, their lanes are aligned with the
|
||||
* lanes of the first input vector. (They must all have a common
|
||||
* {@code VLENGTH}.) The output resulting from a lane-wise operation
|
||||
* will have a {@code VLENGTH} which is equal to the {@code VLENGTH}
|
||||
* of the input(s) to the operation. Thus, lane-wise operations are
|
||||
* <em>length-invariant</em>, in their basic definitions.
|
||||
* {@code VLENGTH}.) For most lane-wise operations, the output resulting
|
||||
* from a lane-wise operation will have a {@code VLENGTH} which is equal to
|
||||
* the {@code VLENGTH} of the input(s) to the operation. Thus, such lane-wise
|
||||
* operations are <em>length-invariant</em>, in their basic definitions.
|
||||
*
|
||||
* <p> The principle of length-invariance is combined with another
|
||||
* basic principle, that lane-wise operations are always
|
||||
* basic principle, that most length-invariant lane-wise operations are also
|
||||
* <em>shape-invariant</em>, meaning that the inputs and the output of
|
||||
* a lane-wise operation will have a common {@code VSHAPE}. When the
|
||||
* principles conflict, because a logical result (with an invariant
|
||||
|
@ -799,7 +799,8 @@ import java.util.Arrays;
|
|||
* approach to the design of such <em>resizing</em> vector operations.
|
||||
*
|
||||
* <p> As a basic principle, lane-wise operations are
|
||||
* <em>length-invariant</em>. Length-invariance simply means that
|
||||
* <em>length-invariant</em>, unless clearly marked otherwise.
|
||||
* Length-invariance simply means that
|
||||
* if {@code VLENGTH} lanes go into an operation, the same number
|
||||
* of lanes come out, with nothing discarded and no extra padding.
|
||||
*
|
||||
|
|
|
@ -565,7 +565,26 @@ public abstract class VectorOperators {
|
|||
public static final Comparison GT = compare("GT", ">", VectorSupport.BT_gt, VO_ALL);
|
||||
/** Compare {@code a>=b}. */
|
||||
public static final Comparison GE = compare("GE", ">=", VectorSupport.BT_ge, VO_ALL);
|
||||
// FIXME: add unsigned comparisons
|
||||
/** Unsigned compare {@code a<b}. Integral only.
|
||||
* @see java.lang.Integer#compareUnsigned
|
||||
* @see java.lang.Long#compareUnsigned
|
||||
*/
|
||||
public static final Comparison UNSIGNED_LT = compare("UNSIGNED_LT", "<", VectorSupport.BT_ult, VO_NOFP);
|
||||
/** Unsigned compare {@code a<=b}. Integral only.
|
||||
* @see java.lang.Integer#compareUnsigned
|
||||
* @see java.lang.Long#compareUnsigned
|
||||
*/
|
||||
public static final Comparison UNSIGNED_LE = compare("UNSIGNED_LE", "<=", VectorSupport.BT_ule, VO_NOFP);
|
||||
/** Unsigned compare {@code a>b}. Integral only.
|
||||
* @see java.lang.Integer#compareUnsigned
|
||||
* @see java.lang.Long#compareUnsigned
|
||||
*/
|
||||
public static final Comparison UNSIGNED_GT = compare("UNSIGNED_GT", ">", VectorSupport.BT_ugt, VO_NOFP);
|
||||
/** Unsigned compare {@code a>=b}. Integral only.
|
||||
* @see java.lang.Integer#compareUnsigned
|
||||
* @see java.lang.Long#compareUnsigned
|
||||
*/
|
||||
public static final Comparison UNSIGNED_GE = compare("UNSIGNED_GE", ">=", VectorSupport.BT_uge, VO_NOFP);
|
||||
|
||||
// Conversion operators
|
||||
|
||||
|
|
|
@ -383,20 +383,6 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
|
|||
return maskFactory(bits);
|
||||
}
|
||||
|
||||
/*package-private*/
|
||||
@ForceInline
|
||||
static boolean doBinTest(int cond, $type$ a, $type$ b) {
|
||||
switch (cond) {
|
||||
case BT_eq: return a == b;
|
||||
case BT_ne: return a != b;
|
||||
case BT_lt: return a < b;
|
||||
case BT_le: return a <= b;
|
||||
case BT_gt: return a > b;
|
||||
case BT_ge: return a >= b;
|
||||
}
|
||||
throw new AssertionError(Integer.toHexString(cond));
|
||||
}
|
||||
|
||||
/*package-private*/
|
||||
@Override
|
||||
abstract $Type$Species vspecies();
|
||||
|
@ -2032,17 +2018,22 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
|
|||
}
|
||||
|
||||
@ForceInline
|
||||
private static
|
||||
boolean compareWithOp(int cond, $type$ a, $type$ b) {
|
||||
switch (cond) {
|
||||
case BT_eq: return a == b;
|
||||
case BT_ne: return a != b;
|
||||
case BT_lt: return a < b;
|
||||
case BT_le: return a <= b;
|
||||
case BT_gt: return a > b;
|
||||
case BT_ge: return a >= b;
|
||||
}
|
||||
throw new AssertionError();
|
||||
private static boolean compareWithOp(int cond, $type$ a, $type$ b) {
|
||||
return switch (cond) {
|
||||
case BT_eq -> a == b;
|
||||
case BT_ne -> a != b;
|
||||
case BT_lt -> a < b;
|
||||
case BT_le -> a <= b;
|
||||
case BT_gt -> a > b;
|
||||
case BT_ge -> a >= b;
|
||||
#if[!FP]
|
||||
case BT_ult -> $Boxtype$.compareUnsigned(a, b) < 0;
|
||||
case BT_ule -> $Boxtype$.compareUnsigned(a, b) <= 0;
|
||||
case BT_ugt -> $Boxtype$.compareUnsigned(a, b) > 0;
|
||||
case BT_uge -> $Boxtype$.compareUnsigned(a, b) >= 0;
|
||||
#end[!FP]
|
||||
default -> throw new AssertionError();
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3375,6 +3366,320 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
|
|||
}
|
||||
#end[byteOrShort]
|
||||
|
||||
#if[short]
|
||||
/**
|
||||
* Loads a vector from an array of type {@code char[]}
|
||||
* starting at an offset.
|
||||
* For each vector lane, where {@code N} is the vector lane index, the
|
||||
* array element at index {@code offset + N}
|
||||
* is first cast to a {@code short} value and then
|
||||
* placed into the resulting vector at lane index {@code N}.
|
||||
*
|
||||
* @param species species of desired vector
|
||||
* @param a the array
|
||||
* @param offset the offset into the array
|
||||
* @return the vector loaded from an array
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code offset+N < 0} or {@code offset+N >= a.length}
|
||||
* for any lane {@code N} in the vector
|
||||
*/
|
||||
@ForceInline
|
||||
public static
|
||||
$abstractvectortype$ fromCharArray(VectorSpecies<$Boxtype$> species,
|
||||
char[] a, int offset) {
|
||||
offset = checkFromIndexSize(offset, species.length(), a.length);
|
||||
$Type$Species vsp = ($Type$Species) species;
|
||||
return vsp.dummyVector().fromCharArray0(a, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a vector from an array of type {@code char[]}
|
||||
* starting at an offset and using a mask.
|
||||
* Lanes where the mask is unset are filled with the default
|
||||
* value of {@code $type$} ({#if[FP]?positive }zero).
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
* if the mask lane at index {@code N} is set then the array element at
|
||||
* index {@code offset + N}
|
||||
* is first cast to a {@code short} value and then
|
||||
* placed into the resulting vector at lane index
|
||||
* {@code N}, otherwise the default element value is placed into the
|
||||
* resulting vector at lane index {@code N}.
|
||||
*
|
||||
* @param species species of desired vector
|
||||
* @param a the array
|
||||
* @param offset the offset into the array
|
||||
* @param m the mask controlling lane selection
|
||||
* @return the vector loaded from an array
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code offset+N < 0} or {@code offset+N >= a.length}
|
||||
* for any lane {@code N} in the vector
|
||||
* where the mask is set
|
||||
*/
|
||||
@ForceInline
|
||||
public static
|
||||
$abstractvectortype$ fromCharArray(VectorSpecies<$Boxtype$> species,
|
||||
char[] a, int offset,
|
||||
VectorMask<$Boxtype$> m) {
|
||||
$Type$Species vsp = ($Type$Species) species;
|
||||
if (offset >= 0 && offset <= (a.length - species.length())) {
|
||||
$abstractvectortype$ zero = vsp.zero();
|
||||
return zero.blend(zero.fromCharArray0(a, offset), m);
|
||||
}
|
||||
|
||||
// FIXME: optimize
|
||||
checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
|
||||
return vsp.vOp(m, i -> (short) a[offset + i]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gathers a new vector composed of elements from an array of type
|
||||
* {@code char[]},
|
||||
* using indexes obtained by adding a fixed {@code offset} to a
|
||||
* series of secondary offsets from an <em>index map</em>.
|
||||
* The index map is a contiguous sequence of {@code VLENGTH}
|
||||
* elements in a second array of {@code int}s, starting at a given
|
||||
* {@code mapOffset}.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
* the lane is loaded from the expression
|
||||
* {@code (short) a[f(N)]}, where {@code f(N)} is the
|
||||
* index mapping expression
|
||||
* {@code offset + indexMap[mapOffset + N]]}.
|
||||
*
|
||||
* @param species species of desired vector
|
||||
* @param a the array
|
||||
* @param offset the offset into the array, may be negative if relative
|
||||
* indexes in the index map compensate to produce a value within the
|
||||
* array bounds
|
||||
* @param indexMap the index map
|
||||
* @param mapOffset the offset into the index map
|
||||
* @return the vector loaded from the indexed elements of the array
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code mapOffset+N < 0}
|
||||
* or if {@code mapOffset+N >= indexMap.length},
|
||||
* or if {@code f(N)=offset+indexMap[mapOffset+N]}
|
||||
* is an invalid index into {@code a},
|
||||
* for any lane {@code N} in the vector
|
||||
* @see $abstractvectortype$#toIntArray()
|
||||
*/
|
||||
@ForceInline
|
||||
public static
|
||||
$abstractvectortype$ fromCharArray(VectorSpecies<$Boxtype$> species,
|
||||
char[] a, int offset,
|
||||
int[] indexMap, int mapOffset) {
|
||||
// FIXME: optimize
|
||||
$Type$Species vsp = ($Type$Species) species;
|
||||
return vsp.vOp(n -> (short) a[offset + indexMap[mapOffset + n]]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gathers a new vector composed of elements from an array of type
|
||||
* {@code char[]},
|
||||
* under the control of a mask, and
|
||||
* using indexes obtained by adding a fixed {@code offset} to a
|
||||
* series of secondary offsets from an <em>index map</em>.
|
||||
* The index map is a contiguous sequence of {@code VLENGTH}
|
||||
* elements in a second array of {@code int}s, starting at a given
|
||||
* {@code mapOffset}.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
* if the lane is set in the mask,
|
||||
* the lane is loaded from the expression
|
||||
* {@code (short) a[f(N)]}, where {@code f(N)} is the
|
||||
* index mapping expression
|
||||
* {@code offset + indexMap[mapOffset + N]]}.
|
||||
* Unset lanes in the resulting vector are set to zero.
|
||||
*
|
||||
* @param species species of desired vector
|
||||
* @param a the array
|
||||
* @param offset the offset into the array, may be negative if relative
|
||||
* indexes in the index map compensate to produce a value within the
|
||||
* array bounds
|
||||
* @param indexMap the index map
|
||||
* @param mapOffset the offset into the index map
|
||||
* @param m the mask controlling lane selection
|
||||
* @return the vector loaded from the indexed elements of the array
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code mapOffset+N < 0}
|
||||
* or if {@code mapOffset+N >= indexMap.length},
|
||||
* or if {@code f(N)=offset+indexMap[mapOffset+N]}
|
||||
* is an invalid index into {@code a},
|
||||
* for any lane {@code N} in the vector
|
||||
* where the mask is set
|
||||
* @see $abstractvectortype$#toIntArray()
|
||||
*/
|
||||
@ForceInline
|
||||
public static
|
||||
$abstractvectortype$ fromCharArray(VectorSpecies<$Boxtype$> species,
|
||||
char[] a, int offset,
|
||||
int[] indexMap, int mapOffset,
|
||||
VectorMask<$Boxtype$> m) {
|
||||
// FIXME: optimize
|
||||
$Type$Species vsp = ($Type$Species) species;
|
||||
return vsp.vOp(m, n -> (short) a[offset + indexMap[mapOffset + n]]);
|
||||
}
|
||||
#end[short]
|
||||
|
||||
#if[byte]
|
||||
/**
|
||||
* Loads a vector from an array of type {@code boolean[]}
|
||||
* starting at an offset.
|
||||
* For each vector lane, where {@code N} is the vector lane index, the
|
||||
* array element at index {@code offset + N}
|
||||
* is first converted to a {@code byte} value and then
|
||||
* placed into the resulting vector at lane index {@code N}.
|
||||
* <p>
|
||||
* A {@code boolean} value is converted to a {@code byte} value by applying the
|
||||
* expression {@code (byte) (b ? 1 : 0)}, where {@code b} is the {@code boolean} value.
|
||||
*
|
||||
* @param species species of desired vector
|
||||
* @param a the array
|
||||
* @param offset the offset into the array
|
||||
* @return the vector loaded from an array
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code offset+N < 0} or {@code offset+N >= a.length}
|
||||
* for any lane {@code N} in the vector
|
||||
*/
|
||||
@ForceInline
|
||||
public static
|
||||
$abstractvectortype$ fromBooleanArray(VectorSpecies<$Boxtype$> species,
|
||||
boolean[] a, int offset) {
|
||||
offset = checkFromIndexSize(offset, species.length(), a.length);
|
||||
$Type$Species vsp = ($Type$Species) species;
|
||||
return vsp.dummyVector().fromBooleanArray0(a, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a vector from an array of type {@code boolean[]}
|
||||
* starting at an offset and using a mask.
|
||||
* Lanes where the mask is unset are filled with the default
|
||||
* value of {@code $type$} ({#if[FP]?positive }zero).
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
* if the mask lane at index {@code N} is set then the array element at
|
||||
* index {@code offset + N}
|
||||
* is first converted to a {@code byte} value and then
|
||||
* placed into the resulting vector at lane index
|
||||
* {@code N}, otherwise the default element value is placed into the
|
||||
* resulting vector at lane index {@code N}.
|
||||
* <p>
|
||||
* A {@code boolean} value is converted to a {@code byte} value by applying the
|
||||
* expression {@code (byte) (b ? 1 : 0)}, where {@code b} is the {@code boolean} value.
|
||||
*
|
||||
* @param species species of desired vector
|
||||
* @param a the array
|
||||
* @param offset the offset into the array
|
||||
* @param m the mask controlling lane selection
|
||||
* @return the vector loaded from an array
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code offset+N < 0} or {@code offset+N >= a.length}
|
||||
* for any lane {@code N} in the vector
|
||||
* where the mask is set
|
||||
*/
|
||||
@ForceInline
|
||||
public static
|
||||
$abstractvectortype$ fromBooleanArray(VectorSpecies<$Boxtype$> species,
|
||||
boolean[] a, int offset,
|
||||
VectorMask<$Boxtype$> m) {
|
||||
$Type$Species vsp = ($Type$Species) species;
|
||||
if (offset >= 0 && offset <= (a.length - species.length())) {
|
||||
$abstractvectortype$ zero = vsp.zero();
|
||||
return zero.blend(zero.fromBooleanArray0(a, offset), m);
|
||||
}
|
||||
|
||||
// FIXME: optimize
|
||||
checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
|
||||
return vsp.vOp(m, i -> (byte) (a[offset + i] ? 1 : 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gathers a new vector composed of elements from an array of type
|
||||
* {@code boolean[]},
|
||||
* using indexes obtained by adding a fixed {@code offset} to a
|
||||
* series of secondary offsets from an <em>index map</em>.
|
||||
* The index map is a contiguous sequence of {@code VLENGTH}
|
||||
* elements in a second array of {@code int}s, starting at a given
|
||||
* {@code mapOffset}.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
* the lane is loaded from the expression
|
||||
* {@code (byte) (a[f(N)] ? 1 : 0)}, where {@code f(N)} is the
|
||||
* index mapping expression
|
||||
* {@code offset + indexMap[mapOffset + N]]}.
|
||||
*
|
||||
* @param species species of desired vector
|
||||
* @param a the array
|
||||
* @param offset the offset into the array, may be negative if relative
|
||||
* indexes in the index map compensate to produce a value within the
|
||||
* array bounds
|
||||
* @param indexMap the index map
|
||||
* @param mapOffset the offset into the index map
|
||||
* @return the vector loaded from the indexed elements of the array
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code mapOffset+N < 0}
|
||||
* or if {@code mapOffset+N >= indexMap.length},
|
||||
* or if {@code f(N)=offset+indexMap[mapOffset+N]}
|
||||
* is an invalid index into {@code a},
|
||||
* for any lane {@code N} in the vector
|
||||
* @see $abstractvectortype$#toIntArray()
|
||||
*/
|
||||
@ForceInline
|
||||
public static
|
||||
$abstractvectortype$ fromBooleanArray(VectorSpecies<$Boxtype$> species,
|
||||
boolean[] a, int offset,
|
||||
int[] indexMap, int mapOffset) {
|
||||
// FIXME: optimize
|
||||
$Type$Species vsp = ($Type$Species) species;
|
||||
return vsp.vOp(n -> (byte) (a[offset + indexMap[mapOffset + n]] ? 1 : 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gathers a new vector composed of elements from an array of type
|
||||
* {@code boolean[]},
|
||||
* under the control of a mask, and
|
||||
* using indexes obtained by adding a fixed {@code offset} to a
|
||||
* series of secondary offsets from an <em>index map</em>.
|
||||
* The index map is a contiguous sequence of {@code VLENGTH}
|
||||
* elements in a second array of {@code int}s, starting at a given
|
||||
* {@code mapOffset}.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
* if the lane is set in the mask,
|
||||
* the lane is loaded from the expression
|
||||
* {@code (byte) (a[f(N)] ? 1 : 0)}, where {@code f(N)} is the
|
||||
* index mapping expression
|
||||
* {@code offset + indexMap[mapOffset + N]]}.
|
||||
* Unset lanes in the resulting vector are set to zero.
|
||||
*
|
||||
* @param species species of desired vector
|
||||
* @param a the array
|
||||
* @param offset the offset into the array, may be negative if relative
|
||||
* indexes in the index map compensate to produce a value within the
|
||||
* array bounds
|
||||
* @param indexMap the index map
|
||||
* @param mapOffset the offset into the index map
|
||||
* @param m the mask controlling lane selection
|
||||
* @return the vector loaded from the indexed elements of the array
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code mapOffset+N < 0}
|
||||
* or if {@code mapOffset+N >= indexMap.length},
|
||||
* or if {@code f(N)=offset+indexMap[mapOffset+N]}
|
||||
* is an invalid index into {@code a},
|
||||
* for any lane {@code N} in the vector
|
||||
* where the mask is set
|
||||
* @see $abstractvectortype$#toIntArray()
|
||||
*/
|
||||
@ForceInline
|
||||
public static
|
||||
$abstractvectortype$ fromBooleanArray(VectorSpecies<$Boxtype$> species,
|
||||
boolean[] a, int offset,
|
||||
int[] indexMap, int mapOffset,
|
||||
VectorMask<$Boxtype$> m) {
|
||||
// FIXME: optimize
|
||||
$Type$Species vsp = ($Type$Species) species;
|
||||
return vsp.vOp(m, n -> (byte) (a[offset + indexMap[mapOffset + n]] ? 1 : 0));
|
||||
}
|
||||
#end[byte]
|
||||
|
||||
/**
|
||||
* Loads a vector from a {@linkplain ByteBuffer byte buffer}
|
||||
* starting at an offset into the byte buffer.
|
||||
|
@ -3513,7 +3818,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Stores this vector into an array of {@code $type$}
|
||||
* Stores this vector into an array of type {@code $type$[]}
|
||||
* starting at offset and using a mask.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
|
@ -3704,6 +4009,331 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
|
|||
}
|
||||
#end[byteOrShort]
|
||||
|
||||
#if[short]
|
||||
/**
|
||||
* Stores this vector into an array of type {@code char[]}
|
||||
* starting at an offset.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
* the lane element at index {@code N}
|
||||
* is first cast to a {@code char} value and then
|
||||
* stored into the array element {@code a[offset+N]}.
|
||||
*
|
||||
* @param a the array, of type {@code char[]}
|
||||
* @param offset the offset into the array
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code offset+N < 0} or {@code offset+N >= a.length}
|
||||
* for any lane {@code N} in the vector
|
||||
*/
|
||||
@ForceInline
|
||||
public final
|
||||
void intoCharArray(char[] a, int offset) {
|
||||
offset = checkFromIndexSize(offset, length(), a.length);
|
||||
$Type$Species vsp = vspecies();
|
||||
VectorSupport.store(
|
||||
vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
|
||||
a, charArrayAddress(a, offset),
|
||||
this,
|
||||
a, offset,
|
||||
(arr, off, v)
|
||||
-> v.stOp(arr, off,
|
||||
(arr_, off_, i, e) -> arr_[off_ + i] = (char) e));
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores this vector into an array of type {@code char[]}
|
||||
* starting at offset and using a mask.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
* the lane element at index {@code N}
|
||||
* is first cast to a {@code char} value and then
|
||||
* stored into the array element {@code a[offset+N]}.
|
||||
* If the mask lane at {@code N} is unset then the corresponding
|
||||
* array element {@code a[offset+N]} is left unchanged.
|
||||
* <p>
|
||||
* Array range checking is done for lanes where the mask is set.
|
||||
* Lanes where the mask is unset are not stored and do not need
|
||||
* to correspond to legitimate elements of {@code a}.
|
||||
* That is, unset lanes may correspond to array indexes less than
|
||||
* zero or beyond the end of the array.
|
||||
*
|
||||
* @param a the array, of type {@code char[]}
|
||||
* @param offset the offset into the array
|
||||
* @param m the mask controlling lane storage
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code offset+N < 0} or {@code offset+N >= a.length}
|
||||
* for any lane {@code N} in the vector
|
||||
* where the mask is set
|
||||
*/
|
||||
@ForceInline
|
||||
public final
|
||||
void intoCharArray(char[] a, int offset,
|
||||
VectorMask<$Boxtype$> m) {
|
||||
if (m.allTrue()) {
|
||||
intoCharArray(a, offset);
|
||||
} else {
|
||||
// FIXME: optimize
|
||||
$Type$Species vsp = vspecies();
|
||||
checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
|
||||
stOp(a, offset, m, (arr, off, i, v) -> arr[off+i] = (char) v);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scatters this vector into an array of type {@code char[]}
|
||||
* using indexes obtained by adding a fixed {@code offset} to a
|
||||
* series of secondary offsets from an <em>index map</em>.
|
||||
* The index map is a contiguous sequence of {@code VLENGTH}
|
||||
* elements in a second array of {@code int}s, starting at a given
|
||||
* {@code mapOffset}.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
* the lane element at index {@code N}
|
||||
* is first cast to a {@code char} value and then
|
||||
* stored into the array
|
||||
* element {@code a[f(N)]}, where {@code f(N)} is the
|
||||
* index mapping expression
|
||||
* {@code offset + indexMap[mapOffset + N]]}.
|
||||
*
|
||||
* @param a the array
|
||||
* @param offset an offset to combine with the index map offsets
|
||||
* @param indexMap the index map
|
||||
* @param mapOffset the offset into the index map
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code mapOffset+N < 0}
|
||||
* or if {@code mapOffset+N >= indexMap.length},
|
||||
* or if {@code f(N)=offset+indexMap[mapOffset+N]}
|
||||
* is an invalid index into {@code a},
|
||||
* for any lane {@code N} in the vector
|
||||
* @see $abstractvectortype$#toIntArray()
|
||||
*/
|
||||
@ForceInline
|
||||
public final
|
||||
void intoCharArray(char[] a, int offset,
|
||||
int[] indexMap, int mapOffset) {
|
||||
// FIXME: optimize
|
||||
stOp(a, offset,
|
||||
(arr, off, i, e) -> {
|
||||
int j = indexMap[mapOffset + i];
|
||||
arr[off + j] = (char) e;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Scatters this vector into an array of type {@code char[]},
|
||||
* under the control of a mask, and
|
||||
* using indexes obtained by adding a fixed {@code offset} to a
|
||||
* series of secondary offsets from an <em>index map</em>.
|
||||
* The index map is a contiguous sequence of {@code VLENGTH}
|
||||
* elements in a second array of {@code int}s, starting at a given
|
||||
* {@code mapOffset}.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
* if the mask lane at index {@code N} is set then
|
||||
* the lane element at index {@code N}
|
||||
* is first cast to a {@code char} value and then
|
||||
* stored into the array
|
||||
* element {@code a[f(N)]}, where {@code f(N)} is the
|
||||
* index mapping expression
|
||||
* {@code offset + indexMap[mapOffset + N]]}.
|
||||
*
|
||||
* @param a the array
|
||||
* @param offset an offset to combine with the index map offsets
|
||||
* @param indexMap the index map
|
||||
* @param mapOffset the offset into the index map
|
||||
* @param m the mask
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code mapOffset+N < 0}
|
||||
* or if {@code mapOffset+N >= indexMap.length},
|
||||
* or if {@code f(N)=offset+indexMap[mapOffset+N]}
|
||||
* is an invalid index into {@code a},
|
||||
* for any lane {@code N} in the vector
|
||||
* where the mask is set
|
||||
* @see $abstractvectortype$#toIntArray()
|
||||
*/
|
||||
@ForceInline
|
||||
public final
|
||||
void intoCharArray(char[] a, int offset,
|
||||
int[] indexMap, int mapOffset,
|
||||
VectorMask<$Boxtype$> m) {
|
||||
// FIXME: optimize
|
||||
stOp(a, offset, m,
|
||||
(arr, off, i, e) -> {
|
||||
int j = indexMap[mapOffset + i];
|
||||
arr[off + j] = (char) e;
|
||||
});
|
||||
}
|
||||
#end[short]
|
||||
|
||||
#if[byte]
|
||||
/**
|
||||
* Stores this vector into an array of type {@code boolean[]}
|
||||
* starting at an offset.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
* the lane element at index {@code N}
|
||||
* is first converted to a {@code boolean} value and then
|
||||
* stored into the array element {@code a[offset+N]}.
|
||||
* <p>
|
||||
* A {@code byte} value is converted to a {@code boolean} value by applying the
|
||||
* expression {@code (b & 1) != 0} where {@code b} is the byte value.
|
||||
*
|
||||
* @param a the array
|
||||
* @param offset the offset into the array
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code offset+N < 0} or {@code offset+N >= a.length}
|
||||
* for any lane {@code N} in the vector
|
||||
*/
|
||||
@ForceInline
|
||||
public final
|
||||
void intoBooleanArray(boolean[] a, int offset) {
|
||||
offset = checkFromIndexSize(offset, length(), a.length);
|
||||
$Type$Species vsp = vspecies();
|
||||
ByteVector normalized = this.and((byte) 1);
|
||||
VectorSupport.store(
|
||||
vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
|
||||
a, booleanArrayAddress(a, offset),
|
||||
normalized,
|
||||
a, offset,
|
||||
(arr, off, v)
|
||||
-> v.stOp(arr, off,
|
||||
(arr_, off_, i, e) -> arr_[off_ + i] = (e & 1) != 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores this vector into an array of type {@code boolean[]}
|
||||
* starting at offset and using a mask.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
* the lane element at index {@code N}
|
||||
* is first converted to a {@code boolean} value and then
|
||||
* stored into the array element {@code a[offset+N]}.
|
||||
* If the mask lane at {@code N} is unset then the corresponding
|
||||
* array element {@code a[offset+N]} is left unchanged.
|
||||
* <p>
|
||||
* A {@code byte} value is converted to a {@code boolean} value by applying the
|
||||
* expression {@code (b & 1) != 0} where {@code b} is the byte value.
|
||||
* <p>
|
||||
* Array range checking is done for lanes where the mask is set.
|
||||
* Lanes where the mask is unset are not stored and do not need
|
||||
* to correspond to legitimate elements of {@code a}.
|
||||
* That is, unset lanes may correspond to array indexes less than
|
||||
* zero or beyond the end of the array.
|
||||
*
|
||||
* @param a the array
|
||||
* @param offset the offset into the array
|
||||
* @param m the mask controlling lane storage
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code offset+N < 0} or {@code offset+N >= a.length}
|
||||
* for any lane {@code N} in the vector
|
||||
* where the mask is set
|
||||
*/
|
||||
@ForceInline
|
||||
public final
|
||||
void intoBooleanArray(boolean[] a, int offset,
|
||||
VectorMask<$Boxtype$> m) {
|
||||
if (m.allTrue()) {
|
||||
intoBooleanArray(a, offset);
|
||||
} else {
|
||||
// FIXME: optimize
|
||||
$Type$Species vsp = vspecies();
|
||||
checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
|
||||
stOp(a, offset, m, (arr, off, i, e) -> arr[off+i] = (e & 1) != 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scatters this vector into an array of type {@code boolean[]}
|
||||
* using indexes obtained by adding a fixed {@code offset} to a
|
||||
* series of secondary offsets from an <em>index map</em>.
|
||||
* The index map is a contiguous sequence of {@code VLENGTH}
|
||||
* elements in a second array of {@code int}s, starting at a given
|
||||
* {@code mapOffset}.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
* the lane element at index {@code N}
|
||||
* is first converted to a {@code boolean} value and then
|
||||
* stored into the array
|
||||
* element {@code a[f(N)]}, where {@code f(N)} is the
|
||||
* index mapping expression
|
||||
* {@code offset + indexMap[mapOffset + N]]}.
|
||||
* <p>
|
||||
* A {@code byte} value is converted to a {@code boolean} value by applying the
|
||||
* expression {@code (b & 1) != 0} where {@code b} is the byte value.
|
||||
*
|
||||
* @param a the array
|
||||
* @param offset an offset to combine with the index map offsets
|
||||
* @param indexMap the index map
|
||||
* @param mapOffset the offset into the index map
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code mapOffset+N < 0}
|
||||
* or if {@code mapOffset+N >= indexMap.length},
|
||||
* or if {@code f(N)=offset+indexMap[mapOffset+N]}
|
||||
* is an invalid index into {@code a},
|
||||
* for any lane {@code N} in the vector
|
||||
* @see $abstractvectortype$#toIntArray()
|
||||
*/
|
||||
@ForceInline
|
||||
public final
|
||||
void intoBooleanArray(boolean[] a, int offset,
|
||||
int[] indexMap, int mapOffset) {
|
||||
// FIXME: optimize
|
||||
stOp(a, offset,
|
||||
(arr, off, i, e) -> {
|
||||
int j = indexMap[mapOffset + i];
|
||||
arr[off + j] = (e & 1) != 0;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Scatters this vector into an array of type {@code boolean[]},
|
||||
* under the control of a mask, and
|
||||
* using indexes obtained by adding a fixed {@code offset} to a
|
||||
* series of secondary offsets from an <em>index map</em>.
|
||||
* The index map is a contiguous sequence of {@code VLENGTH}
|
||||
* elements in a second array of {@code int}s, starting at a given
|
||||
* {@code mapOffset}.
|
||||
* <p>
|
||||
* For each vector lane, where {@code N} is the vector lane index,
|
||||
* if the mask lane at index {@code N} is set then
|
||||
* the lane element at index {@code N}
|
||||
* is first converted to a {@code boolean} value and then
|
||||
* stored into the array
|
||||
* element {@code a[f(N)]}, where {@code f(N)} is the
|
||||
* index mapping expression
|
||||
* {@code offset + indexMap[mapOffset + N]]}.
|
||||
* <p>
|
||||
* A {@code byte} value is converted to a {@code boolean} value by applying the
|
||||
* expression {@code (b & 1) != 0} where {@code b} is the byte value.
|
||||
*
|
||||
* @param a the array
|
||||
* @param offset an offset to combine with the index map offsets
|
||||
* @param indexMap the index map
|
||||
* @param mapOffset the offset into the index map
|
||||
* @param m the mask
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code mapOffset+N < 0}
|
||||
* or if {@code mapOffset+N >= indexMap.length},
|
||||
* or if {@code f(N)=offset+indexMap[mapOffset+N]}
|
||||
* is an invalid index into {@code a},
|
||||
* for any lane {@code N} in the vector
|
||||
* where the mask is set
|
||||
* @see $abstractvectortype$#toIntArray()
|
||||
*/
|
||||
@ForceInline
|
||||
public final
|
||||
void intoBooleanArray(boolean[] a, int offset,
|
||||
int[] indexMap, int mapOffset,
|
||||
VectorMask<$Boxtype$> m) {
|
||||
// FIXME: optimize
|
||||
stOp(a, offset, m,
|
||||
(arr, off, i, e) -> {
|
||||
int j = indexMap[mapOffset + i];
|
||||
arr[off + j] = (e & 1) != 0;
|
||||
});
|
||||
}
|
||||
#end[byte]
|
||||
|
||||
/**
|
||||
* {@inheritDoc} <!--workaround-->
|
||||
*/
|
||||
|
@ -3810,6 +4440,40 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
|
|||
(arr_, off_, i) -> arr_[off_ + i]));
|
||||
}
|
||||
|
||||
#if[short]
|
||||
/*package-private*/
|
||||
abstract
|
||||
$abstractvectortype$ fromCharArray0(char[] a, int offset);
|
||||
@ForceInline
|
||||
final
|
||||
$abstractvectortype$ fromCharArray0Template(char[] a, int offset) {
|
||||
$Type$Species vsp = vspecies();
|
||||
return VectorSupport.load(
|
||||
vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
|
||||
a, charArrayAddress(a, offset),
|
||||
a, offset, vsp,
|
||||
(arr, off, s) -> s.ldOp(arr, off,
|
||||
(arr_, off_, i) -> (short) arr_[off_ + i]));
|
||||
}
|
||||
#end[short]
|
||||
|
||||
#if[byte]
|
||||
/*package-private*/
|
||||
abstract
|
||||
$abstractvectortype$ fromBooleanArray0(boolean[] a, int offset);
|
||||
@ForceInline
|
||||
final
|
||||
$abstractvectortype$ fromBooleanArray0Template(boolean[] a, int offset) {
|
||||
$Type$Species vsp = vspecies();
|
||||
return VectorSupport.load(
|
||||
vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
|
||||
a, booleanArrayAddress(a, offset),
|
||||
a, offset, vsp,
|
||||
(arr, off, s) -> s.ldOp(arr, off,
|
||||
(arr_, off_, i) -> (byte) (arr_[off_ + i] ? 1 : 0)));
|
||||
}
|
||||
#end[byte]
|
||||
|
||||
@Override
|
||||
abstract
|
||||
$abstractvectortype$ fromByteArray0(byte[] a, int offset);
|
||||
|
@ -3947,6 +4611,30 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
|
|||
return ARRAY_BASE + (((long)index) << ARRAY_SHIFT);
|
||||
}
|
||||
|
||||
#if[short]
|
||||
static final int ARRAY_CHAR_SHIFT =
|
||||
31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_CHAR_INDEX_SCALE);
|
||||
static final long ARRAY_CHAR_BASE =
|
||||
Unsafe.ARRAY_CHAR_BASE_OFFSET;
|
||||
|
||||
@ForceInline
|
||||
static long charArrayAddress(char[] a, int index) {
|
||||
return ARRAY_CHAR_BASE + (((long)index) << ARRAY_CHAR_SHIFT);
|
||||
}
|
||||
#end[short]
|
||||
|
||||
#if[byte]
|
||||
static final int ARRAY_BOOLEAN_SHIFT =
|
||||
31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_BOOLEAN_INDEX_SCALE);
|
||||
static final long ARRAY_BOOLEAN_BASE =
|
||||
Unsafe.ARRAY_BOOLEAN_BASE_OFFSET;
|
||||
|
||||
@ForceInline
|
||||
static long booleanArrayAddress(boolean[] a, int index) {
|
||||
return ARRAY_BOOLEAN_BASE + (((long)index) << ARRAY_BOOLEAN_SHIFT);
|
||||
}
|
||||
#end[byte]
|
||||
|
||||
@ForceInline
|
||||
static long byteArrayAddress(byte[] a, int index) {
|
||||
return Unsafe.ARRAY_BYTE_BASE_OFFSET + index;
|
||||
|
|
|
@ -1092,6 +1092,24 @@ final class $vectortype$ extends $abstractvectortype$ {
|
|||
return super.fromArray0Template(a, offset); // specialize
|
||||
}
|
||||
|
||||
#if[short]
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
$abstractvectortype$ fromCharArray0(char[] a, int offset) {
|
||||
return super.fromCharArray0Template(a, offset); // specialize
|
||||
}
|
||||
#end[short]
|
||||
|
||||
#if[byte]
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
$abstractvectortype$ fromBooleanArray0(boolean[] a, int offset) {
|
||||
return super.fromBooleanArray0Template(a, offset); // specialize
|
||||
}
|
||||
#end[byte]
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
final
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue