// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_IA32_LITHIUM_CODEGEN_IA32_H_
#define V8_IA32_LITHIUM_CODEGEN_IA32_H_
-#include "ia32/lithium-ia32.h"
+#include "src/ia32/lithium-ia32.h"
-#include "checks.h"
-#include "deoptimizer.h"
-#include "ia32/lithium-gap-resolver-ia32.h"
-#include "lithium-codegen.h"
-#include "safepoint-table.h"
-#include "scopes.h"
-#include "v8utils.h"
+#include "src/base/logging.h"
+#include "src/deoptimizer.h"
+#include "src/ia32/lithium-gap-resolver-ia32.h"
+#include "src/lithium-codegen.h"
+#include "src/safepoint-table.h"
+#include "src/scopes.h"
+#include "src/utils.h"
namespace v8 {
namespace internal {
support_aligned_spilled_doubles_(false),
osr_pc_offset_(-1),
frame_is_built_(false),
- x87_stack_(assembler),
safepoints_(info->zone()),
resolver_(this),
expected_safepoint_kind_(Safepoint::kSimple) {
Operand ToOperand(LOperand* op) const;
Register ToRegister(LOperand* op) const;
XMMRegister ToDoubleRegister(LOperand* op) const;
- XMMRegister ToFloat32x4Register(LOperand* op) const;
- XMMRegister ToInt32x4Register(LOperand* op) const;
- XMMRegister ToSIMD128Register(LOperand* op) const;
- X87Register ToX87Register(LOperand* op) const;
bool IsInteger32(LConstantOperand* op) const;
bool IsSmi(LConstantOperand* op) const;
}
double ToDouble(LConstantOperand* op) const;
- // Support for non-sse2 (x87) floating point stack handling.
- // These functions maintain the mapping of physical stack registers to our
- // virtual registers between instructions.
- enum X87OperandType { kX87DoubleOperand, kX87FloatOperand, kX87IntOperand };
-
- void X87Mov(X87Register reg, Operand src,
- X87OperandType operand = kX87DoubleOperand);
- void X87Mov(Operand src, X87Register reg,
- X87OperandType operand = kX87DoubleOperand);
-
- void X87PrepareBinaryOp(
- X87Register left, X87Register right, X87Register result);
-
- void X87LoadForUsage(X87Register reg);
- void X87LoadForUsage(X87Register reg1, X87Register reg2);
- void X87PrepareToWrite(X87Register reg) { x87_stack_.PrepareToWrite(reg); }
- void X87CommitWrite(X87Register reg) { x87_stack_.CommitWrite(reg); }
-
- void X87Fxch(X87Register reg, int other_slot = 0) {
- x87_stack_.Fxch(reg, other_slot);
- }
- void X87Free(X87Register reg) {
- x87_stack_.Free(reg);
- }
-
-
- bool X87StackEmpty() {
- return x87_stack_.depth() == 0;
- }
-
Handle<Object> ToHandle(LConstantOperand* op) const;
// The operand denoting the second word (the one with a higher address) of
enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 };
void DoDeferredNumberTagIU(LInstruction* instr,
LOperand* value,
- LOperand* temp1,
- LOperand* temp2,
+ LOperand* temp,
IntegerSignedness signedness);
void DoDeferredTaggedToI(LTaggedToI* instr, Label* done);
- void DoDeferredFloat32x4ToTagged(LInstruction* instr);
- void DoDeferredInt32x4ToTagged(LInstruction* instr);
void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr);
void DoDeferredStackCheck(LStackCheck* instr);
void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
Label* map_check);
void DoDeferredInstanceMigration(LCheckMaps* instr, Register object);
- void DoDeferredSIMD128ToTagged(LInstruction* instr, Runtime::FunctionId id);
-
- template<class T>
- void HandleTaggedToSIMD128(LTaggedToSIMD128* instr);
- template<class T>
- void HandleSIMD128ToTagged(LSIMD128ToTagged* instr);
+ void DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr,
+ Register object,
+ Register index);
// Parallel move support.
void DoParallelMove(LParallelMove* move);
int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
- void Abort(BailoutReason reason);
-
void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }
void SaveCallerDoubles();
// Code generation passes. Returns true if code generation should
// continue.
- void GenerateBodyInstructionPre(LInstruction* instr) V8_OVERRIDE;
- void GenerateBodyInstructionPost(LInstruction* instr) V8_OVERRIDE;
+ void GenerateBodyInstructionPre(LInstruction* instr) OVERRIDE;
+ void GenerateBodyInstructionPost(LInstruction* instr) OVERRIDE;
bool GeneratePrologue();
bool GenerateDeferredCode();
bool GenerateJumpTable();
void RegisterEnvironmentForDeoptimization(LEnvironment* environment,
Safepoint::DeoptMode mode);
- void DeoptimizeIf(Condition cc,
- LEnvironment* environment,
+ void DeoptimizeIf(Condition cc, LInstruction* instr, const char* detail,
Deoptimizer::BailoutType bailout_type);
- void DeoptimizeIf(Condition cc, LEnvironment* environment);
- void ApplyCheckIf(Condition cc, LBoundsCheck* check);
+ void DeoptimizeIf(Condition cc, LInstruction* instr, const char* detail);
bool DeoptEveryNTimes() {
return FLAG_deopt_every_n_times != 0 && !info()->IsStub();
Register ToRegister(int index) const;
XMMRegister ToDoubleRegister(int index) const;
- XMMRegister ToFloat32x4Register(int index) const;
- XMMRegister ToInt32x4Register(int index) const;
- XMMRegister ToSIMD128Register(int index) const;
- X87Register ToX87Register(int index) const;
int32_t ToRepresentation(LConstantOperand* op, const Representation& r) const;
int32_t ToInteger32(LConstantOperand* op) const;
ExternalReference ToExternalReference(LConstantOperand* op) const;
LOperand* key,
Representation key_representation,
ElementsKind elements_kind,
- uint32_t offset,
- uint32_t additional_index = 0);
+ uint32_t base_offset);
Operand BuildSeqStringOperand(Register string,
LOperand* index,
int arguments,
Safepoint::DeoptMode mode);
- void RecordAndWritePosition(int position) V8_OVERRIDE;
+ void RecordAndWritePosition(int position) OVERRIDE;
static Condition TokenToCondition(Token::Value op, bool is_unsigned);
void EmitGoto(int block);
void EmitBranch(InstrType instr, Condition cc);
template<class InstrType>
void EmitFalseBranch(InstrType instr, Condition cc);
- void EmitNumberUntagD(
- Register input,
- Register temp,
- XMMRegister result,
- bool allow_undefined_as_nan,
- bool deoptimize_on_minus_zero,
- LEnvironment* env,
- NumberUntagDMode mode = NUMBER_CANDIDATE_IS_ANY_TAGGED);
-
- void EmitNumberUntagDNoSSE2(
- Register input,
- Register temp,
- X87Register res_reg,
- bool allow_undefined_as_nan,
- bool deoptimize_on_minus_zero,
- LEnvironment* env,
- NumberUntagDMode mode = NUMBER_CANDIDATE_IS_ANY_TAGGED);
+ void EmitNumberUntagD(LNumberUntagD* instr, Register input, Register temp,
+ XMMRegister result, NumberUntagDMode mode);
// Emits optimized code for typeof x == "y". Modifies input register.
// Returns the condition on which a final split to
int* offset,
AllocationSiteMode mode);
- void EnsureSpaceForLazyDeopt(int space_needed) V8_OVERRIDE;
+ void EnsureSpaceForLazyDeopt(int space_needed) OVERRIDE;
void DoLoadKeyedExternalArray(LLoadKeyed* instr);
- void HandleExternalArrayOpRequiresTemp(LOperand* key,
- Representation key_representation,
- ElementsKind elements_kind);
- template<class T>
- void DoLoadKeyedSIMD128ExternalArray(LLoadKeyed* instr);
void DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr);
void DoLoadKeyedFixedArray(LLoadKeyed* instr);
void DoStoreKeyedExternalArray(LStoreKeyed* instr);
- template<class T>
- void DoStoreKeyedSIMD128ExternalArray(LStoreKeyed* instr);
void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr);
void DoStoreKeyedFixedArray(LStoreKeyed* instr);
+ template <class T>
+ void EmitVectorLoadICRegisters(T* instr);
+
void EmitReturn(LReturn* instr, bool dynamic_frame_alignment);
// Emits code for pushing either a tagged constant, a (non-double)
// register, or a stack slot operand.
void EmitPushTaggedOperand(LOperand* operand);
- void X87Fld(Operand src, X87OperandType opts);
-
- void EmitFlushX87ForDeopt();
- void FlushX87StackIfNecessary(LInstruction* instr) {
- x87_stack_.FlushIfNecessary(instr, this);
- }
friend class LGapResolver;
#ifdef _MSC_VER
int osr_pc_offset_;
bool frame_is_built_;
- class X87Stack {
- public:
- explicit X87Stack(MacroAssembler* masm)
- : stack_depth_(0), is_mutable_(true), masm_(masm) { }
- explicit X87Stack(const X87Stack& other)
- : stack_depth_(other.stack_depth_), is_mutable_(false), masm_(masm()) {
- for (int i = 0; i < stack_depth_; i++) {
- stack_[i] = other.stack_[i];
- }
- }
- bool operator==(const X87Stack& other) const {
- if (stack_depth_ != other.stack_depth_) return false;
- for (int i = 0; i < stack_depth_; i++) {
- if (!stack_[i].is(other.stack_[i])) return false;
- }
- return true;
- }
- bool Contains(X87Register reg);
- void Fxch(X87Register reg, int other_slot = 0);
- void Free(X87Register reg);
- void PrepareToWrite(X87Register reg);
- void CommitWrite(X87Register reg);
- void FlushIfNecessary(LInstruction* instr, LCodeGen* cgen);
- void LeavingBlock(int current_block_id, LGoto* goto_instr);
- int depth() const { return stack_depth_; }
- void pop() {
- ASSERT(is_mutable_);
- stack_depth_--;
- }
- void push(X87Register reg) {
- ASSERT(is_mutable_);
- ASSERT(stack_depth_ < X87Register::kNumAllocatableRegisters);
- stack_[stack_depth_] = reg;
- stack_depth_++;
- }
-
- MacroAssembler* masm() const { return masm_; }
-
- private:
- int ArrayIndex(X87Register reg);
- int st2idx(int pos);
-
- X87Register stack_[X87Register::kNumAllocatableRegisters];
- int stack_depth_;
- bool is_mutable_;
- MacroAssembler* masm_;
- };
- X87Stack x87_stack_;
-
// Builder that keeps track of safepoints in the code. The table
// itself is emitted at the end of the generated code.
SafepointTableBuilder safepoints_;
Safepoint::Kind expected_safepoint_kind_;
- class PushSafepointRegistersScope V8_FINAL BASE_EMBEDDED {
+ class PushSafepointRegistersScope FINAL BASE_EMBEDDED {
public:
explicit PushSafepointRegistersScope(LCodeGen* codegen)
: codegen_(codegen) {
- ASSERT(codegen_->expected_safepoint_kind_ == Safepoint::kSimple);
+ DCHECK(codegen_->expected_safepoint_kind_ == Safepoint::kSimple);
codegen_->masm_->PushSafepointRegisters();
codegen_->expected_safepoint_kind_ = Safepoint::kWithRegisters;
- ASSERT(codegen_->info()->is_calling());
+ DCHECK(codegen_->info()->is_calling());
}
~PushSafepointRegistersScope() {
- ASSERT(codegen_->expected_safepoint_kind_ == Safepoint::kWithRegisters);
+ DCHECK(codegen_->expected_safepoint_kind_ == Safepoint::kWithRegisters);
codegen_->masm_->PopSafepointRegisters();
codegen_->expected_safepoint_kind_ = Safepoint::kSimple;
}
class LDeferredCode : public ZoneObject {
public:
- explicit LDeferredCode(LCodeGen* codegen, const LCodeGen::X87Stack& x87_stack)
+ explicit LDeferredCode(LCodeGen* codegen)
: codegen_(codegen),
external_exit_(NULL),
- instruction_index_(codegen->current_instruction_),
- x87_stack_(x87_stack) {
+ instruction_index_(codegen->current_instruction_) {
codegen->AddDeferredCode(this);
}
Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; }
Label* done() { return codegen_->NeedsDeferredFrame() ? &done_ : exit(); }
int instruction_index() const { return instruction_index_; }
- const LCodeGen::X87Stack& x87_stack() const { return x87_stack_; }
protected:
LCodeGen* codegen() const { return codegen_; }
Label* external_exit_;
Label done_;
int instruction_index_;
- LCodeGen::X87Stack x87_stack_;
};
} } // namespace v8::internal