# HG changeset patch # User pli # Date 1572398256 -28800 # Node ID 674131501e98738721dd9ef8ddaca8358262db18 # Parent f1e6442241caec681951d7e6da3e6a41054e2769 8232591: AArch64: Add missing match rules for smaddl, smsubl and smnegl Reviewed-by: aph diff -r f1e6442241ca -r 674131501e98 src/hotspot/cpu/aarch64/aarch64.ad --- a/src/hotspot/cpu/aarch64/aarch64.ad Tue Oct 29 15:35:06 2019 -0700 +++ b/src/hotspot/cpu/aarch64/aarch64.ad Wed Oct 30 09:17:36 2019 +0800 @@ -10413,6 +10413,56 @@ ins_pipe(lmac_reg_reg); %} +// Combine Integer Signed Multiply & Add/Sub/Neg Long + +instruct smaddL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{ + match(Set dst (AddL src3 (MulL (ConvI2L src1) (ConvI2L src2)))); + + ins_cost(INSN_COST * 3); + format %{ "smaddl $dst, $src1, $src2, $src3" %} + + ins_encode %{ + __ smaddl(as_Register($dst$$reg), + as_Register($src1$$reg), + as_Register($src2$$reg), + as_Register($src3$$reg)); + %} + + ins_pipe(imac_reg_reg); +%} + +instruct smsubL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{ + match(Set dst (SubL src3 (MulL (ConvI2L src1) (ConvI2L src2)))); + + ins_cost(INSN_COST * 3); + format %{ "smsubl $dst, $src1, $src2, $src3" %} + + ins_encode %{ + __ smsubl(as_Register($dst$$reg), + as_Register($src1$$reg), + as_Register($src2$$reg), + as_Register($src3$$reg)); + %} + + ins_pipe(imac_reg_reg); +%} + +instruct smnegL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, immL0 zero) %{ + match(Set dst (MulL (SubL zero (ConvI2L src1)) (ConvI2L src2))); + match(Set dst (MulL (ConvI2L src1) (SubL zero (ConvI2L src2)))); + + ins_cost(INSN_COST * 3); + format %{ "smnegl $dst, $src1, $src2" %} + + ins_encode %{ + __ smnegl(as_Register($dst$$reg), + as_Register($src1$$reg), + as_Register($src2$$reg)); + %} + + ins_pipe(imac_reg_reg); +%} + // Integer Divide instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ diff -r f1e6442241ca -r 674131501e98 test/hotspot/jtreg/compiler/codegen/TestSignedMultiplyLong.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/compiler/codegen/TestSignedMultiplyLong.java Wed Oct 30 09:17:36 2019 +0800 @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, Arm Limited. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8232591 + * @summary Test some cases of combined signed multiply long operation + * @library /test/lib + * @run main/othervm -XX:+UnlockDiagnosticVMOptions + * -Xcomp -XX:-TieredCompilation -XX:-Inline + * compiler.codegen.TestSignedMultiplyLong + */ + +package compiler.codegen; + +import jdk.test.lib.Asserts; + +public class TestSignedMultiplyLong { + + private static final int minInt = Integer.MIN_VALUE; // -2147483648 + private static final int maxInt = Integer.MAX_VALUE; // 2147483647 + private static final long minLong = Long.MIN_VALUE; // -9223372036854775808 + private static final long maxLong = Long.MAX_VALUE; // 9223372036854775807 + + private static Case[] testCases = { + // case: a b c resSmaddl resSmsubl resSmnegl + new Case( 1000, -200, 500000L, 300000L, 700000L, 200000L), + new Case(maxInt, 1, 1L, (long)maxInt + 1L, (long)minInt + 2L, (long)minInt + 1L), + new Case(minInt, -1, 1L, (long)maxInt + 2L, (long)minInt + 1L, (long)minInt), + new Case( -10, minInt, 1L, 21474836481L, -21474836479L, -21474836480L), + new Case( 1, 1, maxLong, minLong, maxLong - 1L, -1L), + new Case( 1, -1, minLong, maxLong, minLong + 1L, 1L), + new Case( -1, -1, 0xffffffffeL << 32, 0xfffffffe00000001L, 0xfffffffdffffffffL, -1L) + }; + + private static class Case { + + private int a; + private int b; + private long c; + private long resSmaddl; + private long resSmsubl; + private long resSmnegl; + + public Case(int a, int b, long c, long resSmaddl, long resSmsubl, long resSmnegl) { + this.a = a; + this.b = b; + this.c = c; + this.resSmaddl = resSmaddl; + this.resSmsubl = resSmsubl; + this.resSmnegl = resSmnegl; + } + + public void verify() { + Asserts.assertEQ(smaddl(a, b, c), resSmaddl, + "Unexpected result from signed multiply-add long."); + Asserts.assertEQ(smsubl(a, b, c), resSmsubl, + "Unexpected result from signed multiply-sub long."); + Asserts.assertEQ(smnegl(a, b), resSmnegl, + "Unexpected result from signed multiply-neg long."); + } + } + + private static long smaddl(int a, int b, long c) { + return c + a * (long) b; + } + + private static long smsubl(int a, int b, long c) { + return c - a * (long) b; + } + + private static long smnegl(int a, int b) { + return a * (-(long) b); + } + + public static void main(String[] args) { + for (Case c : testCases) { + c.verify(); + } + } +}