3293 jmp(done); 3294 } 3295 3296 // slow case: runtime call 3297 bind(slow_case); 3298 3299 fpop(); // pop incorrect result or int(Y) 3300 3301 fp_runtime_fallback(is_exp ? CAST_FROM_FN_PTR(address, SharedRuntime::dexp) : CAST_FROM_FN_PTR(address, SharedRuntime::dpow), 3302 is_exp ? 1 : 2, num_fpu_regs_in_use); 3303 3304 // Come here with result in F-TOS 3305 bind(done); 3306 } 3307 3308 void MacroAssembler::fpop() { 3309 ffree(); 3310 fincstp(); 3311 } 3312 3313 void MacroAssembler::fremr(Register tmp) { 3314 save_rax(tmp); 3315 { Label L; 3316 bind(L); 3317 fprem(); 3318 fwait(); fnstsw_ax(); 3319 #ifdef _LP64 3320 testl(rax, 0x400); 3321 jcc(Assembler::notEqual, L); 3322 #else 3323 sahf(); 3324 jcc(Assembler::parity, L); 3325 #endif // _LP64 3326 } 3327 restore_rax(tmp); 3328 // Result is in ST0. 3329 // Note: fxch & fpop to get rid of ST1 3330 // (otherwise FPU stack could overflow eventually) 3331 fxch(1); 3332 fpop(); | 3293 jmp(done); 3294 } 3295 3296 // slow case: runtime call 3297 bind(slow_case); 3298 3299 fpop(); // pop incorrect result or int(Y) 3300 3301 fp_runtime_fallback(is_exp ? CAST_FROM_FN_PTR(address, SharedRuntime::dexp) : CAST_FROM_FN_PTR(address, SharedRuntime::dpow), 3302 is_exp ? 1 : 2, num_fpu_regs_in_use); 3303 3304 // Come here with result in F-TOS 3305 bind(done); 3306 } 3307 3308 void MacroAssembler::fpop() { 3309 ffree(); 3310 fincstp(); 3311 } 3312 3313 void MacroAssembler::load_float(Address src) { 3314 if (UseSSE >= 1) { 3315 movflt(xmm0, src); 3316 } else { 3317 LP64_ONLY(ShouldNotReachHere()); 3318 NOT_LP64(fld_s(src)); 3319 } 3320 } 3321 3322 void MacroAssembler::store_float(Address dst) { 3323 if (UseSSE >= 1) { 3324 movflt(dst, xmm0); 3325 } else { 3326 LP64_ONLY(ShouldNotReachHere()); 3327 NOT_LP64(fstp_s(dst)); 3328 } 3329 } 3330 3331 void MacroAssembler::load_double(Address src) { 3332 if (UseSSE >= 2) { 3333 movdbl(xmm0, src); 3334 } else { 3335 LP64_ONLY(ShouldNotReachHere()); 3336 NOT_LP64(fld_d(src)); 3337 } 3338 } 3339 3340 void MacroAssembler::store_double(Address dst) { 3341 if (UseSSE >= 2) { 3342 movdbl(dst, xmm0); 3343 } else { 3344 LP64_ONLY(ShouldNotReachHere()); 3345 NOT_LP64(fstp_d(dst)); 3346 } 3347 } 3348 3349 void MacroAssembler::fremr(Register tmp) { 3350 save_rax(tmp); 3351 { Label L; 3352 bind(L); 3353 fprem(); 3354 fwait(); fnstsw_ax(); 3355 #ifdef _LP64 3356 testl(rax, 0x400); 3357 jcc(Assembler::notEqual, L); 3358 #else 3359 sahf(); 3360 jcc(Assembler::parity, L); 3361 #endif // _LP64 3362 } 3363 restore_rax(tmp); 3364 // Result is in ST0. 3365 // Note: fxch & fpop to get rid of ST1 3366 // (otherwise FPU stack could overflow eventually) 3367 fxch(1); 3368 fpop(); |