< prev index next >

src/cpu/x86/vm/c1_LIRAssembler_x86.cpp

Print this page




2633     }
2634 #endif // _LP64
2635   }
2636 }
2637 
2638 
2639 // we assume that rax, and rdx can be overwritten
2640 void LIR_Assembler::arithmetic_idiv(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr temp, LIR_Opr result, CodeEmitInfo* info) {
2641 
2642   assert(left->is_single_cpu(),   "left must be register");
2643   assert(right->is_single_cpu() || right->is_constant(),  "right must be register or constant");
2644   assert(result->is_single_cpu(), "result must be register");
2645 
2646   //  assert(left->destroys_register(), "check");
2647   //  assert(right->destroys_register(), "check");
2648 
2649   Register lreg = left->as_register();
2650   Register dreg = result->as_register();
2651 
2652   if (right->is_constant()) {
2653     int divisor = right->as_constant_ptr()->as_jint();
2654     assert(divisor > 0 && is_power_of_2(divisor), "must be");
2655     if (code == lir_idiv) {
2656       assert(lreg == rax, "must be rax,");
2657       assert(temp->as_register() == rdx, "tmp register must be rdx");
2658       __ cdql(); // sign extend into rdx:rax
2659       if (divisor == 2) {
2660         __ subl(lreg, rdx);
2661       } else {
2662         __ andl(rdx, divisor - 1);
2663         __ addl(lreg, rdx);
2664       }
2665       __ sarl(lreg, log2_intptr(divisor));
2666       move_regs(lreg, dreg);
2667     } else if (code == lir_irem) {
2668       Label done;
2669       __ mov(dreg, lreg);
2670       __ andl(dreg, 0x80000000 | (divisor - 1));
2671       __ jcc(Assembler::positive, done);
2672       __ decrement(dreg);
2673       __ orl(dreg, ~(divisor - 1));
2674       __ increment(dreg);
2675       __ bind(done);
2676     } else {
2677       ShouldNotReachHere();
2678     }
2679   } else {
2680     Register rreg = right->as_register();
2681     assert(lreg == rax, "left register must be rax,");
2682     assert(rreg != rdx, "right register must not be rdx");
2683     assert(temp->as_register() == rdx, "tmp register must be rdx");
2684 
2685     move_regs(lreg, rax);




2633     }
2634 #endif // _LP64
2635   }
2636 }
2637 
2638 
2639 // we assume that rax, and rdx can be overwritten
2640 void LIR_Assembler::arithmetic_idiv(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr temp, LIR_Opr result, CodeEmitInfo* info) {
2641 
2642   assert(left->is_single_cpu(),   "left must be register");
2643   assert(right->is_single_cpu() || right->is_constant(),  "right must be register or constant");
2644   assert(result->is_single_cpu(), "result must be register");
2645 
2646   //  assert(left->destroys_register(), "check");
2647   //  assert(right->destroys_register(), "check");
2648 
2649   Register lreg = left->as_register();
2650   Register dreg = result->as_register();
2651 
2652   if (right->is_constant()) {
2653     jint divisor = right->as_constant_ptr()->as_jint();
2654     assert(divisor > 0 && is_power_of_2(divisor), "must be");
2655     if (code == lir_idiv) {
2656       assert(lreg == rax, "must be rax,");
2657       assert(temp->as_register() == rdx, "tmp register must be rdx");
2658       __ cdql(); // sign extend into rdx:rax
2659       if (divisor == 2) {
2660         __ subl(lreg, rdx);
2661       } else {
2662         __ andl(rdx, divisor - 1);
2663         __ addl(lreg, rdx);
2664       }
2665       __ sarl(lreg, log2_jint(divisor));
2666       move_regs(lreg, dreg);
2667     } else if (code == lir_irem) {
2668       Label done;
2669       __ mov(dreg, lreg);
2670       __ andl(dreg, 0x80000000 | (divisor - 1));
2671       __ jcc(Assembler::positive, done);
2672       __ decrement(dreg);
2673       __ orl(dreg, ~(divisor - 1));
2674       __ increment(dreg);
2675       __ bind(done);
2676     } else {
2677       ShouldNotReachHere();
2678     }
2679   } else {
2680     Register rreg = right->as_register();
2681     assert(lreg == rax, "left register must be rax,");
2682     assert(rreg != rdx, "right register must not be rdx");
2683     assert(temp->as_register() == rdx, "tmp register must be rdx");
2684 
2685     move_regs(lreg, rax);


< prev index next >