src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayCompareToOp.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:
49451
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
     1
/*
58299
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 52910
diff changeset
     2
 * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
49451
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
     4
 *
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
     7
 * published by the Free Software Foundation.
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
     8
 *
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    13
 * accompanied this code).
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    14
 *
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    18
 *
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    21
 * questions.
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    22
 */
50858
2d3e99a72541 8205824: Update Graal
never
parents: 50609
diff changeset
    23
2d3e99a72541 8205824: Update Graal
never
parents: 50609
diff changeset
    24
49451
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    25
package org.graalvm.compiler.lir.amd64;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    26
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    27
import static jdk.vm.ci.amd64.AMD64.k7;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    28
import static jdk.vm.ci.amd64.AMD64.rax;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    29
import static jdk.vm.ci.amd64.AMD64.rcx;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    30
import static jdk.vm.ci.amd64.AMD64.rdx;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    31
import static jdk.vm.ci.code.ValueUtil.asRegister;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    32
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    33
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    34
51436
091c0d22e735 8206992: Update Graal
iveresov
parents: 50858
diff changeset
    35
import java.util.EnumSet;
49451
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    36
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    37
import org.graalvm.compiler.asm.Label;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    38
import org.graalvm.compiler.asm.amd64.AMD64Address;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    39
import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    40
import org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    41
import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    42
import org.graalvm.compiler.core.common.LIRKind;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    43
import org.graalvm.compiler.lir.LIRInstructionClass;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    44
import org.graalvm.compiler.lir.Opcode;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    45
import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    46
import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    47
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    48
import jdk.vm.ci.amd64.AMD64;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    49
import jdk.vm.ci.amd64.AMD64.CPUFeature;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    50
import jdk.vm.ci.amd64.AMD64Kind;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    51
import jdk.vm.ci.code.Register;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    52
import jdk.vm.ci.code.TargetDescription;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    53
import jdk.vm.ci.meta.JavaKind;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    54
import jdk.vm.ci.meta.Value;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    55
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    56
/**
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    57
 * Emits code which compares two arrays lexicographically. If the CPU supports any vector
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    58
 * instructions specialized code is emitted to leverage these instructions.
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    59
 */
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    60
@Opcode("ARRAY_COMPARE_TO")
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    61
public final class AMD64ArrayCompareToOp extends AMD64LIRInstruction {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    62
    public static final LIRInstructionClass<AMD64ArrayCompareToOp> TYPE = LIRInstructionClass.create(AMD64ArrayCompareToOp.class);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    63
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    64
    private final JavaKind kind1;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    65
    private final JavaKind kind2;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    66
    private final int array1BaseOffset;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    67
    private final int array2BaseOffset;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    68
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    69
    @Def({REG}) protected Value resultValue;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    70
    @Alive({REG}) protected Value array1Value;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    71
    @Alive({REG}) protected Value array2Value;
49873
26ebfe8ce852 8199755: Update Graal
dlong
parents: 49451
diff changeset
    72
    @Use({REG}) protected Value length1Value;
26ebfe8ce852 8199755: Update Graal
dlong
parents: 49451
diff changeset
    73
    @Use({REG}) protected Value length2Value;
26ebfe8ce852 8199755: Update Graal
dlong
parents: 49451
diff changeset
    74
    @Temp({REG}) protected Value length1ValueTemp;
26ebfe8ce852 8199755: Update Graal
dlong
parents: 49451
diff changeset
    75
    @Temp({REG}) protected Value length2ValueTemp;
49451
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    76
    @Temp({REG}) protected Value temp1;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    77
    @Temp({REG}) protected Value temp2;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    78
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    79
    @Temp({REG, ILLEGAL}) protected Value vectorTemp1;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    80
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    81
    public AMD64ArrayCompareToOp(LIRGeneratorTool tool, JavaKind kind1, JavaKind kind2, Value result, Value array1, Value array2, Value length1, Value length2) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    82
        super(TYPE);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    83
        this.kind1 = kind1;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    84
        this.kind2 = kind2;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    85
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    86
        // Both offsets should be the same but better be safe than sorry.
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    87
        this.array1BaseOffset = tool.getProviders().getMetaAccess().getArrayBaseOffset(kind1);
7dd81e82d083 8210777: Update Graal
dlong
parents: 51436
diff changeset
    88
        this.array2BaseOffset = tool.getProviders().getMetaAccess().getArrayBaseOffset(kind2);
49451
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    89
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    90
        this.resultValue = result;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    91
        this.array1Value = array1;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    92
        this.array2Value = array2;
49873
26ebfe8ce852 8199755: Update Graal
dlong
parents: 49451
diff changeset
    93
        /*
26ebfe8ce852 8199755: Update Graal
dlong
parents: 49451
diff changeset
    94
         * The length values are inputs but are also killed like temporaries so need both Use and
26ebfe8ce852 8199755: Update Graal
dlong
parents: 49451
diff changeset
    95
         * Temp annotations, which will only work with fixed registers.
26ebfe8ce852 8199755: Update Graal
dlong
parents: 49451
diff changeset
    96
         */
49451
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    97
        this.length1Value = length1;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
    98
        this.length2Value = length2;
49873
26ebfe8ce852 8199755: Update Graal
dlong
parents: 49451
diff changeset
    99
        this.length1ValueTemp = length1;
26ebfe8ce852 8199755: Update Graal
dlong
parents: 49451
diff changeset
   100
        this.length2ValueTemp = length2;
49451
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   101
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   102
        // Allocate some temporaries.
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   103
        this.temp1 = tool.newVariable(LIRKind.unknownReference(tool.target().arch.getWordKind()));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   104
        this.temp2 = tool.newVariable(LIRKind.unknownReference(tool.target().arch.getWordKind()));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   105
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   106
        // We only need the vector temporaries if we generate SSE code.
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   107
        if (supportsSSE42(tool.target())) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   108
            this.vectorTemp1 = tool.newVariable(LIRKind.value(AMD64Kind.DOUBLE));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   109
        } else {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   110
            this.vectorTemp1 = Value.ILLEGAL;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   111
        }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   112
    }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   113
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   114
    private static boolean supportsSSE42(TargetDescription target) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   115
        AMD64 arch = (AMD64) target.arch;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   116
        return arch.getFeatures().contains(CPUFeature.SSE4_2);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   117
    }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   118
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   119
    private static boolean supportsAVX2(TargetDescription target) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   120
        AMD64 arch = (AMD64) target.arch;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   121
        return arch.getFeatures().contains(CPUFeature.AVX2);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   122
    }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   123
51436
091c0d22e735 8206992: Update Graal
iveresov
parents: 50858
diff changeset
   124
    private static boolean supportsAVX512VLBW(TargetDescription target) {
091c0d22e735 8206992: Update Graal
iveresov
parents: 50858
diff changeset
   125
        EnumSet<CPUFeature> features = ((AMD64) target.arch).getFeatures();
091c0d22e735 8206992: Update Graal
iveresov
parents: 50858
diff changeset
   126
        return features.contains(CPUFeature.AVX512BW) && features.contains(CPUFeature.AVX512VL);
49451
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   127
    }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   128
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   129
    @Override
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   130
    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   131
        Register result = asRegister(resultValue);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   132
        Register str1 = asRegister(temp1);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   133
        Register str2 = asRegister(temp2);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   134
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   135
        // Load array base addresses.
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   136
        masm.leaq(str1, new AMD64Address(asRegister(array1Value), array1BaseOffset));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   137
        masm.leaq(str2, new AMD64Address(asRegister(array2Value), array2BaseOffset));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   138
        Register cnt1 = asRegister(length1Value);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   139
        Register cnt2 = asRegister(length2Value);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   140
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   141
        // Checkstyle: stop
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   142
        Label LENGTH_DIFF_LABEL = new Label();
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   143
        Label POP_LABEL = new Label();
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   144
        Label DONE_LABEL = new Label();
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   145
        Label WHILE_HEAD_LABEL = new Label();
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   146
        Label COMPARE_WIDE_VECTORS_LOOP_FAILED = new Label(); // used only _LP64 && AVX3
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   147
        int stride, stride2;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   148
        int adr_stride = -1;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   149
        int adr_stride1 = -1;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   150
        int adr_stride2 = -1;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   151
        // Checkstyle: resume
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   152
        int stride2x2 = 0x40;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   153
        AMD64Address.Scale scale = null;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   154
        AMD64Address.Scale scale1 = null;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   155
        AMD64Address.Scale scale2 = null;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   156
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   157
        // if (ae != StrIntrinsicNode::LL) {
58299
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 52910
diff changeset
   158
        if (!(kind1 == JavaKind.Byte && kind2 == JavaKind.Byte)) {
49451
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   159
            stride2x2 = 0x20;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   160
        }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   161
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   162
        // if (ae == StrIntrinsicNode::LU || ae == StrIntrinsicNode::UL) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   163
        if (kind1 != kind2) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   164
            masm.shrl(cnt2, 1);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   165
        }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   166
        // Compute the minimum of the string lengths and the
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   167
        // difference of the string lengths (stack).
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   168
        // Do the conditional move stuff
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   169
        masm.movl(result, cnt1);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   170
        masm.subl(cnt1, cnt2);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   171
        masm.push(cnt1);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   172
        masm.cmovl(ConditionFlag.LessEqual, cnt2, result);    // cnt2 = min(cnt1, cnt2)
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   173
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   174
        // Is the minimum length zero?
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   175
        masm.testl(cnt2, cnt2);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   176
        masm.jcc(ConditionFlag.Zero, LENGTH_DIFF_LABEL);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   177
        // if (ae == StrIntrinsicNode::LL) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   178
        if (kind1 == JavaKind.Byte && kind2 == JavaKind.Byte) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   179
            // Load first bytes
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   180
            masm.movzbl(result, new AMD64Address(str1, 0));  // result = str1[0]
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   181
            masm.movzbl(cnt1, new AMD64Address(str2, 0));    // cnt1 = str2[0]
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   182
            // } else if (ae == StrIntrinsicNode::UU) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   183
        } else if (kind1 == JavaKind.Char && kind2 == JavaKind.Char) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   184
            // Load first characters
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   185
            masm.movzwl(result, new AMD64Address(str1, 0));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   186
            masm.movzwl(cnt1, new AMD64Address(str2, 0));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   187
        } else {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   188
            masm.movzbl(result, new AMD64Address(str1, 0));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   189
            masm.movzwl(cnt1, new AMD64Address(str2, 0));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   190
        }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   191
        masm.subl(result, cnt1);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   192
        masm.jcc(ConditionFlag.NotZero, POP_LABEL);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   193
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   194
        // if (ae == StrIntrinsicNode::UU) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   195
        if (kind1 == JavaKind.Char && kind2 == JavaKind.Char) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   196
            // Divide length by 2 to get number of chars
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   197
            masm.shrl(cnt2, 1);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   198
        }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   199
        masm.cmpl(cnt2, 1);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   200
        masm.jcc(ConditionFlag.Equal, LENGTH_DIFF_LABEL);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   201
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   202
        // Check if the strings start at the same location and setup scale and stride
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   203
        // if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   204
        if (kind1 == kind2) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   205
            masm.cmpptr(str1, str2);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   206
            masm.jcc(ConditionFlag.Equal, LENGTH_DIFF_LABEL);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   207
            // if (ae == StrIntrinsicNode::LL) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   208
            if (kind1 == JavaKind.Byte && kind2 == JavaKind.Byte) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   209
                scale = AMD64Address.Scale.Times1;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   210
                stride = 16;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   211
            } else {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   212
                scale = AMD64Address.Scale.Times2;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   213
                stride = 8;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   214
            }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   215
        } else {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   216
            scale1 = AMD64Address.Scale.Times1;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   217
            scale2 = AMD64Address.Scale.Times2;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   218
            // scale not used
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   219
            stride = 8;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   220
        }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   221
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   222
        // if (UseAVX >= 2 && UseSSE42Intrinsics) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   223
        if (supportsAVX2(crb.target) && supportsSSE42(crb.target)) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   224
            Register vec1 = asRegister(vectorTemp1, AMD64Kind.DOUBLE);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   225
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   226
            // Checkstyle: stop
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   227
            Label COMPARE_WIDE_VECTORS = new Label();
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   228
            Label VECTOR_NOT_EQUAL = new Label();
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   229
            Label COMPARE_WIDE_TAIL = new Label();
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   230
            Label COMPARE_SMALL_STR = new Label();
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   231
            Label COMPARE_WIDE_VECTORS_LOOP = new Label();
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   232
            Label COMPARE_16_CHARS = new Label();
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   233
            Label COMPARE_INDEX_CHAR = new Label();
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   234
            Label COMPARE_WIDE_VECTORS_LOOP_AVX2 = new Label();
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   235
            Label COMPARE_TAIL_LONG = new Label();
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   236
            Label COMPARE_WIDE_VECTORS_LOOP_AVX3 = new Label();  // used only _LP64 && AVX3
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   237
            // Checkstyle: resume
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   238
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   239
            int pcmpmask = 0x19;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   240
            // if (ae == StrIntrinsicNode::LL) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   241
            if (kind1 == JavaKind.Byte && kind2 == JavaKind.Byte) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   242
                pcmpmask &= ~0x01;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   243
            }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   244
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   245
            // Setup to compare 16-chars (32-bytes) vectors,
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   246
            // start from first character again because it has aligned address.
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   247
            // if (ae == StrIntrinsicNode::LL) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   248
            if (kind1 == JavaKind.Byte && kind2 == JavaKind.Byte) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   249
                stride2 = 32;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   250
            } else {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   251
                stride2 = 16;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   252
            }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   253
            // if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   254
            if (kind1 == kind2) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   255
                adr_stride = stride << scale.log2;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   256
            } else {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   257
                adr_stride1 = 8;  // stride << scale1;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   258
                adr_stride2 = 16; // stride << scale2;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   259
            }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   260
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   261
            assert result.equals(rax) && cnt2.equals(rdx) && cnt1.equals(rcx) : "pcmpestri";
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   262
            // rax and rdx are used by pcmpestri as elements counters
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   263
            masm.movl(result, cnt2);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   264
            masm.andl(cnt2, ~(stride2 - 1));   // cnt2 holds the vector count
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   265
            masm.jcc(ConditionFlag.Zero, COMPARE_TAIL_LONG);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   266
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   267
            // fast path : compare first 2 8-char vectors.
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   268
            masm.bind(COMPARE_16_CHARS);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   269
            // if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   270
            if (kind1 == kind2) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   271
                masm.movdqu(vec1, new AMD64Address(str1, 0));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   272
            } else {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   273
                masm.pmovzxbw(vec1, new AMD64Address(str1, 0));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   274
            }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   275
            masm.pcmpestri(vec1, new AMD64Address(str2, 0), pcmpmask);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   276
            masm.jccb(ConditionFlag.Below, COMPARE_INDEX_CHAR);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   277
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   278
            // if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   279
            if (kind1 == kind2) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   280
                masm.movdqu(vec1, new AMD64Address(str1, adr_stride));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   281
                masm.pcmpestri(vec1, new AMD64Address(str2, adr_stride), pcmpmask);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   282
            } else {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   283
                masm.pmovzxbw(vec1, new AMD64Address(str1, adr_stride1));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   284
                masm.pcmpestri(vec1, new AMD64Address(str2, adr_stride2), pcmpmask);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   285
            }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   286
            masm.jccb(ConditionFlag.AboveEqual, COMPARE_WIDE_VECTORS);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   287
            masm.addl(cnt1, stride);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   288
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   289
            // Compare the characters at index in cnt1
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   290
            masm.bind(COMPARE_INDEX_CHAR); // cnt1 has the offset of the mismatching character
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   291
            loadNextElements(masm, result, cnt2, str1, str2, scale, scale1, scale2, cnt1);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   292
            masm.subl(result, cnt2);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   293
            masm.jmp(POP_LABEL);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   294
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   295
            // Setup the registers to start vector comparison loop
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   296
            masm.bind(COMPARE_WIDE_VECTORS);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   297
            // if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   298
            if (kind1 == kind2) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   299
                masm.leaq(str1, new AMD64Address(str1, result, scale));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   300
                masm.leaq(str2, new AMD64Address(str2, result, scale));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   301
            } else {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   302
                masm.leaq(str1, new AMD64Address(str1, result, scale1));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   303
                masm.leaq(str2, new AMD64Address(str2, result, scale2));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   304
            }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   305
            masm.subl(result, stride2);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   306
            masm.subl(cnt2, stride2);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   307
            masm.jcc(ConditionFlag.Zero, COMPARE_WIDE_TAIL);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   308
            masm.negq(result);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   309
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   310
            // In a loop, compare 16-chars (32-bytes) at once using (vpxor+vptest)
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   311
            masm.bind(COMPARE_WIDE_VECTORS_LOOP);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   312
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   313
            // if (VM_Version::supports_avx512vlbw()) { // trying 64 bytes fast loop
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   314
            if (supportsAVX512VLBW(crb.target)) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   315
                masm.cmpl(cnt2, stride2x2);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   316
                masm.jccb(ConditionFlag.Below, COMPARE_WIDE_VECTORS_LOOP_AVX2);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   317
                masm.testl(cnt2, stride2x2 - 1);   // cnt2 holds the vector count
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   318
                // means we cannot subtract by 0x40
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   319
                masm.jccb(ConditionFlag.NotZero, COMPARE_WIDE_VECTORS_LOOP_AVX2);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   320
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   321
                masm.bind(COMPARE_WIDE_VECTORS_LOOP_AVX3); // the hottest loop
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   322
                // if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   323
                if (kind1 == kind2) {
51436
091c0d22e735 8206992: Update Graal
iveresov
parents: 50858
diff changeset
   324
                    masm.evmovdqu64(vec1, new AMD64Address(str1, result, scale));
49451
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   325
                    // k7 == 11..11, if operands equal, otherwise k7 has some 0
51436
091c0d22e735 8206992: Update Graal
iveresov
parents: 50858
diff changeset
   326
                    masm.evpcmpeqb(k7, vec1, new AMD64Address(str2, result, scale));
49451
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   327
                } else {
51436
091c0d22e735 8206992: Update Graal
iveresov
parents: 50858
diff changeset
   328
                    masm.evpmovzxbw(vec1, new AMD64Address(str1, result, scale1));
49451
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   329
                    // k7 == 11..11, if operands equal, otherwise k7 has some 0
51436
091c0d22e735 8206992: Update Graal
iveresov
parents: 50858
diff changeset
   330
                    masm.evpcmpeqb(k7, vec1, new AMD64Address(str2, result, scale2));
49451
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   331
                }
51436
091c0d22e735 8206992: Update Graal
iveresov
parents: 50858
diff changeset
   332
                masm.kortestq(k7, k7);
49451
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   333
                masm.jcc(ConditionFlag.AboveEqual, COMPARE_WIDE_VECTORS_LOOP_FAILED);     // miscompare
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   334
                masm.addq(result, stride2x2);  // update since we already compared at this addr
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   335
                masm.subl(cnt2, stride2x2);      // and sub the size too
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   336
                masm.jccb(ConditionFlag.NotZero, COMPARE_WIDE_VECTORS_LOOP_AVX3);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   337
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   338
                masm.vpxor(vec1, vec1, vec1);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   339
                masm.jmpb(COMPARE_WIDE_TAIL);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   340
            }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   341
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   342
            masm.bind(COMPARE_WIDE_VECTORS_LOOP_AVX2);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   343
            // if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   344
            if (kind1 == kind2) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   345
                masm.vmovdqu(vec1, new AMD64Address(str1, result, scale));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   346
                masm.vpxor(vec1, vec1, new AMD64Address(str2, result, scale));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   347
            } else {
51436
091c0d22e735 8206992: Update Graal
iveresov
parents: 50858
diff changeset
   348
                masm.vpmovzxbw(vec1, new AMD64Address(str1, result, scale1));
49451
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   349
                masm.vpxor(vec1, vec1, new AMD64Address(str2, result, scale2));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   350
            }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   351
            masm.vptest(vec1, vec1);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   352
            masm.jcc(ConditionFlag.NotZero, VECTOR_NOT_EQUAL);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   353
            masm.addq(result, stride2);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   354
            masm.subl(cnt2, stride2);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   355
            masm.jcc(ConditionFlag.NotZero, COMPARE_WIDE_VECTORS_LOOP);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   356
            // clean upper bits of YMM registers
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   357
            masm.vpxor(vec1, vec1, vec1);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   358
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   359
            // compare wide vectors tail
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   360
            masm.bind(COMPARE_WIDE_TAIL);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   361
            masm.testq(result, result);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   362
            masm.jcc(ConditionFlag.Zero, LENGTH_DIFF_LABEL);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   363
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   364
            masm.movl(result, stride2);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   365
            masm.movl(cnt2, result);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   366
            masm.negq(result);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   367
            masm.jmp(COMPARE_WIDE_VECTORS_LOOP_AVX2);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   368
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   369
            // Identifies the mismatching (higher or lower)16-bytes in the 32-byte vectors.
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   370
            masm.bind(VECTOR_NOT_EQUAL);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   371
            // clean upper bits of YMM registers
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   372
            masm.vpxor(vec1, vec1, vec1);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   373
            // if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   374
            if (kind1 == kind2) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   375
                masm.leaq(str1, new AMD64Address(str1, result, scale));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   376
                masm.leaq(str2, new AMD64Address(str2, result, scale));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   377
            } else {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   378
                masm.leaq(str1, new AMD64Address(str1, result, scale1));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   379
                masm.leaq(str2, new AMD64Address(str2, result, scale2));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   380
            }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   381
            masm.jmp(COMPARE_16_CHARS);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   382
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   383
            // Compare tail chars, length between 1 to 15 chars
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   384
            masm.bind(COMPARE_TAIL_LONG);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   385
            masm.movl(cnt2, result);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   386
            masm.cmpl(cnt2, stride);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   387
            masm.jcc(ConditionFlag.Less, COMPARE_SMALL_STR);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   388
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   389
            // if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   390
            if (kind1 == kind2) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   391
                masm.movdqu(vec1, new AMD64Address(str1, 0));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   392
            } else {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   393
                masm.pmovzxbw(vec1, new AMD64Address(str1, 0));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   394
            }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   395
            masm.pcmpestri(vec1, new AMD64Address(str2, 0), pcmpmask);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   396
            masm.jcc(ConditionFlag.Below, COMPARE_INDEX_CHAR);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   397
            masm.subq(cnt2, stride);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   398
            masm.jcc(ConditionFlag.Zero, LENGTH_DIFF_LABEL);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   399
            // if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   400
            if (kind1 == kind2) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   401
                masm.leaq(str1, new AMD64Address(str1, result, scale));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   402
                masm.leaq(str2, new AMD64Address(str2, result, scale));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   403
            } else {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   404
                masm.leaq(str1, new AMD64Address(str1, result, scale1));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   405
                masm.leaq(str2, new AMD64Address(str2, result, scale2));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   406
            }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   407
            masm.negq(cnt2);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   408
            masm.jmpb(WHILE_HEAD_LABEL);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   409
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   410
            masm.bind(COMPARE_SMALL_STR);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   411
        } else if (supportsSSE42(crb.target)) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   412
            Register vec1 = asRegister(vectorTemp1, AMD64Kind.DOUBLE);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   413
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   414
            // Checkstyle: stop
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   415
            Label COMPARE_WIDE_VECTORS = new Label();
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   416
            Label VECTOR_NOT_EQUAL = new Label();
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   417
            Label COMPARE_TAIL = new Label();
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   418
            // Checkstyle: resume
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   419
            int pcmpmask = 0x19;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   420
            // Setup to compare 8-char (16-byte) vectors,
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   421
            // start from first character again because it has aligned address.
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   422
            masm.movl(result, cnt2);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   423
            masm.andl(cnt2, ~(stride - 1));   // cnt2 holds the vector count
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   424
            // if (ae == StrIntrinsicNode::LL) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   425
            if (kind1 == JavaKind.Byte && kind2 == JavaKind.Byte) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   426
                pcmpmask &= ~0x01;
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   427
            }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   428
            masm.jcc(ConditionFlag.Zero, COMPARE_TAIL);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   429
            // if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   430
            if (kind1 == kind2) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   431
                masm.leaq(str1, new AMD64Address(str1, result, scale));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   432
                masm.leaq(str2, new AMD64Address(str2, result, scale));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   433
            } else {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   434
                masm.leaq(str1, new AMD64Address(str1, result, scale1));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   435
                masm.leaq(str2, new AMD64Address(str2, result, scale2));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   436
            }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   437
            masm.negq(result);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   438
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   439
            // pcmpestri
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   440
            // inputs:
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   441
            // vec1- substring
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   442
            // rax - negative string length (elements count)
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   443
            // mem - scanned string
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   444
            // rdx - string length (elements count)
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   445
            // pcmpmask - cmp mode: 11000 (string compare with negated result)
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   446
            // + 00 (unsigned bytes) or + 01 (unsigned shorts)
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   447
            // outputs:
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   448
            // rcx - first mismatched element index
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   449
            assert result.equals(rax) && cnt2.equals(rdx) && cnt1.equals(rcx) : "pcmpestri";
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   450
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   451
            masm.bind(COMPARE_WIDE_VECTORS);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   452
            // if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   453
            if (kind1 == kind2) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   454
                masm.movdqu(vec1, new AMD64Address(str1, result, scale));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   455
                masm.pcmpestri(vec1, new AMD64Address(str2, result, scale), pcmpmask);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   456
            } else {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   457
                masm.pmovzxbw(vec1, new AMD64Address(str1, result, scale1));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   458
                masm.pcmpestri(vec1, new AMD64Address(str2, result, scale2), pcmpmask);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   459
            }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   460
            // After pcmpestri cnt1(rcx) contains mismatched element index
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   461
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   462
            masm.jccb(ConditionFlag.Below, VECTOR_NOT_EQUAL);  // CF==1
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   463
            masm.addq(result, stride);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   464
            masm.subq(cnt2, stride);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   465
            masm.jccb(ConditionFlag.NotZero, COMPARE_WIDE_VECTORS);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   466
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   467
            // compare wide vectors tail
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   468
            masm.testq(result, result);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   469
            masm.jcc(ConditionFlag.Zero, LENGTH_DIFF_LABEL);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   470
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   471
            masm.movl(cnt2, stride);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   472
            masm.movl(result, stride);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   473
            masm.negq(result);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   474
            // if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   475
            if (kind1 == kind2) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   476
                masm.movdqu(vec1, new AMD64Address(str1, result, scale));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   477
                masm.pcmpestri(vec1, new AMD64Address(str2, result, scale), pcmpmask);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   478
            } else {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   479
                masm.pmovzxbw(vec1, new AMD64Address(str1, result, scale1));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   480
                masm.pcmpestri(vec1, new AMD64Address(str2, result, scale2), pcmpmask);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   481
            }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   482
            masm.jccb(ConditionFlag.AboveEqual, LENGTH_DIFF_LABEL);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   483
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   484
            // Mismatched characters in the vectors
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   485
            masm.bind(VECTOR_NOT_EQUAL);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   486
            masm.addq(cnt1, result);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   487
            loadNextElements(masm, result, cnt2, str1, str2, scale, scale1, scale2, cnt1);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   488
            masm.subl(result, cnt2);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   489
            masm.jmpb(POP_LABEL);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   490
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   491
            masm.bind(COMPARE_TAIL); // limit is zero
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   492
            masm.movl(cnt2, result);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   493
            // Fallthru to tail compare
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   494
        }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   495
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   496
        // Shift str2 and str1 to the end of the arrays, negate min
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   497
        // if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   498
        if (kind1 == kind2) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   499
            masm.leaq(str1, new AMD64Address(str1, cnt2, scale));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   500
            masm.leaq(str2, new AMD64Address(str2, cnt2, scale));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   501
        } else {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   502
            masm.leaq(str1, new AMD64Address(str1, cnt2, scale1));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   503
            masm.leaq(str2, new AMD64Address(str2, cnt2, scale2));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   504
        }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   505
        masm.decrementl(cnt2);  // first character was compared already
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   506
        masm.negq(cnt2);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   507
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   508
        // Compare the rest of the elements
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   509
        masm.bind(WHILE_HEAD_LABEL);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   510
        loadNextElements(masm, result, cnt1, str1, str2, scale, scale1, scale2, cnt2);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   511
        masm.subl(result, cnt1);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   512
        masm.jccb(ConditionFlag.NotZero, POP_LABEL);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   513
        masm.incrementq(cnt2, 1);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   514
        masm.jccb(ConditionFlag.NotZero, WHILE_HEAD_LABEL);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   515
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   516
        // Strings are equal up to min length. Return the length difference.
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   517
        masm.bind(LENGTH_DIFF_LABEL);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   518
        masm.pop(result);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   519
        // if (ae == StrIntrinsicNode::UU) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   520
        if (kind1 == JavaKind.Char && kind2 == JavaKind.Char) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   521
            // Divide diff by 2 to get number of chars
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   522
            masm.sarl(result, 1);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   523
        }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   524
        masm.jmpb(DONE_LABEL);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   525
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   526
        // if (VM_Version::supports_avx512vlbw()) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   527
        if (supportsAVX512VLBW(crb.target)) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   528
            masm.bind(COMPARE_WIDE_VECTORS_LOOP_FAILED);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   529
51436
091c0d22e735 8206992: Update Graal
iveresov
parents: 50858
diff changeset
   530
            masm.kmovq(cnt1, k7);
49451
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   531
            masm.notq(cnt1);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   532
            masm.bsfq(cnt2, cnt1);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   533
            // if (ae != StrIntrinsicNode::LL) {
58299
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 52910
diff changeset
   534
            if (!(kind1 == JavaKind.Byte && kind2 == JavaKind.Byte)) {
49451
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   535
                // Divide diff by 2 to get number of chars
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   536
                masm.sarl(cnt2, 1);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   537
            }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   538
            masm.addq(result, cnt2);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   539
            // if (ae == StrIntrinsicNode::LL) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   540
            if (kind1 == JavaKind.Byte && kind2 == JavaKind.Byte) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   541
                masm.movzbl(cnt1, new AMD64Address(str2, result, Scale.Times1));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   542
                masm.movzbl(result, new AMD64Address(str1, result, Scale.Times1));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   543
            } else if (kind1 == JavaKind.Char && kind2 == JavaKind.Char) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   544
                masm.movzwl(cnt1, new AMD64Address(str2, result, scale));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   545
                masm.movzwl(result, new AMD64Address(str1, result, scale));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   546
            } else {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   547
                masm.movzwl(cnt1, new AMD64Address(str2, result, scale2));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   548
                masm.movzbl(result, new AMD64Address(str1, result, scale1));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   549
            }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   550
            masm.subl(result, cnt1);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   551
            masm.jmpb(POP_LABEL);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   552
        }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   553
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   554
        // Discard the stored length difference
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   555
        masm.bind(POP_LABEL);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   556
        masm.pop(cnt1);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   557
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   558
        // That's it
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   559
        masm.bind(DONE_LABEL);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   560
        // if (ae == StrIntrinsicNode::UL) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   561
        if (kind1 == JavaKind.Char && kind2 == JavaKind.Byte) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   562
            masm.negl(result);
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   563
        }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   564
    }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   565
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   566
    private void loadNextElements(AMD64MacroAssembler masm, Register elem1, Register elem2, Register str1, Register str2,
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   567
                    AMD64Address.Scale scale, AMD64Address.Scale scale1,
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   568
                    AMD64Address.Scale scale2, Register index) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   569
        // if (ae == StrIntrinsicNode::LL) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   570
        if (kind1 == JavaKind.Byte && kind2 == JavaKind.Byte) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   571
            masm.movzbl(elem1, new AMD64Address(str1, index, scale, 0));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   572
            masm.movzbl(elem2, new AMD64Address(str2, index, scale, 0));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   573
            // } else if (ae == StrIntrinsicNode::UU) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   574
        } else if (kind1 == JavaKind.Char && kind2 == JavaKind.Char) {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   575
            masm.movzwl(elem1, new AMD64Address(str1, index, scale, 0));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   576
            masm.movzwl(elem2, new AMD64Address(str2, index, scale, 0));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   577
        } else {
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   578
            masm.movzbl(elem1, new AMD64Address(str1, index, scale1, 0));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   579
            masm.movzwl(elem2, new AMD64Address(str2, index, scale2, 0));
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   580
        }
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   581
    }
59095
03fbcd06b4c0 8233841: Update Graal
dlong
parents: 58299
diff changeset
   582
03fbcd06b4c0 8233841: Update Graal
dlong
parents: 58299
diff changeset
   583
    @Override
03fbcd06b4c0 8233841: Update Graal
dlong
parents: 58299
diff changeset
   584
    public boolean needsClearUpperVectorRegisters() {
03fbcd06b4c0 8233841: Update Graal
dlong
parents: 58299
diff changeset
   585
        return true;
03fbcd06b4c0 8233841: Update Graal
dlong
parents: 58299
diff changeset
   586
    }
49451
e06f9607f370 8198969: Update Graal
iveresov
parents:
diff changeset
   587
}