17d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Copyright 2014 the V8 project authors. All rights reserved.
27d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be
37d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// found in the LICENSE file.
47d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
57d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#ifndef V8_COMPILER_FRAME_H_
67d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#define V8_COMPILER_FRAME_H_
77d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
87d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/v8.h"
97d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/data-flow.h"
117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace v8 {
137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace internal {
147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace compiler {
157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Collects the spill slot requirements and the allocated general and double
177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// registers for a compiled function. Frames are usually populated by the
187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// register allocator and are used by Linkage to generate code for the prologue
197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// and epilogue to compiled code.
207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass Frame {
217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public:
227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Frame()
237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      : register_save_area_size_(0),
247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        spill_slot_count_(0),
257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        double_spill_slot_count_(0),
267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        allocated_registers_(NULL),
277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        allocated_double_registers_(NULL) {}
287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  inline int GetSpillSlotCount() { return spill_slot_count_; }
307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  inline int GetDoubleSpillSlotCount() { return double_spill_slot_count_; }
317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void SetAllocatedRegisters(BitVector* regs) {
33e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(allocated_registers_ == NULL);
347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    allocated_registers_ = regs;
357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void SetAllocatedDoubleRegisters(BitVector* regs) {
38e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(allocated_double_registers_ == NULL);
397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    allocated_double_registers_ = regs;
407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  bool DidAllocateDoubleRegisters() {
437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return !allocated_double_registers_->IsEmpty();
447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void SetRegisterSaveAreaSize(int size) {
47e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(IsAligned(size, kPointerSize));
487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    register_save_area_size_ = size;
497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int GetRegisterSaveAreaSize() { return register_save_area_size_; }
527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int AllocateSpillSlot(bool is_double) {
547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    // If 32-bit, skip one if the new slot is a double.
557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    if (is_double) {
567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (kDoubleSize > kPointerSize) {
57e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(kDoubleSize == kPointerSize * 2);
587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        spill_slot_count_++;
597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        spill_slot_count_ |= 1;
607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      double_spill_slot_count_++;
627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return spill_slot_count_++;
647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org private:
677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int register_save_area_size_;
687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int spill_slot_count_;
697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int double_spill_slot_count_;
707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  BitVector* allocated_registers_;
717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  BitVector* allocated_double_registers_;
727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org};
737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Represents an offset from either the stack pointer or frame pointer.
767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass FrameOffset {
777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public:
787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  inline bool from_stack_pointer() { return (offset_ & 1) == kFromSp; }
797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  inline bool from_frame_pointer() { return (offset_ & 1) == kFromFp; }
807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  inline int offset() { return offset_ & ~1; }
817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  inline static FrameOffset FromStackPointer(int offset) {
83e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK((offset & 1) == 0);
847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return FrameOffset(offset | kFromSp);
857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  inline static FrameOffset FromFramePointer(int offset) {
88e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK((offset & 1) == 0);
897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return FrameOffset(offset | kFromFp);
907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org private:
937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  explicit FrameOffset(int offset) : offset_(offset) {}
947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int offset_;  // Encodes SP or FP in the low order bit.
967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  static const int kFromSp = 1;
987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  static const int kFromFp = 0;
997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org};
1007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
1017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
1027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}  // namespace v8::internal::compiler
1037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#endif  // V8_COMPILER_FRAME_H_
105