1 package jdk.incubator.vector;
   2 
   3 import jdk.internal.HotSpotIntrinsicCandidate;
   4 import jdk.internal.misc.Unsafe;
   5 import jdk.internal.vm.annotation.ForceInline;
   6 
   7 import java.util.Objects;
   8 import java.util.function.*;
   9 
  10 /*non-public*/ class VectorIntrinsics {
  11     private static final Unsafe U = Unsafe.getUnsafe();
  12 
  13     // Unary
  14     static final int VECTOR_OP_ABS  = 0;
  15     static final int VECTOR_OP_NEG  = 1;
  16     static final int VECTOR_OP_SQRT = 2;
  17     static final int VECTOR_OP_NOT  = 3;
  18 
  19     // Binary
  20     static final int VECTOR_OP_ADD  = 4;
  21     static final int VECTOR_OP_SUB  = 5;
  22     static final int VECTOR_OP_MUL  = 6;
  23     static final int VECTOR_OP_DIV  = 7;
  24 
  25     static final int VECTOR_OP_AND  = 8;
  26     static final int VECTOR_OP_OR   = 9;
  27     static final int VECTOR_OP_XOR  = 10;
  28 
  29     // Ternary
  30     static final int VECTOR_OP_FMA  = 11;
  31 
  32     // Broadcast int
  33     static final int VECTOR_OP_LSHIFT  = 12;
  34     static final int VECTOR_OP_RSHIFT  = 13;
  35     static final int VECTOR_OP_URSHIFT = 14;
  36 
  37     // Copied from open/src/hotspot/cpu/x86/assembler_x86.hpp
  38     // enum Condition { // The x86 condition codes used for conditional jumps/moves.
  39     static final int COND_zero          = 0x4;
  40     static final int COND_notZero       = 0x5;
  41     static final int COND_equal         = 0x4;
  42     static final int COND_notEqual      = 0x5;
  43     static final int COND_less          = 0xc;
  44     static final int COND_lessEqual     = 0xe;
  45     static final int COND_greater       = 0xf;
  46     static final int COND_greaterEqual  = 0xd;
  47     static final int COND_below         = 0x2;
  48     static final int COND_belowEqual    = 0x6;
  49     static final int COND_above         = 0x7;
  50     static final int COND_aboveEqual    = 0x3;
  51     static final int COND_overflow      = 0x0;
  52     static final int COND_noOverflow    = 0x1;
  53     static final int COND_carrySet      = 0x2;
  54     static final int COND_carryClear    = 0x3;
  55     static final int COND_negative      = 0x8;
  56     static final int COND_positive      = 0x9;
  57     static final int COND_parity        = 0xa;
  58     static final int COND_noParity      = 0xb;
  59 
  60 
  61     // enum BoolTest
  62     static final int BT_eq = 0;
  63     static final int BT_ne = 4;
  64     static final int BT_le = 5;
  65     static final int BT_ge = 7;
  66     static final int BT_lt = 3;
  67     static final int BT_gt = 1;
  68     static final int BT_overflow = 2;
  69     static final int BT_no_overflow = 6;
  70 
  71     /* ============================================================================ */
  72 
  73     @HotSpotIntrinsicCandidate
  74     static <V> V broadcastCoerced(Class<V> vectorClass, Class<?> elementType, int vlen,
  75                                   long bits,
  76                                   LongFunction<V> defaultImpl) {
  77         return defaultImpl.apply(bits);
  78     }
  79 
  80     @HotSpotIntrinsicCandidate
  81     static
  82     <V extends Vector<?,?>>
  83     long reductionCoerced(int oprId, Class<?> vectorClass, Class<?> elementType, int vlen,
  84                           V v,
  85                           Function<V,Long> defaultImpl) {
  86         return defaultImpl.apply(v);
  87     }
  88 
  89     /* ============================================================================ */
  90 
  91     @HotSpotIntrinsicCandidate
  92     static <V> V unaryOp(int oprId, Class<V> vectorClass, Class<?> elementType, int vlen,
  93                          V v1, /*Vector.Mask<E,S> m,*/
  94                          Function<V,V> defaultImpl) {
  95         return defaultImpl.apply(v1);
  96     }
  97 
  98     /* ============================================================================ */
  99 
 100     @HotSpotIntrinsicCandidate
 101     static <V> V binaryOp(int oprId, Class<? extends V> vectorClass, Class<?> elementType, int vlen,
 102                           V v1, V v2, /*Vector.Mask<E,S> m,*/
 103                           BiFunction<V,V,V> defaultImpl) {
 104         return defaultImpl.apply(v1, v2);
 105     }
 106 
 107     /* ============================================================================ */
 108 
 109     interface TernaryOperation<V> {
 110         V apply(V v1, V v2, V v3);
 111     }
 112 
 113     @SuppressWarnings("unchecked")
 114     @HotSpotIntrinsicCandidate
 115     static <V> V ternaryOp(int oprId, Class<V> vectorClass, Class<?> elementType, int vlen,
 116                            V v1, V v2, V v3, /*Vector.Mask<E,S> m,*/
 117                            TernaryOperation<V> defaultImpl) {
 118         return defaultImpl.apply(v1, v2, v3);
 119     }
 120 
 121     /* ============================================================================ */
 122 
 123     // Memory operations
 124 
 125     // FIXME: arrays are erased to Object
 126 
 127     @HotSpotIntrinsicCandidate
 128     static
 129     <V extends Vector<?,?>>
 130     V load(Class<?> vectorClass, Class<?> elementType, int vlen,
 131            Object array, int index, /* Vector.Mask<E,S> m*/
 132            BiFunction<Object, Integer, V> defaultImpl) {
 133         return defaultImpl.apply(array, index);
 134     }
 135 
 136     interface StoreVectorOperation<V extends Vector<?,?>> {
 137         void store(Object array, int index, V v);
 138     }
 139 
 140     @HotSpotIntrinsicCandidate
 141     static
 142     <V extends Vector<?,?>>
 143     void store(Class<?> vectorClass, Class<?> elementType, int vlen,
 144                Object array, int index, V v, /*Vector.Mask<E,S> m*/
 145                StoreVectorOperation<V> defaultImpl) {
 146         defaultImpl.store(array, index, v);
 147     }
 148 
 149     /* ============================================================================ */
 150 
 151     @HotSpotIntrinsicCandidate
 152     static <V> boolean test(int cond, Class<?> vectorClass, Class<?> elementType, int vlen,
 153                             V v1, V v2,
 154                             BiFunction<V, V, Boolean> defaultImpl) {
 155         return defaultImpl.apply(v1, v2);
 156     }
 157 
 158     /* ============================================================================ */
 159 
 160     interface VectorCompareOp<V,M> {
 161         M apply(V v1, V v2);
 162     }
 163 
 164     @HotSpotIntrinsicCandidate
 165     static <V extends Vector<E,S>,
 166             M extends Vector.Mask<E,S>,
 167             S extends Vector.Shape, E>
 168     M compare(int cond, Class<V> vectorClass, Class<M> maskClass, Class<?> elementType, int vlen,
 169               V v1, V v2,
 170               VectorCompareOp<V,M> defaultImpl) {
 171         return defaultImpl.apply(v1, v2);
 172     }
 173 
 174     /* ============================================================================ */
 175 
 176     interface VectorBlendOp<V extends Vector<E,S>,
 177                             M extends Vector.Mask<E,S>,
 178                             S extends Vector.Shape, E> {
 179         V apply(V v1, V v2, M mask);
 180     }
 181 
 182     @HotSpotIntrinsicCandidate
 183     static
 184     <V extends Vector<E,S>,
 185      M extends Vector.Mask<E,S>,
 186      S extends Vector.Shape, E>
 187     V blend(Class<V> vectorClass, Class<M> maskClass, Class<?> elementType, int vlen,
 188             V v1, V v2, M m,
 189             VectorBlendOp<V,M,S,E> defaultImpl) {
 190         return defaultImpl.apply(v1, v2, m);
 191     }
 192 
 193     /* ============================================================================ */
 194 
 195     interface VectorBroadcastIntOp<V extends Vector<?,?>> {
 196         V apply(V v, int i);
 197     }
 198 
 199     @HotSpotIntrinsicCandidate
 200     static
 201     <V extends Vector<?,?>>
 202     V broadcastInt(int opr, Class<V> vectorClass, Class<?> elementType, int vlen,
 203                    V v, int i,
 204                    VectorBroadcastIntOp<V> defaultImpl) {
 205         return defaultImpl.apply(v, i);
 206     }
 207 
 208     /* ============================================================================ */
 209 
 210     interface VectorReinterpretOp<VT, VF> {
 211         VT apply(VF v, Class<?> elementType);
 212     }
 213 
 214     @HotSpotIntrinsicCandidate
 215     static
 216     <VT, VF>
 217     VT reinterpret(Class<VF> fromVectorClass, Class<?> fromElementType, int fromVLen,
 218                    Class<?> toElementType, int toVLen, VF v,
 219                    VectorReinterpretOp<VT,VF> defaultImpl) {
 220         return defaultImpl.apply(v, toElementType);
 221     }
 222 
 223     /* ============================================================================ */
 224 
 225     @HotSpotIntrinsicCandidate
 226     static <V> V maybeRebox(V v) {
 227         // The fence is added here to avoid memory aliasing problems in C2 between scalar & vector accesses.
 228         // TODO: move the fence generation into C2. Generate only when reboxing is taking place.
 229         U.loadFence();
 230         return v;
 231     }
 232 
 233     /* ============================================================================ */
 234 
 235     static final int VECTOR_ACCESS_OOB_CHECK = Integer.getInteger("jdk.incubator.vector.VECTOR_ACCESS_OOB_CHECK", 2);
 236 
 237     @ForceInline
 238     static int checkIndex(int ix, int length, int vlen) {
 239         switch (VectorIntrinsics.VECTOR_ACCESS_OOB_CHECK) {
 240             case 0: return ix; // no range check
 241             case 1: return Objects.checkFromIndexSize(ix, vlen, length);
 242             case 2: return Objects.checkIndex(ix, length - (vlen - 1));
 243             default: throw new InternalError();
 244         }
 245     }
 246 }