| Index: runtime/vm/intermediate_language_ia32.cc
|
| diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
|
| index 4afb6ce8e2ad4eb653d651e4d26b8decdd33ed43..5ef7126f69049c1fe2665f12a2582c6856cdb94e 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()));
|
| + } 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();
|
| @@ -5767,33 +5798,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,
|
| 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:
|
| @@ -5804,17 +5930,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) {
|
| @@ -5822,16 +6014,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: {
|
| @@ -5839,11 +6031,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;
|
| @@ -5851,71 +6043,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:
|
| @@ -5923,23 +6201,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;
|
| }
|
| @@ -5947,25 +6242,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);
|
| }
|
| }
|
|
|
|
|