247 if (Matcher::has_match_rule(Op_MulHiL)) {
248 Node *v = phase->longcon(magic_const);
249 return new (phase->C, 3) MulHiLNode(dividend, v);
250 }
251
252 const int N = 64;
253
254 Node *u_hi = phase->transform(new (phase->C, 3) RShiftLNode(dividend, phase->intcon(N / 2)));
255 Node *u_lo = phase->transform(new (phase->C, 3) AndLNode(dividend, phase->longcon(0xFFFFFFFF)));
256
257 Node *v_hi = phase->longcon(magic_const >> N/2);
258 Node *v_lo = phase->longcon(magic_const & 0XFFFFFFFF);
259
260 Node *hihi_product = phase->transform(new (phase->C, 3) MulLNode(u_hi, v_hi));
261 Node *hilo_product = phase->transform(new (phase->C, 3) MulLNode(u_hi, v_lo));
262 Node *lohi_product = phase->transform(new (phase->C, 3) MulLNode(u_lo, v_hi));
263 Node *lolo_product = phase->transform(new (phase->C, 3) MulLNode(u_lo, v_lo));
264
265 Node *t1 = phase->transform(new (phase->C, 3) URShiftLNode(lolo_product, phase->intcon(N / 2)));
266 Node *t2 = phase->transform(new (phase->C, 3) AddLNode(hilo_product, t1));
267 Node *t3 = phase->transform(new (phase->C, 3) RShiftLNode(t2, phase->intcon(N / 2)));
268 Node *t4 = phase->transform(new (phase->C, 3) AndLNode(t2, phase->longcon(0xFFFFFFFF)));
269 Node *t5 = phase->transform(new (phase->C, 3) AddLNode(t4, lohi_product));
270 Node *t6 = phase->transform(new (phase->C, 3) RShiftLNode(t5, phase->intcon(N / 2)));
271 Node *t7 = phase->transform(new (phase->C, 3) AddLNode(t3, hihi_product));
272
273 return new (phase->C, 3) AddLNode(t7, t6);
274 }
275
276
277 //--------------------------transform_long_divide------------------------------
278 // Convert a division by constant divisor into an alternate Ideal graph.
279 // Return NULL if no transformation occurs.
280 static Node *transform_long_divide( PhaseGVN *phase, Node *dividend, jlong divisor ) {
281 // Check for invalid divisors
282 assert( divisor != 0L && divisor != min_jlong,
283 "bad divisor for transforming to long multiply" );
284
285 bool d_pos = divisor >= 0;
286 jlong d = d_pos ? divisor : -divisor;
287 const int N = 64;
288
|
247 if (Matcher::has_match_rule(Op_MulHiL)) {
248 Node *v = phase->longcon(magic_const);
249 return new (phase->C, 3) MulHiLNode(dividend, v);
250 }
251
252 const int N = 64;
253
254 Node *u_hi = phase->transform(new (phase->C, 3) RShiftLNode(dividend, phase->intcon(N / 2)));
255 Node *u_lo = phase->transform(new (phase->C, 3) AndLNode(dividend, phase->longcon(0xFFFFFFFF)));
256
257 Node *v_hi = phase->longcon(magic_const >> N/2);
258 Node *v_lo = phase->longcon(magic_const & 0XFFFFFFFF);
259
260 Node *hihi_product = phase->transform(new (phase->C, 3) MulLNode(u_hi, v_hi));
261 Node *hilo_product = phase->transform(new (phase->C, 3) MulLNode(u_hi, v_lo));
262 Node *lohi_product = phase->transform(new (phase->C, 3) MulLNode(u_lo, v_hi));
263 Node *lolo_product = phase->transform(new (phase->C, 3) MulLNode(u_lo, v_lo));
264
265 Node *t1 = phase->transform(new (phase->C, 3) URShiftLNode(lolo_product, phase->intcon(N / 2)));
266 Node *t2 = phase->transform(new (phase->C, 3) AddLNode(hilo_product, t1));
267
268 // Construct both t3 and t4 before transforming so t2 doesn't go dead
269 // prematurely.
270 Node *t3 = new (phase->C, 3) RShiftLNode(t2, phase->intcon(N / 2));
271 Node *t4 = new (phase->C, 3) AndLNode(t2, phase->longcon(0xFFFFFFFF));
272 t3 = phase->transform(t3);
273 t4 = phase->transform(t4);
274
275 Node *t5 = phase->transform(new (phase->C, 3) AddLNode(t4, lohi_product));
276 Node *t6 = phase->transform(new (phase->C, 3) RShiftLNode(t5, phase->intcon(N / 2)));
277 Node *t7 = phase->transform(new (phase->C, 3) AddLNode(t3, hihi_product));
278
279 return new (phase->C, 3) AddLNode(t7, t6);
280 }
281
282
283 //--------------------------transform_long_divide------------------------------
284 // Convert a division by constant divisor into an alternate Ideal graph.
285 // Return NULL if no transformation occurs.
286 static Node *transform_long_divide( PhaseGVN *phase, Node *dividend, jlong divisor ) {
287 // Check for invalid divisors
288 assert( divisor != 0L && divisor != min_jlong,
289 "bad divisor for transforming to long multiply" );
290
291 bool d_pos = divisor >= 0;
292 jlong d = d_pos ? divisor : -divisor;
293 const int N = 64;
294
|