src/cpu/x86/vm/macroAssembler_x86.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/cpu/x86/vm

src/cpu/x86/vm/macroAssembler_x86.cpp

Print this page
rev 7609 : 8063086: Math.pow yields different results upon repeated calls
Summary: C2 treats x^2 as a special case and computes x * x while the interpreter and c1 don't have special case code for X^2.
Reviewed-by:


3167   Register tmp2 = rax;
3168   Register tmp3 = rcx;
3169 
3170   if (is_exp) {
3171     // Stack: X
3172     fld_s(0);                   // duplicate argument for runtime call. Stack: X X
3173     fast_exp();                 // Stack: exp(X) X
3174     fcmp(tmp, 0, false, false); // Stack: exp(X) X
3175     // exp(X) not equal to itself: exp(X) is NaN go to slow case.
3176     jcc(Assembler::parity, slow_case);
3177     // get rid of duplicate argument. Stack: exp(X)
3178     if (num_fpu_regs_in_use > 0) {
3179       fxch();
3180       fpop();
3181     } else {
3182       ffree(1);
3183     }
3184     jmp(done);
3185   } else {
3186     // Stack: X Y
3187     Label x_negative, y_odd;















3188 
3189     fldz();                     // Stack: 0 X Y
3190     fcmp(tmp, 1, true, false);  // Stack: X Y
3191     jcc(Assembler::above, x_negative);
3192 
3193     // X >= 0
3194 
3195     fld_s(1);                   // duplicate arguments for runtime call. Stack: Y X Y
3196     fld_s(1);                   // Stack: X Y X Y
3197     fast_pow();                 // Stack: X^Y X Y
3198     fcmp(tmp, 0, false, false); // Stack: X^Y X Y
3199     // X^Y not equal to itself: X^Y is NaN go to slow case.
3200     jcc(Assembler::parity, slow_case);
3201     // get rid of duplicate arguments. Stack: X^Y
3202     if (num_fpu_regs_in_use > 0) {
3203       fxch(); fpop();
3204       fxch(); fpop();
3205     } else {
3206       ffree(2);
3207       ffree(1);




3167   Register tmp2 = rax;
3168   Register tmp3 = rcx;
3169 
3170   if (is_exp) {
3171     // Stack: X
3172     fld_s(0);                   // duplicate argument for runtime call. Stack: X X
3173     fast_exp();                 // Stack: exp(X) X
3174     fcmp(tmp, 0, false, false); // Stack: exp(X) X
3175     // exp(X) not equal to itself: exp(X) is NaN go to slow case.
3176     jcc(Assembler::parity, slow_case);
3177     // get rid of duplicate argument. Stack: exp(X)
3178     if (num_fpu_regs_in_use > 0) {
3179       fxch();
3180       fpop();
3181     } else {
3182       ffree(1);
3183     }
3184     jmp(done);
3185   } else {
3186     // Stack: X Y
3187     Label x_negative, y_not_2;
3188 
3189     static double two = 2.0;
3190     ExternalAddress two_addr((address)&two);
3191 
3192     fld_d(two_addr);            // Stack: 2 X Y
3193     fcmp(tmp, 2, true, false);  // Stack: X Y
3194     jcc(Assembler::parity, y_not_2);
3195     jcc(Assembler::notEqual, y_not_2);
3196 
3197     fxch(); fpop();             // Stack: X
3198     fmul(0);                    // Stack: X*X
3199     
3200     jmp(done);
3201 
3202     bind(y_not_2);
3203 
3204     fldz();                     // Stack: 0 X Y
3205     fcmp(tmp, 1, true, false);  // Stack: X Y
3206     jcc(Assembler::above, x_negative);
3207 
3208     // X >= 0
3209 
3210     fld_s(1);                   // duplicate arguments for runtime call. Stack: Y X Y
3211     fld_s(1);                   // Stack: X Y X Y
3212     fast_pow();                 // Stack: X^Y X Y
3213     fcmp(tmp, 0, false, false); // Stack: X^Y X Y
3214     // X^Y not equal to itself: X^Y is NaN go to slow case.
3215     jcc(Assembler::parity, slow_case);
3216     // get rid of duplicate arguments. Stack: X^Y
3217     if (num_fpu_regs_in_use > 0) {
3218       fxch(); fpop();
3219       fxch(); fpop();
3220     } else {
3221       ffree(2);
3222       ffree(1);


src/cpu/x86/vm/macroAssembler_x86.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File