Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(212)

Side by Side Diff: src/x64/codegen-x64.cc

Issue 300004: X64 Win64: Reimplement fmod so that it works. (Closed)
Patch Set: And it lints. Created 11 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 // operand_1 on TOS+1 , operand_2 on TOS+2; Returns operands as 212 // operand_1 on TOS+1 , operand_2 on TOS+2; Returns operands as
213 // floating point numbers in XMM registers. 213 // floating point numbers in XMM registers.
214 static void LoadFloatOperands(MacroAssembler* masm, 214 static void LoadFloatOperands(MacroAssembler* masm,
215 XMMRegister dst1, 215 XMMRegister dst1,
216 XMMRegister dst2); 216 XMMRegister dst2);
217 217
218 // Code pattern for loading floating point values onto the fp stack. 218 // Code pattern for loading floating point values onto the fp stack.
219 // Input values must be either smi or heap number objects (fp values). 219 // Input values must be either smi or heap number objects (fp values).
220 // Requirements: 220 // Requirements:
221 // Register version: operands in registers lhs and rhs. 221 // Register version: operands in registers lhs and rhs.
222 // Version without scratch memory pushes and pops the stack to get a
223 // memory cell, the version with scratch memory uses 8 bytes (64 bits)
224 // at that location.
222 // Stack version: operands on TOS+1 and TOS+2. 225 // Stack version: operands on TOS+1 and TOS+2.
223 // Returns operands as floating point numbers on fp stack. 226 // Returns operands as floating point numbers on fp stack.
224 static void LoadFloatOperands(MacroAssembler* masm); 227 static void LoadFloatOperands(MacroAssembler* masm);
225 static void LoadFloatOperands(MacroAssembler* masm, 228 static void LoadFloatOperands(MacroAssembler* masm,
226 Register lhs, 229 Register lhs,
227 Register rhs); 230 Register rhs);
231 static void LoadFloatOperands(MacroAssembler* masm,
232 Register lhs,
233 Register rhs,
234 const Operand& scratch_memory);
228 235
229 // Code pattern for loading a floating point value and converting it 236 // Code pattern for loading a floating point value and converting it
230 // to a 32 bit integer. Input value must be either a smi or a heap number 237 // to a 32 bit integer. Input value must be either a smi or a heap number
231 // object. 238 // object.
232 // Returns operands as 32-bit sign extended integers in a general purpose 239 // Returns operands as 32-bit sign extended integers in a general purpose
233 // registers. 240 // registers.
234 static void LoadInt32Operand(MacroAssembler* masm, 241 static void LoadInt32Operand(MacroAssembler* masm,
235 const Operand& src, 242 const Operand& src,
236 Register dst); 243 Register dst);
237 244
(...skipping 3758 matching lines...) Expand 10 before | Expand all | Expand 10 after
3996 answer = frame_->CallRuntime(Runtime::kMath_sin, 1); 4003 answer = frame_->CallRuntime(Runtime::kMath_sin, 1);
3997 break; 4004 break;
3998 case COS: 4005 case COS:
3999 answer = frame_->CallRuntime(Runtime::kMath_cos, 1); 4006 answer = frame_->CallRuntime(Runtime::kMath_cos, 1);
4000 break; 4007 break;
4001 } 4008 }
4002 frame_->Push(&answer); 4009 frame_->Push(&answer);
4003 done.Bind(); 4010 done.Bind();
4004 } 4011 }
4005 4012
4006 4013
William Hesse 2009/10/20 14:50:51 Could this function be documented more, explaining
4014 void CodeGenerator::GenerateNumberMod(ZoneList<Expression*>* args) {
4015 ASSERT_EQ(2, args->length());
4016 #ifdef _WIN64
4017 Load(args->at(0));
4018 Load(args->at(1));
4019 // Allocate rax for using fnstsw_ax.
4020 Result tmp = allocator_->Allocate(rax);
4021 // Allocate callee save register, for storing value while calling runtime.
4022 Result callee_save_result = allocator_->Allocate(r15);
4023 Result divisor_result = frame_->Pop();
4024 Result dividend_result = frame_->Pop();
4025 divisor_result.ToRegister();
4026 dividend_result.ToRegister();
4027 {
4028 // Code uses the physical stack, so it must be in sync.
4029 VirtualFrame::SpilledScope scope;
4030 Register dividend = dividend_result.reg();
4031 Register divisor = divisor_result.reg();
4032 Register callee_save = callee_save_result.reg();
4033
4034 Label done;
4035 // Make room on stack for temporary value.
4036 __ subq(rsp, Immediate(kPointerSize));
4037
4038 // Load operands onto FPU stack.
4039 // Divisor must go first on stack, so order of operands is really rhs, lhs.
4040 FloatingPointHelper::LoadFloatOperands(masm_,
4041 divisor,
4042 dividend,
4043 Operand(rsp, 0));
4044
4045 // Compute the remainder.
4046 {
4047 Label partial_remainder_loop;
4048 __ bind(&partial_remainder_loop);
4049 __ fprem();
4050 __ fwait();
4051 __ fnstsw_ax();
4052 __ testl(rax, Immediate(kCondition2));
4053 __ j(not_zero, &partial_remainder_loop);
4054 }
4055
4056 // Result is in ST(0), garbage in ST(1), and original value
4057 // of dividend in ST(2). Return ST(0) unless a division by zero or
4058 // invalid operation exception has been raised. Status word is in rax.
4059
4060 Label valid_result;
4061 Label allocate_result;
4062 // Test for InvalidOperation or division by zero.
4063 // In those cases, discard the result and use NaN instead.
4064 __ testb(rax, Immediate(kInvalidOperandException | kZeroDivideException));
4065 __ j(zero, &valid_result);
4066
4067 __ fstp(0); // Pop (garbage) result
4068 __ addq(rsp, Immediate(kPointerSize)); // Free stack cell.
4069 int64_t kNaNValue = V8_INT64_C(0x7ff8000000000000);
4070 // Move NaN to (callee save) register for later storing into new HeapNumber.
4071 __ movq(callee_save, kNaNValue, RelocInfo::NONE);
4072 __ jmp(&allocate_result);
4073
4074 // Allocate new space for a HeapNumber (is branched back to if direct heap
4075 // allocation fails in the following code).
4076 Label gc_req;
4077 Label heap_number_allocated;
4078 __ bind(&gc_req);
4079 // Garbage collection required before allocating a heap number.
4080 // Call runtime to do the allocation, and handle the allocation failure.
4081 __ CallRuntime(Runtime::kAllocateHeapNumber, 0);
4082 __ jmp(&heap_number_allocated);
4083
4084 __ bind(&valid_result);
4085
4086 // Result in ST(0), garbage in ST(1) and ST(2).
4087 // Pop result and free stack cell.
4088 __ fstp_d(Operand(rsp, 0));
4089 __ pop(callee_save);
4090
4091 __ bind(&allocate_result);
4092 // Free FPU stack and clear pending FPU exceptions (e.g., Denormal).
4093 __ fstp(0);
4094 Label no_exceptions_set;
4095 __ testb(rax, Immediate(kAnyExceptionMask));
4096 __ j(zero, &no_exceptions_set);
4097 __ fnclex();
4098 __ bind(&no_exceptions_set);
4099
4100 FloatingPointHelper::AllocateHeapNumber(masm_, &gc_req, dividend, rax);
4101 __ bind(&heap_number_allocated); // Return point for gc_req branch.
4102 __ movq(FieldOperand(rax, HeapNumber::kValueOffset), callee_save);
4103
4104 __ bind(&done);
4105 }
4106 frame_->Push(&tmp);
4107
4108 #else
4109 // Simply call the runtime function. Arguments must be numbers.
4110 ASSERT(args->length() == 2);
4111 Load(args->at(0));
4112 Load(args->at(1));
4113
4114 Result answer = frame_->CallRuntime(Runtime::kNumberMod, 2);
4115 frame_->Push(&answer);
4116 #endif
4117 }
4118
4119
4007 void CodeGenerator::GenerateClassOf(ZoneList<Expression*>* args) { 4120 void CodeGenerator::GenerateClassOf(ZoneList<Expression*>* args) {
4008 ASSERT(args->length() == 1); 4121 ASSERT(args->length() == 1);
4009 JumpTarget leave, null, function, non_function_constructor; 4122 JumpTarget leave, null, function, non_function_constructor;
4010 Load(args->at(0)); // Load the object. 4123 Load(args->at(0)); // Load the object.
4011 Result obj = frame_->Pop(); 4124 Result obj = frame_->Pop();
4012 obj.ToRegister(); 4125 obj.ToRegister();
4013 frame_->Spill(obj.reg()); 4126 frame_->Spill(obj.reg());
4014 4127
4015 // If the object is a smi, we return null. 4128 // If the object is a smi, we return null.
4016 Condition is_smi = masm_->CheckSmi(obj.reg()); 4129 Condition is_smi = masm_->CheckSmi(obj.reg());
(...skipping 3300 matching lines...) Expand 10 before | Expand all | Expand 10 after
7317 Label load_smi_lhs, load_smi_rhs, done_load_lhs, done; 7430 Label load_smi_lhs, load_smi_rhs, done_load_lhs, done;
7318 __ JumpIfSmi(lhs, &load_smi_lhs); 7431 __ JumpIfSmi(lhs, &load_smi_lhs);
7319 __ fld_d(FieldOperand(lhs, HeapNumber::kValueOffset)); 7432 __ fld_d(FieldOperand(lhs, HeapNumber::kValueOffset));
7320 __ bind(&done_load_lhs); 7433 __ bind(&done_load_lhs);
7321 7434
7322 __ JumpIfSmi(rhs, &load_smi_rhs); 7435 __ JumpIfSmi(rhs, &load_smi_rhs);
7323 __ fld_d(FieldOperand(rhs, HeapNumber::kValueOffset)); 7436 __ fld_d(FieldOperand(rhs, HeapNumber::kValueOffset));
7324 __ jmp(&done); 7437 __ jmp(&done);
7325 7438
7326 __ bind(&load_smi_lhs); 7439 __ bind(&load_smi_lhs);
7327 __ SmiToInteger64(kScratchRegister, lhs); 7440 __ push(lhs);
7328 __ push(kScratchRegister); 7441 __ FLoadSmi(Operand(rsp, 0));
7329 __ fild_d(Operand(rsp, 0)); 7442 __ addq(rsp, Immediate(kPointerSize));
7330 __ pop(kScratchRegister);
7331 __ jmp(&done_load_lhs); 7443 __ jmp(&done_load_lhs);
7332 7444
7333 __ bind(&load_smi_rhs); 7445 __ bind(&load_smi_rhs);
7334 __ SmiToInteger64(kScratchRegister, rhs); 7446 __ push(rhs);
7335 __ push(kScratchRegister); 7447 __ FLoadSmi(Operand(rsp, 0));
7336 __ fild_d(Operand(rsp, 0)); 7448 __ addq(rsp, Immediate(kPointerSize));
7337 __ pop(kScratchRegister);
7338 7449
7339 __ bind(&done); 7450 __ bind(&done);
7340 } 7451 }
7452
7453
7454 void FloatingPointHelper::LoadFloatOperands(MacroAssembler* masm,
7455 Register lhs,
7456 Register rhs,
7457 const Operand& scratch_memory) {
7458 Label load_smi_lhs, load_smi_rhs, done_load_lhs, done;
7459 __ JumpIfSmi(lhs, &load_smi_lhs);
7460 __ fld_d(FieldOperand(lhs, HeapNumber::kValueOffset));
7461 __ bind(&done_load_lhs);
7462
7463 __ JumpIfSmi(rhs, &load_smi_rhs);
7464 __ fld_d(FieldOperand(rhs, HeapNumber::kValueOffset));
7465 __ jmp(&done);
7466
7467 __ bind(&load_smi_lhs);
7468 __ movq(scratch_memory, lhs);
7469 __ FLoadSmi(scratch_memory);
7470 __ jmp(&done_load_lhs);
7471
7472 __ bind(&load_smi_rhs);
7473 __ movq(scratch_memory, rhs);
7474 __ FLoadSmi(scratch_memory);
7475
7476 __ bind(&done);
7477 }
7341 7478
7342 7479
7343 void FloatingPointHelper::CheckNumberOperands(MacroAssembler* masm, 7480 void FloatingPointHelper::CheckNumberOperands(MacroAssembler* masm,
7344 Label* non_float) { 7481 Label* non_float) {
7345 Label test_other, done; 7482 Label test_other, done;
7346 // Test if both operands are numbers (heap_numbers or smis). 7483 // Test if both operands are numbers (heap_numbers or smis).
7347 // If not, jump to label non_float. 7484 // If not, jump to label non_float.
7348 __ JumpIfSmi(rdx, &test_other); // argument in rdx is OK 7485 __ JumpIfSmi(rdx, &test_other); // argument in rdx is OK
7349 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), Factory::heap_number_map()); 7486 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), Factory::heap_number_map());
7350 __ j(not_equal, non_float); // The argument in rdx is not a number. 7487 __ j(not_equal, non_float); // The argument in rdx is not a number.
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
7692 int CompareStub::MinorKey() { 7829 int CompareStub::MinorKey() {
7693 // Encode the two parameters in a unique 16 bit value. 7830 // Encode the two parameters in a unique 16 bit value.
7694 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); 7831 ASSERT(static_cast<unsigned>(cc_) < (1 << 15));
7695 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); 7832 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0);
7696 } 7833 }
7697 7834
7698 7835
7699 #undef __ 7836 #undef __
7700 7837
7701 } } // namespace v8::internal 7838 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698