< prev index next >

src/share/vm/opto/divnode.cpp

Print this page

 ``` `````` 101 102 // Result 103 Node *q = NULL; 104 105 if (d == 1) { 106 // division by +/- 1 107 if (!d_pos) { 108 // Just negate the value 109 q = new SubINode(phase->intcon(0), dividend); 110 } 111 } else if ( is_power_of_2(d) ) { 112 // division by +/- a power of 2 113 114 // See if we can simply do a shift without rounding 115 bool needs_rounding = true; 116 const Type *dt = phase->type(dividend); 117 const TypeInt *dti = dt->isa_int(); 118 if (dti && dti->_lo >= 0) { 119 // we don't need to round a positive dividend 120 needs_rounding = false; 121 } else if( dividend->Opcode() == Op_AndI ) { 122 // An AND mask of sufficient size clears the low bits and 123 // I can avoid rounding. 124 const TypeInt *andconi_t = phase->type( dividend->in(2) )->isa_int(); 125 if( andconi_t && andconi_t->is_con() ) { 126 jint andconi = andconi_t->get_con(); 127 if( andconi < 0 && is_power_of_2(-andconi) && (-andconi) >= d ) { 128 if( (-andconi) == d ) // Remove AND if it clears bits which will be shifted 129 dividend = dividend->in(1); 130 needs_rounding = false; 131 } 132 } 133 } 134 135 // Add rounding to the shift to handle the sign bit 136 int l = log2_intptr(d-1)+1; 137 if (needs_rounding) { 138 // Divide-by-power-of-2 can be made into a shift, but you have to do 139 // more math for the rounding. You need to add 0 for positive 140 // numbers, and "i-1" for negative numbers. Example: i=4, so the 141 // shift is by 2. You need to add 3 to negative dividends and 0 to `````` 242 r2 = 2*r2; // Update r2 = rem(2**p, |d|). 243 if (r2 >= ad) { // (Must be an unsigned 244 q2 = q2 + 1; // comparison here). 245 r2 = r2 - ad; 246 } 247 delta = ad - r2; 248 } while (q1 < delta || (q1 == delta && r1 == 0)); 249 250 M = q2 + 1; 251 if (d < 0) M = -M; // Magic number and 252 s = p - 64; // shift amount to return. 253 254 return true; 255 } 256 257 //---------------------long_by_long_mulhi-------------------------------------- 258 // Generate ideal node graph for upper half of a 64 bit x 64 bit multiplication 259 static Node* long_by_long_mulhi(PhaseGVN* phase, Node* dividend, jlong magic_const) { 260 // If the architecture supports a 64x64 mulhi, there is 261 // no need to synthesize it in ideal nodes. 262 if (Matcher::has_match_rule(Op_MulHiL)) { 263 Node* v = phase->longcon(magic_const); 264 return new MulHiLNode(dividend, v); 265 } 266 267 // Taken from Hacker's Delight, Fig. 8-2. Multiply high signed. 268 // (http://www.hackersdelight.org/HDcode/mulhs.c) 269 // 270 // int mulhs(int u, int v) { 271 // unsigned u0, v0, w0; 272 // int u1, v1, w1, w2, t; 273 // 274 // u0 = u & 0xFFFF; u1 = u >> 16; 275 // v0 = v & 0xFFFF; v1 = v >> 16; 276 // w0 = u0*v0; 277 // t = u1*v0 + (w0 >> 16); 278 // w1 = t & 0xFFFF; 279 // w2 = t >> 16; 280 // w1 = u0*v1 + w1; 281 // return u1*v1 + w2 + (w1 >> 16); 282 // } `````` 354 Node *q = NULL; 355 356 if (d == 1) { 357 // division by +/- 1 358 if (!d_pos) { 359 // Just negate the value 360 q = new SubLNode(phase->longcon(0), dividend); 361 } 362 } else if ( is_power_of_2_long(d) ) { 363 364 // division by +/- a power of 2 365 366 // See if we can simply do a shift without rounding 367 bool needs_rounding = true; 368 const Type *dt = phase->type(dividend); 369 const TypeLong *dtl = dt->isa_long(); 370 371 if (dtl && dtl->_lo > 0) { 372 // we don't need to round a positive dividend 373 needs_rounding = false; 374 } else if( dividend->Opcode() == Op_AndL ) { 375 // An AND mask of sufficient size clears the low bits and 376 // I can avoid rounding. 377 const TypeLong *andconl_t = phase->type( dividend->in(2) )->isa_long(); 378 if( andconl_t && andconl_t->is_con() ) { 379 jlong andconl = andconl_t->get_con(); 380 if( andconl < 0 && is_power_of_2_long(-andconl) && (-andconl) >= d ) { 381 if( (-andconl) == d ) // Remove AND if it clears bits which will be shifted 382 dividend = dividend->in(1); 383 needs_rounding = false; 384 } 385 } 386 } 387 388 // Add rounding to the shift to handle the sign bit 389 int l = log2_long(d-1)+1; 390 if (needs_rounding) { 391 // Divide-by-power-of-2 can be made into a shift, but you have to do 392 // more math for the rounding. You need to add 0 for positive 393 // numbers, and "i-1" for negative numbers. Example: i=4, so the 394 // shift is by 2. You need to add 3 to negative dividends and 0 to ``````1265 // Make sure that the sign of the fmod is equal to the sign of the dividend 1266 jlong xr = jlong_cast(fmod(f1, f2)); 1267 if ((x1 ^ xr) < 0) { 1268 xr ^= min_jlong; 1269 } 1270 1271 return TypeD::make(jdouble_cast(xr)); 1272 } 1273 1274 //============================================================================= 1275 1276 DivModNode::DivModNode( Node *c, Node *dividend, Node *divisor ) : MultiNode(3) { 1277 init_req(0, c); 1278 init_req(1, dividend); 1279 init_req(2, divisor); 1280 } 1281 1282 //------------------------------make------------------------------------------ 1283 DivModINode* DivModINode::make(Node* div_or_mod) { 1284 Node* n = div_or_mod; 1285 assert(n->Opcode() == Op_DivI || n->Opcode() == Op_ModI, 1286 "only div or mod input pattern accepted"); 1287 1288 DivModINode* divmod = new DivModINode(n->in(0), n->in(1), n->in(2)); 1289 Node* dproj = new ProjNode(divmod, DivModNode::div_proj_num); 1290 Node* mproj = new ProjNode(divmod, DivModNode::mod_proj_num); 1291 return divmod; 1292 } 1293 1294 //------------------------------make------------------------------------------ 1295 DivModLNode* DivModLNode::make(Node* div_or_mod) { 1296 Node* n = div_or_mod; 1297 assert(n->Opcode() == Op_DivL || n->Opcode() == Op_ModL, 1298 "only div or mod input pattern accepted"); 1299 1300 DivModLNode* divmod = new DivModLNode(n->in(0), n->in(1), n->in(2)); 1301 Node* dproj = new ProjNode(divmod, DivModNode::div_proj_num); 1302 Node* mproj = new ProjNode(divmod, DivModNode::mod_proj_num); 1303 return divmod; 1304 } 1305 1306 //------------------------------match------------------------------------------ 1307 // return result(s) along with their RegMask info 1308 Node *DivModINode::match( const ProjNode *proj, const Matcher *match ) { 1309 uint ideal_reg = proj->ideal_reg(); 1310 RegMask rm; 1311 if (proj->_con == div_proj_num) { 1312 rm = match->divI_proj_mask(); 1313 } else { 1314 assert(proj->_con == mod_proj_num, "must be div or mod projection"); 1315 rm = match->modI_proj_mask(); 1316 } 1317 return new MachProjNode(this, proj->_con, rm, ideal_reg); 1318 } 1319 1320 1321 //------------------------------match------------------------------------------ 1322 // return result(s) along with their RegMask info 1323 Node *DivModLNode::match( const ProjNode *proj, const Matcher *match ) { 1324 uint ideal_reg = proj->ideal_reg(); 1325 RegMask rm; 1326 if (proj->_con == div_proj_num) { 1327 rm = match->divL_proj_mask(); 1328 } else { 1329 assert(proj->_con == mod_proj_num, "must be div or mod projection"); 1330 rm = match->modL_proj_mask(); 1331 } 1332 return new MachProjNode(this, proj->_con, rm, ideal_reg); 1333 } ``` ``` `````` 101 102 // Result 103 Node *q = NULL; 104 105 if (d == 1) { 106 // division by +/- 1 107 if (!d_pos) { 108 // Just negate the value 109 q = new SubINode(phase->intcon(0), dividend); 110 } 111 } else if ( is_power_of_2(d) ) { 112 // division by +/- a power of 2 113 114 // See if we can simply do a shift without rounding 115 bool needs_rounding = true; 116 const Type *dt = phase->type(dividend); 117 const TypeInt *dti = dt->isa_int(); 118 if (dti && dti->_lo >= 0) { 119 // we don't need to round a positive dividend 120 needs_rounding = false; 121 } else if( dividend->Opcode() == Opcodes::Op_AndI ) { 122 // An AND mask of sufficient size clears the low bits and 123 // I can avoid rounding. 124 const TypeInt *andconi_t = phase->type( dividend->in(2) )->isa_int(); 125 if( andconi_t && andconi_t->is_con() ) { 126 jint andconi = andconi_t->get_con(); 127 if( andconi < 0 && is_power_of_2(-andconi) && (-andconi) >= d ) { 128 if( (-andconi) == d ) // Remove AND if it clears bits which will be shifted 129 dividend = dividend->in(1); 130 needs_rounding = false; 131 } 132 } 133 } 134 135 // Add rounding to the shift to handle the sign bit 136 int l = log2_intptr(d-1)+1; 137 if (needs_rounding) { 138 // Divide-by-power-of-2 can be made into a shift, but you have to do 139 // more math for the rounding. You need to add 0 for positive 140 // numbers, and "i-1" for negative numbers. Example: i=4, so the 141 // shift is by 2. You need to add 3 to negative dividends and 0 to `````` 242 r2 = 2*r2; // Update r2 = rem(2**p, |d|). 243 if (r2 >= ad) { // (Must be an unsigned 244 q2 = q2 + 1; // comparison here). 245 r2 = r2 - ad; 246 } 247 delta = ad - r2; 248 } while (q1 < delta || (q1 == delta && r1 == 0)); 249 250 M = q2 + 1; 251 if (d < 0) M = -M; // Magic number and 252 s = p - 64; // shift amount to return. 253 254 return true; 255 } 256 257 //---------------------long_by_long_mulhi-------------------------------------- 258 // Generate ideal node graph for upper half of a 64 bit x 64 bit multiplication 259 static Node* long_by_long_mulhi(PhaseGVN* phase, Node* dividend, jlong magic_const) { 260 // If the architecture supports a 64x64 mulhi, there is 261 // no need to synthesize it in ideal nodes. 262 if (Matcher::has_match_rule(Opcodes::Op_MulHiL)) { 263 Node* v = phase->longcon(magic_const); 264 return new MulHiLNode(dividend, v); 265 } 266 267 // Taken from Hacker's Delight, Fig. 8-2. Multiply high signed. 268 // (http://www.hackersdelight.org/HDcode/mulhs.c) 269 // 270 // int mulhs(int u, int v) { 271 // unsigned u0, v0, w0; 272 // int u1, v1, w1, w2, t; 273 // 274 // u0 = u & 0xFFFF; u1 = u >> 16; 275 // v0 = v & 0xFFFF; v1 = v >> 16; 276 // w0 = u0*v0; 277 // t = u1*v0 + (w0 >> 16); 278 // w1 = t & 0xFFFF; 279 // w2 = t >> 16; 280 // w1 = u0*v1 + w1; 281 // return u1*v1 + w2 + (w1 >> 16); 282 // } `````` 354 Node *q = NULL; 355 356 if (d == 1) { 357 // division by +/- 1 358 if (!d_pos) { 359 // Just negate the value 360 q = new SubLNode(phase->longcon(0), dividend); 361 } 362 } else if ( is_power_of_2_long(d) ) { 363 364 // division by +/- a power of 2 365 366 // See if we can simply do a shift without rounding 367 bool needs_rounding = true; 368 const Type *dt = phase->type(dividend); 369 const TypeLong *dtl = dt->isa_long(); 370 371 if (dtl && dtl->_lo > 0) { 372 // we don't need to round a positive dividend 373 needs_rounding = false; 374 } else if( dividend->Opcode() == Opcodes::Op_AndL ) { 375 // An AND mask of sufficient size clears the low bits and 376 // I can avoid rounding. 377 const TypeLong *andconl_t = phase->type( dividend->in(2) )->isa_long(); 378 if( andconl_t && andconl_t->is_con() ) { 379 jlong andconl = andconl_t->get_con(); 380 if( andconl < 0 && is_power_of_2_long(-andconl) && (-andconl) >= d ) { 381 if( (-andconl) == d ) // Remove AND if it clears bits which will be shifted 382 dividend = dividend->in(1); 383 needs_rounding = false; 384 } 385 } 386 } 387 388 // Add rounding to the shift to handle the sign bit 389 int l = log2_long(d-1)+1; 390 if (needs_rounding) { 391 // Divide-by-power-of-2 can be made into a shift, but you have to do 392 // more math for the rounding. You need to add 0 for positive 393 // numbers, and "i-1" for negative numbers. Example: i=4, so the 394 // shift is by 2. You need to add 3 to negative dividends and 0 to ``````1265 // Make sure that the sign of the fmod is equal to the sign of the dividend 1266 jlong xr = jlong_cast(fmod(f1, f2)); 1267 if ((x1 ^ xr) < 0) { 1268 xr ^= min_jlong; 1269 } 1270 1271 return TypeD::make(jdouble_cast(xr)); 1272 } 1273 1274 //============================================================================= 1275 1276 DivModNode::DivModNode( Node *c, Node *dividend, Node *divisor ) : MultiNode(3) { 1277 init_req(0, c); 1278 init_req(1, dividend); 1279 init_req(2, divisor); 1280 } 1281 1282 //------------------------------make------------------------------------------ 1283 DivModINode* DivModINode::make(Node* div_or_mod) { 1284 Node* n = div_or_mod; 1285 assert(n->Opcode() == Opcodes::Op_DivI || n->Opcode() == Opcodes::Op_ModI, 1286 "only div or mod input pattern accepted"); 1287 1288 DivModINode* divmod = new DivModINode(n->in(0), n->in(1), n->in(2)); 1289 Node* dproj = new ProjNode(divmod, DivModNode::div_proj_num); 1290 Node* mproj = new ProjNode(divmod, DivModNode::mod_proj_num); 1291 return divmod; 1292 } 1293 1294 //------------------------------make------------------------------------------ 1295 DivModLNode* DivModLNode::make(Node* div_or_mod) { 1296 Node* n = div_or_mod; 1297 assert(n->Opcode() == Opcodes::Op_DivL || n->Opcode() == Opcodes::Op_ModL, 1298 "only div or mod input pattern accepted"); 1299 1300 DivModLNode* divmod = new DivModLNode(n->in(0), n->in(1), n->in(2)); 1301 Node* dproj = new ProjNode(divmod, DivModNode::div_proj_num); 1302 Node* mproj = new ProjNode(divmod, DivModNode::mod_proj_num); 1303 return divmod; 1304 } 1305 1306 //------------------------------match------------------------------------------ 1307 // return result(s) along with their RegMask info 1308 Node *DivModINode::match( const ProjNode *proj, const Matcher *match ) { 1309 Opcodes ideal_reg = proj->ideal_reg(); 1310 RegMask rm; 1311 if (proj->_con == div_proj_num) { 1312 rm = match->divI_proj_mask(); 1313 } else { 1314 assert(proj->_con == mod_proj_num, "must be div or mod projection"); 1315 rm = match->modI_proj_mask(); 1316 } 1317 return new MachProjNode(this, proj->_con, rm, ideal_reg); 1318 } 1319 1320 1321 //------------------------------match------------------------------------------ 1322 // return result(s) along with their RegMask info 1323 Node *DivModLNode::match( const ProjNode *proj, const Matcher *match ) { 1324 Opcodes ideal_reg = proj->ideal_reg(); 1325 RegMask rm; 1326 if (proj->_con == div_proj_num) { 1327 rm = match->divL_proj_mask(); 1328 } else { 1329 assert(proj->_con == mod_proj_num, "must be div or mod projection"); 1330 rm = match->modL_proj_mask(); 1331 } 1332 return new MachProjNode(this, proj->_con, rm, ideal_reg); 1333 } ```
< prev index next >