| Index: src/x64/lithium-codegen-x64.cc
|
| diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
|
| index 894a4dd3a7584a3da17f6437f02f78bebefbdc65..5103903d5aeba79f907d91b5729cfcfc9e0e477d 100644
|
| --- a/src/x64/lithium-codegen-x64.cc
|
| +++ b/src/x64/lithium-codegen-x64.cc
|
| @@ -284,6 +284,12 @@ void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) {
|
|
|
|
|
| void LCodeGen::GenerateBodyInstructionPost(LInstruction* instr) {
|
| + if (FLAG_debug_code && FLAG_enable_slow_asserts && instr->HasResult() &&
|
| + instr->hydrogen_value()->representation().IsInteger32() &&
|
| + instr->result()->IsRegister()) {
|
| + __ AssertZeroExtended(ToRegister(instr->result()));
|
| + }
|
| +
|
| if (instr->HasResult() && instr->MustSignExtendResult(chunk())) {
|
| if (instr->result()->IsRegister()) {
|
| Register result_reg = ToRegister(instr->result());
|
| @@ -1138,22 +1144,28 @@ void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) {
|
| }
|
|
|
| // If the divisor is negative, we have to negate and handle edge cases.
|
| - Label not_kmin_int, done;
|
| __ negl(dividend);
|
| if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
| DeoptimizeIf(zero, instr->environment());
|
| }
|
| - if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
|
| - // Note that we could emit branch-free code, but that would need one more
|
| - // register.
|
| - __ j(no_overflow, ¬_kmin_int, Label::kNear);
|
| - if (divisor == -1) {
|
| - DeoptimizeIf(no_condition, instr->environment());
|
| - } else {
|
| - __ movl(dividend, Immediate(kMinInt / divisor));
|
| - __ jmp(&done, Label::kNear);
|
| - }
|
| +
|
| + // If the negation could not overflow, simply shifting is OK.
|
| + if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
|
| + __ sarl(dividend, Immediate(shift));
|
| + return;
|
| + }
|
| +
|
| + // Note that we could emit branch-free code, but that would need one more
|
| + // register.
|
| + if (divisor == -1) {
|
| + DeoptimizeIf(overflow, instr->environment());
|
| + return;
|
| }
|
| +
|
| + Label not_kmin_int, done;
|
| + __ j(no_overflow, ¬_kmin_int, Label::kNear);
|
| + __ movl(dividend, Immediate(kMinInt / divisor));
|
| + __ jmp(&done, Label::kNear);
|
| __ bind(¬_kmin_int);
|
| __ sarl(dividend, Immediate(shift));
|
| __ bind(&done);
|
| @@ -1261,7 +1273,7 @@ void LCodeGen::DoDivByConstI(LDivByConstI* instr) {
|
| }
|
|
|
| __ TruncatingDiv(dividend, Abs(divisor));
|
| - if (divisor < 0) __ negp(rdx);
|
| + if (divisor < 0) __ negl(rdx);
|
|
|
| if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
|
| __ movl(rax, rdx);
|
| @@ -1473,13 +1485,25 @@ void LCodeGen::DoBitI(LBitI* instr) {
|
| } else if (right->IsStackSlot()) {
|
| switch (instr->op()) {
|
| case Token::BIT_AND:
|
| - __ andp(ToRegister(left), ToOperand(right));
|
| + if (instr->IsInteger32()) {
|
| + __ andl(ToRegister(left), ToOperand(right));
|
| + } else {
|
| + __ andp(ToRegister(left), ToOperand(right));
|
| + }
|
| break;
|
| case Token::BIT_OR:
|
| - __ orp(ToRegister(left), ToOperand(right));
|
| + if (instr->IsInteger32()) {
|
| + __ orl(ToRegister(left), ToOperand(right));
|
| + } else {
|
| + __ orp(ToRegister(left), ToOperand(right));
|
| + }
|
| break;
|
| case Token::BIT_XOR:
|
| - __ xorp(ToRegister(left), ToOperand(right));
|
| + if (instr->IsInteger32()) {
|
| + __ xorl(ToRegister(left), ToOperand(right));
|
| + } else {
|
| + __ xorp(ToRegister(left), ToOperand(right));
|
| + }
|
| break;
|
| default:
|
| UNREACHABLE();
|
| @@ -1489,13 +1513,25 @@ void LCodeGen::DoBitI(LBitI* instr) {
|
| ASSERT(right->IsRegister());
|
| switch (instr->op()) {
|
| case Token::BIT_AND:
|
| - __ andp(ToRegister(left), ToRegister(right));
|
| + if (instr->IsInteger32()) {
|
| + __ andl(ToRegister(left), ToRegister(right));
|
| + } else {
|
| + __ andp(ToRegister(left), ToRegister(right));
|
| + }
|
| break;
|
| case Token::BIT_OR:
|
| - __ orp(ToRegister(left), ToRegister(right));
|
| + if (instr->IsInteger32()) {
|
| + __ orl(ToRegister(left), ToRegister(right));
|
| + } else {
|
| + __ orp(ToRegister(left), ToRegister(right));
|
| + }
|
| break;
|
| case Token::BIT_XOR:
|
| - __ xorp(ToRegister(left), ToRegister(right));
|
| + if (instr->IsInteger32()) {
|
| + __ xorl(ToRegister(left), ToRegister(right));
|
| + } else {
|
| + __ xorp(ToRegister(left), ToRegister(right));
|
| + }
|
| break;
|
| default:
|
| UNREACHABLE();
|
| @@ -1602,7 +1638,12 @@ void LCodeGen::DoSubI(LSubI* instr) {
|
|
|
|
|
| void LCodeGen::DoConstantI(LConstantI* instr) {
|
| - __ Set(ToRegister(instr->result()), instr->value());
|
| + Register dst = ToRegister(instr->result());
|
| + if (instr->value() == 0) {
|
| + __ xorl(dst, dst);
|
| + } else {
|
| + __ movl(dst, Immediate(instr->value()));
|
| + }
|
| }
|
|
|
|
|
| @@ -2981,25 +3022,25 @@ void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
|
| switch (elements_kind) {
|
| case EXTERNAL_INT8_ELEMENTS:
|
| case INT8_ELEMENTS:
|
| - __ movsxbq(result, operand);
|
| + __ movsxbl(result, operand);
|
| break;
|
| case EXTERNAL_UINT8_ELEMENTS:
|
| case EXTERNAL_UINT8_CLAMPED_ELEMENTS:
|
| case UINT8_ELEMENTS:
|
| case UINT8_CLAMPED_ELEMENTS:
|
| - __ movzxbp(result, operand);
|
| + __ movzxbl(result, operand);
|
| break;
|
| case EXTERNAL_INT16_ELEMENTS:
|
| case INT16_ELEMENTS:
|
| - __ movsxwq(result, operand);
|
| + __ movsxwl(result, operand);
|
| break;
|
| case EXTERNAL_UINT16_ELEMENTS:
|
| case UINT16_ELEMENTS:
|
| - __ movzxwp(result, operand);
|
| + __ movzxwl(result, operand);
|
| break;
|
| case EXTERNAL_INT32_ELEMENTS:
|
| case INT32_ELEMENTS:
|
| - __ movsxlq(result, operand);
|
| + __ movl(result, operand);
|
| break;
|
| case EXTERNAL_UINT32_ELEMENTS:
|
| case UINT32_ELEMENTS:
|
|
|