Revision: 17217
Author:   [email protected]
Date:     Tue Oct 15 12:51:58 2013 UTC
Log:      Fixed bug in extractps instruction on ia32 and x64

This is a fixed version of https://codereview.chromium.org/27097002/
which was originally written by [email protected].

[email protected]

Review URL: https://codereview.chromium.org/27301003
http://code.google.com/p/v8/source/detail?r=17217

Modified:
 /branches/bleeding_edge/src/ia32/assembler-ia32.cc
 /branches/bleeding_edge/src/ia32/assembler-ia32.h
 /branches/bleeding_edge/src/ia32/disasm-ia32.cc
 /branches/bleeding_edge/src/x64/assembler-x64.cc
 /branches/bleeding_edge/src/x64/disasm-x64.cc
 /branches/bleeding_edge/test/cctest/test-assembler-ia32.cc
 /branches/bleeding_edge/test/cctest/test-assembler-x64.cc
 /branches/bleeding_edge/test/cctest/test-disasm-ia32.cc
 /branches/bleeding_edge/test/cctest/test-disasm-x64.cc

=======================================
--- /branches/bleeding_edge/src/ia32/assembler-ia32.cc Thu Oct 10 08:45:40 2013 UTC +++ /branches/bleeding_edge/src/ia32/assembler-ia32.cc Tue Oct 15 12:51:58 2013 UTC
@@ -2347,7 +2347,7 @@
   EMIT(0x0F);
   EMIT(0x3A);
   EMIT(0x17);
-  emit_sse_operand(dst, src);
+  emit_sse_operand(src, dst);
   EMIT(imm8);
 }

@@ -2484,6 +2484,11 @@
 void Assembler::emit_sse_operand(Register dst, XMMRegister src) {
   EMIT(0xC0 | dst.code() << 3 | src.code());
 }
+
+
+void Assembler::emit_sse_operand(XMMRegister dst, Register src) {
+  EMIT(0xC0 | (dst.code() << 3) | src.code());
+}


 void Assembler::Print() {
=======================================
--- /branches/bleeding_edge/src/ia32/assembler-ia32.h Thu Oct 10 08:45:40 2013 UTC +++ /branches/bleeding_edge/src/ia32/assembler-ia32.h Tue Oct 15 12:51:58 2013 UTC
@@ -1168,6 +1168,7 @@
   void emit_sse_operand(XMMRegister reg, const Operand& adr);
   void emit_sse_operand(XMMRegister dst, XMMRegister src);
   void emit_sse_operand(Register dst, XMMRegister src);
+  void emit_sse_operand(XMMRegister dst, Register src);

   byte* addr_at(int pos) { return buffer_ + pos; }

=======================================
--- /branches/bleeding_edge/src/ia32/disasm-ia32.cc Thu Sep 12 07:49:03 2013 UTC +++ /branches/bleeding_edge/src/ia32/disasm-ia32.cc Tue Oct 15 12:51:58 2013 UTC
@@ -942,13 +942,13 @@

     case SHORT_IMMEDIATE_INSTR: {
byte* addr = reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data+1));
-      AppendToBuffer("%s eax, %s", idesc.mnem, NameOfAddress(addr));
+      AppendToBuffer("%s eax,%s", idesc.mnem, NameOfAddress(addr));
       data += 5;
       break;
     }

     case BYTE_IMMEDIATE_INSTR: {
-      AppendToBuffer("%s al, 0x%x", idesc.mnem, data[1]);
+      AppendToBuffer("%s al,0x%x", idesc.mnem, data[1]);
       data += 2;
       break;
     }
@@ -1239,8 +1239,8 @@
               get_modrm(*data, &mod, &regop, &rm);
               int8_t imm8 = static_cast<int8_t>(data[1]);
               AppendToBuffer("extractps %s,%s,%d",
-                             NameOfCPURegister(regop),
-                             NameOfXMMRegister(rm),
+                             NameOfCPURegister(rm),
+                             NameOfXMMRegister(regop),
                              static_cast<int>(imm8));
               data += 2;
             } else if (*data == 0x22) {
=======================================
--- /branches/bleeding_edge/src/x64/assembler-x64.cc Thu Oct 10 08:45:40 2013 UTC +++ /branches/bleeding_edge/src/x64/assembler-x64.cc Tue Oct 15 12:51:58 2013 UTC
@@ -2554,15 +2554,15 @@


 void Assembler::extractps(Register dst, XMMRegister src, byte imm8) {
-  ASSERT(CpuFeatures::IsSupported(SSE4_1));
+  ASSERT(IsEnabled(SSE4_1));
   ASSERT(is_uint8(imm8));
   EnsureSpace ensure_space(this);
   emit(0x66);
-  emit_optional_rex_32(dst, src);
+  emit_optional_rex_32(src, dst);
   emit(0x0F);
   emit(0x3A);
   emit(0x17);
-  emit_sse_operand(dst, src);
+  emit_sse_operand(src, dst);
   emit(imm8);
 }

=======================================
--- /branches/bleeding_edge/src/x64/disasm-x64.cc Tue Sep 17 09:09:44 2013 UTC +++ /branches/bleeding_edge/src/x64/disasm-x64.cc Tue Oct 15 12:51:58 2013 UTC
@@ -1036,14 +1036,14 @@
         get_modrm(*current, &mod, &regop, &rm);
         AppendToBuffer("extractps ");  // reg/m32, xmm, imm8
         current += PrintRightOperand(current);
- AppendToBuffer(", %s, %d", NameOfCPURegister(regop), (*current) & 3);
+        AppendToBuffer(",%s,%d", NameOfXMMRegister(regop), (*current) & 3);
         current += 1;
       } else if (third_byte == 0x0b) {
         get_modrm(*current, &mod, &regop, &rm);
          // roundsd xmm, xmm/m64, imm8
-        AppendToBuffer("roundsd %s, ", NameOfCPURegister(regop));
-        current += PrintRightOperand(current);
-        AppendToBuffer(", %d", (*current) & 3);
+        AppendToBuffer("roundsd %s,", NameOfXMMRegister(regop));
+        current += PrintRightXMMOperand(current);
+        AppendToBuffer(",%d", (*current) & 3);
         current += 1;
       } else {
         UnimplementedInstruction();
@@ -1062,12 +1062,12 @@
         }  // else no immediate displacement.
         AppendToBuffer("nop");
       } else if (opcode == 0x28) {
-        AppendToBuffer("movapd %s, ", NameOfXMMRegister(regop));
+        AppendToBuffer("movapd %s,", NameOfXMMRegister(regop));
         current += PrintRightXMMOperand(current);
       } else if (opcode == 0x29) {
         AppendToBuffer("movapd ");
         current += PrintRightXMMOperand(current);
-        AppendToBuffer(", %s", NameOfXMMRegister(regop));
+        AppendToBuffer(",%s", NameOfXMMRegister(regop));
       } else if (opcode == 0x6E) {
         AppendToBuffer("mov%c %s,",
                        rex_w() ? 'q' : 'd',
@@ -1081,15 +1081,15 @@
         AppendToBuffer("mov%c ",
                        rex_w() ? 'q' : 'd');
         current += PrintRightOperand(current);
-        AppendToBuffer(", %s", NameOfXMMRegister(regop));
+        AppendToBuffer(",%s", NameOfXMMRegister(regop));
       } else if (opcode == 0x7F) {
         AppendToBuffer("movdqa ");
         current += PrintRightXMMOperand(current);
-        AppendToBuffer(", %s", NameOfXMMRegister(regop));
+        AppendToBuffer(",%s", NameOfXMMRegister(regop));
       } else if (opcode == 0xD6) {
         AppendToBuffer("movq ");
         current += PrintRightXMMOperand(current);
-        AppendToBuffer(", %s", NameOfXMMRegister(regop));
+        AppendToBuffer(",%s", NameOfXMMRegister(regop));
       } else if (opcode == 0x50) {
         AppendToBuffer("movmskpd %s,", NameOfCPURegister(regop));
         current += PrintRightXMMOperand(current);
@@ -1214,7 +1214,7 @@
     } else if (opcode == 0x7E) {
       int mod, regop, rm;
       get_modrm(*current, &mod, &regop, &rm);
-      AppendToBuffer("movq %s, ", NameOfXMMRegister(regop));
+      AppendToBuffer("movq %s,", NameOfXMMRegister(regop));
       current += PrintRightXMMOperand(current);
     } else {
       UnimplementedInstruction();
@@ -1238,7 +1238,7 @@
     // movaps xmm, xmm/m128
     int mod, regop, rm;
     get_modrm(*current, &mod, &regop, &rm);
-    AppendToBuffer("movaps %s, ", NameOfXMMRegister(regop));
+    AppendToBuffer("movaps %s,", NameOfXMMRegister(regop));
     current += PrintRightXMMOperand(current);

   } else if (opcode == 0x29) {
@@ -1247,7 +1247,7 @@
     get_modrm(*current, &mod, &regop, &rm);
     AppendToBuffer("movaps ");
     current += PrintRightXMMOperand(current);
-    AppendToBuffer(", %s", NameOfXMMRegister(regop));
+    AppendToBuffer(",%s", NameOfXMMRegister(regop));

   } else if (opcode == 0xA2) {
     // CPUID
@@ -1264,14 +1264,14 @@
     // xorps xmm, xmm/m128
     int mod, regop, rm;
     get_modrm(*current, &mod, &regop, &rm);
-    AppendToBuffer("xorps %s, ", NameOfXMMRegister(regop));
+    AppendToBuffer("xorps %s,", NameOfXMMRegister(regop));
     current += PrintRightXMMOperand(current);

   } else if (opcode == 0x50) {
     // movmskps reg, xmm
     int mod, regop, rm;
     get_modrm(*current, &mod, &regop, &rm);
-    AppendToBuffer("movmskps %s, ", NameOfCPURegister(regop));
+    AppendToBuffer("movmskps %s,", NameOfCPURegister(regop));
     current += PrintRightXMMOperand(current);

   } else if ((opcode & 0xF0) == 0x80) {
@@ -1450,7 +1450,7 @@
     case SHORT_IMMEDIATE_INSTR: {
       byte* addr =
           reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data + 1));
-      AppendToBuffer("%s rax, %s", idesc.mnem, NameOfAddress(addr));
+      AppendToBuffer("%s rax,%s", idesc.mnem, NameOfAddress(addr));
       data += 5;
       break;
     }
@@ -1599,7 +1599,7 @@
         if (reg == 0) {
           AppendToBuffer("nop");  // Common name for xchg rax,rax.
         } else {
-          AppendToBuffer("xchg%c rax, %s",
+          AppendToBuffer("xchg%c rax,%s",
                          operand_size_code(),
                          NameOfCPURegister(reg));
         }
@@ -1628,12 +1628,12 @@
         bool is_32bit = (opcode >= 0xB8);
         int reg = (opcode & 0x7) | (rex_b() ? 8 : 0);
         if (is_32bit) {
-          AppendToBuffer("mov%c %s, ",
+          AppendToBuffer("mov%c %s,",
                          operand_size_code(),
                          NameOfCPURegister(reg));
           data += PrintImmediate(data, OPERAND_DOUBLEWORD_SIZE);
         } else {
-          AppendToBuffer("movb %s, ",
+          AppendToBuffer("movb %s,",
                          NameOfByteCPURegister(reg));
           data += PrintImmediate(data, OPERAND_BYTE_SIZE);
         }
@@ -1755,7 +1755,7 @@
         break;

       case 0x3C:
- AppendToBuffer("cmp al, 0x%x", *reinterpret_cast<int8_t*>(data + 1)); + AppendToBuffer("cmp al,0x%x", *reinterpret_cast<int8_t*>(data + 1));
         data +=2;
         break;

=======================================
--- /branches/bleeding_edge/test/cctest/test-assembler-ia32.cc Thu Sep 19 08:54:58 2013 UTC +++ /branches/bleeding_edge/test/cctest/test-assembler-ia32.cc Tue Oct 15 12:51:58 2013 UTC
@@ -564,4 +564,35 @@
 #endif  // __GNUC__


+TEST(AssemblerIa32Extractps) {
+  CcTest::InitializeVM();
+  if (!CpuFeatures::IsSupported(SSE4_1)) return;
+
+  Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
+  HandleScope scope(isolate);
+  v8::internal::byte buffer[256];
+  MacroAssembler assm(isolate, buffer, sizeof buffer);
+  { CpuFeatureScope fscope2(&assm, SSE2);
+    CpuFeatureScope fscope41(&assm, SSE4_1);
+    __ movdbl(xmm1, Operand(esp, 4));
+    __ extractps(eax, xmm1, 0x1);
+    __ ret(0);
+  }
+
+  CodeDesc desc;
+  assm.GetCode(&desc);
+  Code* code = Code::cast(isolate->heap()->CreateCode(
+      desc,
+      Code::ComputeFlags(Code::STUB),
+      Handle<Code>())->ToObjectChecked());
+  CHECK(code->IsCode());
+#ifdef OBJECT_PRINT
+  Code::cast(code)->Print();
+#endif
+
+  F4 f = FUNCTION_CAST<F4>(Code::cast(code)->entry());
+  CHECK_EQ(0x7FF80000, f(OS::nan_value()));
+}
+
+
 #undef __
=======================================
--- /branches/bleeding_edge/test/cctest/test-assembler-x64.cc Thu Sep 19 13:30:47 2013 UTC +++ /branches/bleeding_edge/test/cctest/test-assembler-x64.cc Tue Oct 15 12:51:58 2013 UTC
@@ -35,34 +35,7 @@
 #include "serialize.h"
 #include "cctest.h"

-using v8::internal::Assembler;
-using v8::internal::Code;
-using v8::internal::CodeDesc;
-using v8::internal::FUNCTION_CAST;
-using v8::internal::Immediate;
-using v8::internal::Isolate;
-using v8::internal::Label;
-using v8::internal::OS;
-using v8::internal::Operand;
-using v8::internal::byte;
-using v8::internal::greater;
-using v8::internal::less_equal;
-using v8::internal::equal;
-using v8::internal::not_equal;
-using v8::internal::r13;
-using v8::internal::r15;
-using v8::internal::r8;
-using v8::internal::r9;
-using v8::internal::rax;
-using v8::internal::rbx;
-using v8::internal::rbp;
-using v8::internal::rcx;
-using v8::internal::rdi;
-using v8::internal::rdx;
-using v8::internal::rsi;
-using v8::internal::rsp;
-using v8::internal::times_1;
-using v8::internal::xmm0;
+using namespace v8::internal;

 // Test the x64 assembler by compiling some simple functions into
 // a buffer and executing them.  These tests do not initialize the
@@ -77,13 +50,14 @@
 typedef int (*F0)();
 typedef int (*F1)(int64_t x);
 typedef int (*F2)(int64_t x, int64_t y);
+typedef int (*F3)(double x);

 #ifdef _WIN64
-static const v8::internal::Register arg1 = rcx;
-static const v8::internal::Register arg2 = rdx;
+static const Register arg1 = rcx;
+static const Register arg2 = rdx;
 #else
-static const v8::internal::Register arg1 = rdi;
-static const v8::internal::Register arg2 = rsi;
+static const Register arg1 = rdi;
+static const Register arg2 = rsi;
 #endif

 #define __ assm.
@@ -366,7 +340,7 @@
 TEST(AssemblerMultiByteNop) {
   CcTest::InitializeVM();
   v8::HandleScope scope(CcTest::isolate());
-  v8::internal::byte buffer[1024];
+  byte buffer[1024];
   Isolate* isolate = CcTest::i_isolate();
   Assembler assm(isolate, buffer, sizeof(buffer));
   __ push(rbx);
@@ -420,7 +394,7 @@
   Code* code = Code::cast(isolate->heap()->CreateCode(
       desc,
       Code::ComputeFlags(Code::STUB),
-      v8::internal::Handle<Code>())->ToObjectChecked());
+      Handle<Code>())->ToObjectChecked());
   CHECK(code->IsCode());

   F0 f = FUNCTION_CAST<F0>(code->entry());
@@ -434,7 +408,7 @@

 void DoSSE2(const v8::FunctionCallbackInfo<v8::Value>& args) {
   v8::HandleScope scope(CcTest::isolate());
-  v8::internal::byte buffer[1024];
+  byte buffer[1024];

   CHECK(args[0]->IsArray());
   v8::Local<v8::Array> vec = v8::Local<v8::Array>::Cast(args[0]);
@@ -472,7 +446,7 @@
   Code* code = Code::cast(isolate->heap()->CreateCode(
       desc,
       Code::ComputeFlags(Code::STUB),
-      v8::internal::Handle<Code>())->ToObjectChecked());
+      Handle<Code>())->ToObjectChecked());
   CHECK(code->IsCode());

   F0 f = FUNCTION_CAST<F0>(code->entry());
@@ -517,4 +491,33 @@
 #endif  // __GNUC__


+TEST(AssemblerX64Extractps) {
+  CcTest::InitializeVM();
+  if (!CpuFeatures::IsSupported(SSE4_1)) return;
+
+  v8::HandleScope scope(CcTest::isolate());
+  byte buffer[256];
+  Isolate* isolate = CcTest::i_isolate();
+  Assembler assm(isolate, buffer, sizeof(buffer));
+  { CpuFeatureScope fscope2(&assm, SSE4_1);
+    __ extractps(rax, xmm0, 0x1);
+    __ ret(0);
+  }
+
+  CodeDesc desc;
+  assm.GetCode(&desc);
+  Code* code = Code::cast(isolate->heap()->CreateCode(
+      desc,
+      Code::ComputeFlags(Code::STUB),
+      Handle<Code>())->ToObjectChecked());
+  CHECK(code->IsCode());
+#ifdef OBJECT_PRINT
+  Code::cast(code)->Print();
+#endif
+
+  F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
+  CHECK_EQ(0x7FF80000, f(OS::nan_value()));
+}
+
+
 #undef __
=======================================
--- /branches/bleeding_edge/test/cctest/test-disasm-ia32.cc Mon Aug 26 09:37:39 2013 UTC +++ /branches/bleeding_edge/test/cctest/test-disasm-ia32.cc Tue Oct 15 12:51:58 2013 UTC
@@ -429,6 +429,7 @@
       CpuFeatureScope scope(&assm, SSE4_1);
       __ pextrd(eax, xmm0, 1);
       __ pinsrd(xmm1, eax, 0);
+      __ extractps(eax, xmm1, 0);
     }
   }

=======================================
--- /branches/bleeding_edge/test/cctest/test-disasm-x64.cc Thu Sep 19 09:46:15 2013 UTC +++ /branches/bleeding_edge/test/cctest/test-disasm-x64.cc Tue Oct 15 12:51:58 2013 UTC
@@ -391,6 +391,13 @@
       __ movaps(xmm1, xmm2);
     }
   }
+
+  {
+    if (CpuFeatures::IsSupported(SSE4_1)) {
+      CpuFeatureScope scope(&assm, SSE4_1);
+      __ extractps(rax, xmm1, 0);
+    }
+  }

   // Nop instructions
   for (int i = 0; i < 16; i++) {

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to