8222785: aarch64: add necessary masking for immediate shift counts

Reviewed-by: aph
This commit is contained in:
Fei Yang 2019-04-20 15:55:07 +08:00
parent c576c3c3f5
commit 055a822a06
2 changed files with 28 additions and 48 deletions

View File

@ -11343,14 +11343,11 @@ instruct SubL_reg_LShift_reg(iRegLNoSp dst,
instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count)
%{
match(Set dst (RShiftL (LShiftL src lshift_count) rshift_count));
// Make sure we are not going to exceed what sbfm can do.
predicate((unsigned int)n->in(2)->get_int() <= 63
&& (unsigned int)n->in(1)->in(2)->get_int() <= 63);
ins_cost(INSN_COST * 2);
format %{ "sbfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %}
ins_encode %{
int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant;
int lshift = $lshift_count$$constant & 63;
int rshift = $rshift_count$$constant & 63;
int s = 63 - lshift;
int r = (rshift - lshift) & 63;
__ sbfm(as_Register($dst$$reg),
@ -11366,14 +11363,11 @@ instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count)
instruct sbfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count)
%{
match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count));
// Make sure we are not going to exceed what sbfmw can do.
predicate((unsigned int)n->in(2)->get_int() <= 31
&& (unsigned int)n->in(1)->in(2)->get_int() <= 31);
ins_cost(INSN_COST * 2);
format %{ "sbfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %}
ins_encode %{
int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant;
int lshift = $lshift_count$$constant & 31;
int rshift = $rshift_count$$constant & 31;
int s = 31 - lshift;
int r = (rshift - lshift) & 31;
__ sbfmw(as_Register($dst$$reg),
@ -11389,14 +11383,11 @@ instruct sbfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_co
instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count)
%{
match(Set dst (URShiftL (LShiftL src lshift_count) rshift_count));
// Make sure we are not going to exceed what ubfm can do.
predicate((unsigned int)n->in(2)->get_int() <= 63
&& (unsigned int)n->in(1)->in(2)->get_int() <= 63);
ins_cost(INSN_COST * 2);
format %{ "ubfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %}
ins_encode %{
int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant;
int lshift = $lshift_count$$constant & 63;
int rshift = $rshift_count$$constant & 63;
int s = 63 - lshift;
int r = (rshift - lshift) & 63;
__ ubfm(as_Register($dst$$reg),
@ -11412,14 +11403,11 @@ instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count)
instruct ubfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count)
%{
match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count));
// Make sure we are not going to exceed what ubfmw can do.
predicate((unsigned int)n->in(2)->get_int() <= 31
&& (unsigned int)n->in(1)->in(2)->get_int() <= 31);
ins_cost(INSN_COST * 2);
format %{ "ubfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %}
ins_encode %{
int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant;
int lshift = $lshift_count$$constant & 31;
int rshift = $rshift_count$$constant & 31;
int s = 31 - lshift;
int r = (rshift - lshift) & 31;
__ ubfmw(as_Register($dst$$reg),
@ -11491,13 +11479,12 @@ instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask m
instruct ubfizwI(iRegINoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask)
%{
match(Set dst (LShiftI (AndI src mask) lshift));
predicate((unsigned int)n->in(2)->get_int() <= 31 &&
(exact_log2(n->in(1)->in(2)->get_int()+1) + (unsigned int)n->in(2)->get_int()) <= (31+1));
predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 31)) <= (31 + 1));
ins_cost(INSN_COST);
format %{ "ubfizw $dst, $src, $lshift, $mask" %}
ins_encode %{
int lshift = $lshift$$constant;
int lshift = $lshift$$constant & 31;
long mask = $mask$$constant;
int width = exact_log2(mask+1);
__ ubfizw(as_Register($dst$$reg),
@ -11510,13 +11497,12 @@ instruct ubfizwI(iRegINoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask)
instruct ubfizL(iRegLNoSp dst, iRegL src, immI lshift, immL_bitmask mask)
%{
match(Set dst (LShiftL (AndL src mask) lshift));
predicate((unsigned int)n->in(2)->get_int() <= 63 &&
(exact_log2_long(n->in(1)->in(2)->get_long()+1) + (unsigned int)n->in(2)->get_int()) <= (63+1));
predicate((exact_log2_long(n->in(1)->in(2)->get_long() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1));
ins_cost(INSN_COST);
format %{ "ubfiz $dst, $src, $lshift, $mask" %}
ins_encode %{
int lshift = $lshift$$constant;
int lshift = $lshift$$constant & 63;
long mask = $mask$$constant;
int width = exact_log2_long(mask+1);
__ ubfiz(as_Register($dst$$reg),
@ -11528,14 +11514,13 @@ instruct ubfizL(iRegLNoSp dst, iRegL src, immI lshift, immL_bitmask mask)
// If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz
instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask)
%{
match(Set dst (LShiftL (ConvI2L(AndI src mask)) lshift));
predicate((unsigned int)n->in(2)->get_int() <= 31 &&
(exact_log2((unsigned int)n->in(1)->in(1)->in(2)->get_int()+1) + (unsigned int)n->in(2)->get_int()) <= 32);
match(Set dst (LShiftL (ConvI2L (AndI src mask)) lshift));
predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1));
ins_cost(INSN_COST);
format %{ "ubfiz $dst, $src, $lshift, $mask" %}
ins_encode %{
int lshift = $lshift$$constant;
int lshift = $lshift$$constant & 63;
long mask = $mask$$constant;
int width = exact_log2(mask+1);
__ ubfiz(as_Register($dst$$reg),
@ -11549,7 +11534,7 @@ instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask
instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr)
%{
match(Set dst (OrL (LShiftL src1 lshift) (URShiftL src2 rshift)));
predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 63));
predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63));
ins_cost(INSN_COST);
format %{ "extr $dst, $src1, $src2, #$rshift" %}
@ -11564,7 +11549,7 @@ instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift
instruct extrOrI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr)
%{
match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift)));
predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 31));
predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31));
ins_cost(INSN_COST);
format %{ "extr $dst, $src1, $src2, #$rshift" %}
@ -11579,7 +11564,7 @@ instruct extrOrI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, i
instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr)
%{
match(Set dst (AddL (LShiftL src1 lshift) (URShiftL src2 rshift)));
predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 63));
predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63));
ins_cost(INSN_COST);
format %{ "extr $dst, $src1, $src2, #$rshift" %}
@ -11594,7 +11579,7 @@ instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshif
instruct extrAddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr)
%{
match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift)));
predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 31));
predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31));
ins_cost(INSN_COST);
format %{ "extr $dst, $src1, $src2, #$rshift" %}

View File

@ -154,14 +154,11 @@ define(`BFM_INSN',`
instruct $4$1(iReg$1NoSp dst, iReg$1`'ORL2I($1) src, immI lshift_count, immI rshift_count)
%{
match(Set dst EXTEND($1, $3, src, lshift_count, rshift_count));
// Make sure we are not going to exceed what $4 can do.
predicate((unsigned int)n->in(2)->get_int() <= $2
&& (unsigned int)n->in(1)->in(2)->get_int() <= $2);
ins_cost(INSN_COST * 2);
format %{ "$4 $dst, $src, $rshift_count - $lshift_count, #$2 - $lshift_count" %}
ins_encode %{
int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant;
int lshift = $lshift_count$$constant & $2;
int rshift = $rshift_count$$constant & $2;
int s = $2 - lshift;
int r = (rshift - lshift) & $2;
__ $4(as_Register($dst$$reg),
@ -224,13 +221,12 @@ define(`UBFIZ_INSN',
`instruct $2$1(iReg$1NoSp dst, iReg$1`'ORL2I($1) src, immI lshift, imm$1_bitmask mask)
%{
match(Set dst (LShift$1 (And$1 src mask) lshift));
predicate((unsigned int)n->in(2)->get_int() <= $3 &&
(exact_log2$5(n->in(1)->in(2)->get_$4()+1) + (unsigned int)n->in(2)->get_int()) <= ($3+1));
predicate((exact_log2$5(n->in(1)->in(2)->get_$4() + 1) + (n->in(2)->get_int() & $3)) <= ($3 + 1));
ins_cost(INSN_COST);
format %{ "$2 $dst, $src, $lshift, $mask" %}
ins_encode %{
int lshift = $lshift$$constant;
int lshift = $lshift$$constant & $3;
long mask = $mask$$constant;
int width = exact_log2$5(mask+1);
__ $2(as_Register($dst$$reg),
@ -239,19 +235,18 @@ define(`UBFIZ_INSN',
ins_pipe(ialu_reg_shift);
%}')
UBFIZ_INSN(I, ubfizw, 31, int)
UBFIZ_INSN(L, ubfiz, 63, long, _long)
UBFIZ_INSN(L, ubfiz, 63, long, _long)
// If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz
instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask)
%{
match(Set dst (LShiftL (ConvI2L(AndI src mask)) lshift));
predicate((unsigned int)n->in(2)->get_int() <= 31 &&
(exact_log2((unsigned int)n->in(1)->in(1)->in(2)->get_int()+1) + (unsigned int)n->in(2)->get_int()) <= 32);
match(Set dst (LShiftL (ConvI2L (AndI src mask)) lshift));
predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1));
ins_cost(INSN_COST);
format %{ "ubfiz $dst, $src, $lshift, $mask" %}
ins_encode %{
int lshift = $lshift$$constant;
int lshift = $lshift$$constant & 63;
long mask = $mask$$constant;
int width = exact_log2(mask+1);
__ ubfiz(as_Register($dst$$reg),
@ -266,7 +261,7 @@ define(`EXTRACT_INSN',
`instruct extr$3$1(iReg$1NoSp dst, iReg$1`'ORL2I($1) src1, iReg$1`'ORL2I($1) src2, immI lshift, immI rshift, rFlagsReg cr)
%{
match(Set dst ($3$1 (LShift$1 src1 lshift) (URShift$1 src2 rshift)));
predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & $2));
predicate(0 == (((n->in(1)->in(2)->get_int() & $2) + (n->in(2)->in(2)->get_int() & $2)) & $2));
ins_cost(INSN_COST);
format %{ "extr $dst, $src1, $src2, #$rshift" %}