src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayIndexOfOp.java
author dlong
Thu, 14 Nov 2019 12:21:00 -0800
changeset 59095 03fbcd06b4c0
parent 58299 6df94ce3ab2f
permissions -rw-r--r--
8233841: Update Graal Reviewed-by: kvn
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
     1
/*
54204
55c262f4f5a1 8220389: Update Graal
jwilhelm
parents: 53290
diff changeset
     2
 * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
     4
 *
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
     7
 * published by the Free Software Foundation.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
     8
 *
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    13
 * accompanied this code).
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    14
 *
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    18
 *
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    21
 * questions.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    22
 */
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    23
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    24
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    25
package org.graalvm.compiler.lir.amd64;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    26
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    27
import static jdk.vm.ci.code.ValueUtil.asRegister;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    28
import static jdk.vm.ci.code.ValueUtil.isRegister;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    29
import static jdk.vm.ci.code.ValueUtil.isStackSlot;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    30
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.CONST;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    31
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    32
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    33
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    34
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    35
import java.util.Objects;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    36
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    37
import org.graalvm.compiler.asm.Label;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    38
import org.graalvm.compiler.asm.amd64.AMD64Address;
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    39
import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    40
import org.graalvm.compiler.asm.amd64.AMD64Assembler;
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    41
import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp;
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    42
import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexMoveOp;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    43
import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRMIOp;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    44
import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRMOp;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    45
import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp;
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    46
import org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize;
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    47
import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    48
import org.graalvm.compiler.asm.amd64.AVXKind;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    49
import org.graalvm.compiler.core.common.LIRKind;
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    50
import org.graalvm.compiler.core.common.NumUtil;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    51
import org.graalvm.compiler.lir.ConstantValue;
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    52
import org.graalvm.compiler.lir.LIRInstructionClass;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    53
import org.graalvm.compiler.lir.Opcode;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    54
import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    55
import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    56
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    57
import jdk.vm.ci.amd64.AMD64;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    58
import jdk.vm.ci.amd64.AMD64.CPUFeature;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    59
import jdk.vm.ci.amd64.AMD64Kind;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    60
import jdk.vm.ci.code.Register;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    61
import jdk.vm.ci.meta.JavaConstant;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    62
import jdk.vm.ci.meta.JavaKind;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    63
import jdk.vm.ci.meta.Value;
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    64
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    65
/**
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    66
 */
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    67
@Opcode("AMD64_ARRAY_INDEX_OF")
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    68
public final class AMD64ArrayIndexOfOp extends AMD64LIRInstruction {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    69
    public static final LIRInstructionClass<AMD64ArrayIndexOfOp> TYPE = LIRInstructionClass.create(AMD64ArrayIndexOfOp.class);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    70
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    71
    private final JavaKind valueKind;
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    72
    private final int nValues;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    73
    private final boolean findTwoConsecutive;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    74
    private final AMD64Kind vectorKind;
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    75
    private final int arrayBaseOffset;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    76
    private final Scale arrayIndexScale;
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    77
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    78
    @Def({REG}) protected Value resultValue;
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    79
    @Alive({REG}) protected Value arrayPtrValue;
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    80
    @Alive({REG}) protected Value arrayLengthValue;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    81
    @Use({REG}) protected Value fromIndexValue;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    82
    @Alive({REG, STACK, CONST}) protected Value searchValue1;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    83
    @Alive({REG, STACK, CONST, ILLEGAL}) protected Value searchValue2;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    84
    @Alive({REG, STACK, CONST, ILLEGAL}) protected Value searchValue3;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    85
    @Alive({REG, STACK, CONST, ILLEGAL}) protected Value searchValue4;
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    86
    @Temp({REG}) protected Value comparisonResult1;
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    87
    @Temp({REG, ILLEGAL}) protected Value comparisonResult2;
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    88
    @Temp({REG, ILLEGAL}) protected Value vectorCompareVal1;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    89
    @Temp({REG, ILLEGAL}) protected Value vectorCompareVal2;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    90
    @Temp({REG, ILLEGAL}) protected Value vectorCompareVal3;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    91
    @Temp({REG, ILLEGAL}) protected Value vectorCompareVal4;
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    92
    @Temp({REG, ILLEGAL}) protected Value vectorArray1;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    93
    @Temp({REG, ILLEGAL}) protected Value vectorArray2;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    94
    @Temp({REG, ILLEGAL}) protected Value vectorArray3;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    95
    @Temp({REG, ILLEGAL}) protected Value vectorArray4;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    96
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    97
    public AMD64ArrayIndexOfOp(JavaKind arrayKind, JavaKind valueKind, boolean findTwoConsecutive, int maxVectorSize, LIRGeneratorTool tool,
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
    98
                    Value result, Value arrayPtr, Value arrayLength, Value fromIndex, Value... searchValues) {
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    99
        super(TYPE);
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   100
        this.valueKind = valueKind;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   101
        this.arrayBaseOffset = tool.getProviders().getMetaAccess().getArrayBaseOffset(arrayKind);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   102
        this.arrayIndexScale = Objects.requireNonNull(Scale.fromInt(tool.getProviders().getMetaAccess().getArrayIndexScale(valueKind)));
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   103
        this.findTwoConsecutive = findTwoConsecutive;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   104
        assert 0 < searchValues.length && searchValues.length <= 4;
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   105
        assert byteMode(valueKind) || charMode(valueKind);
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   106
        assert supports(tool, CPUFeature.SSE2) || supports(tool, CPUFeature.AVX) || supportsAVX2(tool);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   107
        nValues = searchValues.length;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   108
        assert !findTwoConsecutive || nValues == 1;
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   109
        resultValue = result;
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   110
        arrayPtrValue = arrayPtr;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   111
        arrayLengthValue = arrayLength;
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   112
        fromIndexValue = fromIndex;
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   113
        searchValue1 = searchValues[0];
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   114
        searchValue2 = nValues > 1 ? searchValues[1] : Value.ILLEGAL;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   115
        searchValue3 = nValues > 2 ? searchValues[2] : Value.ILLEGAL;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   116
        searchValue4 = nValues > 3 ? searchValues[3] : Value.ILLEGAL;
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   117
        comparisonResult1 = tool.newVariable(LIRKind.value(tool.target().arch.getWordKind()));
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   118
        comparisonResult2 = findTwoConsecutive ? tool.newVariable(LIRKind.value(tool.target().arch.getWordKind())) : Value.ILLEGAL;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   119
        vectorKind = supportsAVX2(tool) && (maxVectorSize < 0 || maxVectorSize >= 32) ? byteMode(valueKind) ? AMD64Kind.V256_BYTE : AMD64Kind.V256_WORD
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   120
                        : byteMode(valueKind) ? AMD64Kind.V128_BYTE : AMD64Kind.V128_WORD;
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   121
        vectorCompareVal1 = tool.newVariable(LIRKind.value(vectorKind));
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   122
        vectorCompareVal2 = nValues > 1 ? tool.newVariable(LIRKind.value(vectorKind)) : Value.ILLEGAL;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   123
        vectorCompareVal3 = nValues > 2 ? tool.newVariable(LIRKind.value(vectorKind)) : Value.ILLEGAL;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   124
        vectorCompareVal4 = nValues > 3 ? tool.newVariable(LIRKind.value(vectorKind)) : Value.ILLEGAL;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   125
        vectorArray1 = tool.newVariable(LIRKind.value(vectorKind));
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   126
        vectorArray2 = tool.newVariable(LIRKind.value(vectorKind));
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   127
        vectorArray3 = tool.newVariable(LIRKind.value(vectorKind));
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   128
        vectorArray4 = tool.newVariable(LIRKind.value(vectorKind));
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   129
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   130
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   131
    private static boolean byteMode(JavaKind kind) {
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   132
        return kind == JavaKind.Byte;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   133
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   134
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   135
    private static boolean charMode(JavaKind kind) {
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   136
        return kind == JavaKind.Char;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   137
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   138
53290
b685bc048276 8215313: [AOT] java/lang/String/Split.java fails with AOTed java.base
dnsimon
parents: 52578
diff changeset
   139
    private JavaKind getComparisonKind() {
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   140
        return findTwoConsecutive ? (byteMode(valueKind) ? JavaKind.Char : JavaKind.Int) : valueKind;
53290
b685bc048276 8215313: [AOT] java/lang/String/Split.java fails with AOTed java.base
dnsimon
parents: 52578
diff changeset
   141
    }
b685bc048276 8215313: [AOT] java/lang/String/Split.java fails with AOTed java.base
dnsimon
parents: 52578
diff changeset
   142
b685bc048276 8215313: [AOT] java/lang/String/Split.java fails with AOTed java.base
dnsimon
parents: 52578
diff changeset
   143
    private AVXKind.AVXSize getVectorSize() {
b685bc048276 8215313: [AOT] java/lang/String/Split.java fails with AOTed java.base
dnsimon
parents: 52578
diff changeset
   144
        return AVXKind.getDataSize(vectorKind);
b685bc048276 8215313: [AOT] java/lang/String/Split.java fails with AOTed java.base
dnsimon
parents: 52578
diff changeset
   145
    }
b685bc048276 8215313: [AOT] java/lang/String/Split.java fails with AOTed java.base
dnsimon
parents: 52578
diff changeset
   146
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   147
    @Override
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   148
    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler asm) {
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   149
        int nVectors = nValues == 1 ? 4 : nValues == 2 ? 2 : 1;
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   150
        Register arrayPtr = asRegister(arrayPtrValue);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   151
        Register arrayLength = asRegister(arrayLengthValue);
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   152
        Register fromIndex = asRegister(fromIndexValue);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   153
        Register index = asRegister(resultValue);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   154
        Value[] searchValue = {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   155
                        nValues > 0 ? searchValue1 : null,
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   156
                        nValues > 1 ? searchValue2 : null,
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   157
                        nValues > 2 ? searchValue3 : null,
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   158
                        nValues > 3 ? searchValue4 : null,
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   159
        };
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   160
        Register[] vecCmp = {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   161
                        nValues > 0 ? asRegister(vectorCompareVal1) : null,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   162
                        nValues > 1 ? asRegister(vectorCompareVal2) : null,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   163
                        nValues > 2 ? asRegister(vectorCompareVal3) : null,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   164
                        nValues > 3 ? asRegister(vectorCompareVal4) : null,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   165
        };
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   166
        Register[] vecArray = {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   167
                        asRegister(vectorArray1),
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   168
                        asRegister(vectorArray2),
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   169
                        asRegister(vectorArray3),
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   170
                        asRegister(vectorArray4),
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   171
        };
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   172
        Register[] cmpResult = {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   173
                        asRegister(comparisonResult1),
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   174
                        findTwoConsecutive ? asRegister(comparisonResult2) : null,
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   175
        };
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   176
        Label ret = new Label();
53290
b685bc048276 8215313: [AOT] java/lang/String/Split.java fails with AOTed java.base
dnsimon
parents: 52578
diff changeset
   177
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   178
        Label bulkVectorLoop = new Label();
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   179
        Label singleVectorLoop = new Label();
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   180
        Label[] vectorFound = {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   181
                        new Label(),
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   182
                        new Label(),
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   183
                        new Label(),
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   184
                        new Label(),
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   185
        };
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   186
        Label runVectorized = new Label();
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   187
        Label elementWiseLoop = new Label();
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   188
        Label elementWiseFound = new Label();
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   189
        Label elementWiseNotFound = new Label();
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   190
        Label skipBulkVectorLoop = new Label();
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   191
        int vectorSize = getVectorSize().getBytes() / valueKind.getByteCount();
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   192
        int bulkSize = vectorSize * nVectors;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   193
        JavaKind vectorCompareKind = valueKind;
53290
b685bc048276 8215313: [AOT] java/lang/String/Split.java fails with AOTed java.base
dnsimon
parents: 52578
diff changeset
   194
        if (findTwoConsecutive) {
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   195
            bulkSize /= 2;
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   196
            vectorCompareKind = byteMode(valueKind) ? JavaKind.Char : JavaKind.Int;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   197
        }
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   198
        // index = fromIndex + vectorSize (+1 if findTwoConsecutive)
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   199
        // important: this must be the first register manipulation, since fromIndex is
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   200
        // annotated with @Use
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   201
        asm.leaq(index, new AMD64Address(fromIndex, vectorSize + (findTwoConsecutive ? 1 : 0)));
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   202
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   203
        // check if vector vector load is in bounds
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   204
        asm.cmpq(index, arrayLength);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   205
        asm.jccb(AMD64Assembler.ConditionFlag.LessEqual, runVectorized);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   206
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   207
        // search range is smaller than vector size, do element-wise comparison
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   208
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   209
        // index = fromIndex (+ 1 if findTwoConsecutive)
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   210
        asm.subq(index, vectorSize);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   211
        // check if enough array slots remain
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   212
        asm.cmpq(index, arrayLength);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   213
        asm.jccb(AMD64Assembler.ConditionFlag.GreaterEqual, elementWiseNotFound);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   214
        // compare one-by-one
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   215
        asm.bind(elementWiseLoop);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   216
        // check for match
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   217
        OperandSize cmpSize = getOpSize(getComparisonKind());
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   218
        // address = findTwoConsecutive ? array[index - 1] : array[index]
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   219
        AMD64Address arrayAddr = new AMD64Address(arrayPtr, index, arrayIndexScale, arrayBaseOffset - (findTwoConsecutive ? valueKind.getByteCount() : 0));
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   220
        boolean valuesOnStack = searchValuesOnStack(searchValue);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   221
        if (valuesOnStack) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   222
            (cmpSize == OperandSize.BYTE ? AMD64RMOp.MOVB : AMD64RMOp.MOV).emit(asm, cmpSize, cmpResult[0], arrayAddr);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   223
            for (int i = 0; i < nValues; i++) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   224
                if (isConstant(searchValue[i])) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   225
                    int imm = asConstant(searchValue[i]).asInt();
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   226
                    AMD64Assembler.AMD64BinaryArithmetic.CMP.getMIOpcode(cmpSize, NumUtil.isByte(imm)).emit(asm, cmpSize, cmpResult[0], imm);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   227
                } else if (isStackSlot(searchValue[i])) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   228
                    AMD64Assembler.AMD64BinaryArithmetic.CMP.getRMOpcode(cmpSize).emit(asm, cmpSize, cmpResult[0], (AMD64Address) crb.asAddress(searchValue[i]));
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   229
                } else {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   230
                    AMD64Assembler.AMD64BinaryArithmetic.CMP.getRMOpcode(cmpSize).emit(asm, cmpSize, cmpResult[0], asRegister(searchValue[i]));
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   231
                }
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   232
                asm.jccb(AMD64Assembler.ConditionFlag.Equal, elementWiseFound);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   233
            }
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   234
        } else {
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   235
            for (int i = 0; i < nValues; i++) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   236
                if (isConstant(searchValue[i])) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   237
                    int imm = asConstant(searchValue[i]).asInt();
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   238
                    AMD64Assembler.AMD64BinaryArithmetic.CMP.getMIOpcode(cmpSize, NumUtil.isByte(imm)).emit(asm, cmpSize, arrayAddr, imm);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   239
                } else {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   240
                    AMD64Assembler.AMD64BinaryArithmetic.CMP.getRMOpcode(cmpSize).emit(asm, cmpSize, asRegister(searchValue[i]), arrayAddr);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   241
                }
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   242
                asm.jccb(AMD64Assembler.ConditionFlag.Equal, elementWiseFound);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   243
            }
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   244
        }
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   245
        // adjust index
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   246
        asm.incrementq(index, 1);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   247
        // continue loop
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   248
        asm.cmpq(index, arrayLength);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   249
        asm.jccb(AMD64Assembler.ConditionFlag.Less, elementWiseLoop);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   250
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   251
        asm.bind(elementWiseNotFound);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   252
        asm.xorq(index, index);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   253
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   254
        if (findTwoConsecutive) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   255
            asm.bind(elementWiseFound);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   256
            asm.decrementq(index, 1);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   257
        } else {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   258
            asm.decrementq(index, 1);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   259
            asm.bind(elementWiseFound);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   260
        }
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   261
        asm.jmp(ret);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   262
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   263
        // vectorized implementation
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   264
        asm.bind(runVectorized);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   265
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   266
        // move search values to vectors
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   267
        for (int i = 0; i < nValues; i++) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   268
            // fill comparison vector with copies of the search value
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   269
            broadcastSearchValue(crb, asm, vecCmp[i], searchValue[i], cmpResult[0], vecArray[0]);
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   270
        }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   271
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   272
        // do one unaligned vector comparison pass and adjust alignment afterwards
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   273
        emitVectorCompare(asm, vectorCompareKind, findTwoConsecutive ? 2 : 1, arrayPtr, index, vecCmp, vecArray, cmpResult, vectorFound, false, false);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   274
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   275
        // adjust index to vector size alignment
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   276
        asm.leaq(cmpResult[0], new AMD64Address(arrayPtr, arrayBaseOffset));
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   277
        if (charMode(valueKind)) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   278
            asm.shrq(cmpResult[0], 1);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   279
        }
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   280
        asm.addq(index, cmpResult[0]);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   281
        // adjust to next lower multiple of vector size
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   282
        asm.andq(index, ~(vectorSize - 1));
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   283
        asm.subq(index, cmpResult[0]);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   284
        // add bulk size
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   285
        asm.addq(index, bulkSize);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   286
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   287
        // check if there are enough array slots remaining for the bulk loop
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   288
        asm.cmpq(index, arrayLength);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   289
        asm.jccb(AMD64Assembler.ConditionFlag.Greater, skipBulkVectorLoop);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   290
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   291
        emitAlign(crb, asm);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   292
        asm.bind(bulkVectorLoop);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   293
        // memory-aligned bulk comparison
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   294
        emitVectorCompare(asm, vectorCompareKind, nVectors, arrayPtr, index, vecCmp, vecArray, cmpResult, vectorFound, false, !findTwoConsecutive);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   295
        // adjust index
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   296
        asm.addq(index, bulkSize);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   297
        // check if there are enough array slots remaining for the bulk loop
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   298
        asm.cmpq(index, arrayLength);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   299
        asm.jccb(AMD64Assembler.ConditionFlag.LessEqual, bulkVectorLoop);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   300
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   301
        asm.bind(skipBulkVectorLoop);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   302
        if ((findTwoConsecutive && nVectors == 2) || nVectors == 1) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   303
            // do last load from end of array
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   304
            asm.movq(index, arrayLength);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   305
            // compare
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   306
            emitVectorCompare(asm, vectorCompareKind, findTwoConsecutive ? 2 : 1, arrayPtr, index, vecCmp, vecArray, cmpResult, vectorFound, true, false);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   307
        } else {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   308
            // remove bulk offset
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   309
            asm.subq(index, bulkSize);
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   310
            emitAlign(crb, asm);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   311
            // same loop as bulkVectorLoop, with only one vector
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   312
            asm.bind(singleVectorLoop);
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   313
            // add vector size
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   314
            asm.addq(index, vectorSize);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   315
            // check if vector load is in bounds
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   316
            asm.cmpq(index, arrayLength);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   317
            // if load would be over bounds, set the load to the end of the array
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   318
            asm.cmovq(AMD64Assembler.ConditionFlag.Greater, index, arrayLength);
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   319
            // compare
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   320
            emitVectorCompare(asm, vectorCompareKind, findTwoConsecutive ? 2 : 1, arrayPtr, index, vecCmp, vecArray, cmpResult, vectorFound, true, false);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   321
            // check if there are enough array slots remaining for the loop
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   322
            asm.cmpq(index, arrayLength);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   323
            asm.jccb(AMD64Assembler.ConditionFlag.Less, singleVectorLoop);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   324
        }
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   325
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   326
        asm.movl(index, -1);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   327
        asm.jmpb(ret);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   328
53290
b685bc048276 8215313: [AOT] java/lang/String/Split.java fails with AOTed java.base
dnsimon
parents: 52578
diff changeset
   329
        if (findTwoConsecutive) {
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   330
            Label vectorFound2Done = new Label();
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   331
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   332
            // vectorFound[0] and vectorFound[2] behave like the single-char case
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   333
            asm.bind(vectorFound[2]);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   334
            // add static offset
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   335
            asm.subq(index, getResultIndexDelta(2));
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   336
            asm.jmpb(vectorFound2Done);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   337
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   338
            asm.bind(vectorFound[0]);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   339
            // add static offset
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   340
            asm.subq(index, getResultIndexDelta(0));
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   341
            asm.bind(vectorFound2Done);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   342
            // find offset
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   343
            asm.bsfq(cmpResult[0], cmpResult[0]);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   344
            if (charMode(valueKind)) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   345
                // convert byte offset to chars
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   346
                asm.shrl(cmpResult[0], 1);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   347
            }
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   348
            // add offset to index
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   349
            asm.addq(index, cmpResult[0]);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   350
            asm.jmpb(ret);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   351
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   352
            Label minResult = new Label();
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   353
            Label minResultDone = new Label();
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   354
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   355
            // in vectorFound[1] and vectorFound[3], we have to check the results 0 and 2 as well
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   356
            if (nVectors > 2) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   357
                asm.bind(vectorFound[3]);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   358
                // add offset
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   359
                asm.subq(index, getResultIndexDelta(3));
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   360
                asm.jmpb(minResult);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   361
            }
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   362
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   363
            asm.bind(vectorFound[1]);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   364
            // add offset
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   365
            asm.subq(index, getResultIndexDelta(1));
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   366
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   367
            asm.bind(minResult);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   368
            // find offset 0
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   369
            asm.bsfq(cmpResult[1], cmpResult[1]);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   370
            // check if second result is also a match
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   371
            asm.testq(cmpResult[0], cmpResult[0]);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   372
            asm.jccb(AMD64Assembler.ConditionFlag.Zero, minResultDone);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   373
            // find offset 1
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   374
            asm.bsfq(cmpResult[0], cmpResult[0]);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   375
            asm.addq(cmpResult[0], valueKind.getByteCount());
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   376
            // if first result is greater than second, replace it with the second result
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   377
            asm.cmpq(cmpResult[1], cmpResult[0]);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   378
            asm.cmovq(AMD64Assembler.ConditionFlag.Greater, cmpResult[1], cmpResult[0]);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   379
            asm.bind(minResultDone);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   380
            if (charMode(valueKind)) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   381
                // convert byte offset to chars
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   382
                asm.shrl(cmpResult[1], 1);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   383
            }
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   384
            // add offset to index
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   385
            asm.addq(index, cmpResult[1]);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   386
        } else {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   387
            Label end = new Label();
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   388
            for (int i = 0; i < nVectors; i++) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   389
                asm.bind(vectorFound[i]);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   390
                // add static offset
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   391
                asm.subq(index, getResultIndexDelta(i));
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   392
                if (i < nVectors - 1) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   393
                    asm.jmpb(end);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   394
                }
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   395
            }
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   396
            asm.bind(end);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   397
            // find offset
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   398
            asm.bsfq(cmpResult[0], cmpResult[0]);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   399
            if (charMode(valueKind)) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   400
                // convert byte offset to chars
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   401
                asm.shrl(cmpResult[0], 1);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   402
            }
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   403
            // add offset to index
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   404
            asm.addq(index, cmpResult[0]);
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   405
        }
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   406
        asm.bind(ret);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   407
    }
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   408
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   409
    private boolean searchValuesOnStack(Value[] searchValue) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   410
        for (int i = 0; i < nValues; i++) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   411
            if (isStackSlot(searchValue[i])) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   412
                return true;
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   413
            }
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   414
        }
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   415
        return false;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   416
    }
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   417
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   418
    private int getResultIndexDelta(int i) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   419
        return (((findTwoConsecutive ? i / 2 : i) + 1) * (getVectorSize().getBytes() / valueKind.getByteCount())) + (findTwoConsecutive ? (i & 1) : 0);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   420
    }
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   421
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   422
    private int getVectorOffset(int i) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   423
        return arrayBaseOffset - getResultIndexDelta(i) * valueKind.getByteCount();
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   424
    }
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   425
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   426
    private void broadcastSearchValue(CompilationResultBuilder crb, AMD64MacroAssembler asm, Register dst, Value srcVal, Register tmpReg, Register tmpVector) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   427
        Register src = asRegOrTmpReg(crb, asm, srcVal, tmpReg);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   428
        if (asm.supports(CPUFeature.AVX)) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   429
            VexMoveOp.VMOVD.emit(asm, AVXKind.AVXSize.DWORD, dst, src);
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   430
        } else {
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   431
            asm.movdl(dst, src);
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   432
        }
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   433
        emitBroadcast(asm, getComparisonKind(), dst, tmpVector, getVectorSize());
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   434
    }
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   435
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   436
    private static boolean isConstant(Value val) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   437
        assert !(val instanceof ConstantValue) || ((ConstantValue) val).isJavaConstant();
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   438
        return val instanceof ConstantValue;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   439
    }
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   440
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   441
    private static JavaConstant asConstant(Value val) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   442
        return ((ConstantValue) val).getJavaConstant();
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   443
    }
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   444
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   445
    private static Register asRegOrTmpReg(CompilationResultBuilder crb, AMD64MacroAssembler asm, Value val, Register tmpReg) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   446
        if (isRegister(val)) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   447
            return asRegister(val);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   448
        } else if (isStackSlot(val)) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   449
            asm.movl(tmpReg, (AMD64Address) crb.asAddress(val));
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   450
            return tmpReg;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   451
        } else {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   452
            assert isConstant(val);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   453
            asm.movl(tmpReg, asConstant(val).asInt());
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   454
            return tmpReg;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   455
        }
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   456
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   457
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   458
    private static void emitAlign(CompilationResultBuilder crb, AMD64MacroAssembler asm) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   459
        asm.align(crb.target.wordSize * 2);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   460
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   461
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   462
    /**
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   463
     * Fills {@code vecDst} with copies of its lowest byte, word or dword.
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   464
     */
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   465
    private static void emitBroadcast(AMD64MacroAssembler asm, JavaKind kind, Register vecDst, Register vecTmp, AVXKind.AVXSize vectorSize) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   466
        switch (kind) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   467
            case Byte:
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   468
                if (asm.supports(CPUFeature.AVX2)) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   469
                    VexRMOp.VPBROADCASTB.emit(asm, vectorSize, vecDst, vecDst);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   470
                } else if (asm.supports(CPUFeature.AVX)) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   471
                    VexRVMOp.VPXOR.emit(asm, vectorSize, vecTmp, vecTmp, vecTmp);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   472
                    VexRVMOp.VPSHUFB.emit(asm, vectorSize, vecDst, vecDst, vecTmp);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   473
                } else if (asm.supports(CPUFeature.SSSE3)) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   474
                    asm.pxor(vecTmp, vecTmp);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   475
                    asm.pshufb(vecDst, vecTmp);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   476
                } else { // SSE2
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   477
                    asm.punpcklbw(vecDst, vecDst);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   478
                    asm.punpcklbw(vecDst, vecDst);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   479
                    asm.pshufd(vecDst, vecDst, 0);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   480
                }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   481
                break;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   482
            case Short:
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   483
            case Char:
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   484
                if (asm.supports(CPUFeature.AVX2)) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   485
                    VexRMOp.VPBROADCASTW.emit(asm, vectorSize, vecDst, vecDst);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   486
                } else if (asm.supports(CPUFeature.AVX)) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   487
                    VexRMIOp.VPSHUFLW.emit(asm, vectorSize, vecDst, vecDst, 0);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   488
                    VexRMIOp.VPSHUFD.emit(asm, vectorSize, vecDst, vecDst, 0);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   489
                } else { // SSE
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   490
                    asm.pshuflw(vecDst, vecDst, 0);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   491
                    asm.pshufd(vecDst, vecDst, 0);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   492
                }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   493
                break;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   494
            case Int:
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   495
                if (asm.supports(CPUFeature.AVX2)) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   496
                    VexRMOp.VPBROADCASTD.emit(asm, vectorSize, vecDst, vecDst);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   497
                } else if (asm.supports(CPUFeature.AVX)) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   498
                    VexRMIOp.VPSHUFD.emit(asm, vectorSize, vecDst, vecDst, 0);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   499
                } else { // SSE
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   500
                    asm.pshufd(vecDst, vecDst, 0);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   501
                }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   502
                break;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   503
            default:
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   504
                throw new UnsupportedOperationException();
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   505
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   506
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   507
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   508
    private void emitVectorCompare(AMD64MacroAssembler asm,
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   509
                    JavaKind kind,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   510
                    int nVectors,
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   511
                    Register arrayPtr,
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   512
                    Register index,
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   513
                    Register[] vecCmp,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   514
                    Register[] vecArray,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   515
                    Register[] cmpResult,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   516
                    Label[] vectorFound,
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   517
                    boolean shortJmp,
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   518
                    boolean alignedLoad) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   519
        // load array contents into vectors
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   520
        for (int i = 0; i < nVectors; i++) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   521
            int base = i * nValues;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   522
            for (int j = 0; j < nValues; j++) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   523
                emitArrayLoad(asm, getVectorSize(), vecArray[base + j], arrayPtr, index, getVectorOffset(nVectors - (i + 1)), alignedLoad);
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   524
            }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   525
        }
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   526
        // compare all loaded bytes to the search value.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   527
        // matching bytes are set to 0xff, non-matching bytes are set to 0x00.
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   528
        if (!findTwoConsecutive) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   529
            for (int i = 0; i < nVectors; i++) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   530
                int base = i * nValues;
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   531
                for (int j = 0; j < nValues; j++) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   532
                    emitVectorCompareInst(asm, kind, getVectorSize(), vecArray[base + j], vecCmp[j]);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   533
                    if ((j & 1) == 1) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   534
                        emitPOR(asm, getVectorSize(), vecArray[base + j - 1], vecArray[base + j]);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   535
                    }
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   536
                }
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   537
                if (nValues > 2) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   538
                    emitPOR(asm, getVectorSize(), vecArray[base], vecArray[base + 2]);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   539
                }
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   540
                emitMOVMSK(asm, getVectorSize(), cmpResult[0], vecArray[base]);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   541
                emitJnz(asm, cmpResult[0], vectorFound[nVectors - (i + 1)], shortJmp);
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   542
            }
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   543
        } else {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   544
            for (int i = 0; i < nVectors; i += 2) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   545
                emitVectorCompareInst(asm, kind, getVectorSize(), vecArray[i], vecCmp[0]);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   546
                emitVectorCompareInst(asm, kind, getVectorSize(), vecArray[i + 1], vecCmp[0]);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   547
                emitMOVMSK(asm, getVectorSize(), cmpResult[1], vecArray[i]);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   548
                emitMOVMSK(asm, getVectorSize(), cmpResult[0], vecArray[i + 1]);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   549
                emitJnz(asm, cmpResult[1], vectorFound[nVectors - (i + 1)], shortJmp);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   550
                emitJnz(asm, cmpResult[0], vectorFound[nVectors - (i + 2)], shortJmp);
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   551
            }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   552
        }
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   553
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   554
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   555
    private static void emitJnz(AMD64MacroAssembler asm, Register cond, Label tgt, boolean shortJmp) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   556
        asm.testl(cond, cond);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   557
        if (shortJmp) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   558
            asm.jccb(AMD64Assembler.ConditionFlag.NotZero, tgt);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   559
        } else {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   560
            asm.jcc(AMD64Assembler.ConditionFlag.NotZero, tgt);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   561
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   562
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   563
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   564
    private void emitArrayLoad(AMD64MacroAssembler asm, AVXKind.AVXSize vectorSize, Register vecDst, Register arrayPtr, Register index, int offset, boolean alignedLoad) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   565
        AMD64Address src = new AMD64Address(arrayPtr, index, arrayIndexScale, offset);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   566
        if (asm.supports(CPUFeature.AVX)) {
58299
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 57537
diff changeset
   567
            VexMoveOp loadOp = alignedLoad ? VexMoveOp.VMOVDQA32 : VexMoveOp.VMOVDQU32;
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   568
            loadOp.emit(asm, vectorSize, vecDst, src);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   569
        } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   570
            // SSE
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   571
            asm.movdqu(vecDst, src);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   572
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   573
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   574
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   575
    /**
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   576
     * Compares all packed bytes/words/dwords in {@code vecArray} to {@code vecCmp}. Matching values
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   577
     * are set to all ones (0xff, 0xffff, ...), non-matching values are set to zero.
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   578
     */
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   579
    private static void emitVectorCompareInst(AMD64MacroAssembler asm, JavaKind kind, AVXKind.AVXSize vectorSize, Register vecArray, Register vecCmp) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   580
        switch (kind) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   581
            case Byte:
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   582
                if (asm.supports(CPUFeature.AVX)) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   583
                    VexRVMOp.VPCMPEQB.emit(asm, vectorSize, vecArray, vecCmp, vecArray);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   584
                } else { // SSE
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   585
                    asm.pcmpeqb(vecArray, vecCmp);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   586
                }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   587
                break;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   588
            case Short:
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   589
            case Char:
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   590
                if (asm.supports(CPUFeature.AVX)) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   591
                    VexRVMOp.VPCMPEQW.emit(asm, vectorSize, vecArray, vecCmp, vecArray);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   592
                } else { // SSE
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   593
                    asm.pcmpeqw(vecArray, vecCmp);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   594
                }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   595
                break;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   596
            case Int:
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   597
                if (asm.supports(CPUFeature.AVX)) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   598
                    VexRVMOp.VPCMPEQD.emit(asm, vectorSize, vecArray, vecCmp, vecArray);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   599
                } else { // SSE
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   600
                    asm.pcmpeqd(vecArray, vecCmp);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   601
                }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   602
                break;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   603
            default:
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   604
                throw new UnsupportedOperationException();
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   605
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   606
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   607
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   608
    private static void emitPOR(AMD64MacroAssembler asm, AVXKind.AVXSize vectorSize, Register dst, Register vecSrc) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   609
        if (asm.supports(CPUFeature.AVX)) {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   610
            VexRVMOp.VPOR.emit(asm, vectorSize, dst, dst, vecSrc);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   611
        } else {
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   612
            // SSE
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   613
            asm.por(dst, vecSrc);
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   614
        }
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   615
    }
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   616
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   617
    private static void emitMOVMSK(AMD64MacroAssembler asm, AVXKind.AVXSize vectorSize, Register dst, Register vecSrc) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   618
        if (asm.supports(CPUFeature.AVX)) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   619
            VexRMOp.VPMOVMSKB.emit(asm, vectorSize, dst, vecSrc);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   620
        } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   621
            // SSE
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   622
            asm.pmovmskb(dst, vecSrc);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   623
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   624
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   625
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   626
    private static OperandSize getOpSize(JavaKind kind) {
53290
b685bc048276 8215313: [AOT] java/lang/String/Split.java fails with AOTed java.base
dnsimon
parents: 52578
diff changeset
   627
        switch (kind) {
b685bc048276 8215313: [AOT] java/lang/String/Split.java fails with AOTed java.base
dnsimon
parents: 52578
diff changeset
   628
            case Byte:
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   629
                return OperandSize.BYTE;
53290
b685bc048276 8215313: [AOT] java/lang/String/Split.java fails with AOTed java.base
dnsimon
parents: 52578
diff changeset
   630
            case Short:
b685bc048276 8215313: [AOT] java/lang/String/Split.java fails with AOTed java.base
dnsimon
parents: 52578
diff changeset
   631
            case Char:
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   632
                return OperandSize.WORD;
53290
b685bc048276 8215313: [AOT] java/lang/String/Split.java fails with AOTed java.base
dnsimon
parents: 52578
diff changeset
   633
            case Int:
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   634
                return OperandSize.DWORD;
53290
b685bc048276 8215313: [AOT] java/lang/String/Split.java fails with AOTed java.base
dnsimon
parents: 52578
diff changeset
   635
            default:
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54328
diff changeset
   636
                return OperandSize.QWORD;
53290
b685bc048276 8215313: [AOT] java/lang/String/Split.java fails with AOTed java.base
dnsimon
parents: 52578
diff changeset
   637
        }
b685bc048276 8215313: [AOT] java/lang/String/Split.java fails with AOTed java.base
dnsimon
parents: 52578
diff changeset
   638
    }
b685bc048276 8215313: [AOT] java/lang/String/Split.java fails with AOTed java.base
dnsimon
parents: 52578
diff changeset
   639
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   640
    private static boolean supportsAVX2(LIRGeneratorTool tool) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   641
        return supports(tool, CPUFeature.AVX2);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   642
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   643
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   644
    private static boolean supports(LIRGeneratorTool tool, CPUFeature cpuFeature) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   645
        return ((AMD64) tool.target().arch).getFeatures().contains(cpuFeature);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   646
    }
59095
03fbcd06b4c0 8233841: Update Graal
dlong
parents: 58299
diff changeset
   647
03fbcd06b4c0 8233841: Update Graal
dlong
parents: 58299
diff changeset
   648
    @Override
03fbcd06b4c0 8233841: Update Graal
dlong
parents: 58299
diff changeset
   649
    public boolean needsClearUpperVectorRegisters() {
03fbcd06b4c0 8233841: Update Graal
dlong
parents: 58299
diff changeset
   650
        return true;
03fbcd06b4c0 8233841: Update Graal
dlong
parents: 58299
diff changeset
   651
    }
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   652
}