152 // Shift Left followed by Shift Right. |
152 // Shift Left followed by Shift Right. |
153 // This idiom is used by the compiler for the i2b bytecode etc. |
153 // This idiom is used by the compiler for the i2b bytecode etc. |
154 instruct $4$1(iReg$1NoSp dst, iReg$1`'ORL2I($1) src, immI lshift_count, immI rshift_count) |
154 instruct $4$1(iReg$1NoSp dst, iReg$1`'ORL2I($1) src, immI lshift_count, immI rshift_count) |
155 %{ |
155 %{ |
156 match(Set dst EXTEND($1, $3, src, lshift_count, rshift_count)); |
156 match(Set dst EXTEND($1, $3, src, lshift_count, rshift_count)); |
157 // Make sure we are not going to exceed what $4 can do. |
|
158 predicate((unsigned int)n->in(2)->get_int() <= $2 |
|
159 && (unsigned int)n->in(1)->in(2)->get_int() <= $2); |
|
160 |
|
161 ins_cost(INSN_COST * 2); |
157 ins_cost(INSN_COST * 2); |
162 format %{ "$4 $dst, $src, $rshift_count - $lshift_count, #$2 - $lshift_count" %} |
158 format %{ "$4 $dst, $src, $rshift_count - $lshift_count, #$2 - $lshift_count" %} |
163 ins_encode %{ |
159 ins_encode %{ |
164 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; |
160 int lshift = $lshift_count$$constant & $2; |
|
161 int rshift = $rshift_count$$constant & $2; |
165 int s = $2 - lshift; |
162 int s = $2 - lshift; |
166 int r = (rshift - lshift) & $2; |
163 int r = (rshift - lshift) & $2; |
167 __ $4(as_Register($dst$$reg), |
164 __ $4(as_Register($dst$$reg), |
168 as_Register($src$$reg), |
165 as_Register($src$$reg), |
169 r, s); |
166 r, s); |
222 // We can use ubfiz when masking by a positive number and then left shifting the result. |
219 // We can use ubfiz when masking by a positive number and then left shifting the result. |
223 // We know that the mask is positive because imm$1_bitmask guarantees it. |
220 // We know that the mask is positive because imm$1_bitmask guarantees it. |
224 `instruct $2$1(iReg$1NoSp dst, iReg$1`'ORL2I($1) src, immI lshift, imm$1_bitmask mask) |
221 `instruct $2$1(iReg$1NoSp dst, iReg$1`'ORL2I($1) src, immI lshift, imm$1_bitmask mask) |
225 %{ |
222 %{ |
226 match(Set dst (LShift$1 (And$1 src mask) lshift)); |
223 match(Set dst (LShift$1 (And$1 src mask) lshift)); |
227 predicate((unsigned int)n->in(2)->get_int() <= $3 && |
224 predicate((exact_log2$5(n->in(1)->in(2)->get_$4() + 1) + (n->in(2)->get_int() & $3)) <= ($3 + 1)); |
228 (exact_log2$5(n->in(1)->in(2)->get_$4()+1) + (unsigned int)n->in(2)->get_int()) <= ($3+1)); |
|
229 |
225 |
230 ins_cost(INSN_COST); |
226 ins_cost(INSN_COST); |
231 format %{ "$2 $dst, $src, $lshift, $mask" %} |
227 format %{ "$2 $dst, $src, $lshift, $mask" %} |
232 ins_encode %{ |
228 ins_encode %{ |
233 int lshift = $lshift$$constant; |
229 int lshift = $lshift$$constant & $3; |
234 long mask = $mask$$constant; |
230 long mask = $mask$$constant; |
235 int width = exact_log2$5(mask+1); |
231 int width = exact_log2$5(mask+1); |
236 __ $2(as_Register($dst$$reg), |
232 __ $2(as_Register($dst$$reg), |
237 as_Register($src$$reg), lshift, width); |
233 as_Register($src$$reg), lshift, width); |
238 %} |
234 %} |
239 ins_pipe(ialu_reg_shift); |
235 ins_pipe(ialu_reg_shift); |
240 %}') |
236 %}') |
241 UBFIZ_INSN(I, ubfizw, 31, int) |
237 UBFIZ_INSN(I, ubfizw, 31, int) |
242 UBFIZ_INSN(L, ubfiz, 63, long, _long) |
238 UBFIZ_INSN(L, ubfiz, 63, long, _long) |
243 |
239 |
244 // If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz |
240 // If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz |
245 instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) |
241 instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) |
246 %{ |
242 %{ |
247 match(Set dst (LShiftL (ConvI2L(AndI src mask)) lshift)); |
243 match(Set dst (LShiftL (ConvI2L (AndI src mask)) lshift)); |
248 predicate((unsigned int)n->in(2)->get_int() <= 31 && |
244 predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1)); |
249 (exact_log2((unsigned int)n->in(1)->in(1)->in(2)->get_int()+1) + (unsigned int)n->in(2)->get_int()) <= 32); |
|
250 |
245 |
251 ins_cost(INSN_COST); |
246 ins_cost(INSN_COST); |
252 format %{ "ubfiz $dst, $src, $lshift, $mask" %} |
247 format %{ "ubfiz $dst, $src, $lshift, $mask" %} |
253 ins_encode %{ |
248 ins_encode %{ |
254 int lshift = $lshift$$constant; |
249 int lshift = $lshift$$constant & 63; |
255 long mask = $mask$$constant; |
250 long mask = $mask$$constant; |
256 int width = exact_log2(mask+1); |
251 int width = exact_log2(mask+1); |
257 __ ubfiz(as_Register($dst$$reg), |
252 __ ubfiz(as_Register($dst$$reg), |
258 as_Register($src$$reg), lshift, width); |
253 as_Register($src$$reg), lshift, width); |
259 %} |
254 %} |
264 |
259 |
265 define(`EXTRACT_INSN', |
260 define(`EXTRACT_INSN', |
266 `instruct extr$3$1(iReg$1NoSp dst, iReg$1`'ORL2I($1) src1, iReg$1`'ORL2I($1) src2, immI lshift, immI rshift, rFlagsReg cr) |
261 `instruct extr$3$1(iReg$1NoSp dst, iReg$1`'ORL2I($1) src1, iReg$1`'ORL2I($1) src2, immI lshift, immI rshift, rFlagsReg cr) |
267 %{ |
262 %{ |
268 match(Set dst ($3$1 (LShift$1 src1 lshift) (URShift$1 src2 rshift))); |
263 match(Set dst ($3$1 (LShift$1 src1 lshift) (URShift$1 src2 rshift))); |
269 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & $2)); |
264 predicate(0 == (((n->in(1)->in(2)->get_int() & $2) + (n->in(2)->in(2)->get_int() & $2)) & $2)); |
270 |
265 |
271 ins_cost(INSN_COST); |
266 ins_cost(INSN_COST); |
272 format %{ "extr $dst, $src1, $src2, #$rshift" %} |
267 format %{ "extr $dst, $src1, $src2, #$rshift" %} |
273 |
268 |
274 ins_encode %{ |
269 ins_encode %{ |