1 /*
2 * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
138 Register cnt1 = asRegister(length1Value);
139 Register cnt2 = asRegister(length2Value);
140
141 // Checkstyle: stop
142 Label LENGTH_DIFF_LABEL = new Label();
143 Label POP_LABEL = new Label();
144 Label DONE_LABEL = new Label();
145 Label WHILE_HEAD_LABEL = new Label();
146 Label COMPARE_WIDE_VECTORS_LOOP_FAILED = new Label(); // used only _LP64 && AVX3
147 int stride, stride2;
148 int adr_stride = -1;
149 int adr_stride1 = -1;
150 int adr_stride2 = -1;
151 // Checkstyle: resume
152 int stride2x2 = 0x40;
153 AMD64Address.Scale scale = null;
154 AMD64Address.Scale scale1 = null;
155 AMD64Address.Scale scale2 = null;
156
157 // if (ae != StrIntrinsicNode::LL) {
158 if (kind1 == JavaKind.Byte && kind2 == JavaKind.Byte) {
159 stride2x2 = 0x20;
160 }
161
162 // if (ae == StrIntrinsicNode::LU || ae == StrIntrinsicNode::UL) {
163 if (kind1 != kind2) {
164 masm.shrl(cnt2, 1);
165 }
166 // Compute the minimum of the string lengths and the
167 // difference of the string lengths (stack).
168 // Do the conditional move stuff
169 masm.movl(result, cnt1);
170 masm.subl(cnt1, cnt2);
171 masm.push(cnt1);
172 masm.cmovl(ConditionFlag.LessEqual, cnt2, result); // cnt2 = min(cnt1, cnt2)
173
174 // Is the minimum length zero?
175 masm.testl(cnt2, cnt2);
176 masm.jcc(ConditionFlag.Zero, LENGTH_DIFF_LABEL);
177 // if (ae == StrIntrinsicNode::LL) {
178 if (kind1 == JavaKind.Byte && kind2 == JavaKind.Byte) {
514 masm.jccb(ConditionFlag.NotZero, WHILE_HEAD_LABEL);
515
516 // Strings are equal up to min length. Return the length difference.
517 masm.bind(LENGTH_DIFF_LABEL);
518 masm.pop(result);
519 // if (ae == StrIntrinsicNode::UU) {
520 if (kind1 == JavaKind.Char && kind2 == JavaKind.Char) {
521 // Divide diff by 2 to get number of chars
522 masm.sarl(result, 1);
523 }
524 masm.jmpb(DONE_LABEL);
525
526 // if (VM_Version::supports_avx512vlbw()) {
527 if (supportsAVX512VLBW(crb.target)) {
528 masm.bind(COMPARE_WIDE_VECTORS_LOOP_FAILED);
529
530 masm.kmovq(cnt1, k7);
531 masm.notq(cnt1);
532 masm.bsfq(cnt2, cnt1);
533 // if (ae != StrIntrinsicNode::LL) {
534 if (kind1 != JavaKind.Byte && kind2 != JavaKind.Byte) {
535 // Divide diff by 2 to get number of chars
536 masm.sarl(cnt2, 1);
537 }
538 masm.addq(result, cnt2);
539 // if (ae == StrIntrinsicNode::LL) {
540 if (kind1 == JavaKind.Byte && kind2 == JavaKind.Byte) {
541 masm.movzbl(cnt1, new AMD64Address(str2, result, Scale.Times1));
542 masm.movzbl(result, new AMD64Address(str1, result, Scale.Times1));
543 } else if (kind1 == JavaKind.Char && kind2 == JavaKind.Char) {
544 masm.movzwl(cnt1, new AMD64Address(str2, result, scale));
545 masm.movzwl(result, new AMD64Address(str1, result, scale));
546 } else {
547 masm.movzwl(cnt1, new AMD64Address(str2, result, scale2));
548 masm.movzbl(result, new AMD64Address(str1, result, scale1));
549 }
550 masm.subl(result, cnt1);
551 masm.jmpb(POP_LABEL);
552 }
553
554 // Discard the stored length difference
|
1 /*
2 * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
138 Register cnt1 = asRegister(length1Value);
139 Register cnt2 = asRegister(length2Value);
140
141 // Checkstyle: stop
142 Label LENGTH_DIFF_LABEL = new Label();
143 Label POP_LABEL = new Label();
144 Label DONE_LABEL = new Label();
145 Label WHILE_HEAD_LABEL = new Label();
146 Label COMPARE_WIDE_VECTORS_LOOP_FAILED = new Label(); // used only _LP64 && AVX3
147 int stride, stride2;
148 int adr_stride = -1;
149 int adr_stride1 = -1;
150 int adr_stride2 = -1;
151 // Checkstyle: resume
152 int stride2x2 = 0x40;
153 AMD64Address.Scale scale = null;
154 AMD64Address.Scale scale1 = null;
155 AMD64Address.Scale scale2 = null;
156
157 // if (ae != StrIntrinsicNode::LL) {
158 if (!(kind1 == JavaKind.Byte && kind2 == JavaKind.Byte)) {
159 stride2x2 = 0x20;
160 }
161
162 // if (ae == StrIntrinsicNode::LU || ae == StrIntrinsicNode::UL) {
163 if (kind1 != kind2) {
164 masm.shrl(cnt2, 1);
165 }
166 // Compute the minimum of the string lengths and the
167 // difference of the string lengths (stack).
168 // Do the conditional move stuff
169 masm.movl(result, cnt1);
170 masm.subl(cnt1, cnt2);
171 masm.push(cnt1);
172 masm.cmovl(ConditionFlag.LessEqual, cnt2, result); // cnt2 = min(cnt1, cnt2)
173
174 // Is the minimum length zero?
175 masm.testl(cnt2, cnt2);
176 masm.jcc(ConditionFlag.Zero, LENGTH_DIFF_LABEL);
177 // if (ae == StrIntrinsicNode::LL) {
178 if (kind1 == JavaKind.Byte && kind2 == JavaKind.Byte) {
514 masm.jccb(ConditionFlag.NotZero, WHILE_HEAD_LABEL);
515
516 // Strings are equal up to min length. Return the length difference.
517 masm.bind(LENGTH_DIFF_LABEL);
518 masm.pop(result);
519 // if (ae == StrIntrinsicNode::UU) {
520 if (kind1 == JavaKind.Char && kind2 == JavaKind.Char) {
521 // Divide diff by 2 to get number of chars
522 masm.sarl(result, 1);
523 }
524 masm.jmpb(DONE_LABEL);
525
526 // if (VM_Version::supports_avx512vlbw()) {
527 if (supportsAVX512VLBW(crb.target)) {
528 masm.bind(COMPARE_WIDE_VECTORS_LOOP_FAILED);
529
530 masm.kmovq(cnt1, k7);
531 masm.notq(cnt1);
532 masm.bsfq(cnt2, cnt1);
533 // if (ae != StrIntrinsicNode::LL) {
534 if (!(kind1 == JavaKind.Byte && kind2 == JavaKind.Byte)) {
535 // Divide diff by 2 to get number of chars
536 masm.sarl(cnt2, 1);
537 }
538 masm.addq(result, cnt2);
539 // if (ae == StrIntrinsicNode::LL) {
540 if (kind1 == JavaKind.Byte && kind2 == JavaKind.Byte) {
541 masm.movzbl(cnt1, new AMD64Address(str2, result, Scale.Times1));
542 masm.movzbl(result, new AMD64Address(str1, result, Scale.Times1));
543 } else if (kind1 == JavaKind.Char && kind2 == JavaKind.Char) {
544 masm.movzwl(cnt1, new AMD64Address(str2, result, scale));
545 masm.movzwl(result, new AMD64Address(str1, result, scale));
546 } else {
547 masm.movzwl(cnt1, new AMD64Address(str2, result, scale2));
548 masm.movzbl(result, new AMD64Address(str1, result, scale1));
549 }
550 masm.subl(result, cnt1);
551 masm.jmpb(POP_LABEL);
552 }
553
554 // Discard the stored length difference
|