changeset 57650:7f2642fd19a1

8230591: AArch64: Missing intrinsics for Math.ceil, floor, rint Reviewed-by: aph
author pli
date Wed, 15 Jan 2020 13:24:51 +0800
parents 14c78683c9f0
children 9c53fdf6ba63
files src/hotspot/cpu/aarch64/aarch64.ad src/hotspot/cpu/aarch64/assembler_aarch64.hpp
diffstat 2 files changed, 69 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/cpu/aarch64/aarch64.ad	Tue Jan 14 19:27:03 2020 -0800
+++ b/src/hotspot/cpu/aarch64/aarch64.ad	Wed Jan 15 13:24:51 2020 +0800
@@ -1,6 +1,6 @@
 //
-// Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
-// Copyright (c) 2014, 2019, Red Hat, Inc. All rights reserved.
+// Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2014, 2020, Red Hat, Inc. 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
@@ -983,6 +983,7 @@
 #include "gc/shared/cardTableBarrierSet.hpp"
 #include "gc/shared/collectedHeap.hpp"
 #include "opto/addnode.hpp"
+#include "opto/convertnode.hpp"
 
 extern RegMask _ANY_REG32_mask;
 extern RegMask _ANY_REG_mask;
@@ -13232,6 +13233,29 @@
   ins_pipe(fp_div_d);
 %}
 
+// Math.rint, floor, ceil
+instruct roundD_reg(vRegD dst, vRegD src, immI rmode) %{
+  match(Set dst (RoundDoubleMode src rmode));
+  format %{ "frint  $dst, $src, $rmode" %}
+  ins_encode %{
+    switch ($rmode$$constant) {
+      case RoundDoubleModeNode::rmode_rint:
+        __ frintnd(as_FloatRegister($dst$$reg),
+                   as_FloatRegister($src$$reg));
+        break;
+      case RoundDoubleModeNode::rmode_floor:
+        __ frintmd(as_FloatRegister($dst$$reg),
+                   as_FloatRegister($src$$reg));
+        break;
+      case RoundDoubleModeNode::rmode_ceil:
+        __ frintpd(as_FloatRegister($dst$$reg),
+                   as_FloatRegister($src$$reg));
+        break;
+    }
+  %}
+  ins_pipe(fp_uop_d);
+%}
+
 // ============================================================================
 // Logical Instructions
 
@@ -17939,6 +17963,29 @@
   ins_pipe(vdop_fp128);
 %}
 
+instruct vround2D_reg(vecX dst, vecX src, immI rmode) %{
+  predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE);
+  match(Set dst (RoundDoubleModeV src rmode));
+  format %{ "frint  $dst, $src, $rmode" %}
+  ins_encode %{
+    switch ($rmode$$constant) {
+      case RoundDoubleModeNode::rmode_rint:
+        __ frintn(as_FloatRegister($dst$$reg), __ T2D,
+                  as_FloatRegister($src$$reg));
+        break;
+      case RoundDoubleModeNode::rmode_floor:
+        __ frintm(as_FloatRegister($dst$$reg), __ T2D,
+                  as_FloatRegister($src$$reg));
+        break;
+      case RoundDoubleModeNode::rmode_ceil:
+        __ frintp(as_FloatRegister($dst$$reg), __ T2D,
+                  as_FloatRegister($src$$reg));
+        break;
+    }
+  %}
+  ins_pipe(vdop_fp128);
+%}
+
 //----------PEEPHOLE RULES-----------------------------------------------------
 // These must follow all instruction definitions as they use the names
 // defined in the instructions definitions.
--- a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp	Tue Jan 14 19:27:03 2020 -0800
+++ b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp	Wed Jan 15 13:24:51 2020 +0800
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2014, 2019, Red Hat Inc. All rights reserved.
+ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2020, Red Hat Inc. 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
@@ -2613,42 +2613,42 @@
 #undef INSN
 
   // AdvSIMD two-reg misc
-#define INSN(NAME, U, opcode)                                                       \
+  // In this instruction group, the 2 bits in the size field ([23:22]) may be
+  // fixed or determined by the "SIMD_Arrangement T", or both. The additional
+  // parameter "tmask" is a 2-bit mask used to indicate which bits in the size
+  // field are determined by the SIMD_Arrangement. The bit of "tmask" should be
+  // set to 1 if corresponding bit marked as "x" in the ArmARM.
+#define INSN(NAME, U, size, tmask, opcode)                                          \
   void NAME(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn) {               \
        starti;                                                                      \
        assert((ASSERTION), MSG);                                                    \
        f(0, 31), f((int)T & 1, 30), f(U, 29), f(0b01110, 28, 24);                   \
-       f((int)(T >> 1), 23, 22), f(0b10000, 21, 17), f(opcode, 16, 12);             \
-       f(0b10, 11, 10), rf(Vn, 5), rf(Vd, 0);                                       \
+       f(size | ((int)(T >> 1) & tmask), 23, 22), f(0b10000, 21, 17);               \
+       f(opcode, 16, 12), f(0b10, 11, 10), rf(Vn, 5), rf(Vd, 0);                    \
  }
 
 #define MSG "invalid arrangement"
 
 #define ASSERTION (T == T2S || T == T4S || T == T2D)
-  INSN(fsqrt, 1, 0b11111);
-  INSN(fabs,  0, 0b01111);
-  INSN(fneg,  1, 0b01111);
+  INSN(fsqrt,  1, 0b10, 0b01, 0b11111);
+  INSN(fabs,   0, 0b10, 0b01, 0b01111);
+  INSN(fneg,   1, 0b10, 0b01, 0b01111);
+  INSN(frintn, 0, 0b00, 0b01, 0b11000);
+  INSN(frintm, 0, 0b00, 0b01, 0b11001);
+  INSN(frintp, 0, 0b10, 0b01, 0b11000);
 #undef ASSERTION
 
 #define ASSERTION (T == T8B || T == T16B || T == T4H || T == T8H || T == T2S || T == T4S)
-  INSN(rev64, 0, 0b00000);
+  INSN(rev64, 0, 0b00, 0b11, 0b00000);
 #undef ASSERTION
 
 #define ASSERTION (T == T8B || T == T16B || T == T4H || T == T8H)
-  INSN(rev32, 1, 0b00000);
-private:
-  INSN(_rbit, 1, 0b00101);
-public:
-
+  INSN(rev32, 1, 0b00, 0b11, 0b00000);
 #undef ASSERTION
 
 #define ASSERTION (T == T8B || T == T16B)
-  INSN(rev16, 0, 0b00001);
-  // RBIT only allows T8B and T16B but encodes them oddly.  Argh...
-  void rbit(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn) {
-    assert((ASSERTION), MSG);
-    _rbit(Vd, SIMD_Arrangement((T & 1) | 0b010), Vn);
-  }
+  INSN(rev16, 0, 0b00, 0b11, 0b00001);
+  INSN(rbit,  1, 0b01, 0b00, 0b00101);
 #undef ASSERTION
 
 #undef MSG