Commit a5a144c7 authored by olivf@chromium.org's avatar olivf@chromium.org

Implement X87 stack tracking and x87 multiplication

BUG=
R=mvstanton@chromium.org

Review URL: https://codereview.chromium.org/18041003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15628 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent b2f909cf
...@@ -65,7 +65,7 @@ int IntelDoubleRegister::NumAllocatableRegisters() { ...@@ -65,7 +65,7 @@ int IntelDoubleRegister::NumAllocatableRegisters() {
if (CpuFeatures::IsSupported(SSE2)) { if (CpuFeatures::IsSupported(SSE2)) {
return XMMRegister::kNumAllocatableRegisters; return XMMRegister::kNumAllocatableRegisters;
} else { } else {
return X87TopOfStackRegister::kNumAllocatableRegisters; return X87Register::kNumAllocatableRegisters;
} }
} }
...@@ -74,7 +74,7 @@ int IntelDoubleRegister::NumRegisters() { ...@@ -74,7 +74,7 @@ int IntelDoubleRegister::NumRegisters() {
if (CpuFeatures::IsSupported(SSE2)) { if (CpuFeatures::IsSupported(SSE2)) {
return XMMRegister::kNumRegisters; return XMMRegister::kNumRegisters;
} else { } else {
return X87TopOfStackRegister::kNumRegisters; return X87Register::kNumRegisters;
} }
} }
...@@ -83,7 +83,7 @@ const char* IntelDoubleRegister::AllocationIndexToString(int index) { ...@@ -83,7 +83,7 @@ const char* IntelDoubleRegister::AllocationIndexToString(int index) {
if (CpuFeatures::IsSupported(SSE2)) { if (CpuFeatures::IsSupported(SSE2)) {
return XMMRegister::AllocationIndexToString(index); return XMMRegister::AllocationIndexToString(index);
} else { } else {
return X87TopOfStackRegister::AllocationIndexToString(index); return X87Register::AllocationIndexToString(index);
} }
} }
...@@ -1784,6 +1784,12 @@ void Assembler::fisub_s(const Operand& adr) { ...@@ -1784,6 +1784,12 @@ void Assembler::fisub_s(const Operand& adr) {
} }
void Assembler::fmul_i(int i) {
EnsureSpace ensure_space(this);
emit_farith(0xD8, 0xC8, i);
}
void Assembler::fmul(int i) { void Assembler::fmul(int i) {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
emit_farith(0xDC, 0xC8, i); emit_farith(0xDC, 0xC8, i);
......
...@@ -229,30 +229,40 @@ struct XMMRegister : IntelDoubleRegister { ...@@ -229,30 +229,40 @@ struct XMMRegister : IntelDoubleRegister {
#define xmm7 (static_cast<const XMMRegister&>(double_register_7)) #define xmm7 (static_cast<const XMMRegister&>(double_register_7))
struct X87TopOfStackRegister : IntelDoubleRegister { struct X87Register : IntelDoubleRegister {
static const int kNumAllocatableRegisters = 1; static const int kNumAllocatableRegisters = 5;
static const int kNumRegisters = 1; static const int kNumRegisters = 5;
bool is(X87TopOfStackRegister reg) const { bool is(X87Register reg) const {
return code_ == reg.code_; return code_ == reg.code_;
} }
static const char* AllocationIndexToString(int index) { static const char* AllocationIndexToString(int index) {
ASSERT(index >= 0 && index < kNumAllocatableRegisters); ASSERT(index >= 0 && index < kNumAllocatableRegisters);
const char* const names[] = { const char* const names[] = {
"st0", "stX_0", "stX_1", "stX_2", "stX_3", "stX_4"
}; };
return names[index]; return names[index];
} }
static int ToAllocationIndex(X87TopOfStackRegister reg) { static X87Register FromAllocationIndex(int index) {
ASSERT(reg.code() == 0); STATIC_ASSERT(sizeof(X87Register) == sizeof(IntelDoubleRegister));
return 0; ASSERT(index >= 0 && index < NumAllocatableRegisters());
X87Register result;
result.code_ = index;
return result;
}
static int ToAllocationIndex(X87Register reg) {
return reg.code_;
} }
}; };
#define x87tos \ #define stX_0 static_cast<const X87Register&>(double_register_0)
static_cast<const X87TopOfStackRegister&>(double_register_0) #define stX_1 static_cast<const X87Register&>(double_register_1)
#define stX_2 static_cast<const X87Register&>(double_register_2)
#define stX_3 static_cast<const X87Register&>(double_register_3)
#define stX_4 static_cast<const X87Register&>(double_register_4)
typedef IntelDoubleRegister DoubleRegister; typedef IntelDoubleRegister DoubleRegister;
...@@ -947,6 +957,7 @@ class Assembler : public AssemblerBase { ...@@ -947,6 +957,7 @@ class Assembler : public AssemblerBase {
void fadd(int i); void fadd(int i);
void fsub(int i); void fsub(int i);
void fmul(int i); void fmul(int i);
void fmul_i(int i);
void fdiv(int i); void fdiv(int i);
void fisub_s(const Operand& adr); void fisub_s(const Operand& adr);
......
This diff is collapsed.
...@@ -105,7 +105,7 @@ class LCodeGen BASE_EMBEDDED { ...@@ -105,7 +105,7 @@ class LCodeGen BASE_EMBEDDED {
Operand ToOperand(LOperand* op) const; Operand ToOperand(LOperand* op) const;
Register ToRegister(LOperand* op) const; Register ToRegister(LOperand* op) const;
XMMRegister ToDoubleRegister(LOperand* op) const; XMMRegister ToDoubleRegister(LOperand* op) const;
bool IsX87TopOfStack(LOperand* op) const; X87Register ToX87Register(LOperand* op) const;
bool IsInteger32(LConstantOperand* op) const; bool IsInteger32(LConstantOperand* op) const;
bool IsSmi(LConstantOperand* op) const; bool IsSmi(LConstantOperand* op) const;
...@@ -118,14 +118,20 @@ class LCodeGen BASE_EMBEDDED { ...@@ -118,14 +118,20 @@ class LCodeGen BASE_EMBEDDED {
double ToDouble(LConstantOperand* op) const; double ToDouble(LConstantOperand* op) const;
// Support for non-sse2 (x87) floating point stack handling. // Support for non-sse2 (x87) floating point stack handling.
// These functions maintain the depth of the stack (either 0 or 1) // These functions maintain the mapping of physical stack registers to our
void PushX87DoubleOperand(Operand src); // virtual registers between instructions.
void PushX87FloatOperand(Operand src); enum X87OperandType { kX87DoubleOperand, kX87FloatOperand, kX87IntOperand };
void ReadX87Operand(Operand dst);
bool X87StackNonEmpty() const { return x87_stack_depth_ > 0; } void X87Mov(X87Register reg, Operand src,
void PopX87(); X87OperandType operand = kX87DoubleOperand);
void CurrentInstructionReturnsX87Result(); void X87Mov(Operand src, X87Register reg);
void FlushX87StackIfNecessary(LInstruction* instr);
void X87PrepareBinaryOp(
X87Register left, X87Register right, X87Register result);
void X87LoadForUsage(X87Register reg);
void X87PrepareToWrite(X87Register reg);
void X87CommitWrite(X87Register reg);
Handle<Object> ToHandle(LConstantOperand* op) const; Handle<Object> ToHandle(LConstantOperand* op) const;
...@@ -292,6 +298,7 @@ class LCodeGen BASE_EMBEDDED { ...@@ -292,6 +298,7 @@ class LCodeGen BASE_EMBEDDED {
Register ToRegister(int index) const; Register ToRegister(int index) const;
XMMRegister ToDoubleRegister(int index) const; XMMRegister ToDoubleRegister(int index) const;
X87Register ToX87Register(int index) const;
int ToInteger32(LConstantOperand* op) const; int ToInteger32(LConstantOperand* op) const;
Operand BuildFastArrayOperand(LOperand* elements_pointer, Operand BuildFastArrayOperand(LOperand* elements_pointer,
...@@ -331,6 +338,7 @@ class LCodeGen BASE_EMBEDDED { ...@@ -331,6 +338,7 @@ class LCodeGen BASE_EMBEDDED {
void EmitNumberUntagDNoSSE2( void EmitNumberUntagDNoSSE2(
Register input, Register input,
Register temp, Register temp,
X87Register res_reg,
bool allow_undefined_as_nan, bool allow_undefined_as_nan,
bool deoptimize_on_minus_zero, bool deoptimize_on_minus_zero,
LEnvironment* env, LEnvironment* env,
...@@ -392,6 +400,16 @@ class LCodeGen BASE_EMBEDDED { ...@@ -392,6 +400,16 @@ class LCodeGen BASE_EMBEDDED {
// register, or a stack slot operand. // register, or a stack slot operand.
void EmitPushTaggedOperand(LOperand* operand); void EmitPushTaggedOperand(LOperand* operand);
void X87Fxch(X87Register reg, int other_slot = 0);
void X87Fld(Operand src, X87OperandType opts);
void X87Free(X87Register reg);
void FlushX87StackIfNecessary(LInstruction* instr);
void EmitFlushX87ForDeopt();
bool X87StackContains(X87Register reg);
int X87ArrayIndex(X87Register reg);
int x87_st2idx(int pos);
Zone* zone_; Zone* zone_;
LPlatformChunk* const chunk_; LPlatformChunk* const chunk_;
MacroAssembler* const masm_; MacroAssembler* const masm_;
...@@ -413,6 +431,7 @@ class LCodeGen BASE_EMBEDDED { ...@@ -413,6 +431,7 @@ class LCodeGen BASE_EMBEDDED {
int osr_pc_offset_; int osr_pc_offset_;
int last_lazy_deopt_pc_; int last_lazy_deopt_pc_;
bool frame_is_built_; bool frame_is_built_;
X87Register x87_stack_[X87Register::kNumAllocatableRegisters];
int x87_stack_depth_; int x87_stack_depth_;
// Builder that keeps track of safepoints in the code. The table // Builder that keeps track of safepoints in the code. The table
......
...@@ -332,10 +332,8 @@ void LGapResolver::EmitMove(int index) { ...@@ -332,10 +332,8 @@ void LGapResolver::EmitMove(int index) {
} else { } else {
__ push(Immediate(upper)); __ push(Immediate(upper));
__ push(Immediate(lower)); __ push(Immediate(lower));
if (cgen_->X87StackNonEmpty()) { X87Register dst = cgen_->ToX87Register(destination);
cgen_->PopX87(); cgen_->X87Mov(dst, MemOperand(esp, 0));
}
cgen_->PushX87DoubleOperand(MemOperand(esp, 0));
__ add(esp, Immediate(kDoubleSize)); __ add(esp, Immediate(kDoubleSize));
} }
} else { } else {
...@@ -367,10 +365,10 @@ void LGapResolver::EmitMove(int index) { ...@@ -367,10 +365,10 @@ void LGapResolver::EmitMove(int index) {
} else { } else {
// load from the register onto the stack, store in destination, which must // load from the register onto the stack, store in destination, which must
// be a double stack slot in the non-SSE2 case. // be a double stack slot in the non-SSE2 case.
ASSERT(source->index() == 0); // source is on top of the stack
ASSERT(destination->IsDoubleStackSlot()); ASSERT(destination->IsDoubleStackSlot());
Operand dst = cgen_->ToOperand(destination); Operand dst = cgen_->ToOperand(destination);
cgen_->ReadX87Operand(dst); X87Register src = cgen_->ToX87Register(source);
cgen_->X87Mov(dst, src);
} }
} else if (source->IsDoubleStackSlot()) { } else if (source->IsDoubleStackSlot()) {
if (CpuFeatures::IsSupported(SSE2)) { if (CpuFeatures::IsSupported(SSE2)) {
...@@ -403,10 +401,8 @@ void LGapResolver::EmitMove(int index) { ...@@ -403,10 +401,8 @@ void LGapResolver::EmitMove(int index) {
__ mov(dst1, tmp); __ mov(dst1, tmp);
} else { } else {
Operand src = cgen_->ToOperand(source); Operand src = cgen_->ToOperand(source);
if (cgen_->X87StackNonEmpty()) { X87Register dst = cgen_->ToX87Register(destination);
cgen_->PopX87(); cgen_->X87Mov(dst, src);
}
cgen_->PushX87DoubleOperand(src);
} }
} }
} else { } else {
......
...@@ -82,6 +82,17 @@ bool LInstruction::HasDoubleRegisterInput() { ...@@ -82,6 +82,17 @@ bool LInstruction::HasDoubleRegisterInput() {
} }
bool LInstruction::IsDoubleInput(X87Register reg, LCodeGen* cgen) {
for (int i = 0; i < InputCount(); i++) {
LOperand* op = InputAt(i);
if (op != NULL && op->IsDoubleRegister()) {
if (cgen->ToX87Register(op).is(reg)) return true;
}
}
return false;
}
void LInstruction::PrintTo(StringStream* stream) { void LInstruction::PrintTo(StringStream* stream) {
stream->Add("%s ", this->Mnemonic()); stream->Add("%s ", this->Mnemonic());
...@@ -494,12 +505,6 @@ LUnallocated* LChunkBuilder::ToUnallocated(XMMRegister reg) { ...@@ -494,12 +505,6 @@ LUnallocated* LChunkBuilder::ToUnallocated(XMMRegister reg) {
} }
LUnallocated* LChunkBuilder::ToUnallocated(X87TopOfStackRegister reg) {
return new(zone()) LUnallocated(LUnallocated::FIXED_DOUBLE_REGISTER,
X87TopOfStackRegister::ToAllocationIndex(reg));
}
LOperand* LChunkBuilder::UseFixed(HValue* value, Register fixed_register) { LOperand* LChunkBuilder::UseFixed(HValue* value, Register fixed_register) {
return Use(value, ToUnallocated(fixed_register)); return Use(value, ToUnallocated(fixed_register));
} }
...@@ -510,11 +515,6 @@ LOperand* LChunkBuilder::UseFixedDouble(HValue* value, XMMRegister reg) { ...@@ -510,11 +515,6 @@ LOperand* LChunkBuilder::UseFixedDouble(HValue* value, XMMRegister reg) {
} }
LOperand* LChunkBuilder::UseX87TopOfStack(HValue* value) {
return Use(value, ToUnallocated(x87tos));
}
LOperand* LChunkBuilder::UseRegister(HValue* value) { LOperand* LChunkBuilder::UseRegister(HValue* value) {
return Use(value, new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER)); return Use(value, new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER));
} }
...@@ -642,13 +642,6 @@ LInstruction* LChunkBuilder::DefineFixedDouble( ...@@ -642,13 +642,6 @@ LInstruction* LChunkBuilder::DefineFixedDouble(
} }
template<int I, int T>
LInstruction* LChunkBuilder::DefineX87TOS(
LTemplateInstruction<1, I, T>* instr) {
return Define(instr, ToUnallocated(x87tos));
}
LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) { LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) {
HEnvironment* hydrogen_env = current_block_->last_environment(); HEnvironment* hydrogen_env = current_block_->last_environment();
int argument_index_accumulator = 0; int argument_index_accumulator = 0;
...@@ -1577,17 +1570,7 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) { ...@@ -1577,17 +1570,7 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) {
} }
return DefineSameAsFirst(mul); return DefineSameAsFirst(mul);
} else if (instr->representation().IsDouble()) { } else if (instr->representation().IsDouble()) {
if (CpuFeatures::IsSafeForSnapshot(SSE2)) { return DoArithmeticD(Token::MUL, instr);
return DoArithmeticD(Token::MUL, instr);
}
ASSERT(instr->right()->IsConstant() &&
static_cast<HConstant*>(instr->right())->DoubleValue() == -1);
// TODO(olivf) This is currently just a hack to support the UnaryOp Minus
// Stub. This will go away once we can use more than one X87 register,
// thus fully support binary instructions without SSE2.
LOperand* left = UseX87TopOfStack(instr->left());
LNegateNoSSE2D* result = new(zone()) LNegateNoSSE2D(left);
return DefineX87TOS(result);
} else { } else {
ASSERT(instr->representation().IsSmiOrTagged()); ASSERT(instr->representation().IsSmiOrTagged());
return DoArithmeticT(Token::MUL, instr); return DoArithmeticT(Token::MUL, instr);
...@@ -1937,11 +1920,7 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) { ...@@ -1937,11 +1920,7 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
? TempRegister() ? TempRegister()
: NULL; : NULL;
LNumberUntagD* res = new(zone()) LNumberUntagD(value, temp); LNumberUntagD* res = new(zone()) LNumberUntagD(value, temp);
if (CpuFeatures::IsSafeForSnapshot(SSE2)) { return AssignEnvironment(DefineAsRegister(res));
return AssignEnvironment(DefineAsRegister(res));
} else {
return AssignEnvironment(DefineX87TOS(res));
}
} else if (to.IsSmi()) { } else if (to.IsSmi()) {
HValue* val = instr->value(); HValue* val = instr->value();
LOperand* value = UseRegister(val); LOperand* value = UseRegister(val);
...@@ -1976,9 +1955,7 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) { ...@@ -1976,9 +1955,7 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
} else if (from.IsDouble()) { } else if (from.IsDouble()) {
if (to.IsTagged()) { if (to.IsTagged()) {
info()->MarkAsDeferredCalling(); info()->MarkAsDeferredCalling();
LOperand* value = CpuFeatures::IsSupported(SSE2) LOperand* value = UseRegisterAtStart(instr->value());
? UseRegisterAtStart(instr->value())
: UseAtStart(instr->value());
LOperand* temp = FLAG_inline_new ? TempRegister() : NULL; LOperand* temp = FLAG_inline_new ? TempRegister() : NULL;
// Make sure that temp and result_temp are different registers. // Make sure that temp and result_temp are different registers.
...@@ -2140,12 +2117,8 @@ LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { ...@@ -2140,12 +2117,8 @@ LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
} else if (r.IsDouble()) { } else if (r.IsDouble()) {
double value = instr->DoubleValue(); double value = instr->DoubleValue();
bool value_is_zero = BitCast<uint64_t, double>(value) == 0; bool value_is_zero = BitCast<uint64_t, double>(value) == 0;
if (CpuFeatures::IsSafeForSnapshot(SSE2)) { LOperand* temp = value_is_zero ? NULL : TempRegister();
LOperand* temp = value_is_zero ? NULL : TempRegister(); return DefineAsRegister(new(zone()) LConstantD(temp));
return DefineAsRegister(new(zone()) LConstantD(temp));
} else {
return DefineX87TOS(new(zone()) LConstantD(NULL));
}
} else if (r.IsTagged()) { } else if (r.IsTagged()) {
return DefineAsRegister(new(zone()) LConstantT); return DefineAsRegister(new(zone()) LConstantT);
} else { } else {
...@@ -2337,11 +2310,7 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { ...@@ -2337,11 +2310,7 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
if (instr->value()->representation().IsDouble()) { if (instr->value()->representation().IsDouble()) {
LOperand* object = UseRegisterAtStart(instr->elements()); LOperand* object = UseRegisterAtStart(instr->elements());
LOperand* val = NULL; LOperand* val = NULL;
if (CpuFeatures::IsSafeForSnapshot(SSE2)) { val = UseRegisterAtStart(instr->value());
val = UseRegisterAtStart(instr->value());
} else if (!instr->IsConstantHoleStore()) {
val = UseX87TopOfStack(instr->value());
}
LOperand* key = UseRegisterOrConstantAtStart(instr->key()); LOperand* key = UseRegisterOrConstantAtStart(instr->key());
return new(zone()) LStoreKeyed(object, key, val); return new(zone()) LStoreKeyed(object, key, val);
} else { } else {
...@@ -2471,11 +2440,7 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { ...@@ -2471,11 +2440,7 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
val = UseTempRegister(instr->value()); val = UseTempRegister(instr->value());
} else if (FLAG_track_double_fields && } else if (FLAG_track_double_fields &&
instr->field_representation().IsDouble()) { instr->field_representation().IsDouble()) {
if (CpuFeatures::IsSafeForSnapshot(SSE2)) { val = UseRegisterAtStart(instr->value());
val = UseRegisterAtStart(instr->value());
} else {
val = UseX87TopOfStack(instr->value());
}
} else { } else {
val = UseRegister(instr->value()); val = UseRegister(instr->value());
} }
......
...@@ -141,7 +141,6 @@ class LCodeGen; ...@@ -141,7 +141,6 @@ class LCodeGen;
V(MathTan) \ V(MathTan) \
V(ModI) \ V(ModI) \
V(MulI) \ V(MulI) \
V(NegateNoSSE2D) \
V(NumberTagD) \ V(NumberTagD) \
V(NumberTagI) \ V(NumberTagI) \
V(NumberTagU) \ V(NumberTagU) \
...@@ -265,7 +264,11 @@ class LInstruction: public ZoneObject { ...@@ -265,7 +264,11 @@ class LInstruction: public ZoneObject {
bool ClobbersTemps() const { return is_call_; } bool ClobbersTemps() const { return is_call_; }
bool ClobbersRegisters() const { return is_call_; } bool ClobbersRegisters() const { return is_call_; }
virtual bool ClobbersDoubleRegisters() const { virtual bool ClobbersDoubleRegisters() const {
return is_call_ || !CpuFeatures::IsSupported(SSE2); return is_call_ ||
(!CpuFeatures::IsSupported(SSE2) &&
// We only have rudimentary X87Stack tracking, thus in general
// cannot handle deoptimization nor phi-nodes.
(HasEnvironment() || IsControl()));
} }
virtual bool HasResult() const = 0; virtual bool HasResult() const = 0;
...@@ -273,6 +276,7 @@ class LInstruction: public ZoneObject { ...@@ -273,6 +276,7 @@ class LInstruction: public ZoneObject {
bool HasDoubleRegisterResult(); bool HasDoubleRegisterResult();
bool HasDoubleRegisterInput(); bool HasDoubleRegisterInput();
bool IsDoubleInput(X87Register reg, LCodeGen* cgen);
LOperand* FirstInput() { return InputAt(0); } LOperand* FirstInput() { return InputAt(0); }
LOperand* Output() { return HasResult() ? result() : NULL; } LOperand* Output() { return HasResult() ? result() : NULL; }
...@@ -377,7 +381,6 @@ class LGap: public LTemplateInstruction<0, 0, 0> { ...@@ -377,7 +381,6 @@ class LGap: public LTemplateInstruction<0, 0, 0> {
class LInstructionGap: public LGap { class LInstructionGap: public LGap {
public: public:
explicit LInstructionGap(HBasicBlock* block) : LGap(block) { } explicit LInstructionGap(HBasicBlock* block) : LGap(block) { }
virtual bool ClobbersDoubleRegisters() const { return false; }
virtual bool HasInterestingComment(LCodeGen* gen) const { virtual bool HasInterestingComment(LCodeGen* gen) const {
return !IsRedundant(); return !IsRedundant();
...@@ -659,18 +662,6 @@ class LMathFloorOfDiv: public LTemplateInstruction<1, 2, 1> { ...@@ -659,18 +662,6 @@ class LMathFloorOfDiv: public LTemplateInstruction<1, 2, 1> {
}; };
class LNegateNoSSE2D: public LTemplateInstruction<1, 1, 0> {
public:
explicit LNegateNoSSE2D(LOperand* value) {
inputs_[0] = value;
}
LOperand* value() { return inputs_[0]; }
DECLARE_CONCRETE_INSTRUCTION(NegateNoSSE2D, "negate-no-sse2-d")
};
class LMulI: public LTemplateInstruction<1, 2, 1> { class LMulI: public LTemplateInstruction<1, 2, 1> {
public: public:
LMulI(LOperand* left, LOperand* right, LOperand* temp) { LMulI(LOperand* left, LOperand* right, LOperand* temp) {
...@@ -1222,10 +1213,6 @@ class LConstantD: public LTemplateInstruction<1, 0, 1> { ...@@ -1222,10 +1213,6 @@ class LConstantD: public LTemplateInstruction<1, 0, 1> {
temps_[0] = temp; temps_[0] = temp;
} }
virtual bool ClobbersDoubleRegisters() const {
return false;
}
LOperand* temp() { return temps_[0]; } LOperand* temp() { return temps_[0]; }
DECLARE_CONCRETE_INSTRUCTION(ConstantD, "constant-d") DECLARE_CONCRETE_INSTRUCTION(ConstantD, "constant-d")
...@@ -2206,9 +2193,7 @@ class LNumberUntagD: public LTemplateInstruction<1, 1, 1> { ...@@ -2206,9 +2193,7 @@ class LNumberUntagD: public LTemplateInstruction<1, 1, 1> {
LOperand* value() { return inputs_[0]; } LOperand* value() { return inputs_[0]; }
LOperand* temp() { return temps_[0]; } LOperand* temp() { return temps_[0]; }
virtual bool ClobbersDoubleRegisters() const { virtual bool ClobbersDoubleRegisters() const { return false; }
return false;
}
DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag") DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
DECLARE_HYDROGEN_ACCESSOR(Change); DECLARE_HYDROGEN_ACCESSOR(Change);
...@@ -2852,14 +2837,13 @@ class LChunkBuilder BASE_EMBEDDED { ...@@ -2852,14 +2837,13 @@ class LChunkBuilder BASE_EMBEDDED {
// Methods for getting operands for Use / Define / Temp. // Methods for getting operands for Use / Define / Temp.
LUnallocated* ToUnallocated(Register reg); LUnallocated* ToUnallocated(Register reg);
LUnallocated* ToUnallocated(XMMRegister reg); LUnallocated* ToUnallocated(XMMRegister reg);
LUnallocated* ToUnallocated(X87TopOfStackRegister reg); LUnallocated* ToUnallocated(X87Register reg);
// Methods for setting up define-use relationships. // Methods for setting up define-use relationships.
MUST_USE_RESULT LOperand* Use(HValue* value, LUnallocated* operand); MUST_USE_RESULT LOperand* Use(HValue* value, LUnallocated* operand);
MUST_USE_RESULT LOperand* UseFixed(HValue* value, Register fixed_register); MUST_USE_RESULT LOperand* UseFixed(HValue* value, Register fixed_register);
MUST_USE_RESULT LOperand* UseFixedDouble(HValue* value, MUST_USE_RESULT LOperand* UseFixedDouble(HValue* value,
XMMRegister fixed_register); XMMRegister fixed_register);
MUST_USE_RESULT LOperand* UseX87TopOfStack(HValue* value);
// A value that is guaranteed to be allocated to a register. // A value that is guaranteed to be allocated to a register.
// Operand created by UseRegister is guaranteed to be live until the end of // Operand created by UseRegister is guaranteed to be live until the end of
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment