--- a/src/hotspot/cpu/aarch64/aarch64.ad Tue Apr 09 06:11:54 2019 -0700
+++ b/src/hotspot/cpu/aarch64/aarch64.ad Mon Apr 08 14:40:31 2019 +0800
@@ -3932,7 +3932,8 @@
operand immL_bitmask()
%{
- predicate(((n->get_long() & 0xc000000000000000l) == 0)
+ predicate((n->get_long() != 0)
+ && ((n->get_long() & 0xc000000000000000l) == 0)
&& is_power_of_2(n->get_long() + 1));
match(ConL);
@@ -3943,7 +3944,8 @@
operand immI_bitmask()
%{
- predicate(((n->get_int() & 0xc0000000) == 0)
+ predicate((n->get_int() != 0)
+ && ((n->get_int() & 0xc0000000) == 0)
&& is_power_of_2(n->get_int() + 1));
match(ConI);
@@ -11432,11 +11434,13 @@
instruct ubfxwI(iRegINoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask)
%{
match(Set dst (AndI (URShiftI src rshift) mask));
+ // Make sure we are not going to exceed what ubfxw can do.
+ predicate((exact_log2(n->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= (31 + 1));
ins_cost(INSN_COST);
format %{ "ubfxw $dst, $src, $rshift, $mask" %}
ins_encode %{
- int rshift = $rshift$$constant;
+ int rshift = $rshift$$constant & 31;
long mask = $mask$$constant;
int width = exact_log2(mask+1);
__ ubfxw(as_Register($dst$$reg),
@@ -11447,13 +11451,15 @@
instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask)
%{
match(Set dst (AndL (URShiftL src rshift) mask));
+ // Make sure we are not going to exceed what ubfx can do.
+ predicate((exact_log2_long(n->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= (63 + 1));
ins_cost(INSN_COST);
format %{ "ubfx $dst, $src, $rshift, $mask" %}
ins_encode %{
- int rshift = $rshift$$constant;
+ int rshift = $rshift$$constant & 63;
long mask = $mask$$constant;
- int width = exact_log2(mask+1);
+ int width = exact_log2_long(mask+1);
__ ubfx(as_Register($dst$$reg),
as_Register($src$$reg), rshift, width);
%}
@@ -11465,11 +11471,13 @@
instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask)
%{
match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask)));
+ // Make sure we are not going to exceed what ubfxw can do.
+ predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(1)->in(2)->get_int() & 31)) <= (31 + 1));
ins_cost(INSN_COST * 2);
format %{ "ubfx $dst, $src, $rshift, $mask" %}
ins_encode %{
- int rshift = $rshift$$constant;
+ int rshift = $rshift$$constant & 31;
long mask = $mask$$constant;
int width = exact_log2(mask+1);
__ ubfx(as_Register($dst$$reg),
@@ -11510,7 +11518,7 @@
ins_encode %{
int lshift = $lshift$$constant;
long mask = $mask$$constant;
- int width = exact_log2(mask+1);
+ int width = exact_log2_long(mask+1);
__ ubfiz(as_Register($dst$$reg),
as_Register($src$$reg), lshift, width);
%}
--- a/src/hotspot/cpu/aarch64/aarch64_ad.m4 Tue Apr 09 06:11:54 2019 -0700
+++ b/src/hotspot/cpu/aarch64/aarch64_ad.m4 Mon Apr 08 14:40:31 2019 +0800
@@ -181,31 +181,35 @@
`instruct $3$1(iReg$1NoSp dst, iReg$1`'ORL2I($1) src, immI rshift, imm$1_bitmask mask)
%{
match(Set dst (And$1 ($2$1 src rshift) mask));
+ // Make sure we are not going to exceed what $3 can do.
+ predicate((exact_log2$6(n->in(2)->get_$5() + 1) + (n->in(1)->in(2)->get_int() & $4)) <= ($4 + 1));
ins_cost(INSN_COST);
format %{ "$3 $dst, $src, $rshift, $mask" %}
ins_encode %{
- int rshift = $rshift$$constant;
+ int rshift = $rshift$$constant & $4;
long mask = $mask$$constant;
- int width = exact_log2(mask+1);
+ int width = exact_log2$6(mask+1);
__ $3(as_Register($dst$$reg),
as_Register($src$$reg), rshift, width);
%}
ins_pipe(ialu_reg_shift);
%}')
-BFX_INSN(I,URShift,ubfxw)
-BFX_INSN(L,URShift,ubfx)
+BFX_INSN(I, URShift, ubfxw, 31, int)
+BFX_INSN(L, URShift, ubfx, 63, long, _long)
// We can use ubfx when extending an And with a mask when we know mask
// is positive. We know that because immI_bitmask guarantees it.
instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask)
%{
match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask)));
+ // Make sure we are not going to exceed what ubfxw can do.
+ predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(1)->in(2)->get_int() & 31)) <= (31 + 1));
ins_cost(INSN_COST * 2);
format %{ "ubfx $dst, $src, $rshift, $mask" %}
ins_encode %{
- int rshift = $rshift$$constant;
+ int rshift = $rshift$$constant & 31;
long mask = $mask$$constant;
int width = exact_log2(mask+1);
__ ubfx(as_Register($dst$$reg),
@@ -228,7 +232,7 @@
ins_encode %{
int lshift = $lshift$$constant;
long mask = $mask$$constant;
- int width = exact_log2(mask+1);
+ int width = exact_log2$5(mask+1);
__ $2(as_Register($dst$$reg),
as_Register($src$$reg), lshift, width);
%}