Index: runtime/vm/intermediate_language_ia32.cc |
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc |
index a8f9823fcc7f96807495cf217f1a2fc13a97c9de..7e082dde93bb163676d582cf03b1bf2aa70eaff9 100644 |
--- a/runtime/vm/intermediate_language_ia32.cc |
+++ b/runtime/vm/intermediate_language_ia32.cc |
@@ -253,12 +253,13 @@ static Condition TokenKindToSmiCondition(Token::Kind kind) { |
LocationSummary* EqualityCompareInstr::MakeLocationSummary(bool opt) const { |
const intptr_t kNumInputs = 2; |
if (operation_cid() == kMintCid) { |
- const intptr_t kNumTemps = 1; |
+ const intptr_t kNumTemps = 0; |
LocationSummary* locs = |
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
- locs->set_in(0, Location::RequiresFpuRegister()); |
- locs->set_in(1, Location::RequiresFpuRegister()); |
- locs->set_temp(0, Location::RequiresRegister()); |
+ locs->set_in(0, Location::Pair(Location::RequiresRegister(), |
+ Location::RequiresRegister())); |
+ locs->set_in(1, Location::Pair(Location::RequiresRegister(), |
+ Location::RequiresRegister())); |
locs->set_out(0, Location::RequiresRegister()); |
return locs; |
} |
@@ -392,22 +393,19 @@ static Condition EmitSmiComparisonOp(FlowGraphCompiler* compiler, |
static void EmitJavascriptIntOverflowCheck(FlowGraphCompiler* compiler, |
Label* overflow, |
- XmmRegister result, |
- Register tmp) { |
+ Register result_lo, |
+ Register result_hi) { |
// Compare upper half. |
Label check_lower; |
- __ pextrd(tmp, result, Immediate(1)); |
- __ cmpl(tmp, Immediate(0x00200000)); |
+ __ cmpl(result_hi, Immediate(0x00200000)); |
__ j(GREATER, overflow); |
__ j(NOT_EQUAL, &check_lower); |
- __ pextrd(tmp, result, Immediate(0)); |
- __ cmpl(tmp, Immediate(0)); |
+ __ cmpl(result_lo, Immediate(0)); |
__ j(ABOVE, overflow); |
__ Bind(&check_lower); |
- __ pextrd(tmp, result, Immediate(1)); |
- __ cmpl(tmp, Immediate(-0x00200000)); |
+ __ cmpl(result_hi, Immediate(-0x00200000)); |
__ j(LESS, overflow); |
// Anything in the lower part would make the number bigger than the lower |
// bound, so we are done. |
@@ -434,15 +432,20 @@ static Condition EmitUnboxedMintEqualityOp(FlowGraphCompiler* compiler, |
Token::Kind kind, |
BranchLabels labels) { |
ASSERT(Token::IsEqualityOperator(kind)); |
- XmmRegister left = locs.in(0).fpu_reg(); |
- XmmRegister right = locs.in(1).fpu_reg(); |
- Register temp = locs.temp(0).reg(); |
- __ movaps(XMM0, left); |
- __ pcmpeqq(XMM0, right); |
- __ movd(temp, XMM0); |
- |
+ PairLocation* left_pair = locs.in(0).AsPairLocation(); |
+ Register left1 = left_pair->At(0).reg(); |
+ Register left2 = left_pair->At(1).reg(); |
+ PairLocation* right_pair = locs.in(1).AsPairLocation(); |
+ Register right1 = right_pair->At(0).reg(); |
+ Register right2 = right_pair->At(1).reg(); |
+ Label done; |
+ // Compare lower. |
+ __ cmpl(left1, right1); |
+ __ j(NOT_EQUAL, &done); |
+ // Lower is equal, compare upper. |
+ __ cmpl(left2, right2); |
+ __ Bind(&done); |
Condition true_condition = TokenKindToMintCondition(kind); |
- __ cmpl(temp, Immediate(-1)); |
return true_condition; |
} |
@@ -451,10 +454,12 @@ static Condition EmitUnboxedMintComparisonOp(FlowGraphCompiler* compiler, |
const LocationSummary& locs, |
Token::Kind kind, |
BranchLabels labels) { |
- XmmRegister left = locs.in(0).fpu_reg(); |
- XmmRegister right = locs.in(1).fpu_reg(); |
- Register left_tmp = locs.temp(0).reg(); |
- Register right_tmp = locs.temp(1).reg(); |
+ PairLocation* left_pair = locs.in(0).AsPairLocation(); |
+ Register left1 = left_pair->At(0).reg(); |
+ Register left2 = left_pair->At(1).reg(); |
+ PairLocation* right_pair = locs.in(1).AsPairLocation(); |
+ Register right1 = right_pair->At(0).reg(); |
+ Register right2 = right_pair->At(1).reg(); |
Condition hi_cond = OVERFLOW, lo_cond = OVERFLOW; |
switch (kind) { |
@@ -480,16 +485,12 @@ static Condition EmitUnboxedMintComparisonOp(FlowGraphCompiler* compiler, |
ASSERT(hi_cond != OVERFLOW && lo_cond != OVERFLOW); |
Label is_true, is_false; |
// Compare upper halves first. |
- __ pextrd(left_tmp, left, Immediate(1)); |
- __ pextrd(right_tmp, right, Immediate(1)); |
- __ cmpl(left_tmp, right_tmp); |
+ __ cmpl(left2, right2); |
__ j(hi_cond, labels.true_label); |
__ j(FlipCondition(hi_cond), labels.false_label); |
// If upper is equal, compare lower half. |
- __ pextrd(left_tmp, left, Immediate(0)); |
- __ pextrd(right_tmp, right, Immediate(0)); |
- __ cmpl(left_tmp, right_tmp); |
+ __ cmpl(left1, right1); |
return lo_cond; |
} |
@@ -688,13 +689,13 @@ LocationSummary* RelationalOpInstr::MakeLocationSummary(bool opt) const { |
const intptr_t kNumInputs = 2; |
const intptr_t kNumTemps = 0; |
if (operation_cid() == kMintCid) { |
- const intptr_t kNumTemps = 2; |
+ const intptr_t kNumTemps = 0; |
LocationSummary* locs = |
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
- locs->set_in(0, Location::RequiresFpuRegister()); |
- locs->set_in(1, Location::RequiresFpuRegister()); |
- locs->set_temp(0, Location::RequiresRegister()); |
- locs->set_temp(1, Location::RequiresRegister()); |
+ locs->set_in(0, Location::Pair(Location::RequiresRegister(), |
+ Location::RequiresRegister())); |
+ locs->set_in(1, Location::Pair(Location::RequiresRegister(), |
+ Location::RequiresRegister())); |
locs->set_out(0, Location::RequiresRegister()); |
return locs; |
} |
@@ -1020,7 +1021,17 @@ LocationSummary* LoadIndexedInstr::MakeLocationSummary(bool opt) const { |
(representation() == kUnboxedInt32x4) || |
(representation() == kUnboxedFloat64x2)) { |
locs->set_out(0, Location::RequiresFpuRegister()); |
+ } else if (representation() == kUnboxedMint) { |
+ if (class_id() == kTypedDataInt32ArrayCid) { |
+ locs->set_out(0, Location::Pair(Location::RegisterLocation(EAX), |
+ Location::RegisterLocation(EDX))); |
+ } else { |
+ ASSERT(class_id() == kTypedDataUint32ArrayCid); |
+ locs->set_out(0, Location::Pair(Location::RequiresRegister(), |
+ Location::RequiresRegister())); |
+ } |
} else { |
+ ASSERT(representation() == kTagged); |
locs->set_out(0, Location::RequiresRegister()); |
} |
return locs; |
@@ -1049,7 +1060,6 @@ void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
} |
if ((representation() == kUnboxedDouble) || |
- (representation() == kUnboxedMint) || |
(representation() == kUnboxedFloat32x4) || |
(representation() == kUnboxedInt32x4) || |
(representation() == kUnboxedFloat64x2)) { |
@@ -1058,14 +1068,6 @@ void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
__ SmiUntag(index.reg()); |
} |
switch (class_id()) { |
- case kTypedDataInt32ArrayCid: |
- __ movss(result, element_address); |
- __ pmovsxdq(result, result); |
- break; |
- case kTypedDataUint32ArrayCid: |
- __ xorpd(result, result); |
- __ movss(result, element_address); |
- break; |
case kTypedDataFloat32ArrayCid: |
__ movss(result, element_address); |
break; |
@@ -1077,10 +1079,39 @@ void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
case kTypedDataFloat64x2ArrayCid: |
__ movups(result, element_address); |
break; |
+ default: |
+ UNREACHABLE(); |
+ } |
+ return; |
+ } |
+ |
+ if (representation() == kUnboxedMint) { |
+ ASSERT(locs()->out(0).IsPairLocation()); |
+ PairLocation* result_pair = locs()->out(0).AsPairLocation(); |
+ Register result1 = result_pair->At(0).reg(); |
+ Register result2 = result_pair->At(1).reg(); |
+ if ((index_scale() == 1) && index.IsRegister()) { |
+ __ SmiUntag(index.reg()); |
+ } |
+ switch (class_id()) { |
+ case kTypedDataInt32ArrayCid: |
+ ASSERT(result1 == EAX); |
+ ASSERT(result2 == EDX); |
+ __ movl(result1, element_address); |
+ __ cdq(); |
+ break; |
+ case kTypedDataUint32ArrayCid: |
+ __ movl(result1, element_address); |
+ __ xorl(result2, result2); |
+ break; |
+ default: |
+ UNREACHABLE(); |
} |
return; |
} |
+ ASSERT(representation() == kTagged); |
+ |
Register result = locs()->out(0).reg(); |
if ((index_scale() == 1) && index.IsRegister()) { |
__ SmiUntag(index.reg()); |
@@ -1212,11 +1243,16 @@ LocationSummary* StoreIndexedInstr::MakeLocationSummary(bool opt) const { |
break; |
case kTypedDataInt32ArrayCid: |
case kTypedDataUint32ArrayCid: |
- // Mints are stored in XMM registers. For smis, use a writable register |
- // because the value must be untagged before storing. |
- locs->set_in(2, value()->IsSmiValue() |
- ? Location::WritableRegister() |
- : Location::RequiresFpuRegister()); |
+ // For smis, use a writable register because the value must be untagged |
+ // before storing. Mints are stored in registers pairs. |
+ if (value()->IsSmiValue()) { |
+ locs->set_in(2, Location::WritableRegister()); |
+ } else { |
+ // We only move the lower 32-bits so we don't care where the high bits |
+ // are located. |
+ locs->set_in(2, Location::Pair(Location::RequiresRegister(), |
+ Location::Any())); |
+ } |
break; |
case kTypedDataFloat32ArrayCid: |
case kTypedDataFloat64ArrayCid: |
@@ -1333,7 +1369,9 @@ void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
__ movl(element_address, value); |
} else { |
ASSERT(RequiredInputRepresentation(2) == kUnboxedMint); |
- __ movss(element_address, locs()->in(2).fpu_reg()); |
+ PairLocation* value_pair = locs()->in(2).AsPairLocation(); |
+ Register value1 = value_pair->At(0).reg(); |
+ __ movl(element_address, value1); |
} |
break; |
case kTypedDataFloat32ArrayCid: |
@@ -5536,19 +5574,12 @@ void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
LocationSummary* UnboxIntegerInstr::MakeLocationSummary(bool opt) const { |
const intptr_t kNumInputs = 1; |
- const intptr_t value_cid = value()->Type()->ToCid(); |
- const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kMintCid)); |
- const bool needs_writable_input = (value_cid == kSmiCid); |
- const intptr_t kNumTemps = needs_temp ? 1 : 0; |
+ const intptr_t kNumTemps = 0; |
LocationSummary* summary = |
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
- summary->set_in(0, needs_writable_input |
- ? Location::WritableRegister() |
- : Location::RequiresRegister()); |
- if (needs_temp) { |
- summary->set_temp(0, Location::RequiresRegister()); |
- } |
- summary->set_out(0, Location::RequiresFpuRegister()); |
+ summary->set_in(0, Location::RequiresRegister()); |
+ summary->set_out(0, Location::Pair(Location::RegisterLocation(EAX), |
+ Location::RegisterLocation(EDX))); |
return summary; |
} |
@@ -5556,30 +5587,39 @@ LocationSummary* UnboxIntegerInstr::MakeLocationSummary(bool opt) const { |
void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
const intptr_t value_cid = value()->Type()->ToCid(); |
const Register value = locs()->in(0).reg(); |
- const XmmRegister result = locs()->out(0).fpu_reg(); |
+ PairLocation* result_pair = locs()->out(0).AsPairLocation(); |
+ Register result_lo = result_pair->At(0).reg(); |
+ Register result_hi = result_pair->At(1).reg(); |
+ |
+ ASSERT(value != result_lo); |
+ ASSERT(value != result_hi); |
+ ASSERT(result_lo == EAX); |
+ ASSERT(result_hi == EDX); |
if (value_cid == kMintCid) { |
- __ movsd(result, FieldAddress(value, Mint::value_offset())); |
+ __ movl(result_lo, FieldAddress(value, Mint::value_offset())); |
+ __ movl(result_hi, FieldAddress(value, Mint::value_offset() + kWordSize)); |
} else if (value_cid == kSmiCid) { |
- __ SmiUntag(value); // Untag input before conversion. |
- __ movd(result, value); |
- __ pmovsxdq(result, result); |
+ __ movl(result_lo, value); |
+ __ SmiUntag(result_lo); |
+ // Sign extend into result_hi. |
+ __ cdq(); |
} else { |
- Register temp = locs()->temp(0).reg(); |
Label* deopt = compiler->AddDeoptStub(deopt_id_, |
ICData::kDeoptUnboxInteger); |
Label is_smi, done; |
__ testl(value, Immediate(kSmiTagMask)); |
__ j(ZERO, &is_smi); |
- __ CompareClassId(value, kMintCid, temp); |
+ __ CompareClassId(value, kMintCid, result_lo); |
__ j(NOT_EQUAL, deopt); |
- __ movsd(result, FieldAddress(value, Mint::value_offset())); |
+ __ movl(result_lo, FieldAddress(value, Mint::value_offset())); |
+ __ movl(result_hi, FieldAddress(value, Mint::value_offset() + kWordSize)); |
__ jmp(&done); |
__ Bind(&is_smi); |
- __ movl(temp, value); |
- __ SmiUntag(temp); |
- __ movd(result, temp); |
- __ pmovsxdq(result, result); |
+ __ movl(result_lo, value); |
+ __ SmiUntag(result_lo); |
+ // Sign extend into result_hi. |
+ __ cdq(); |
__ Bind(&done); |
} |
} |
@@ -5587,15 +5627,14 @@ void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
LocationSummary* BoxIntegerInstr::MakeLocationSummary(bool opt) const { |
const intptr_t kNumInputs = 1; |
- const intptr_t kNumTemps = 2; |
+ const intptr_t kNumTemps = 1; |
LocationSummary* summary = |
new LocationSummary(kNumInputs, |
kNumTemps, |
LocationSummary::kCallOnSlowPath); |
- summary->set_in(0, Location::RequiresFpuRegister()); |
- summary->set_temp(0, Location::RegisterLocation(EAX)); |
- summary->set_temp(1, Location::RegisterLocation(EDX)); |
- // TODO(fschneider): Save one temp by using result register as a temp. |
+ summary->set_in(0, Location::Pair(Location::RequiresRegister(), |
+ Location::RequiresRegister())); |
+ summary->set_temp(0, Location::RequiresRegister()); |
summary->set_out(0, Location::RequiresRegister()); |
return summary; |
} |
@@ -5637,30 +5676,32 @@ class BoxIntegerSlowPath : public SlowPathCode { |
void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
BoxIntegerSlowPath* slow_path = new BoxIntegerSlowPath(this); |
compiler->AddSlowPathCode(slow_path); |
- |
+ PairLocation* value_pair = locs()->in(0).AsPairLocation(); |
+ Register value_lo = value_pair->At(0).reg(); |
+ Register value_hi = value_pair->At(1).reg(); |
Register out_reg = locs()->out(0).reg(); |
- XmmRegister value = locs()->in(0).fpu_reg(); |
+ |
+ // Copy value_hi into out_reg as a temporary. |
+ // We modify value_lo but restore it before using it. |
+ __ movl(out_reg, value_hi); |
// Unboxed operations produce smis or mint-sized values. |
// Check if value fits into a smi. |
Label not_smi, done; |
- __ pextrd(EDX, value, Immediate(1)); // Upper half. |
- __ pextrd(EAX, value, Immediate(0)); // Lower half. |
+ |
// 1. Compute (x + -kMinSmi) which has to be in the range |
// 0 .. -kMinSmi+kMaxSmi for x to fit into a smi. |
- __ addl(EAX, Immediate(0x40000000)); |
- __ adcl(EDX, Immediate(0)); |
+ __ addl(value_lo, Immediate(0x40000000)); |
+ __ adcl(out_reg, Immediate(0)); |
// 2. Unsigned compare to -kMinSmi+kMaxSmi. |
- __ cmpl(EAX, Immediate(0x80000000)); |
- __ sbbl(EDX, Immediate(0)); |
+ __ cmpl(value_lo, Immediate(0x80000000)); |
+ __ sbbl(out_reg, Immediate(0)); |
__ j(ABOVE_EQUAL, ¬_smi); |
// 3. Restore lower half if result is a smi. |
- __ subl(EAX, Immediate(0x40000000)); |
- |
- __ SmiTag(EAX); |
- __ movl(out_reg, EAX); |
+ __ subl(value_lo, Immediate(0x40000000)); |
+ __ movl(out_reg, value_lo); |
+ __ SmiTag(out_reg); |
__ jmp(&done); |
- |
__ Bind(¬_smi); |
__ TryAllocate( |
Class::ZoneHandle(Isolate::Current()->object_store()->mint_class()), |
@@ -5669,7 +5710,10 @@ void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
out_reg, |
kNoRegister); |
__ Bind(slow_path->exit_label()); |
- __ movsd(FieldAddress(out_reg, Mint::value_offset()), value); |
+ // 3. Restore lower half of input before using it. |
+ __ subl(value_lo, Immediate(0x40000000)); |
+ __ movl(FieldAddress(out_reg, Mint::value_offset()), value_lo); |
+ __ movl(FieldAddress(out_reg, Mint::value_offset() + kWordSize), value_hi); |
__ Bind(&done); |
} |
@@ -5680,27 +5724,25 @@ LocationSummary* BinaryMintOpInstr::MakeLocationSummary(bool opt) const { |
case Token::kBIT_AND: |
case Token::kBIT_OR: |
case Token::kBIT_XOR: { |
- const intptr_t kNumTemps = |
- FLAG_throw_on_javascript_int_overflow ? 1 : 0; |
+ const intptr_t kNumTemps = 0; |
LocationSummary* summary = |
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
- summary->set_in(0, Location::RequiresFpuRegister()); |
- summary->set_in(1, Location::RequiresFpuRegister()); |
- if (FLAG_throw_on_javascript_int_overflow) { |
- summary->set_temp(0, Location::RequiresRegister()); |
- } |
+ summary->set_in(0, Location::Pair(Location::RequiresRegister(), |
+ Location::RequiresRegister())); |
+ summary->set_in(1, Location::Pair(Location::RequiresRegister(), |
+ Location::RequiresRegister())); |
summary->set_out(0, Location::SameAsFirstInput()); |
return summary; |
} |
case Token::kADD: |
case Token::kSUB: { |
- const intptr_t kNumTemps = 2; |
+ const intptr_t kNumTemps = 0; |
LocationSummary* summary = |
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
- summary->set_in(0, Location::RequiresFpuRegister()); |
- summary->set_in(1, Location::RequiresFpuRegister()); |
- summary->set_temp(0, Location::RequiresRegister()); |
- summary->set_temp(1, Location::RequiresRegister()); |
+ summary->set_in(0, Location::Pair(Location::RequiresRegister(), |
+ Location::RequiresRegister())); |
+ summary->set_in(1, Location::Pair(Location::RequiresRegister(), |
+ Location::RequiresRegister())); |
summary->set_out(0, Location::SameAsFirstInput()); |
return summary; |
} |
@@ -5712,67 +5754,68 @@ LocationSummary* BinaryMintOpInstr::MakeLocationSummary(bool opt) const { |
void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
- XmmRegister left = locs()->in(0).fpu_reg(); |
- XmmRegister right = locs()->in(1).fpu_reg(); |
- |
- ASSERT(locs()->out(0).fpu_reg() == left); |
+ PairLocation* left_pair = locs()->in(0).AsPairLocation(); |
+ Register left_lo = left_pair->At(0).reg(); |
+ Register left_hi = left_pair->At(1).reg(); |
+ PairLocation* right_pair = locs()->in(1).AsPairLocation(); |
+ Register right_lo = right_pair->At(0).reg(); |
+ Register right_hi = right_pair->At(1).reg(); |
+ PairLocation* out_pair = locs()->out(0).AsPairLocation(); |
+ Register out_lo = out_pair->At(0).reg(); |
+ Register out_hi = out_pair->At(1).reg(); |
+ ASSERT(out_lo == left_lo); |
+ ASSERT(out_hi == left_hi); |
Label* deopt = NULL; |
if (FLAG_throw_on_javascript_int_overflow) { |
deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp); |
} |
switch (op_kind()) { |
- case Token::kBIT_AND: __ andpd(left, right); break; |
- case Token::kBIT_OR: __ orpd(left, right); break; |
- case Token::kBIT_XOR: __ xorpd(left, right); break; |
+ case Token::kBIT_AND: |
+ __ andl(left_lo, right_lo); |
+ __ andl(left_hi, right_hi); |
+ break; |
+ case Token::kBIT_OR: |
+ __ orl(left_lo, right_lo); |
+ __ orl(left_hi, right_hi); |
+ break; |
+ case Token::kBIT_XOR: |
+ __ xorl(left_lo, right_lo); |
+ __ xorl(left_hi, right_hi); |
+ break; |
case Token::kADD: |
case Token::kSUB: { |
- Register lo = locs()->temp(0).reg(); |
- Register hi = locs()->temp(1).reg(); |
if (!FLAG_throw_on_javascript_int_overflow) { |
deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp); |
} |
- |
- Label done, overflow; |
- __ pextrd(lo, right, Immediate(0)); // Lower half |
- __ pextrd(hi, right, Immediate(1)); // Upper half |
- __ subl(ESP, Immediate(2 * kWordSize)); |
- __ movq(Address(ESP, 0), left); |
if (op_kind() == Token::kADD) { |
- __ addl(Address(ESP, 0), lo); |
- __ adcl(Address(ESP, 1 * kWordSize), hi); |
+ __ addl(left_lo, right_lo); |
+ __ adcl(left_hi, right_hi); |
} else { |
- __ subl(Address(ESP, 0), lo); |
- __ sbbl(Address(ESP, 1 * kWordSize), hi); |
+ __ subl(left_lo, right_lo); |
+ __ sbbl(left_hi, right_hi); |
} |
- __ j(OVERFLOW, &overflow); |
- __ movq(left, Address(ESP, 0)); |
- __ addl(ESP, Immediate(2 * kWordSize)); |
- __ jmp(&done); |
- __ Bind(&overflow); |
- __ addl(ESP, Immediate(2 * kWordSize)); |
- __ jmp(deopt); |
- __ Bind(&done); |
+ __ j(OVERFLOW, deopt); |
break; |
} |
default: UNREACHABLE(); |
} |
if (FLAG_throw_on_javascript_int_overflow) { |
- Register tmp = locs()->temp(0).reg(); |
- EmitJavascriptIntOverflowCheck(compiler, deopt, left, tmp); |
+ EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); |
} |
} |
LocationSummary* ShiftMintOpInstr::MakeLocationSummary(bool opt) const { |
const intptr_t kNumInputs = 2; |
- const intptr_t kNumTemps = op_kind() == Token::kSHL ? 2 : 1; |
+ const intptr_t kNumTemps = op_kind() == Token::kSHL ? 2 : 0; |
LocationSummary* summary = |
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
- summary->set_in(0, Location::RequiresFpuRegister()); |
+ summary->set_in(0, Location::Pair(Location::RequiresRegister(), |
+ Location::RequiresRegister())); |
summary->set_in(1, Location::RegisterLocation(ECX)); |
- summary->set_temp(0, Location::RequiresRegister()); |
if (op_kind() == Token::kSHL) { |
+ summary->set_temp(0, Location::RequiresRegister()); |
summary->set_temp(1, Location::RequiresRegister()); |
} |
summary->set_out(0, Location::SameAsFirstInput()); |
@@ -5781,16 +5824,19 @@ LocationSummary* ShiftMintOpInstr::MakeLocationSummary(bool opt) const { |
void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
- XmmRegister left = locs()->in(0).fpu_reg(); |
- ASSERT(locs()->in(1).reg() == ECX); |
- ASSERT(locs()->out(0).fpu_reg() == left); |
+ PairLocation* left_pair = locs()->in(0).AsPairLocation(); |
+ Register left_lo = left_pair->At(0).reg(); |
+ Register left_hi = left_pair->At(1).reg(); |
+ PairLocation* out_pair = locs()->out(0).AsPairLocation(); |
+ Register out_lo = out_pair->At(0).reg(); |
+ Register out_hi = out_pair->At(1).reg(); |
+ ASSERT(out_lo == left_lo); |
+ ASSERT(out_hi == left_hi); |
Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp); |
Label done; |
__ testl(ECX, ECX); |
__ j(ZERO, &done); // Shift by 0 is a nop. |
- __ subl(ESP, Immediate(2 * kWordSize)); |
- __ movq(Address(ESP, 0), left); |
// Deoptimize if shift count is > 31. |
// sarl operation masks the count to 5 bits and |
// shrd is undefined with count > operand size (32) |
@@ -5801,23 +5847,21 @@ void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
__ j(ABOVE, deopt); |
switch (op_kind()) { |
case Token::kSHR: { |
- Register temp = locs()->temp(0).reg(); |
- __ movl(temp, Address(ESP, 1 * kWordSize)); // High half. |
- __ shrd(Address(ESP, 0), temp); // Shift count in CL. |
- __ sarl(Address(ESP, 1 * kWordSize), ECX); // Shift count in CL. |
+ __ shrd(left_lo, left_hi); // Shift count in CL. |
+ __ sarl(left_hi, ECX); // Shift count in CL. |
break; |
} |
case Token::kSHL: { |
Register temp1 = locs()->temp(0).reg(); |
Register temp2 = locs()->temp(1).reg(); |
- __ movl(temp1, Address(ESP, 0 * kWordSize)); // Low 32 bits. |
- __ movl(temp2, Address(ESP, 1 * kWordSize)); // High 32 bits. |
- __ shll(Address(ESP, 0 * kWordSize), ECX); // Shift count in CL. |
- __ shld(Address(ESP, 1 * kWordSize), temp1); // Shift count in CL. |
+ __ movl(temp1, left_lo); // Low 32 bits. |
+ __ movl(temp2, left_hi); // High 32 bits. |
+ __ shll(left_lo, ECX); // Shift count in CL. |
+ __ shld(left_hi, temp1); // Shift count in CL. |
// Check for overflow by shifting back the high 32 bits |
// and comparing with the input. |
__ movl(temp1, temp2); |
- __ movl(temp2, Address(ESP, 1 * kWordSize)); |
+ __ movl(temp2, left_hi); |
__ sarl(temp2, ECX); |
__ cmpl(temp1, temp2); |
__ j(NOT_EQUAL, deopt); |
@@ -5827,23 +5871,20 @@ void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
UNREACHABLE(); |
break; |
} |
- __ movq(left, Address(ESP, 0)); |
- __ addl(ESP, Immediate(2 * kWordSize)); |
__ Bind(&done); |
if (FLAG_throw_on_javascript_int_overflow) { |
- Register tmp = locs()->temp(0).reg(); |
- EmitJavascriptIntOverflowCheck(compiler, deopt, left, tmp); |
+ EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); |
} |
} |
LocationSummary* UnaryMintOpInstr::MakeLocationSummary(bool opt) const { |
const intptr_t kNumInputs = 1; |
- const intptr_t kNumTemps = |
- FLAG_throw_on_javascript_int_overflow ? 1 : 0; |
+ const intptr_t kNumTemps = 0; |
LocationSummary* summary = |
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
- summary->set_in(0, Location::RequiresFpuRegister()); |
+ summary->set_in(0, Location::Pair(Location::RequiresRegister(), |
+ Location::RequiresRegister())); |
summary->set_out(0, Location::SameAsFirstInput()); |
if (FLAG_throw_on_javascript_int_overflow) { |
summary->set_temp(0, Location::RequiresRegister()); |
@@ -5854,17 +5895,25 @@ LocationSummary* UnaryMintOpInstr::MakeLocationSummary(bool opt) const { |
void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
ASSERT(op_kind() == Token::kBIT_NOT); |
- XmmRegister value = locs()->in(0).fpu_reg(); |
- ASSERT(value == locs()->out(0).fpu_reg()); |
+ PairLocation* left_pair = locs()->in(0).AsPairLocation(); |
+ Register left_lo = left_pair->At(0).reg(); |
+ Register left_hi = left_pair->At(1).reg(); |
+ PairLocation* out_pair = locs()->out(0).AsPairLocation(); |
+ Register out_lo = out_pair->At(0).reg(); |
+ Register out_hi = out_pair->At(1).reg(); |
+ ASSERT(out_lo == left_lo); |
+ ASSERT(out_hi == left_hi); |
+ |
Label* deopt = NULL; |
if (FLAG_throw_on_javascript_int_overflow) { |
deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryMintOp); |
} |
- __ pcmpeqq(XMM0, XMM0); // Generate all 1's. |
- __ pxor(value, XMM0); |
+ |
+ __ notl(left_lo); |
+ __ notl(left_hi); |
+ |
if (FLAG_throw_on_javascript_int_overflow) { |
- Register tmp = locs()->temp(0).reg(); |
- EmitJavascriptIntOverflowCheck(compiler, deopt, value, tmp); |
+ EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); |
} |
} |