src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayIndexOfOp.java
author dlong
Thu, 15 Nov 2018 09:04:07 -0800
changeset 52578 7dd81e82d083
parent 51436 091c0d22e735
child 53290 b685bc048276
permissions -rw-r--r--
8210777: 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
/*
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
     2
 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
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
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    27
import jdk.vm.ci.amd64.AMD64;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    28
import jdk.vm.ci.amd64.AMD64.CPUFeature;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    29
import jdk.vm.ci.amd64.AMD64Kind;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    30
import jdk.vm.ci.code.Register;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    31
import jdk.vm.ci.meta.JavaKind;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    32
import jdk.vm.ci.meta.Value;
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    33
import org.graalvm.compiler.asm.Label;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    34
import org.graalvm.compiler.asm.amd64.AMD64Address;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    35
import org.graalvm.compiler.asm.amd64.AMD64Assembler;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    36
import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexMoveOp;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    37
import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRMIOp;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    38
import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRMOp;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    39
import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    40
import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    41
import org.graalvm.compiler.asm.amd64.AVXKind;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    42
import org.graalvm.compiler.core.common.LIRKind;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    43
import org.graalvm.compiler.lir.LIRInstructionClass;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    44
import org.graalvm.compiler.lir.Opcode;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    45
import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    46
import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    47
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    48
import static jdk.vm.ci.code.ValueUtil.asRegister;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    49
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    50
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    51
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    52
/**
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    53
 */
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    54
@Opcode("AMD64_ARRAY_INDEX_OF")
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    55
public final class AMD64ArrayIndexOfOp extends AMD64LIRInstruction {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    56
    public static final LIRInstructionClass<AMD64ArrayIndexOfOp> TYPE = LIRInstructionClass.create(AMD64ArrayIndexOfOp.class);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    57
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    58
    private final JavaKind kind;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    59
    private final int vmPageSize;
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    60
    private final int nValues;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    61
    private final boolean findTwoConsecutive;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    62
    private final AMD64Kind vectorKind;
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    63
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    64
    @Def({REG}) protected Value resultValue;
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    65
    @Alive({REG}) protected Value arrayPtrValue;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    66
    @Use({REG}) protected Value arrayLengthValue;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    67
    @Alive({REG}) protected Value searchValue1;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    68
    @Alive({REG, ILLEGAL}) protected Value searchValue2;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    69
    @Alive({REG, ILLEGAL}) protected Value searchValue3;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    70
    @Alive({REG, ILLEGAL}) protected Value searchValue4;
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    71
    @Temp({REG}) protected Value arraySlotsRemaining;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    72
    @Temp({REG}) protected Value comparisonResult1;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    73
    @Temp({REG}) protected Value comparisonResult2;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    74
    @Temp({REG}) protected Value comparisonResult3;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    75
    @Temp({REG}) protected Value comparisonResult4;
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    76
    @Temp({REG, ILLEGAL}) protected Value vectorCompareVal1;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    77
    @Temp({REG, ILLEGAL}) protected Value vectorCompareVal2;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    78
    @Temp({REG, ILLEGAL}) protected Value vectorCompareVal3;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    79
    @Temp({REG, ILLEGAL}) protected Value vectorCompareVal4;
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    80
    @Temp({REG, ILLEGAL}) protected Value vectorArray1;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    81
    @Temp({REG, ILLEGAL}) protected Value vectorArray2;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    82
    @Temp({REG, ILLEGAL}) protected Value vectorArray3;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    83
    @Temp({REG, ILLEGAL}) protected Value vectorArray4;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    84
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    85
    public AMD64ArrayIndexOfOp(JavaKind kind, boolean findTwoConsecutive, int vmPageSize, int maxVectorSize, LIRGeneratorTool tool, Value result, Value arrayPtr, Value arrayLength,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    86
                    Value... searchValues) {
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    87
        super(TYPE);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    88
        this.kind = kind;
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    89
        this.findTwoConsecutive = findTwoConsecutive;
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    90
        this.vmPageSize = vmPageSize;
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    91
        assert 0 < searchValues.length && searchValues.length <= 4;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    92
        assert byteMode(kind) || charMode(kind);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    93
        assert supports(tool, CPUFeature.SSE2) || supports(tool, CPUFeature.AVX) || supportsAVX2(tool);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    94
        nValues = searchValues.length;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    95
        assert !findTwoConsecutive || nValues == 1;
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
    96
        resultValue = result;
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    97
        arrayPtrValue = arrayPtr;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    98
        arrayLengthValue = arrayLength;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    99
        searchValue1 = searchValues[0];
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   100
        searchValue2 = nValues > 1 ? searchValues[1] : Value.ILLEGAL;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   101
        searchValue3 = nValues > 2 ? searchValues[2] : Value.ILLEGAL;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   102
        searchValue4 = nValues > 3 ? searchValues[3] : Value.ILLEGAL;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   103
        arraySlotsRemaining = tool.newVariable(LIRKind.value(AMD64Kind.DWORD));
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   104
        comparisonResult1 = tool.newVariable(LIRKind.value(AMD64Kind.DWORD));
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   105
        comparisonResult2 = tool.newVariable(LIRKind.value(AMD64Kind.DWORD));
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   106
        comparisonResult3 = tool.newVariable(LIRKind.value(AMD64Kind.DWORD));
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   107
        comparisonResult4 = tool.newVariable(LIRKind.value(AMD64Kind.DWORD));
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   108
        vectorKind = supportsAVX2(tool) && (maxVectorSize < 0 || maxVectorSize >= 32) ? byteMode(kind) ? AMD64Kind.V256_BYTE : AMD64Kind.V256_WORD
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   109
                        : byteMode(kind) ? AMD64Kind.V128_BYTE : AMD64Kind.V128_WORD;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   110
        vectorCompareVal1 = tool.newVariable(LIRKind.value(vectorKind));
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   111
        vectorCompareVal2 = nValues > 1 ? tool.newVariable(LIRKind.value(vectorKind)) : Value.ILLEGAL;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   112
        vectorCompareVal3 = nValues > 2 ? tool.newVariable(LIRKind.value(vectorKind)) : Value.ILLEGAL;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   113
        vectorCompareVal4 = nValues > 3 ? tool.newVariable(LIRKind.value(vectorKind)) : Value.ILLEGAL;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   114
        vectorArray1 = tool.newVariable(LIRKind.value(vectorKind));
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   115
        vectorArray2 = tool.newVariable(LIRKind.value(vectorKind));
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   116
        vectorArray3 = tool.newVariable(LIRKind.value(vectorKind));
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   117
        vectorArray4 = tool.newVariable(LIRKind.value(vectorKind));
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   118
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   119
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   120
    private static boolean byteMode(JavaKind kind) {
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   121
        return kind == JavaKind.Byte;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   122
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   123
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   124
    private static boolean charMode(JavaKind kind) {
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   125
        return kind == JavaKind.Char;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   126
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   127
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   128
    @Override
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   129
    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler asm) {
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   130
        Register arrayPtr = asRegister(arrayPtrValue);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   131
        Register arrayLength = asRegister(arrayLengthValue);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   132
        Register result = asRegister(resultValue);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   133
        Register slotsRemaining = asRegister(arraySlotsRemaining);
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   134
        Register[] searchValue = {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   135
                        nValues > 0 ? asRegister(searchValue1) : null,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   136
                        nValues > 1 ? asRegister(searchValue2) : null,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   137
                        nValues > 2 ? asRegister(searchValue3) : null,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   138
                        nValues > 3 ? asRegister(searchValue4) : null,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   139
        };
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   140
        Register[] vecCmp = {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   141
                        nValues > 0 ? asRegister(vectorCompareVal1) : null,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   142
                        nValues > 1 ? asRegister(vectorCompareVal2) : null,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   143
                        nValues > 2 ? asRegister(vectorCompareVal3) : null,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   144
                        nValues > 3 ? asRegister(vectorCompareVal4) : null,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   145
        };
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   146
        Register[] vecArray = {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   147
                        asRegister(vectorArray1),
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   148
                        asRegister(vectorArray2),
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   149
                        asRegister(vectorArray3),
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   150
                        asRegister(vectorArray4),
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   151
        };
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   152
        Register[] cmpResult = {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   153
                        asRegister(comparisonResult1),
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   154
                        asRegister(comparisonResult2),
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   155
                        asRegister(comparisonResult3),
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   156
                        asRegister(comparisonResult4),
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   157
        };
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   158
        Label retFound = new Label();
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   159
        Label retNotFound = new Label();
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   160
        Label end = new Label();
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   161
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   162
        AVXKind.AVXSize vectorSize = AVXKind.getDataSize(vectorKind);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   163
        int nVectors = nValues == 1 ? 4 : nValues == 2 ? 2 : 1;
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   164
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   165
        // load array length
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   166
        // important: this must be the first register manipulation, since arrayLengthValue is
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   167
        // annotated with @Use
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   168
        asm.movl(slotsRemaining, arrayLength);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   169
        // load array pointer
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   170
        asm.movq(result, arrayPtr);
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   171
        // move search values to vectors
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   172
        for (int i = 0; i < nValues; i++) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   173
            if (asm.supports(CPUFeature.AVX)) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   174
                VexMoveOp.VMOVD.emit(asm, AVXKind.AVXSize.DWORD, vecCmp[i], searchValue[i]);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   175
            } else {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   176
                asm.movdl(vecCmp[i], searchValue[i]);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   177
            }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   178
        }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   179
        // fill comparison vector with copies of the search value
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   180
        for (int i = 0; i < nValues; i++) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   181
            emitBroadcast(asm, findTwoConsecutive ? (byteMode(kind) ? JavaKind.Char : JavaKind.Int) : kind, vecCmp[i], vecArray[0], vectorSize);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   182
        }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   183
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   184
        emitArrayIndexOfChars(crb, asm, kind, vectorSize, result, slotsRemaining, searchValue, vecCmp, vecArray, cmpResult, retFound, retNotFound, vmPageSize, nValues, nVectors, findTwoConsecutive);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   185
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   186
        // return -1 (no match)
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   187
        asm.bind(retNotFound);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   188
        asm.movq(result, -1);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   189
        asm.jmpb(end);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   190
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   191
        asm.bind(retFound);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   192
        // convert array pointer to offset
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   193
        asm.subq(result, arrayPtr);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   194
        if (charMode(kind)) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   195
            asm.shrq(result, 1);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   196
        }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   197
        asm.bind(end);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   198
    }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   199
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   200
    private static void emitArrayIndexOfChars(CompilationResultBuilder crb, AMD64MacroAssembler asm, JavaKind kind, AVXKind.AVXSize vectorSize,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   201
                    Register arrayPtr,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   202
                    Register slotsRemaining,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   203
                    Register[] searchValue,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   204
                    Register[] vecCmp,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   205
                    Register[] vecArray,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   206
                    Register[] cmpResult,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   207
                    Label retFound,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   208
                    Label retNotFound,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   209
                    int vmPageSize,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   210
                    int nValues,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   211
                    int nVectors,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   212
                    boolean findTwoCharPrefix) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   213
        Label bulkVectorLoop = new Label();
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   214
        Label singleVectorLoop = new Label();
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   215
        Label[] vectorFound = {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   216
                        new Label(),
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   217
                        new Label(),
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   218
                        new Label(),
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   219
                        new Label(),
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   220
        };
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   221
        Label lessThanVectorSizeRemaining = new Label();
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   222
        Label lessThanVectorSizeRemainingLoop = new Label();
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   223
        Label bulkVectorLoopExit = nVectors == 1 ? lessThanVectorSizeRemaining : singleVectorLoop;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   224
        int bytesPerVector = vectorSize.getBytes();
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   225
        int arraySlotsPerVector = vectorSize.getBytes() / kind.getByteCount();
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   226
        int singleVectorLoopCondition = arraySlotsPerVector;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   227
        int bulkSize = arraySlotsPerVector * nVectors;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   228
        int bulkSizeBytes = bytesPerVector * nVectors;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   229
        int bulkLoopCondition = bulkSize;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   230
        int[] vectorOffsets;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   231
        JavaKind vectorCompareKind = kind;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   232
        if (findTwoCharPrefix) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   233
            singleVectorLoopCondition++;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   234
            bulkLoopCondition++;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   235
            bulkSize /= 2;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   236
            bulkSizeBytes /= 2;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   237
            vectorOffsets = new int[]{0, kind.getByteCount(), bytesPerVector, bytesPerVector + kind.getByteCount()};
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   238
            vectorCompareKind = byteMode(kind) ? JavaKind.Char : JavaKind.Int;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   239
        } else {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   240
            vectorOffsets = new int[]{0, bytesPerVector, bytesPerVector * 2, bytesPerVector * 3};
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   241
        }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   242
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   243
        // load copy of low part of array pointer
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   244
        Register tmpArrayPtrLow = cmpResult[0];
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   245
        asm.movl(tmpArrayPtrLow, arrayPtr);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   246
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   247
        // check if bulk vector load is in bounds
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   248
        asm.cmpl(slotsRemaining, bulkLoopCondition);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   249
        asm.jcc(AMD64Assembler.ConditionFlag.Below, bulkVectorLoopExit);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   250
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   251
        // check if array pointer is aligned to bulkSize
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   252
        asm.andl(tmpArrayPtrLow, bulkSizeBytes - 1);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   253
        asm.jcc(AMD64Assembler.ConditionFlag.Zero, bulkVectorLoop);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   254
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   255
        // do one unaligned bulk comparison pass and adjust alignment afterwards
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   256
        emitVectorCompare(asm, vectorCompareKind, vectorSize, nValues, nVectors, vectorOffsets, arrayPtr, vecCmp, vecArray, cmpResult, vectorFound, false);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   257
        // load copy of low part of array pointer
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   258
        asm.movl(tmpArrayPtrLow, arrayPtr);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   259
        // adjust array pointer
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   260
        asm.addq(arrayPtr, bulkSizeBytes);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   261
        // adjust number of array slots remaining
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   262
        asm.subl(slotsRemaining, bulkSize);
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   263
        // get offset to bulk size alignment
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   264
        asm.andl(tmpArrayPtrLow, bulkSizeBytes - 1);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   265
        emitBytesToArraySlots(asm, kind, tmpArrayPtrLow);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   266
        // adjust array pointer to bulk size alignment
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   267
        asm.andq(arrayPtr, ~(bulkSizeBytes - 1));
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   268
        // adjust number of array slots remaining
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   269
        asm.addl(slotsRemaining, tmpArrayPtrLow);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   270
        // check if there are enough array slots remaining for the bulk loop
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   271
        asm.cmpl(slotsRemaining, bulkLoopCondition);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   272
        asm.jcc(AMD64Assembler.ConditionFlag.Below, bulkVectorLoopExit);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   273
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   274
        emitAlign(crb, asm);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   275
        asm.bind(bulkVectorLoop);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   276
        // memory-aligned bulk comparison
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   277
        emitVectorCompare(asm, vectorCompareKind, vectorSize, nValues, nVectors, vectorOffsets, arrayPtr, vecCmp, vecArray, cmpResult, vectorFound, !findTwoCharPrefix);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   278
        // adjust number of array slots remaining
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   279
        asm.subl(slotsRemaining, bulkSize);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   280
        // adjust array pointer
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   281
        asm.addq(arrayPtr, bulkSizeBytes);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   282
        // check if there are enough array slots remaining for the bulk loop
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   283
        asm.cmpl(slotsRemaining, bulkLoopCondition);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   284
        asm.jcc(AMD64Assembler.ConditionFlag.Below, bulkVectorLoopExit);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   285
        // continue loop
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   286
        asm.jmp(bulkVectorLoop);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   287
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   288
        if (nVectors > 1) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   289
            emitAlign(crb, asm);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   290
            // same loop as bulkVectorLoop, with only one vector
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   291
            asm.bind(singleVectorLoop);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   292
            // check if single vector load is in bounds
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   293
            asm.cmpl(slotsRemaining, singleVectorLoopCondition);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   294
            asm.jcc(AMD64Assembler.ConditionFlag.Below, lessThanVectorSizeRemaining);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   295
            // compare
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   296
            emitVectorCompare(asm, vectorCompareKind, vectorSize, nValues, findTwoCharPrefix ? 2 : 1, vectorOffsets, arrayPtr, vecCmp, vecArray, cmpResult, vectorFound, false);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   297
            // adjust number of array slots remaining
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   298
            asm.subl(slotsRemaining, arraySlotsPerVector);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   299
            // adjust array pointer
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   300
            asm.addq(arrayPtr, bytesPerVector);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   301
            // continue loop
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   302
            asm.jmpb(singleVectorLoop);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   303
        }
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   304
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   305
        asm.bind(lessThanVectorSizeRemaining);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   306
        // check if any array slots remain
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   307
        asm.testl(slotsRemaining, slotsRemaining);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   308
        asm.jcc(AMD64Assembler.ConditionFlag.Zero, retNotFound);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   309
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   310
        // a vector compare will read out of bounds of the input array.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   311
        // check if the out-of-bounds read would cross a memory page boundary.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   312
        // load copy of low part of array pointer
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   313
        asm.movl(tmpArrayPtrLow, arrayPtr);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   314
        // check if pointer + vector size would cross the page boundary
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   315
        asm.andl(tmpArrayPtrLow, (vmPageSize - 1));
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   316
        asm.cmpl(tmpArrayPtrLow, (vmPageSize - (findTwoCharPrefix ? bytesPerVector + kind.getByteCount() : bytesPerVector)));
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   317
        // if the page boundary would be crossed, do byte/character-wise comparison instead.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   318
        asm.jccb(AMD64Assembler.ConditionFlag.Above, lessThanVectorSizeRemainingLoop);
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   319
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   320
        Label[] overBoundsMatch = {new Label(), new Label()};
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   321
        // otherwise, do a vector compare that reads beyond array bounds
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   322
        emitVectorCompare(asm, vectorCompareKind, vectorSize, nValues, findTwoCharPrefix ? 2 : 1, vectorOffsets, arrayPtr, vecCmp, vecArray, cmpResult, overBoundsMatch, false);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   323
        // no match
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   324
        asm.jmp(retNotFound);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   325
        if (findTwoCharPrefix) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   326
            Label overBoundsFinish = new Label();
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   327
            asm.bind(overBoundsMatch[1]);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   328
            // get match offset of second result
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   329
            asm.bsfq(cmpResult[1], cmpResult[1]);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   330
            asm.addl(cmpResult[1], kind.getByteCount());
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   331
            // replace first result with second and continue
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   332
            asm.movl(cmpResult[0], cmpResult[1]);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   333
            asm.jmpb(overBoundsFinish);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   334
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   335
            asm.bind(overBoundsMatch[0]);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   336
            emitFindTwoCharPrefixMinResult(asm, kind, cmpResult, overBoundsFinish);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   337
        } else {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   338
            asm.bind(overBoundsMatch[0]);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   339
            // find match offset
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   340
            asm.bsfq(cmpResult[0], cmpResult[0]);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   341
        }
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   342
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   343
        // adjust array pointer for match result
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   344
        asm.addq(arrayPtr, cmpResult[0]);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   345
        if (charMode(kind)) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   346
            // convert byte offset to chars
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   347
            asm.shrl(cmpResult[0], 1);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   348
        }
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   349
        // check if offset of matched value is greater than number of bytes remaining / out of array
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   350
        // bounds
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   351
        if (findTwoCharPrefix) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   352
            asm.decrementl(slotsRemaining);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   353
        }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   354
        asm.cmpl(cmpResult[0], slotsRemaining);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   355
        // match is out of bounds, return no match
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   356
        asm.jcc(AMD64Assembler.ConditionFlag.GreaterEqual, retNotFound);
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   357
        // adjust number of array slots remaining
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   358
        if (findTwoCharPrefix) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   359
            asm.incrementl(slotsRemaining, 1);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   360
        }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   361
        asm.subl(slotsRemaining, cmpResult[0]);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   362
        // match is in bounds, return offset
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   363
        asm.jmp(retFound);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   364
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   365
        // compare remaining slots in the array one-by-one
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   366
        asm.bind(lessThanVectorSizeRemainingLoop);
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   367
        // check if enough array slots remain
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   368
        asm.cmpl(slotsRemaining, findTwoCharPrefix ? 1 : 0);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   369
        asm.jcc(AMD64Assembler.ConditionFlag.LessEqual, retNotFound);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   370
        // load char / byte
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   371
        if (byteMode(kind)) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   372
            if (findTwoCharPrefix) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   373
                asm.movzwl(cmpResult[0], new AMD64Address(arrayPtr));
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   374
            } else {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   375
                asm.movzbl(cmpResult[0], new AMD64Address(arrayPtr));
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   376
            }
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   377
        } else {
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   378
            if (findTwoCharPrefix) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   379
                asm.movl(cmpResult[0], new AMD64Address(arrayPtr));
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   380
            } else {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   381
                asm.movzwl(cmpResult[0], new AMD64Address(arrayPtr));
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   382
            }
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   383
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   384
        // check for match
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   385
        for (int i = 0; i < nValues; i++) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   386
            asm.cmpl(cmpResult[0], searchValue[i]);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   387
            asm.jcc(AMD64Assembler.ConditionFlag.Equal, retFound);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   388
        }
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   389
        // adjust number of array slots remaining
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   390
        asm.decrementl(slotsRemaining);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   391
        // adjust array pointer
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   392
        asm.addq(arrayPtr, kind.getByteCount());
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   393
        // continue loop
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   394
        asm.jmpb(lessThanVectorSizeRemainingLoop);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   395
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   396
        for (int i = 1; i < nVectors; i += (findTwoCharPrefix ? 2 : 1)) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   397
            emitVectorFoundWithOffset(asm, kind, vectorOffsets[i], arrayPtr, cmpResult[i], slotsRemaining, vectorFound[i], retFound);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   398
        }
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   399
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   400
        if (findTwoCharPrefix) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   401
            asm.bind(vectorFound[2]);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   402
            asm.addq(arrayPtr, vectorOffsets[2]);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   403
            // adjust number of array slots remaining
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   404
            asm.subl(slotsRemaining, charMode(kind) ? vectorOffsets[2] / 2 : vectorOffsets[2]);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   405
            asm.movl(cmpResult[0], cmpResult[2]);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   406
            asm.movl(cmpResult[1], cmpResult[3]);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   407
            asm.bind(vectorFound[0]);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   408
            emitFindTwoCharPrefixMinResult(asm, kind, cmpResult, new Label());
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   409
        } else {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   410
            asm.bind(vectorFound[0]);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   411
            // find index of first set bit in bit mask
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   412
            asm.bsfq(cmpResult[0], cmpResult[0]);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   413
        }
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   414
        // add offset to array pointer
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   415
        asm.addq(arrayPtr, cmpResult[0]);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   416
        if (charMode(kind)) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   417
            // convert byte offset to chars
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   418
            asm.shrl(cmpResult[0], 1);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   419
        }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   420
        // adjust number of array slots remaining
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   421
        asm.subl(slotsRemaining, cmpResult[0]);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   422
        asm.jmpb(retFound);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   423
    }
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   424
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   425
    private static void emitFindTwoCharPrefixMinResult(AMD64MacroAssembler asm, JavaKind kind, Register[] cmpResult, Label done) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   426
        // find match offset
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   427
        asm.bsfq(cmpResult[0], cmpResult[0]);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   428
        // check if second result is also a match
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   429
        asm.testl(cmpResult[1], cmpResult[1]);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   430
        asm.jcc(AMD64Assembler.ConditionFlag.Zero, done);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   431
        // get match offset of second result
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   432
        asm.bsfq(cmpResult[1], cmpResult[1]);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   433
        asm.addl(cmpResult[1], kind.getByteCount());
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   434
        // check if first result is less than second
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   435
        asm.cmpl(cmpResult[0], cmpResult[1]);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   436
        asm.jcc(AMD64Assembler.ConditionFlag.LessEqual, done);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   437
        // first result is greater than second, replace it with the second result
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   438
        asm.movl(cmpResult[0], cmpResult[1]);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   439
        asm.bind(done);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   440
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   441
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   442
    private static void emitAlign(CompilationResultBuilder crb, AMD64MacroAssembler asm) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   443
        asm.align(crb.target.wordSize * 2);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   444
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   445
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   446
    /**
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   447
     * Fills {@code vecDst} with copies of its lowest byte, word or dword.
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   448
     */
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   449
    private static void emitBroadcast(AMD64MacroAssembler asm, JavaKind kind, Register vecDst, Register vecTmp, AVXKind.AVXSize vectorSize) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   450
        switch (kind) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   451
            case Byte:
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   452
                if (asm.supports(CPUFeature.AVX2)) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   453
                    VexRMOp.VPBROADCASTB.emit(asm, vectorSize, vecDst, vecDst);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   454
                } else if (asm.supports(CPUFeature.AVX)) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   455
                    VexRVMOp.VPXOR.emit(asm, vectorSize, vecTmp, vecTmp, vecTmp);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   456
                    VexRVMOp.VPSHUFB.emit(asm, vectorSize, vecDst, vecDst, vecTmp);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   457
                } else if (asm.supports(CPUFeature.SSSE3)) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   458
                    asm.pxor(vecTmp, vecTmp);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   459
                    asm.pshufb(vecDst, vecTmp);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   460
                } else { // SSE2
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   461
                    asm.punpcklbw(vecDst, vecDst);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   462
                    asm.punpcklbw(vecDst, vecDst);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   463
                    asm.pshufd(vecDst, vecDst, 0);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   464
                }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   465
                break;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   466
            case Short:
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   467
            case Char:
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.VPBROADCASTW.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
                    VexRMIOp.VPSHUFLW.emit(asm, vectorSize, vecDst, vecDst, 0);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   472
                    VexRMIOp.VPSHUFD.emit(asm, vectorSize, vecDst, vecDst, 0);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   473
                } else { // SSE
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   474
                    asm.pshuflw(vecDst, vecDst, 0);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   475
                    asm.pshufd(vecDst, vecDst, 0);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   476
                }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   477
                break;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   478
            case Int:
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   479
                if (asm.supports(CPUFeature.AVX2)) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   480
                    VexRMOp.VPBROADCASTD.emit(asm, vectorSize, vecDst, vecDst);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   481
                } else if (asm.supports(CPUFeature.AVX)) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   482
                    VexRMIOp.VPSHUFD.emit(asm, vectorSize, vecDst, vecDst, 0);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   483
                } else { // SSE
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   484
                    asm.pshufd(vecDst, vecDst, 0);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   485
                }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   486
                break;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   487
            default:
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   488
                throw new UnsupportedOperationException();
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   489
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   490
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   491
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   492
    /**
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   493
     * Convert a byte offset stored in {@code bytes} to an array index offset.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   494
     */
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   495
    private static void emitBytesToArraySlots(AMD64MacroAssembler asm, JavaKind kind, Register bytes) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   496
        if (charMode(kind)) {
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   497
            asm.shrl(bytes, 1);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   498
        } else {
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   499
            assert byteMode(kind);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   500
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   501
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   502
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   503
    private static void emitVectorCompare(AMD64MacroAssembler asm,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   504
                    JavaKind kind,
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   505
                    AVXKind.AVXSize vectorSize,
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   506
                    int nValues,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   507
                    int nVectors,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   508
                    int[] vectorOffsets,
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   509
                    Register arrayPtr,
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   510
                    Register[] vecCmp,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   511
                    Register[] vecArray,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   512
                    Register[] cmpResult,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   513
                    Label[] vectorFound,
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   514
                    boolean alignedLoad) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   515
        // load array contents into vectors
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   516
        for (int i = 0; i < nValues; i++) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   517
            for (int j = 0; j < nVectors; j++) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   518
                emitArrayLoad(asm, vectorSize, vecArray[(i * nVectors) + j], arrayPtr, vectorOffsets[j], alignedLoad);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   519
            }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   520
        }
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   521
        // compare all loaded bytes to the search value.
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   522
        // matching bytes are set to 0xff, non-matching bytes are set to 0x00.
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   523
        for (int i = 0; i < nValues; i++) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   524
            for (int j = 0; j < nVectors; j++) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   525
                emitVectorCompareInst(asm, kind, vectorSize, vecArray[(i * nVectors) + j], vecCmp[i]);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   526
            }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   527
        }
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   528
        // create 32-bit-masks from the most significant bit of every byte in the comparison
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   529
        // results.
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   530
        for (int i = 0; i < nValues * nVectors; i++) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   531
            emitMOVMSK(asm, vectorSize, cmpResult[i], vecArray[i]);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   532
        }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   533
        // join results of comparisons against multiple values
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   534
        for (int stride = 1; stride < nValues; stride *= 2) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   535
            for (int i = 0; i < nVectors; i++) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   536
                for (int j = 0; j + stride < nValues; j += stride * 2) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   537
                    asm.orl(cmpResult[i + (j * nVectors)], cmpResult[i + ((j + stride) * nVectors)]);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   538
                }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   539
            }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   540
        }
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   541
        // check if a match was found
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   542
        for (int i = 0; i < nVectors; i++) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   543
            asm.testl(cmpResult[i], cmpResult[i]);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   544
            asm.jcc(AMD64Assembler.ConditionFlag.NotZero, vectorFound[i]);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   545
        }
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   546
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   547
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   548
    private static void emitVectorFoundWithOffset(AMD64MacroAssembler asm,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   549
                    JavaKind kind,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   550
                    int resultOffset,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   551
                    Register result,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   552
                    Register cmpResult,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   553
                    Register slotsRemaining,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   554
                    Label entry,
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   555
                    Label ret) {
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   556
        asm.bind(entry);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   557
        if (resultOffset > 0) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   558
            // adjust array pointer
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   559
            asm.addq(result, resultOffset);
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   560
            // adjust number of array slots remaining
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   561
            asm.subl(slotsRemaining, charMode(kind) ? resultOffset / 2 : resultOffset);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   562
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   563
        // find index of first set bit in bit mask
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   564
        asm.bsfq(cmpResult, cmpResult);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   565
        // add offset to array pointer
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   566
        asm.addq(result, cmpResult);
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   567
        if (charMode(kind)) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   568
            // convert byte offset to chars
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   569
            asm.shrl(cmpResult, 1);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   570
        }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   571
        // adjust number of array slots remaining
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   572
        asm.subl(slotsRemaining, cmpResult);
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   573
        asm.jmpb(ret);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   574
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   575
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   576
    private static void emitArrayLoad(AMD64MacroAssembler asm, AVXKind.AVXSize vectorSize, Register vecDst, Register arrayPtr, int offset, boolean alignedLoad) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   577
        AMD64Address src = new AMD64Address(arrayPtr, offset);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   578
        if (asm.supports(CPUFeature.AVX)) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   579
            VexMoveOp loadOp = alignedLoad ? VexMoveOp.VMOVDQA : VexMoveOp.VMOVDQU;
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   580
            loadOp.emit(asm, vectorSize, vecDst, src);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   581
        } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   582
            // SSE
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   583
            asm.movdqu(vecDst, src);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   584
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   585
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   586
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   587
    /**
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   588
     * Compares all packed bytes/words/dwords in {@code vecArray} to {@code vecCmp}. Matching values
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   589
     * are set to all ones (0xff, 0xffff, ...), non-matching values are set to zero.
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   590
     */
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   591
    private static void emitVectorCompareInst(AMD64MacroAssembler asm, JavaKind kind, AVXKind.AVXSize vectorSize, Register vecArray, Register vecCmp) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   592
        switch (kind) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   593
            case Byte:
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   594
                if (asm.supports(CPUFeature.AVX)) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   595
                    VexRVMOp.VPCMPEQB.emit(asm, vectorSize, vecArray, vecCmp, vecArray);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   596
                } else { // SSE
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   597
                    asm.pcmpeqb(vecArray, vecCmp);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   598
                }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   599
                break;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   600
            case Short:
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   601
            case Char:
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   602
                if (asm.supports(CPUFeature.AVX)) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   603
                    VexRVMOp.VPCMPEQW.emit(asm, vectorSize, vecArray, vecCmp, vecArray);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   604
                } else { // SSE
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   605
                    asm.pcmpeqw(vecArray, vecCmp);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   606
                }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   607
                break;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   608
            case Int:
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   609
                if (asm.supports(CPUFeature.AVX)) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   610
                    VexRVMOp.VPCMPEQD.emit(asm, vectorSize, vecArray, vecCmp, vecArray);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   611
                } else { // SSE
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   612
                    asm.pcmpeqd(vecArray, vecCmp);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   613
                }
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   614
                break;
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   615
            default:
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
   616
                throw new UnsupportedOperationException();
51436
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   617
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   618
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   619
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   620
    private static void emitMOVMSK(AMD64MacroAssembler asm, AVXKind.AVXSize vectorSize, Register dst, Register vecSrc) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   621
        if (asm.supports(CPUFeature.AVX)) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   622
            VexRMOp.VPMOVMSKB.emit(asm, vectorSize, dst, vecSrc);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   623
        } else {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   624
            // SSE
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   625
            asm.pmovmskb(dst, vecSrc);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   626
        }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   627
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   628
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   629
    private static boolean supportsAVX2(LIRGeneratorTool tool) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   630
        return supports(tool, CPUFeature.AVX2);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   631
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   632
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   633
    private static boolean supports(LIRGeneratorTool tool, CPUFeature cpuFeature) {
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   634
        return ((AMD64) tool.target().arch).getFeatures().contains(cpuFeature);
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   635
    }
091c0d22e735 8206992: Update Graal
iveresov
parents:
diff changeset
   636
}