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

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

Issue 119420: Fix fp code for mixed-endian ARM. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | src/objects.h » ('j') | src/objects.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-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 4385 matching lines...) Expand 10 before | Expand all | Expand 10 after
4396 4396
4397 const char* GetName() { return "ConvertToDoubleStub"; } 4397 const char* GetName() { return "ConvertToDoubleStub"; }
4398 4398
4399 #ifdef DEBUG 4399 #ifdef DEBUG
4400 void Print() { PrintF("ConvertToDoubleStub\n"); } 4400 void Print() { PrintF("ConvertToDoubleStub\n"); }
4401 #endif 4401 #endif
4402 }; 4402 };
4403 4403
4404 4404
4405 void ConvertToDoubleStub::Generate(MacroAssembler* masm) { 4405 void ConvertToDoubleStub::Generate(MacroAssembler* masm) {
4406 Label not_special, done; 4406 #ifndef BIG_ENDIAN_FLOATING_POINT
4407 Register exponent = result1_;
4408 Register mantissa = result2_;
4409 #else
4410 Register exponent = result2_;
4411 Register mantissa = result1_;
4412 #endif
4413 Label not_special;
4407 // Convert from Smi to integer. 4414 // Convert from Smi to integer.
4408 __ mov(source_, Operand(source_, ASR, kSmiTagSize)); 4415 __ mov(source_, Operand(source_, ASR, kSmiTagSize));
4409 // Move sign bit from source to destination. This works because the sign bit 4416 // Move sign bit from source to destination. This works because the sign bit
4410 // in the exponent word of the double has the same position and polarity as 4417 // in the exponent word of the double has the same position and polarity as
4411 // the 2's complement sign bit in a Smi. 4418 // the 2's complement sign bit in a Smi.
4412 ASSERT(HeapNumber::kSignMask == 0x80000000u); 4419 ASSERT(HeapNumber::kSignMask == 0x80000000u);
4413 __ and_(result1_, source_, Operand(HeapNumber::kSignMask), SetCC); 4420 __ and_(exponent, source_, Operand(HeapNumber::kSignMask), SetCC);
4414 // Subtract from 0 if source was negative. 4421 // Subtract from 0 if source was negative.
4415 __ rsb(source_, source_, Operand(0), LeaveCC, ne); 4422 __ rsb(source_, source_, Operand(0), LeaveCC, ne);
4416 __ cmp(source_, Operand(1)); 4423 __ cmp(source_, Operand(1));
4417 __ b(gt, &not_special); 4424 __ b(gt, &not_special);
4418 4425
4419 // We have -1, 0 or 1, which we treat specially. 4426 // We have -1, 0 or 1, which we treat specially.
4420 __ cmp(source_, Operand(0)); 4427 __ cmp(source_, Operand(0));
4421 // For 1 or -1 we need to or in the 0 exponent (biased to 1023). 4428 // For 1 or -1 we need to or in the 0 exponent (biased to 1023).
4422 static const uint32_t exponent_word_for_1 = 4429 static const uint32_t exponent_word_for_1 =
4423 HeapNumber::kExponentBias << HeapNumber::kExponentShift; 4430 HeapNumber::kExponentBias << HeapNumber::kExponentShift;
4424 __ orr(result1_, result1_, Operand(exponent_word_for_1), LeaveCC, ne); 4431 __ orr(exponent, exponent, Operand(exponent_word_for_1), LeaveCC, ne);
4425 // 1, 0 and -1 all have 0 for the second word. 4432 // 1, 0 and -1 all have 0 for the second word.
4426 __ mov(result2_, Operand(0)); 4433 __ mov(mantissa, Operand(0));
4427 __ jmp(&done); 4434 __ Ret();
4428 4435
4429 __ bind(&not_special); 4436 __ bind(&not_special);
4430 // Count leading zeros. Uses result2 for a scratch register on pre-ARM5. 4437 // Count leading zeros. Uses result2 for a scratch register on pre-ARM5.
4431 // Gets the wrong answer for 0, but we already checked for that case above. 4438 // Gets the wrong answer for 0, but we already checked for that case above.
4432 CountLeadingZeros(masm, source_, result2_, zeros_); 4439 CountLeadingZeros(masm, source_, mantissa, zeros_);
4433 // Compute exponent and or it into the exponent register. 4440 // Compute exponent and or it into the exponent register.
4434 // We use result2 as a scratch register here. 4441 // We use result2 as a scratch register here.
4435 __ rsb(result2_, zeros_, Operand(31 + HeapNumber::kExponentBias)); 4442 __ rsb(mantissa, zeros_, Operand(31 + HeapNumber::kExponentBias));
4436 __ orr(result1_, 4443 __ orr(exponent,
4437 result1_, 4444 exponent,
4438 Operand(result2_, LSL, HeapNumber::kExponentShift)); 4445 Operand(mantissa, LSL, HeapNumber::kExponentShift));
4439 // Shift up the source chopping the top bit off. 4446 // Shift up the source chopping the top bit off.
4440 __ add(zeros_, zeros_, Operand(1)); 4447 __ add(zeros_, zeros_, Operand(1));
4441 // This wouldn't work for 1.0 or -1.0 as the shift would be 32 which means 0. 4448 // This wouldn't work for 1.0 or -1.0 as the shift would be 32 which means 0.
4442 __ mov(source_, Operand(source_, LSL, zeros_)); 4449 __ mov(source_, Operand(source_, LSL, zeros_));
4443 // Compute lower part of fraction (last 12 bits). 4450 // Compute lower part of fraction (last 12 bits).
4444 __ mov(result2_, Operand(source_, LSL, HeapNumber::kMantissaBitsInTopWord)); 4451 __ mov(mantissa, Operand(source_, LSL, HeapNumber::kMantissaBitsInTopWord));
4445 // And the top (top 20 bits). 4452 // And the top (top 20 bits).
4446 __ orr(result1_, 4453 __ orr(exponent,
4447 result1_, 4454 exponent,
4448 Operand(source_, LSR, 32 - HeapNumber::kMantissaBitsInTopWord)); 4455 Operand(source_, LSR, 32 - HeapNumber::kMantissaBitsInTopWord));
4449 __ bind(&done);
4450 __ Ret(); 4456 __ Ret();
4451 } 4457 }
4452 4458
4453 4459
4454 // This stub can convert a signed int32 to a heap number (double). It does 4460 // This stub can convert a signed int32 to a heap number (double). It does
4455 // not work for int32s that are in Smi range! No GC occurs during this stub 4461 // not work for int32s that are in Smi range! No GC occurs during this stub
4456 // so you don't have to set up the frame. 4462 // so you don't have to set up the frame.
4457 class WriteInt32ToHeapNumberStub : public CodeStub { 4463 class WriteInt32ToHeapNumberStub : public CodeStub {
4458 public: 4464 public:
4459 WriteInt32ToHeapNumberStub(Register the_int, 4465 WriteInt32ToHeapNumberStub(Register the_int,
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
4620 4626
4621 // Move r0 to a double in r2-r3. 4627 // Move r0 to a double in r2-r3.
4622 __ tst(r0, Operand(kSmiTagMask)); 4628 __ tst(r0, Operand(kSmiTagMask));
4623 __ b(eq, &r0_is_smi); // It's a Smi so don't check it's a heap number. 4629 __ b(eq, &r0_is_smi); // It's a Smi so don't check it's a heap number.
4624 __ CompareObjectType(r0, r4, r4, HEAP_NUMBER_TYPE); 4630 __ CompareObjectType(r0, r4, r4, HEAP_NUMBER_TYPE);
4625 __ b(ne, &slow); 4631 __ b(ne, &slow);
4626 if (mode == OVERWRITE_RIGHT) { 4632 if (mode == OVERWRITE_RIGHT) {
4627 __ mov(r5, Operand(r0)); // Overwrite this heap number. 4633 __ mov(r5, Operand(r0)); // Overwrite this heap number.
4628 } 4634 }
4629 // Calling convention says that second double is in r2 and r3. 4635 // Calling convention says that second double is in r2 and r3.
4630 __ ldr(r2, FieldMemOperand(r0, HeapNumber::kMantissaOffset)); 4636 __ ldr(r2, FieldMemOperand(r0, HeapNumber::kValueOffset));
4631 __ ldr(r3, FieldMemOperand(r0, HeapNumber::kExponentOffset)); 4637 __ ldr(r3, FieldMemOperand(r0, HeapNumber::kValueOffset + 4));
4632 __ jmp(&finished_loading_r0); 4638 __ jmp(&finished_loading_r0);
4633 __ bind(&r0_is_smi); 4639 __ bind(&r0_is_smi);
4634 if (mode == OVERWRITE_RIGHT) { 4640 if (mode == OVERWRITE_RIGHT) {
4635 // We can't overwrite a Smi so get address of new heap number into r5. 4641 // We can't overwrite a Smi so get address of new heap number into r5.
4636 AllocateHeapNumber(masm, &slow, r5, r6, r7); 4642 AllocateHeapNumber(masm, &slow, r5, r6, r7);
4637 } 4643 }
4638 // Write Smi from r0 to r3 and r2 in double format. 4644 // Write Smi from r0 to r3 and r2 in double format.
4639 __ mov(r7, Operand(r0)); 4645 __ mov(r7, Operand(r0));
4640 ConvertToDoubleStub stub3(r3, r2, r7, r6); 4646 ConvertToDoubleStub stub3(r3, r2, r7, r6);
4641 __ push(lr); 4647 __ push(lr);
4642 __ Call(stub3.GetCode(), RelocInfo::CODE_TARGET); 4648 __ Call(stub3.GetCode(), RelocInfo::CODE_TARGET);
4643 __ pop(lr); 4649 __ pop(lr);
4644 __ bind(&finished_loading_r0); 4650 __ bind(&finished_loading_r0);
4645 4651
4646 // Move r1 to a double in r0-r1. 4652 // Move r1 to a double in r0-r1.
4647 __ tst(r1, Operand(kSmiTagMask)); 4653 __ tst(r1, Operand(kSmiTagMask));
4648 __ b(eq, &r1_is_smi); // It's a Smi so don't check it's a heap number. 4654 __ b(eq, &r1_is_smi); // It's a Smi so don't check it's a heap number.
4649 __ CompareObjectType(r1, r4, r4, HEAP_NUMBER_TYPE); 4655 __ CompareObjectType(r1, r4, r4, HEAP_NUMBER_TYPE);
4650 __ b(ne, &slow); 4656 __ b(ne, &slow);
4651 if (mode == OVERWRITE_LEFT) { 4657 if (mode == OVERWRITE_LEFT) {
4652 __ mov(r5, Operand(r1)); // Overwrite this heap number. 4658 __ mov(r5, Operand(r1)); // Overwrite this heap number.
4653 } 4659 }
4654 // Calling convention says that first double is in r0 and r1. 4660 // Calling convention says that first double is in r0 and r1.
4655 __ ldr(r0, FieldMemOperand(r1, HeapNumber::kMantissaOffset)); 4661 __ ldr(r0, FieldMemOperand(r1, HeapNumber::kValueOffset));
4656 __ ldr(r1, FieldMemOperand(r1, HeapNumber::kExponentOffset)); 4662 __ ldr(r1, FieldMemOperand(r1, HeapNumber::kValueOffset + 4));
4657 __ jmp(&finished_loading_r1); 4663 __ jmp(&finished_loading_r1);
4658 __ bind(&r1_is_smi); 4664 __ bind(&r1_is_smi);
4659 if (mode == OVERWRITE_LEFT) { 4665 if (mode == OVERWRITE_LEFT) {
4660 // We can't overwrite a Smi so get address of new heap number into r5. 4666 // We can't overwrite a Smi so get address of new heap number into r5.
4661 AllocateHeapNumber(masm, &slow, r5, r6, r7); 4667 AllocateHeapNumber(masm, &slow, r5, r6, r7);
4662 } 4668 }
4663 // Write Smi from r1 to r1 and r0 in double format. 4669 // Write Smi from r1 to r1 and r0 in double format.
4664 __ mov(r7, Operand(r1)); 4670 __ mov(r7, Operand(r1));
4665 ConvertToDoubleStub stub4(r1, r0, r7, r6); 4671 ConvertToDoubleStub stub4(r1, r0, r7, r6);
4666 __ push(lr); 4672 __ push(lr);
(...skipping 15 matching lines...) Expand all
4682 // Store answer in the overwritable heap number. 4688 // Store answer in the overwritable heap number.
4683 __ pop(r4); 4689 __ pop(r4);
4684 #if !defined(USE_ARM_EABI) 4690 #if !defined(USE_ARM_EABI)
4685 // Double returned in fp coprocessor register 0 and 1, encoded as register 4691 // Double returned in fp coprocessor register 0 and 1, encoded as register
4686 // cr8. Offsets must be divisible by 4 for coprocessor so we need to 4692 // cr8. Offsets must be divisible by 4 for coprocessor so we need to
4687 // substract the tag from r4. 4693 // substract the tag from r4.
4688 __ sub(r5, r4, Operand(kHeapObjectTag)); 4694 __ sub(r5, r4, Operand(kHeapObjectTag));
4689 __ stc(p1, cr8, MemOperand(r5, HeapNumber::kValueOffset)); 4695 __ stc(p1, cr8, MemOperand(r5, HeapNumber::kValueOffset));
4690 #else 4696 #else
4691 // Double returned in registers 0 and 1. 4697 // Double returned in registers 0 and 1.
4692 __ str(r0, FieldMemOperand(r4, HeapNumber::kMantissaOffset)); 4698 __ str(r0, FieldMemOperand(r4, HeapNumber::kValueOffset));
4693 __ str(r1, FieldMemOperand(r4, HeapNumber::kExponentOffset)); 4699 __ str(r1, FieldMemOperand(r4, HeapNumber::kValueOffset + 4));
4694 #endif 4700 #endif
4695 __ mov(r0, Operand(r4)); 4701 __ mov(r0, Operand(r4));
4696 // And we are done. 4702 // And we are done.
4697 __ pop(pc); 4703 __ pop(pc);
4698 } 4704 }
4699 4705
4700 4706
4701 // Tries to get a signed int32 out of a double precision floating point heap 4707 // Tries to get a signed int32 out of a double precision floating point heap
4702 // number. Rounds towards 0. Only succeeds for doubles that are in the ranges 4708 // number. Rounds towards 0. Only succeeds for doubles that are in the ranges
4703 // -0x7fffffff to -0x40000000 or 0x40000000 to 0x7fffffff. This corresponds 4709 // -0x7fffffff to -0x40000000 or 0x40000000 to 0x7fffffff. This corresponds
(...skipping 946 matching lines...) Expand 10 before | Expand all | Expand 10 after
5650 __ mov(r2, Operand(0)); 5656 __ mov(r2, Operand(0));
5651 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); 5657 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION);
5652 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), 5658 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)),
5653 RelocInfo::CODE_TARGET); 5659 RelocInfo::CODE_TARGET);
5654 } 5660 }
5655 5661
5656 5662
5657 #undef __ 5663 #undef __
5658 5664
5659 } } // namespace v8::internal 5665 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/objects.h » ('j') | src/objects.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698