Index: runtime/vm/intermediate_language_ia32.cc |
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc |
index 457d62d73a4dcce751f1c4b3c656aa86a45f2c2a..2c6c36274c211172bc4d827f0d21ff69ad3be7fa 100644 |
--- a/runtime/vm/intermediate_language_ia32.cc |
+++ b/runtime/vm/intermediate_language_ia32.cc |
@@ -5613,8 +5613,12 @@ LocationSummary* UnboxIntegerInstr::MakeLocationSummary(Isolate* isolate, |
LocationSummary* summary = new(isolate) LocationSummary( |
isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
summary->set_in(0, Location::RequiresRegister()); |
- summary->set_out(0, Location::Pair(Location::RegisterLocation(EAX), |
- Location::RegisterLocation(EDX))); |
+ if (is_32_bit()) { |
+ summary->set_out(0, Location::RequiresRegister()); |
+ } else { |
+ summary->set_out(0, Location::Pair(Location::RegisterLocation(EAX), |
+ Location::RegisterLocation(EDX))); |
+ } |
return summary; |
} |
@@ -5622,6 +5626,33 @@ LocationSummary* UnboxIntegerInstr::MakeLocationSummary(Isolate* isolate, |
void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
const intptr_t value_cid = value()->Type()->ToCid(); |
const Register value = locs()->in(0).reg(); |
+ |
+ if (is_32_bit()) { |
+ const Register out = locs()->out(0).reg(); |
+ if (value_cid == kMintCid) { |
+ __ movl(out, FieldAddress(value, Mint::value_offset())); |
Vyacheslav Egorov (Google)
2014/06/23 20:02:06
for constants here it is beneficial to emit immedi
|
+ } else if (value_cid == kSmiCid) { |
+ __ movl(out, value); |
+ __ SmiUntag(out); |
+ } else { |
+ Label* deopt = compiler->AddDeoptStub(deopt_id_, |
+ ICData::kDeoptUnboxInteger); |
+ Label is_smi, done; |
+ __ testl(value, Immediate(kSmiTagMask)); |
+ __ j(ZERO, &is_smi); |
+ __ CompareClassId(value, kMintCid, out); |
+ __ j(NOT_EQUAL, deopt); |
+ __ movl(out, FieldAddress(value, Mint::value_offset())); |
+ __ jmp(&done); |
+ __ Bind(&is_smi); |
+ __ movl(out, value); |
+ __ SmiUntag(out); |
+ __ Bind(&done); |
+ } |
+ return; |
+ } |
+ |
+ ASSERT(!is_32_bit()); |
PairLocation* result_pair = locs()->out(0).AsPairLocation(); |
Register result_lo = result_pair->At(0).reg(); |
Register result_hi = result_pair->At(1).reg(); |
@@ -5754,33 +5785,128 @@ void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
} |
+LocationSummary* MintConverterInstr::MakeLocationSummary(Isolate* isolate, |
+ bool opt) const { |
+ // We should only see this in optimized code. |
+ ASSERT(opt); |
+ const intptr_t kNumInputs = 1; |
+ const intptr_t kNumTemps = 0; |
+ LocationSummary* summary = new(isolate) LocationSummary( |
+ isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
+ if (conversion_kind() == kMint32ToMint) { |
+ summary->set_in(0, Location::RequiresRegister()); |
+ summary->set_out(0, Location::Pair(Location::RequiresRegister(), |
+ Location::RequiresRegister())); |
+ } else if (conversion_kind() == kMintToMint32) { |
+ summary->set_in(0, Location::Pair(Location::RequiresRegister(), |
+ Location::RequiresRegister())); |
+ summary->set_out(0, Location::RequiresRegister()); |
+ } else { |
+ UNREACHABLE(); |
+ } |
+ return summary; |
+} |
+ |
+ |
+void MintConverterInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
+ if (conversion_kind() == kMint32ToMint) { |
+ Register in = locs()->in(0).reg(); |
+ PairLocation* out_pair = locs()->out(0).AsPairLocation(); |
+ Register out_lo = out_pair->At(0).reg(); |
+ Register out_hi = out_pair->At(1).reg(); |
+ // Copy lo. |
+ __ movl(out_lo, in); |
+ // Zero hi. |
+ __ xorl(out_hi, out_hi); |
+ } else if (conversion_kind() == kMintToMint32) { |
+ PairLocation* in_pair = locs()->in(0).AsPairLocation(); |
+ Register in_lo = in_pair->At(0).reg(); |
+ Register out = locs()->out(0).reg(); |
+ // Copy lo. |
+ __ movl(out, in_lo); |
+ } else { |
+ UNREACHABLE(); |
+ } |
+} |
+ |
+ |
+static bool BinaryMintOutputSameAsInput(const BinaryMintOpInstr* instr) { |
+ return instr->is_32_bit() == instr->IsInput32Bit(0); |
+} |
+ |
LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Isolate* isolate, |
Vyacheslav Egorov (Google)
2014/06/23 20:02:06
This instruction became way too complex. We need t
|
bool opt) const { |
const intptr_t kNumInputs = 2; |
+ // Need a temporary right high word if we are computing a 64-bit value |
+ // and the right operand is 32-bits. |
+ const intptr_t kNumTemps = (!is_32_bit() && IsInput32Bit(1)) ? 1 : 0; |
switch (op_kind()) { |
case Token::kBIT_AND: |
case Token::kBIT_OR: |
case Token::kBIT_XOR: { |
- const intptr_t kNumTemps = 0; |
LocationSummary* summary = new(isolate) LocationSummary( |
isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
- 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()); |
+ |
+ if (kNumTemps > 0) { |
+ ASSERT(kNumTemps == 1); |
+ summary->set_temp(0, Location::RequiresRegister()); |
+ } |
+ |
+ if (IsInput32Bit(0)) { |
+ summary->set_in(0, Location::RequiresRegister()); |
+ } else { |
+ summary->set_in(0, Location::Pair(Location::RequiresRegister(), |
+ Location::RequiresRegister())); |
+ } |
+ |
+ if (IsInput32Bit(1)) { |
+ summary->set_in(1, Location::RequiresRegister()); |
+ } else { |
+ summary->set_in(1, Location::Pair(Location::RequiresRegister(), |
+ Location::RequiresRegister())); |
+ } |
+ |
+ if (BinaryMintOutputSameAsInput(this)) { |
+ summary->set_out(0, Location::SameAsFirstInput()); |
+ } else if (is_32_bit()) { |
+ summary->set_out(0, Location::RequiresRegister()); |
+ } else { |
+ summary->set_out(0, Location::Pair(Location::RequiresRegister(), |
+ Location::RequiresRegister())); |
+ } |
return summary; |
} |
case Token::kADD: |
case Token::kSUB: { |
- const intptr_t kNumTemps = 0; |
LocationSummary* summary = new(isolate) LocationSummary( |
isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
- 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()); |
+ |
+ if (kNumTemps > 0) { |
+ ASSERT(kNumTemps == 1); |
+ summary->set_temp(0, Location::RequiresRegister()); |
+ } |
+ if (IsInput32Bit(0)) { |
+ summary->set_in(0, Location::RequiresRegister()); |
+ } else { |
+ summary->set_in(0, Location::Pair(Location::RequiresRegister(), |
+ Location::RequiresRegister())); |
+ } |
+ |
+ if (IsInput32Bit(1)) { |
+ summary->set_in(1, Location::RequiresRegister()); |
+ } else { |
+ summary->set_in(1, Location::Pair(Location::RequiresRegister(), |
+ Location::RequiresRegister())); |
+ } |
+ |
+ if (BinaryMintOutputSameAsInput(this)) { |
+ summary->set_out(0, Location::SameAsFirstInput()); |
+ } else if (is_32_bit()) { |
+ summary->set_out(0, Location::RequiresRegister()); |
+ } else { |
+ summary->set_out(0, Location::Pair(Location::RequiresRegister(), |
+ Location::RequiresRegister())); |
+ } |
return summary; |
} |
default: |
@@ -5791,17 +5917,83 @@ LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Isolate* isolate, |
void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
- 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(); |
+ Register left_lo = kNoRegister; |
+ Register left_hi = kNoRegister; |
+ Register right_lo = kNoRegister; |
+ Register right_hi = kNoRegister; |
+ Register out_lo = kNoRegister; |
+ Register out_hi = kNoRegister; |
+ |
+ if (IsInput32Bit(0)) { |
+ left_lo = locs()->in(0).reg(); |
+ } else { |
+ PairLocation* left_pair = locs()->in(0).AsPairLocation(); |
+ left_lo = left_pair->At(0).reg(); |
+ left_hi = left_pair->At(1).reg(); |
+ } |
+ |
+ if (IsInput32Bit(1)) { |
+ right_lo = locs()->in(1).reg(); |
+ } else { |
+ PairLocation* right_pair = locs()->in(1).AsPairLocation(); |
+ right_lo = right_pair->At(0).reg(); |
+ right_hi = right_pair->At(1).reg(); |
+ } |
+ |
+ if (is_32_bit()) { |
+ out_lo = locs()->out(0).reg(); |
+ if (!BinaryMintOutputSameAsInput(this)) { |
+ // Copy lo part of left. |
+ __ movl(out_lo, left_lo); |
+ } else { |
+ ASSERT(out_lo == left_lo); |
+ } |
+ switch (op_kind()) { |
+ case Token::kBIT_AND: |
+ __ andl(out_lo, right_lo); |
+ break; |
+ case Token::kBIT_OR: |
+ __ orl(out_lo, right_lo); |
+ break; |
+ case Token::kBIT_XOR: |
+ __ xorl(out_lo, right_lo); |
+ break; |
+ case Token::kADD: |
+ case Token::kSUB: { |
+ if (op_kind() == Token::kADD) { |
+ __ addl(out_lo, right_lo); |
+ } else { |
+ __ subl(out_lo, right_lo); |
+ } |
+ break; |
+ } |
+ default: UNREACHABLE(); |
+ } |
+ return; |
+ } |
+ |
+ ASSERT(!is_32_bit()); |
+ |
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); |
+ out_lo = out_pair->At(0).reg(); |
+ out_hi = out_pair->At(1).reg(); |
+ if (BinaryMintOutputSameAsInput(this)) { |
+ ASSERT(out_lo == left_lo); |
+ ASSERT(out_hi == left_hi); |
+ } else { |
+ // Left input is 32-bits. |
+ ASSERT(IsInput32Bit(0)); |
+ // Copy lo input. |
+ __ movl(out_lo, left_lo); |
+ // Zero output. |
+ __ xorl(out_hi, out_hi); |
+ } |
+ |
+ if (IsInput32Bit(1)) { |
+ // Zero temporary right high word. |
+ right_hi = locs()->temp(0).reg(); |
+ __ xorl(right_hi, right_hi); |
+ } |
Label* deopt = NULL; |
if (FLAG_throw_on_javascript_int_overflow) { |
@@ -5809,16 +6001,16 @@ void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
} |
switch (op_kind()) { |
case Token::kBIT_AND: |
- __ andl(left_lo, right_lo); |
- __ andl(left_hi, right_hi); |
+ __ andl(out_lo, right_lo); |
+ __ andl(out_hi, right_hi); |
break; |
case Token::kBIT_OR: |
- __ orl(left_lo, right_lo); |
- __ orl(left_hi, right_hi); |
+ __ orl(out_lo, right_lo); |
+ __ orl(out_hi, right_hi); |
break; |
case Token::kBIT_XOR: |
- __ xorl(left_lo, right_lo); |
- __ xorl(left_hi, right_hi); |
+ __ xorl(out_lo, right_lo); |
+ __ xorl(out_hi, right_hi); |
break; |
case Token::kADD: |
case Token::kSUB: { |
@@ -5826,11 +6018,11 @@ void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp); |
} |
if (op_kind() == Token::kADD) { |
- __ addl(left_lo, right_lo); |
- __ adcl(left_hi, right_hi); |
+ __ addl(out_lo, right_lo); |
+ __ adcl(out_hi, right_hi); |
} else { |
- __ subl(left_lo, right_lo); |
- __ sbbl(left_hi, right_hi); |
+ __ subl(out_lo, right_lo); |
+ __ sbbl(out_hi, right_hi); |
} |
__ j(OVERFLOW, deopt); |
break; |
@@ -5838,71 +6030,157 @@ void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
default: UNREACHABLE(); |
} |
if (FLAG_throw_on_javascript_int_overflow) { |
- EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); |
+ EmitJavascriptIntOverflowCheck(compiler, deopt, out_lo, out_hi); |
} |
} |
+static bool ShiftMintOpInstrOutputSameAsInput(const ShiftMintOpInstr* instr) { |
+ return instr->is_32_bit() == instr->IsInput32Bit(0); |
+} |
+ |
+ |
LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate, |
bool opt) const { |
+ const bool need_temps = (op_kind() == Token::kSHL) && CanShiftLeftOverflow(); |
const intptr_t kNumInputs = 2; |
- const intptr_t kNumTemps = op_kind() == Token::kSHL ? 2 : 0; |
+ const intptr_t kNumTemps = need_temps ? 2 : 0; |
LocationSummary* summary = new(isolate) LocationSummary( |
isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
- summary->set_in(0, Location::Pair(Location::RequiresRegister(), |
- Location::RequiresRegister())); |
+ |
+ |
+ if (IsInput32Bit(0)) { |
+ summary->set_in(0, Location::RequiresRegister()); |
+ } else { |
+ summary->set_in(0, Location::Pair(Location::RequiresRegister(), |
+ Location::RequiresRegister())); |
+ } |
+ |
summary->set_in(1, Location::RegisterLocation(ECX)); |
- if (op_kind() == Token::kSHL) { |
+ |
+ if (need_temps) { |
summary->set_temp(0, Location::RequiresRegister()); |
summary->set_temp(1, Location::RequiresRegister()); |
} |
- summary->set_out(0, Location::SameAsFirstInput()); |
+ |
+ if (ShiftMintOpInstrOutputSameAsInput(this)) { |
+ summary->set_out(0, Location::SameAsFirstInput()); |
+ } else if (is_32_bit()) { |
+ summary->set_out(0, Location::RequiresRegister()); |
+ } else { |
+ ASSERT(IsInput32Bit(0)); |
+ summary->set_out(0, Location::Pair(Location::RequiresRegister(), |
+ Location::RequiresRegister())); |
+ } |
+ |
return summary; |
} |
void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
- 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); |
+ // Shift count is in ECX. |
+ ASSERT(locs()->in(1).reg() == ECX); |
+ Register left_lo; |
+ Register left_hi; |
+ Register out_lo; |
+ Register out_hi; |
+ |
+ if (IsInput32Bit(0)) { |
+ left_lo = locs()->in(0).reg(); |
+ left_hi = kNoRegister; |
+ } else { |
+ PairLocation* left_pair = locs()->in(0).AsPairLocation(); |
+ left_lo = left_pair->At(0).reg(); |
+ left_hi = left_pair->At(1).reg(); |
+ } |
+ |
+ if (is_32_bit()) { |
+ out_lo = locs()->out(0).reg(); |
+ out_hi = kNoRegister; |
+ } else { |
+ PairLocation* out_pair = locs()->out(0).AsPairLocation(); |
+ out_lo = out_pair->At(0).reg(); |
+ out_hi = out_pair->At(1).reg(); |
+ } |
+ |
+ if (ShiftMintOpInstrOutputSameAsInput(this)) { |
+ ASSERT(out_lo == left_lo); |
+ ASSERT(out_hi == left_hi); |
+ } else if (is_32_bit()) { |
+ ASSERT(!IsInput32Bit(0)); |
+ // Copy lo. |
+ __ movl(out_lo, left_lo); |
+ } else if (IsInput32Bit(0)) { |
+ ASSERT(!is_32_bit()); |
+ // Copy lo. |
+ __ movl(out_lo, left_lo); |
+ // Zero hi. |
+ __ xorl(out_hi, out_hi); |
+ } |
+ |
- Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp); |
Label done; |
__ testl(ECX, ECX); |
__ j(ZERO, &done); // Shift by 0 is a nop. |
+ __ SmiUntag(ECX); |
+ |
// Deoptimize if shift count is > 31. |
// sarl operation masks the count to 5 bits and |
// shrd is undefined with count > operand size (32) |
// TODO(fschneider): Support shift counts > 31 without deoptimization. |
- __ SmiUntag(ECX); |
+ |
+ Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp); |
const Immediate& kCountLimit = Immediate(31); |
__ cmpl(ECX, kCountLimit); |
__ j(ABOVE, deopt); |
+ |
switch (op_kind()) { |
case Token::kSHR: { |
- __ shrd(left_lo, left_hi); // Shift count in CL. |
- __ sarl(left_hi, ECX); // Shift count in CL. |
+ if (IsInput32Bit(0)) { |
+ // 32-bit input. |
+ // Upper word is 0, use logical shift. |
+ __ shrl(out_lo, ECX); |
+ // If needed, out_hi is already zero. |
+ } else { |
+ // 64-bit input, |
+ if (is_32_bit()) { |
+ // 32-bit output |
+ __ shrd(out_lo, left_hi); // Shift count in CL. |
+ } else { |
+ // 64-bit output. |
+ __ shrd(out_lo, left_hi); // Shift count in CL. |
+ __ sarl(out_hi, ECX); // Shift count in CL. |
+ } |
+ } |
break; |
} |
case Token::kSHL: { |
- Register temp1 = locs()->temp(0).reg(); |
- Register temp2 = locs()->temp(1).reg(); |
- __ 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, left_hi); |
- __ sarl(temp2, ECX); |
- __ cmpl(temp1, temp2); |
- __ j(NOT_EQUAL, deopt); |
+ if (CanShiftLeftOverflow()) { |
+ // 64-bit input and 64-bit output. |
+ Register temp1 = locs()->temp(0).reg(); |
+ Register temp2 = locs()->temp(1).reg(); |
+ __ movl(temp1, out_lo); // Low 32 bits. |
+ __ movl(temp2, out_hi); // High 32 bits. |
+ __ shll(out_lo, ECX); // Shift count in CL. |
+ __ shld(out_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, out_hi); |
+ __ sarl(temp2, ECX); |
+ __ cmpl(temp1, temp2); |
+ __ j(NOT_EQUAL, deopt); |
+ } else { |
+ if (is_32_bit()) { |
+ // 32-bit output (can be 64-bit or 32-bit input). |
+ __ shll(out_lo, ECX); |
+ } else { |
+ // 64-bit output and 32-bit input. |
+ ASSERT(out_lo != left_lo); |
+ __ shll(out_lo, ECX); |
+ __ shld(out_hi, left_lo); |
+ } |
+ } |
break; |
} |
default: |
@@ -5910,23 +6188,40 @@ void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
break; |
} |
__ Bind(&done); |
- if (FLAG_throw_on_javascript_int_overflow) { |
- EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); |
+ if (FLAG_throw_on_javascript_int_overflow && !is_32_bit()) { |
+ EmitJavascriptIntOverflowCheck(compiler, deopt, out_lo, out_hi); |
} |
} |
+static bool UnaryMintOutputSameAsInput(const UnaryMintOpInstr* instr) { |
+ return instr->is_32_bit() == instr->IsInput32Bit(0); |
+} |
+ |
+ |
LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Isolate* isolate, |
bool opt) const { |
const intptr_t kNumInputs = 1; |
const intptr_t kNumTemps = 0; |
LocationSummary* summary = new(isolate) LocationSummary( |
isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
- 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()); |
+ |
+ if (IsInput32Bit(0)) { |
+ summary->set_in(0, Location::RequiresRegister()); |
+ } else { |
+ summary->set_in(0, Location::Pair(Location::RequiresRegister(), |
+ Location::RequiresRegister())); |
+ } |
+ |
+ if (UnaryMintOutputSameAsInput(this)) { |
+ summary->set_out(0, Location::SameAsFirstInput()); |
+ } else if (IsInput32Bit(0)) { |
+ ASSERT(!is_32_bit()); |
+ summary->set_out(0, Location::Pair(Location::RequiresRegister(), |
+ Location::RequiresRegister())); |
+ } else { |
+ ASSERT(is_32_bit()); |
+ summary->set_out(0, Location::RequiresRegister()); |
} |
return summary; |
} |
@@ -5934,25 +6229,52 @@ LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Isolate* isolate, |
void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
ASSERT(op_kind() == Token::kBIT_NOT); |
- 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); |
+ |
+ // Extract registers. |
+ Register out_lo; |
+ Register out_hi = kNoRegister; |
+ Register left_lo; |
+ Register left_hi = kNoRegister; |
+ |
+ if (IsInput32Bit(0)) { |
+ left_lo = locs()->in(0).reg(); |
+ } else { |
+ PairLocation* left_pair = locs()->in(0).AsPairLocation(); |
+ left_lo = left_pair->At(0).reg(); |
+ left_hi = left_pair->At(1).reg(); |
+ } |
+ |
+ if (is_32_bit()) { |
+ out_lo = locs()->out(0).reg(); |
+ } else { |
+ PairLocation* out_pair = locs()->out(0).AsPairLocation(); |
+ out_lo = out_pair->At(0).reg(); |
+ out_hi = out_pair->At(1).reg(); |
+ } |
+ |
+ if (UnaryMintOutputSameAsInput(this)) { |
+ ASSERT(out_lo == left_lo); |
+ ASSERT(out_hi == left_hi); |
+ } else { |
+ __ movl(out_lo, left_lo); |
+ if (!is_32_bit() && IsInput32Bit(0)) { |
+ // Zero high word. |
+ __ xorl(out_hi, out_hi); |
+ } |
+ } |
Label* deopt = NULL; |
- if (FLAG_throw_on_javascript_int_overflow) { |
+ if (FLAG_throw_on_javascript_int_overflow && !is_32_bit()) { |
deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryMintOp); |
} |
- __ notl(left_lo); |
- __ notl(left_hi); |
+ __ notl(out_lo); |
+ if (!is_32_bit()) { |
+ __ notl(out_hi); |
+ } |
- if (FLAG_throw_on_javascript_int_overflow) { |
- EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); |
+ if (FLAG_throw_on_javascript_int_overflow && !is_32_bit()) { |
+ EmitJavascriptIntOverflowCheck(compiler, deopt, out_lo, out_hi); |
} |
} |