| Index: src/x87/lithium-codegen-x87.h
|
| diff --git a/src/ia32/lithium-codegen-ia32.h b/src/x87/lithium-codegen-x87.h
|
| similarity index 80%
|
| copy from src/ia32/lithium-codegen-ia32.h
|
| copy to src/x87/lithium-codegen-x87.h
|
| index d5a192ebba5c686d12638eab6bc02590f418cbd7..ed74b929ed23cd6e6bdf5296d0e8187c47894796 100644
|
| --- a/src/ia32/lithium-codegen-ia32.h
|
| +++ b/src/x87/lithium-codegen-x87.h
|
| @@ -2,14 +2,14 @@
|
| // 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_
|
| +#ifndef V8_X87_LITHIUM_CODEGEN_X87_H_
|
| +#define V8_X87_LITHIUM_CODEGEN_X87_H_
|
|
|
| -#include "ia32/lithium-ia32.h"
|
| +#include "x87/lithium-x87.h"
|
|
|
| #include "checks.h"
|
| #include "deoptimizer.h"
|
| -#include "ia32/lithium-gap-resolver-ia32.h"
|
| +#include "x87/lithium-gap-resolver-x87.h"
|
| #include "lithium-codegen.h"
|
| #include "safepoint-table.h"
|
| #include "scopes.h"
|
| @@ -38,6 +38,7 @@ class LCodeGen: public LCodeGenBase {
|
| 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) {
|
| @@ -65,7 +66,7 @@ class LCodeGen: public LCodeGenBase {
|
| // Support for converting LOperands to assembler types.
|
| Operand ToOperand(LOperand* op) const;
|
| Register ToRegister(LOperand* op) const;
|
| - XMMRegister ToDoubleRegister(LOperand* op) const;
|
| + X87Register ToX87Register(LOperand* op) const;
|
|
|
| bool IsInteger32(LConstantOperand* op) const;
|
| bool IsSmi(LConstantOperand* op) const;
|
| @@ -74,6 +75,36 @@ class LCodeGen: public LCodeGenBase {
|
| }
|
| 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
|
| @@ -95,8 +126,7 @@ class LCodeGen: public LCodeGenBase {
|
| 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);
|
| @@ -131,8 +161,6 @@ class LCodeGen: public LCodeGenBase {
|
|
|
| Scope* scope() const { return scope_; }
|
|
|
| - XMMRegister double_scratch0() const { return xmm0; }
|
| -
|
| void EmitClassOfTest(Label* if_true,
|
| Label* if_false,
|
| Handle<String> class_name,
|
| @@ -144,9 +172,6 @@ class LCodeGen: public LCodeGenBase {
|
|
|
| void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }
|
|
|
| - void SaveCallerDoubles();
|
| - void RestoreCallerDoubles();
|
| -
|
| // Code generation passes. Returns true if code generation should
|
| // continue.
|
| void GenerateBodyInstructionPre(LInstruction* instr) V8_OVERRIDE;
|
| @@ -175,8 +200,7 @@ class LCodeGen: public LCodeGenBase {
|
|
|
| void CallRuntime(const Runtime::Function* fun,
|
| int argc,
|
| - LInstruction* instr,
|
| - SaveFPRegsMode save_doubles = kDontSaveFPRegs);
|
| + LInstruction* instr);
|
|
|
| void CallRuntime(Runtime::FunctionId id,
|
| int argc,
|
| @@ -232,7 +256,7 @@ class LCodeGen: public LCodeGenBase {
|
| void PopulateDeoptimizationLiteralsWithInlinedFunctions();
|
|
|
| Register ToRegister(int index) const;
|
| - XMMRegister ToDoubleRegister(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;
|
| @@ -270,10 +294,10 @@ class LCodeGen: public LCodeGenBase {
|
| void EmitBranch(InstrType instr, Condition cc);
|
| template<class InstrType>
|
| void EmitFalseBranch(InstrType instr, Condition cc);
|
| - void EmitNumberUntagD(
|
| + void EmitNumberUntagDNoSSE2(
|
| Register input,
|
| Register temp,
|
| - XMMRegister result,
|
| + X87Register res_reg,
|
| bool allow_undefined_as_nan,
|
| bool deoptimize_on_minus_zero,
|
| LEnvironment* env,
|
| @@ -326,6 +350,12 @@ class LCodeGen: public LCodeGenBase {
|
| // 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
|
| @@ -348,6 +378,56 @@ class LCodeGen: public LCodeGenBase {
|
| 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::kMaxNumAllocatableRegisters);
|
| + stack_[stack_depth_] = reg;
|
| + stack_depth_++;
|
| + }
|
| +
|
| + MacroAssembler* masm() const { return masm_; }
|
| + Isolate* isolate() const { return masm_->isolate(); }
|
| +
|
| + private:
|
| + int ArrayIndex(X87Register reg);
|
| + int st2idx(int pos);
|
| +
|
| + X87Register stack_[X87Register::kMaxNumAllocatableRegisters];
|
| + 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_;
|
| @@ -386,10 +466,11 @@ class LCodeGen: public LCodeGenBase {
|
|
|
| class LDeferredCode : public ZoneObject {
|
| public:
|
| - explicit LDeferredCode(LCodeGen* codegen)
|
| + explicit LDeferredCode(LCodeGen* codegen, const LCodeGen::X87Stack& x87_stack)
|
| : codegen_(codegen),
|
| external_exit_(NULL),
|
| - instruction_index_(codegen->current_instruction_) {
|
| + instruction_index_(codegen->current_instruction_),
|
| + x87_stack_(x87_stack) {
|
| codegen->AddDeferredCode(this);
|
| }
|
|
|
| @@ -402,6 +483,7 @@ class LDeferredCode : public ZoneObject {
|
| 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_; }
|
| @@ -414,8 +496,9 @@ class LDeferredCode : public ZoneObject {
|
| Label* external_exit_;
|
| Label done_;
|
| int instruction_index_;
|
| + LCodeGen::X87Stack x87_stack_;
|
| };
|
|
|
| } } // namespace v8::internal
|
|
|
| -#endif // V8_IA32_LITHIUM_CODEGEN_IA32_H_
|
| +#endif // V8_X87_LITHIUM_CODEGEN_X87_H_
|
|
|