8278173: [vectorapi] Add x64 intrinsics for unsigned (zero extended) casts

Reviewed-by: psandoz, sviswanathan
This commit is contained in:
Quan Anh Mai 2022-02-15 18:57:53 +00:00 committed by Sandhya Viswanathan
parent a24498b777
commit 0af356bb4b
19 changed files with 466 additions and 62 deletions

View file

@ -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);

View file

@ -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");