x64: Make sure that the upper half of a 64bit register contains 0 for int32 values.
authorsvenpanne@chromium.org <svenpanne@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 11 Apr 2014 06:32:06 +0000 (06:32 +0000)
committersvenpanne@chromium.org <svenpanne@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 11 Apr 2014 06:32:06 +0000 (06:32 +0000)
BUG=360611
LOG=y
R=bmeurer@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20664 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/x64/assembler-x64.cc
src/x64/assembler-x64.h
src/x64/lithium-codegen-x64.cc
src/x64/lithium-x64.h
src/x64/macro-assembler-x64.cc
test/cctest/test-disasm-x64.cc

index 75eeff55387d2dce0a594493e20f6bc494559ebb..19bd82856e4da18fe547069179b6c7b8db94ff66 100644 (file)
@@ -1389,6 +1389,15 @@ void Assembler::movl(const Operand& dst, Label* src) {
 }
 
 
+void Assembler::movsxbl(Register dst, const Operand& src) {
+  EnsureSpace ensure_space(this);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0xBE);
+  emit_operand(dst, src);
+}
+
+
 void Assembler::movsxbq(Register dst, const Operand& src) {
   EnsureSpace ensure_space(this);
   emit_rex_64(dst, src);
@@ -1398,6 +1407,15 @@ void Assembler::movsxbq(Register dst, const Operand& src) {
 }
 
 
+void Assembler::movsxwl(Register dst, const Operand& src) {
+  EnsureSpace ensure_space(this);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0xBF);
+  emit_operand(dst, src);
+}
+
+
 void Assembler::movsxwq(Register dst, const Operand& src) {
   EnsureSpace ensure_space(this);
   emit_rex_64(dst, src);
index 9009e4ff59dcbe5a7b9584212ed6d71493014d9c..ebcd532a136bf691c1d855d7c923495f9d8503cd 100644 (file)
@@ -794,7 +794,9 @@ class Assembler : public AssemblerBase {
   void movq(Register dst, int64_t value);
   void movq(Register dst, uint64_t value);
 
+  void movsxbl(Register dst, const Operand& src);
   void movsxbq(Register dst, const Operand& src);
+  void movsxwl(Register dst, const Operand& src);
   void movsxwq(Register dst, const Operand& src);
   void movsxlq(Register dst, Register src);
   void movsxlq(Register dst, const Operand& src);
index 706b9f129f40602ffb77a8edf8dff0f928037d5a..bb2ba8748a4211963562ee0455638d89daacc6dc 100644 (file)
@@ -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());
@@ -1321,7 +1327,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);
@@ -1525,13 +1531,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();
@@ -1541,13 +1559,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();
@@ -1654,7 +1684,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()));
+  }
 }
 
 
@@ -3035,25 +3070,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:
index 1c8bb0d381d23f749849636136134ef03500c6aa..43a676c8b49241dbe8183483328b33b3c73e11dd 100644 (file)
@@ -1246,6 +1246,9 @@ class LBitI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
   LOperand* right() { return inputs_[1]; }
 
   Token::Value op() const { return hydrogen()->op(); }
+  bool IsInteger32() const {
+    return hydrogen()->representation().IsInteger32();
+  }
 
   DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i")
   DECLARE_HYDROGEN_ACCESSOR(Bitwise)
index 80f61db7774f2455a79e703271c31c1f9d800fe8..b36f4f059332b93b0be6eeea2fc52f9bb0b07b2e 100644 (file)
@@ -3278,6 +3278,8 @@ void MacroAssembler::TruncateHeapNumberToI(Register result_reg,
   }
 
   bind(&done);
+  // Keep our invariant that the upper 32 bits are zero.
+  movl(result_reg, result_reg);
 }
 
 
@@ -3294,6 +3296,8 @@ void MacroAssembler::TruncateDoubleToI(Register result_reg,
   addp(rsp, Immediate(kDoubleSize));
 
   bind(&done);
+  // Keep our invariant that the upper 32 bits are zero.
+  movl(result_reg, result_reg);
 }
 
 
index 1b3edf460f4e5c7bfcd76b7e2c882746cef48955..52f4e17ad0509f1f01f64f61011df52925033d50 100644 (file)
@@ -104,7 +104,9 @@ TEST(DisasmX64) {
   __ xorq(rdx, Immediate(3));
   __ nop();
   __ cpuid();
+  __ movsxbl(rdx, Operand(rcx, 0));
   __ movsxbq(rdx, Operand(rcx, 0));
+  __ movsxwl(rdx, Operand(rcx, 0));
   __ movsxwq(rdx, Operand(rcx, 0));
   __ movzxbl(rdx, Operand(rcx, 0));
   __ movzxwl(rdx, Operand(rcx, 0));