| Index: src/a64/lithium-codegen-a64.cc
|
| diff --git a/src/a64/lithium-codegen-a64.cc b/src/a64/lithium-codegen-a64.cc
|
| index 5b7a71b55311bfbd4712718514c8db82dcf9d58c..060b3a6817c1b919b3c8d5f6f40fd295652e645c 100644
|
| --- a/src/a64/lithium-codegen-a64.cc
|
| +++ b/src/a64/lithium-codegen-a64.cc
|
| @@ -617,6 +617,42 @@ bool LCodeGen::GenerateCode() {
|
| }
|
|
|
|
|
| +void LCodeGen::SaveCallerDoubles() {
|
| + ASSERT(info()->saves_caller_doubles());
|
| + ASSERT(NeedsEagerFrame());
|
| + Comment(";;; Save clobbered callee double registers");
|
| + BitVector* doubles = chunk()->allocated_double_registers();
|
| + BitVector::Iterator iterator(doubles);
|
| + int count = 0;
|
| + while (!iterator.Done()) {
|
| + // TODO(all): Is this supposed to save just the callee-saved doubles? It
|
| + // looks like it's saving all of them.
|
| + FPRegister value = FPRegister::FromAllocationIndex(iterator.Current());
|
| + __ Poke(value, count * kDoubleSize);
|
| + iterator.Advance();
|
| + count++;
|
| + }
|
| +}
|
| +
|
| +
|
| +void LCodeGen::RestoreCallerDoubles() {
|
| + ASSERT(info()->saves_caller_doubles());
|
| + ASSERT(NeedsEagerFrame());
|
| + Comment(";;; Restore clobbered callee double registers");
|
| + BitVector* doubles = chunk()->allocated_double_registers();
|
| + BitVector::Iterator iterator(doubles);
|
| + int count = 0;
|
| + while (!iterator.Done()) {
|
| + // TODO(all): Is this supposed to restore just the callee-saved doubles? It
|
| + // looks like it's restoring all of them.
|
| + FPRegister value = FPRegister::FromAllocationIndex(iterator.Current());
|
| + __ Peek(value, count * kDoubleSize);
|
| + iterator.Advance();
|
| + count++;
|
| + }
|
| +}
|
| +
|
| +
|
| bool LCodeGen::GeneratePrologue() {
|
| ASSERT(is_generating());
|
|
|
| @@ -655,17 +691,7 @@ bool LCodeGen::GeneratePrologue() {
|
| }
|
|
|
| if (info()->saves_caller_doubles()) {
|
| - Comment(";;; Save clobbered callee double registers");
|
| - ASSERT(NeedsEagerFrame());
|
| - BitVector* doubles = chunk()->allocated_double_registers();
|
| - BitVector::Iterator iterator(doubles);
|
| - int count = 0;
|
| - while (!iterator.Done()) {
|
| - FPRegister value = FPRegister::FromAllocationIndex(iterator.Current());
|
| - __ Poke(value, count * kDoubleSize);
|
| - iterator.Advance();
|
| - count++;
|
| - }
|
| + SaveCallerDoubles();
|
| }
|
|
|
| // Allocate a local context if needed.
|
| @@ -803,6 +829,7 @@ bool LCodeGen::GenerateDeoptJumpTable() {
|
| Comment(";;; jump table entry %d: deoptimization bailout %d.", i, id);
|
| }
|
| if (deopt_jump_table_[i].needs_frame) {
|
| + ASSERT(!info()->saves_caller_doubles());
|
| __ Mov(__ Tmp0(), Operand(ExternalReference::ForDeoptEntry(entry)));
|
| if (needs_frame.is_bound()) {
|
| __ B(&needs_frame);
|
| @@ -819,6 +846,10 @@ bool LCodeGen::GenerateDeoptJumpTable() {
|
| __ Call(__ Tmp0());
|
| }
|
| } else {
|
| + if (info()->saves_caller_doubles()) {
|
| + ASSERT(info()->IsStub());
|
| + RestoreCallerDoubles();
|
| + }
|
| __ Call(entry, RelocInfo::RUNTIME_ENTRY);
|
| }
|
| masm()->CheckConstPool(false, false);
|
| @@ -972,7 +1003,8 @@ void LCodeGen::Deoptimize(LEnvironment* environment,
|
|
|
|
|
| ASSERT(info()->IsStub() || frame_is_built_);
|
| - if (frame_is_built_) {
|
| + // Go through jump table if we need to build frame, or restore caller doubles.
|
| + if (frame_is_built_ && !info()->saves_caller_doubles()) {
|
| __ Call(entry, RelocInfo::RUNTIME_ENTRY);
|
| } else {
|
| // We often have several deopts to the same entry, reuse the last
|
| @@ -3709,78 +3741,6 @@ void LCodeGen::DoMathCos(LMathCos* instr) {
|
| }
|
|
|
|
|
| -// TODO(all): This will disappear when Math.random is rewritten in JavaScript.
|
| -void LCodeGen::DoRandom(LRandom* instr) {
|
| - class DeferredDoRandom: public LDeferredCode {
|
| - public:
|
| - DeferredDoRandom(LCodeGen* codegen, LRandom* instr)
|
| - : LDeferredCode(codegen), instr_(instr) { }
|
| - virtual void Generate() { codegen()->DoDeferredRandom(instr_); }
|
| - virtual LInstruction* instr() { return instr_; }
|
| -
|
| - private:
|
| - LRandom* instr_;
|
| - };
|
| -
|
| - DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr);
|
| -
|
| - // Having marked this instruction as a call we can use any registers.
|
| - ASSERT(instr->IsMarkedAsCall());
|
| - ASSERT(ToDoubleRegister(instr->result()).is(d7));
|
| - ASSERT(ToRegister(instr->global_object()).is(x0));
|
| -
|
| - static const int kSeedSize = sizeof(uint32_t);
|
| - STATIC_ASSERT(kPointerSize == 2 * kSeedSize);
|
| -
|
| - Register global_object = x0;
|
| - __ Ldr(global_object,
|
| - FieldMemOperand(global_object, GlobalObject::kNativeContextOffset));
|
| - static const int kRandomSeedOffset =
|
| - FixedArray::kHeaderSize + Context::RANDOM_SEED_INDEX * kPointerSize;
|
| - __ Ldr(x1, FieldMemOperand(global_object, kRandomSeedOffset));
|
| - // x1: FixedArray of the native context's random seeds
|
| -
|
| - // Load state[0].
|
| - __ Ldr(w2, FieldMemOperand(x1, ByteArray::kHeaderSize));
|
| - // If state[0] == 0, call runtime to initialize seeds.
|
| - __ Cbz(w2, deferred->entry());
|
| - // Load state[1].
|
| - __ Ldr(w3, FieldMemOperand(x1, ByteArray::kHeaderSize + kSeedSize));
|
| -
|
| - // state[0] = 18273 * (state[0] & 0xFFFF) + (state[0] >> 16)
|
| - __ And(w4, w2, 0xFFFF);
|
| - __ Mov(w5, 18273);
|
| - __ Mul(w5, w5, w4);
|
| - __ Add(w2, w5, Operand(w2, LSR, 16));
|
| - // Save state[0].
|
| - __ Str(w2, FieldMemOperand(x1, ByteArray::kHeaderSize));
|
| -
|
| - // state[1] = 36969 * (state[1] & 0xFFFF) + (state[1] >> 16)
|
| - __ And(w4, w3, 0xFFFF);
|
| - __ Mov(w5, 36969);
|
| - __ Mul(w5, w5, w4);
|
| - __ Add(w3, w5, Operand(w3, LSR, 16));
|
| - // Save state[1].
|
| - __ Str(w3, FieldMemOperand(x1, ByteArray::kHeaderSize + kSeedSize));
|
| -
|
| - // Random bit pattern = (state[0] << 14) + (state[1] & 0x3FFFF)
|
| - __ And(w3, w3, 0x3FFFF);
|
| - __ Add(w0, w3, Operand(w2, LSL, 14));
|
| -
|
| - __ Bind(deferred->exit());
|
| - // Interpret the 32 random bits as a 0.32 fixed point number, and convert to
|
| - // a double in the range 0.0 <= number < 1.0.
|
| - __ Ucvtf(d7, w0, 32);
|
| -}
|
| -
|
| -
|
| -// TODO(all): This will disappear when Math.random is rewritten in JavaScript.
|
| -void LCodeGen::DoDeferredRandom(LRandom* instr) {
|
| - __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1);
|
| - // Return value is in x0.
|
| -}
|
| -
|
| -
|
| void LCodeGen::DoMathExp(LMathExp* instr) {
|
| DoubleRegister input = ToDoubleRegister(instr->value());
|
| DoubleRegister result = ToDoubleRegister(instr->result());
|
| @@ -4482,16 +4442,7 @@ void LCodeGen::DoReturn(LReturn* instr) {
|
| }
|
|
|
| if (info()->saves_caller_doubles()) {
|
| - ASSERT(NeedsEagerFrame());
|
| - BitVector* doubles = chunk()->allocated_double_registers();
|
| - BitVector::Iterator iterator(doubles);
|
| - int count = 0;
|
| - while (!iterator.Done()) {
|
| - FPRegister value = FPRegister::FromAllocationIndex(iterator.Current());
|
| - __ Peek(value, count * kDoubleSize);
|
| - iterator.Advance();
|
| - count++;
|
| - }
|
| + RestoreCallerDoubles();
|
| }
|
|
|
| int no_frame_start = -1;
|
|
|