mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8278173: [vectorapi] Add x64 intrinsics for unsigned (zero extended) casts
Reviewed-by: psandoz, sviswanathan
This commit is contained in:
parent
a24498b777
commit
0af356bb4b
19 changed files with 466 additions and 62 deletions
|
@ -639,6 +639,25 @@ abstract class AbstractVector<E> extends Vector<E> {
|
|||
throw new AssertionError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for all sorts of lane-wise unsigned conversions.
|
||||
* This function kicks in after intrinsic failure.
|
||||
*/
|
||||
/*package-private*/
|
||||
@ForceInline
|
||||
final <F>
|
||||
AbstractVector<F> defaultUCast(AbstractSpecies<F> dsp) {
|
||||
AbstractSpecies<?> vsp = this.vspecies();
|
||||
if (vsp.elementSize() >= dsp.elementSize()) {
|
||||
// clip in place
|
||||
return this.convert0('C', dsp);
|
||||
} else {
|
||||
// extend in place, but remove unwanted sign extension
|
||||
long mask = -1L >>> -vsp.elementSize();
|
||||
return (AbstractVector<F>) this.convert0('C', dsp).lanewise(AND, dsp.broadcast(mask));
|
||||
}
|
||||
}
|
||||
|
||||
// Constant-folded access to conversion intrinsics:
|
||||
|
||||
/**
|
||||
|
@ -658,6 +677,7 @@ abstract class AbstractVector<E> extends Vector<E> {
|
|||
final <F>
|
||||
AbstractVector<F> convert0(char kind, AbstractSpecies<F> rsp) {
|
||||
// Derive some JIT-time constants:
|
||||
Class<?> vtype;
|
||||
Class<?> etype; // fill in after switch (constant)
|
||||
int vlength; // fill in after switch (mark type profile?)
|
||||
Class<?> rvtype; // fill in after switch (mark type profile)
|
||||
|
@ -665,9 +685,22 @@ abstract class AbstractVector<E> extends Vector<E> {
|
|||
int rlength;
|
||||
switch (kind) {
|
||||
case 'Z': // lane-wise size change, maybe with sign clip
|
||||
// Maybe this should be an intrinsic also.
|
||||
AbstractSpecies<?> rspi = rsp.asIntegral();
|
||||
AbstractVector<?> bitv = resizeLanes0(this, rspi);
|
||||
AbstractSpecies<?> vsp = this.vspecies();
|
||||
AbstractSpecies<?> vspi = vsp.asIntegral();
|
||||
AbstractVector<?> biti = vspi == vsp ? this : this.convert0('X', vspi);
|
||||
rtype = rspi.elementType();
|
||||
rlength = rspi.laneCount();
|
||||
etype = vspi.elementType();
|
||||
vlength = vspi.laneCount();
|
||||
rvtype = rspi.dummyVector().getClass();
|
||||
vtype = vspi.dummyVector().getClass();
|
||||
int opc = vspi.elementSize() < rspi.elementSize() ? VectorSupport.VECTOR_OP_UCAST : VectorSupport.VECTOR_OP_CAST;
|
||||
AbstractVector<?> bitv = VectorSupport.convert(opc,
|
||||
vtype, etype, vlength,
|
||||
rvtype, rtype, rlength,
|
||||
biti, rspi,
|
||||
AbstractVector::defaultUCast);
|
||||
return (rspi == rsp ? bitv.check0(rsp) : bitv.convert0('X', rsp));
|
||||
case 'C': // lane-wise cast (but not identity)
|
||||
rtype = rsp.elementType();
|
||||
|
@ -675,8 +708,9 @@ abstract class AbstractVector<E> extends Vector<E> {
|
|||
etype = this.elementType(); // (profile)
|
||||
vlength = this.length(); // (profile)
|
||||
rvtype = rsp.dummyVector().getClass(); // (profile)
|
||||
vtype = this.getClass();
|
||||
return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST,
|
||||
this.getClass(), etype, vlength,
|
||||
vtype, etype, vlength,
|
||||
rvtype, rtype, rlength,
|
||||
this, rsp,
|
||||
AbstractVector::defaultCast);
|
||||
|
@ -686,8 +720,9 @@ abstract class AbstractVector<E> extends Vector<E> {
|
|||
etype = this.elementType(); // (profile)
|
||||
vlength = this.length(); // (profile)
|
||||
rvtype = rsp.dummyVector().getClass(); // (profile)
|
||||
vtype = this.getClass();
|
||||
return VectorSupport.convert(VectorSupport.VECTOR_OP_REINTERPRET,
|
||||
this.getClass(), etype, vlength,
|
||||
vtype, etype, vlength,
|
||||
rvtype, rtype, rlength,
|
||||
this, rsp,
|
||||
AbstractVector::defaultReinterpret);
|
||||
|
@ -695,24 +730,6 @@ abstract class AbstractVector<E> extends Vector<E> {
|
|||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
private static <F>
|
||||
AbstractVector<F>
|
||||
resizeLanes0(AbstractVector<?> v, AbstractSpecies<F> rspi) {
|
||||
AbstractSpecies<?> dsp = v.vspecies();
|
||||
int sizeChange = rspi.elementSize() - dsp.elementSize();
|
||||
AbstractSpecies<?> dspi = dsp.asIntegral();
|
||||
if (dspi != dsp) v = v.convert0('R', dspi);
|
||||
if (sizeChange <= 0) { // clip in place
|
||||
return v.convert0('C', rspi);
|
||||
}
|
||||
// extend in place, but remove unwanted sign extension
|
||||
long mask = -1L >>> -dsp.elementSize();
|
||||
return (AbstractVector<F>)
|
||||
v.convert0('C', rspi)
|
||||
.lanewise(AND, rspi.broadcast(mask));
|
||||
}
|
||||
|
||||
// Byte buffer wrappers.
|
||||
static ByteBuffer wrapper(ByteBuffer bb, ByteOrder bo) {
|
||||
return bb.duplicate().order(bo);
|
||||
|
|
|
@ -95,10 +95,12 @@ enum LaneType {
|
|||
return printName;
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
LaneType asIntegral() {
|
||||
return asIntegral.check();
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
LaneType asFloating() {
|
||||
if (asFloating == null) {
|
||||
throw badElementType(elementType, "either int or long, to reinterpret as float or double");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue