[x86] Introduce vandps/vandpd/vxorps/vxorpd.
authorWeiliang Lin <weiliang.lin@intel.com>
Sat, 11 Apr 2015 01:02:22 +0000 (09:02 +0800)
committerWeiliang Lin <weiliang.lin@intel.com>
Sat, 11 Apr 2015 00:58:38 +0000 (00:58 +0000)
R=bmeurer@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#27768}

16 files changed:
src/compiler/ia32/code-generator-ia32.cc
src/compiler/ia32/instruction-codes-ia32.h
src/compiler/ia32/instruction-selector-ia32.cc
src/compiler/x64/code-generator-x64.cc
src/compiler/x64/instruction-codes-x64.h
src/compiler/x64/instruction-selector-x64.cc
src/ia32/assembler-ia32.cc
src/ia32/assembler-ia32.h
src/ia32/disasm-ia32.cc
src/x64/assembler-x64.cc
src/x64/assembler-x64.h
src/x64/disasm-x64.cc
test/cctest/test-disasm-ia32.cc
test/cctest/test-disasm-x64.cc
test/unittests/compiler/ia32/instruction-selector-ia32-unittest.cc
test/unittests/compiler/x64/instruction-selector-x64-unittest.cc

index 586d5488e906c6c3777b8b2704b974671c32c205..aaa34dcfd66f3dcc58fc70edc50f044651074dbf 100644 (file)
@@ -480,7 +480,6 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
       break;
     case kSSEFloat32Abs: {
       // TODO(bmeurer): Use 128-bit constants.
-      // TODO(turbofan): Add AVX version with relaxed register constraints.
       __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
       __ psrlq(kScratchDoubleReg, 33);
       __ andps(i.OutputDoubleRegister(), kScratchDoubleReg);
@@ -488,7 +487,6 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
     }
     case kSSEFloat32Neg: {
       // TODO(bmeurer): Use 128-bit constants.
-      // TODO(turbofan): Add AVX version with relaxed register constraints.
       __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
       __ psllq(kScratchDoubleReg, 31);
       __ xorps(i.OutputDoubleRegister(), kScratchDoubleReg);
@@ -542,7 +540,6 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
     }
     case kSSEFloat64Abs: {
       // TODO(bmeurer): Use 128-bit constants.
-      // TODO(turbofan): Add AVX version with relaxed register constraints.
       __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
       __ psrlq(kScratchDoubleReg, 1);
       __ andpd(i.OutputDoubleRegister(), kScratchDoubleReg);
@@ -550,7 +547,6 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
     }
     case kSSEFloat64Neg: {
       // TODO(bmeurer): Use 128-bit constants.
-      // TODO(turbofan): Add AVX version with relaxed register constraints.
       __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
       __ psllq(kScratchDoubleReg, 63);
       __ xorpd(i.OutputDoubleRegister(), kScratchDoubleReg);
@@ -683,6 +679,38 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
                 i.InputOperand(1));
       break;
     }
+    case kAVXFloat32Abs: {
+      // TODO(bmeurer): Use RIP relative 128-bit constants.
+      __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
+      __ psrlq(kScratchDoubleReg, 33);
+      CpuFeatureScope avx_scope(masm(), AVX);
+      __ vandps(i.OutputDoubleRegister(), kScratchDoubleReg, i.InputOperand(0));
+      break;
+    }
+    case kAVXFloat32Neg: {
+      // TODO(bmeurer): Use RIP relative 128-bit constants.
+      __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
+      __ psllq(kScratchDoubleReg, 31);
+      CpuFeatureScope avx_scope(masm(), AVX);
+      __ vxorps(i.OutputDoubleRegister(), kScratchDoubleReg, i.InputOperand(0));
+      break;
+    }
+    case kAVXFloat64Abs: {
+      // TODO(bmeurer): Use RIP relative 128-bit constants.
+      __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
+      __ psrlq(kScratchDoubleReg, 1);
+      CpuFeatureScope avx_scope(masm(), AVX);
+      __ vandpd(i.OutputDoubleRegister(), kScratchDoubleReg, i.InputOperand(0));
+      break;
+    }
+    case kAVXFloat64Neg: {
+      // TODO(bmeurer): Use RIP relative 128-bit constants.
+      __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
+      __ psllq(kScratchDoubleReg, 63);
+      CpuFeatureScope avx_scope(masm(), AVX);
+      __ vxorpd(i.OutputDoubleRegister(), kScratchDoubleReg, i.InputOperand(0));
+      break;
+    }
     case kIA32Movsxbl:
       __ movsx_b(i.OutputRegister(), i.MemoryOperand());
       break;
index 472dd57e14fdf8328d9b8786ef6bd1f16b8c622b..3962040104c8f697b5272a053b230e99c090d0fb 100644 (file)
@@ -76,6 +76,10 @@ namespace compiler {
   V(AVXFloat64Div)                 \
   V(AVXFloat64Max)                 \
   V(AVXFloat64Min)                 \
+  V(AVXFloat64Abs)                 \
+  V(AVXFloat64Neg)                 \
+  V(AVXFloat32Abs)                 \
+  V(AVXFloat32Neg)                 \
   V(IA32Movsxbl)                   \
   V(IA32Movzxbl)                   \
   V(IA32Movb)                      \
index 93644a90be0b2f959bb39716ea92bb5c22430b1b..1eadc024f5c10817f939c669b024e0347a92b5e7 100644 (file)
@@ -153,6 +153,18 @@ void VisitRROFloat(InstructionSelector* selector, Node* node,
   }
 }
 
+
+void VisitFloatUnop(InstructionSelector* selector, Node* node, Node* input,
+                    ArchOpcode avx_opcode, ArchOpcode sse_opcode) {
+  IA32OperandGenerator g(selector);
+  if (selector->IsSupported(AVX)) {
+    selector->Emit(avx_opcode, g.DefineAsRegister(node), g.Use(input));
+  } else {
+    selector->Emit(sse_opcode, g.DefineSameAsFirst(node), g.UseRegister(input));
+  }
+}
+
+
 }  // namespace
 
 
@@ -684,8 +696,8 @@ void InstructionSelector::VisitFloat32Sub(Node* node) {
   IA32OperandGenerator g(this);
   Float32BinopMatcher m(node);
   if (m.left().IsMinusZero()) {
-    Emit(kSSEFloat32Neg, g.DefineSameAsFirst(node),
-         g.UseRegister(m.right().node()));
+    VisitFloatUnop(this, node, m.right().node(), kAVXFloat32Neg,
+                   kSSEFloat32Neg);
     return;
   }
   VisitRROFloat(this, node, kAVXFloat32Sub, kSSEFloat32Sub);
@@ -708,8 +720,8 @@ void InstructionSelector::VisitFloat64Sub(Node* node) {
         }
       }
     }
-    Emit(kSSEFloat64Neg, g.DefineSameAsFirst(node),
-         g.UseRegister(m.right().node()));
+    VisitFloatUnop(this, node, m.right().node(), kAVXFloat64Neg,
+                   kSSEFloat64Neg);
     return;
   }
   VisitRROFloat(this, node, kAVXFloat64Sub, kSSEFloat64Sub);
@@ -767,13 +779,13 @@ void InstructionSelector::VisitFloat64Min(Node* node) {
 
 void InstructionSelector::VisitFloat32Abs(Node* node) {
   IA32OperandGenerator g(this);
-  Emit(kSSEFloat32Abs, g.DefineSameAsFirst(node), g.Use(node->InputAt(0)));
+  VisitFloatUnop(this, node, node->InputAt(0), kAVXFloat32Abs, kSSEFloat32Abs);
 }
 
 
 void InstructionSelector::VisitFloat64Abs(Node* node) {
   IA32OperandGenerator g(this);
-  Emit(kSSEFloat64Abs, g.DefineSameAsFirst(node), g.Use(node->InputAt(0)));
+  VisitFloatUnop(this, node, node->InputAt(0), kAVXFloat64Abs, kSSEFloat64Abs);
 }
 
 
index c13e1697c442fc34b031b9f12a19e9f4b67e9cc2..1e5d62f7e3c522a336c29bbf9214d5d24afc5d3a 100644 (file)
@@ -729,7 +729,6 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
       break;
     case kSSEFloat32Abs: {
       // TODO(bmeurer): Use RIP relative 128-bit constants.
-      // TODO(turbofan): Add AVX version with relaxed register constraints.
       __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
       __ psrlq(kScratchDoubleReg, 33);
       __ andps(i.OutputDoubleRegister(), kScratchDoubleReg);
@@ -737,7 +736,6 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
     }
     case kSSEFloat32Neg: {
       // TODO(bmeurer): Use RIP relative 128-bit constants.
-      // TODO(turbofan): Add AVX version with relaxed register constraints.
       __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
       __ psllq(kScratchDoubleReg, 31);
       __ xorps(i.OutputDoubleRegister(), kScratchDoubleReg);
@@ -810,7 +808,6 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
       break;
     case kSSEFloat64Abs: {
       // TODO(bmeurer): Use RIP relative 128-bit constants.
-      // TODO(turbofan): Add AVX version with relaxed register constraints.
       __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
       __ psrlq(kScratchDoubleReg, 1);
       __ andpd(i.OutputDoubleRegister(), kScratchDoubleReg);
@@ -818,7 +815,6 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
     }
     case kSSEFloat64Neg: {
       // TODO(bmeurer): Use RIP relative 128-bit constants.
-      // TODO(turbofan): Add AVX version with relaxed register constraints.
       __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
       __ psllq(kScratchDoubleReg, 63);
       __ xorpd(i.OutputDoubleRegister(), kScratchDoubleReg);
@@ -957,6 +953,62 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
     case kAVXFloat64Min:
       ASSEMBLE_AVX_BINOP(vminsd);
       break;
+    case kAVXFloat32Abs: {
+      // TODO(bmeurer): Use RIP relative 128-bit constants.
+      __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
+      __ psrlq(kScratchDoubleReg, 33);
+      CpuFeatureScope avx_scope(masm(), AVX);
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ vandps(i.OutputDoubleRegister(), kScratchDoubleReg,
+                  i.InputDoubleRegister(0));
+      } else {
+        __ vandps(i.OutputDoubleRegister(), kScratchDoubleReg,
+                  i.InputOperand(0));
+      }
+      break;
+    }
+    case kAVXFloat32Neg: {
+      // TODO(bmeurer): Use RIP relative 128-bit constants.
+      __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
+      __ psllq(kScratchDoubleReg, 31);
+      CpuFeatureScope avx_scope(masm(), AVX);
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ vxorps(i.OutputDoubleRegister(), kScratchDoubleReg,
+                  i.InputDoubleRegister(0));
+      } else {
+        __ vxorps(i.OutputDoubleRegister(), kScratchDoubleReg,
+                  i.InputOperand(0));
+      }
+      break;
+    }
+    case kAVXFloat64Abs: {
+      // TODO(bmeurer): Use RIP relative 128-bit constants.
+      __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
+      __ psrlq(kScratchDoubleReg, 1);
+      CpuFeatureScope avx_scope(masm(), AVX);
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ vandpd(i.OutputDoubleRegister(), kScratchDoubleReg,
+                  i.InputDoubleRegister(0));
+      } else {
+        __ vandpd(i.OutputDoubleRegister(), kScratchDoubleReg,
+                  i.InputOperand(0));
+      }
+      break;
+    }
+    case kAVXFloat64Neg: {
+      // TODO(bmeurer): Use RIP relative 128-bit constants.
+      __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
+      __ psllq(kScratchDoubleReg, 63);
+      CpuFeatureScope avx_scope(masm(), AVX);
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ vxorpd(i.OutputDoubleRegister(), kScratchDoubleReg,
+                  i.InputDoubleRegister(0));
+      } else {
+        __ vxorpd(i.OutputDoubleRegister(), kScratchDoubleReg,
+                  i.InputOperand(0));
+      }
+      break;
+    }
     case kX64Movsxbl:
       ASSEMBLE_MOVX(movsxbl);
       __ AssertZeroExtended(i.OutputRegister());
index 87e011006899d0ec5c31ca21b1fdc3b64cc5382f..428b7dc1865ee74dc1fc51694dcb016f6db6e59d 100644 (file)
@@ -94,6 +94,10 @@ namespace compiler {
   V(AVXFloat64Div)                 \
   V(AVXFloat64Max)                 \
   V(AVXFloat64Min)                 \
+  V(AVXFloat64Abs)                 \
+  V(AVXFloat64Neg)                 \
+  V(AVXFloat32Abs)                 \
+  V(AVXFloat32Neg)                 \
   V(X64Movsxbl)                    \
   V(X64Movzxbl)                    \
   V(X64Movb)                       \
index 68bc0352270b283fef2a1a2dd7f691fa0064842c..21db735b40176dd3ee76f935514e059c997322a7 100644 (file)
@@ -856,6 +856,18 @@ void VisitFloatBinop(InstructionSelector* selector, Node* node,
   }
 }
 
+
+void VisitFloatUnop(InstructionSelector* selector, Node* node, Node* input,
+                    ArchOpcode avx_opcode, ArchOpcode sse_opcode) {
+  X64OperandGenerator g(selector);
+  if (selector->IsSupported(AVX)) {
+    selector->Emit(avx_opcode, g.DefineAsRegister(node), g.Use(input));
+  } else {
+    selector->Emit(sse_opcode, g.DefineSameAsFirst(node), g.UseRegister(input));
+  }
+}
+
+
 }  // namespace
 
 
@@ -868,8 +880,8 @@ void InstructionSelector::VisitFloat32Sub(Node* node) {
   X64OperandGenerator g(this);
   Float32BinopMatcher m(node);
   if (m.left().IsMinusZero()) {
-    Emit(kSSEFloat32Neg, g.DefineSameAsFirst(node),
-         g.UseRegister(m.right().node()));
+    VisitFloatUnop(this, node, m.right().node(), kAVXFloat32Neg,
+                   kSSEFloat32Neg);
     return;
   }
   VisitFloatBinop(this, node, kAVXFloat32Sub, kSSEFloat32Sub);
@@ -898,7 +910,7 @@ void InstructionSelector::VisitFloat32Min(Node* node) {
 
 void InstructionSelector::VisitFloat32Abs(Node* node) {
   X64OperandGenerator g(this);
-  Emit(kSSEFloat32Abs, g.DefineSameAsFirst(node), g.Use(node->InputAt(0)));
+  VisitFloatUnop(this, node, node->InputAt(0), kAVXFloat32Abs, kSSEFloat32Abs);
 }
 
 
@@ -929,8 +941,8 @@ void InstructionSelector::VisitFloat64Sub(Node* node) {
         }
       }
     }
-    Emit(kSSEFloat64Neg, g.DefineSameAsFirst(node),
-         g.UseRegister(m.right().node()));
+    VisitFloatUnop(this, node, m.right().node(), kAVXFloat64Neg,
+                   kSSEFloat64Neg);
     return;
   }
   VisitFloatBinop(this, node, kAVXFloat64Sub, kSSEFloat64Sub);
@@ -968,7 +980,7 @@ void InstructionSelector::VisitFloat64Min(Node* node) {
 
 void InstructionSelector::VisitFloat64Abs(Node* node) {
   X64OperandGenerator g(this);
-  Emit(kSSEFloat64Abs, g.DefineSameAsFirst(node), g.Use(node->InputAt(0)));
+  VisitFloatUnop(this, node, node->InputAt(0), kAVXFloat64Abs, kSSEFloat64Abs);
 }
 
 
index 98caaeb897133bd73352fef683a155c284debd69..a3c19af7866bc144e2b2b37acce21ef7ce630f9b 100644 (file)
@@ -2665,6 +2665,26 @@ void Assembler::vss(byte op, XMMRegister dst, XMMRegister src1,
 }
 
 
+void Assembler::vps(byte op, XMMRegister dst, XMMRegister src1,
+                    const Operand& src2) {
+  DCHECK(IsEnabled(AVX));
+  EnsureSpace ensure_space(this);
+  emit_vex_prefix(src1, kL128, kNone, k0F, kWIG);
+  EMIT(op);
+  emit_sse_operand(dst, src2);
+}
+
+
+void Assembler::vpd(byte op, XMMRegister dst, XMMRegister src1,
+                    const Operand& src2) {
+  DCHECK(IsEnabled(AVX));
+  EnsureSpace ensure_space(this);
+  emit_vex_prefix(src1, kL128, k66, k0F, kWIG);
+  EMIT(op);
+  emit_sse_operand(dst, src2);
+}
+
+
 void Assembler::bmi1(byte op, Register reg, Register vreg, const Operand& rm) {
   DCHECK(IsEnabled(BMI1));
   EnsureSpace ensure_space(this);
index bb8098daee4fb41329460cbb074f7896983a0826..48f06037525cf48c30ce1eea9206b55235630e1a 100644 (file)
@@ -1398,6 +1398,30 @@ class Assembler : public AssemblerBase {
   }
   void rorx(Register dst, const Operand& src, byte imm8);
 
+#define PACKED_OP_LIST(V) \
+  V(and, 0x54)            \
+  V(xor, 0x57)
+
+#define AVX_PACKED_OP_DECLARE(name, opcode)                                  \
+  void v##name##ps(XMMRegister dst, XMMRegister src1, XMMRegister src2) {    \
+    vps(opcode, dst, src1, Operand(src2));                                   \
+  }                                                                          \
+  void v##name##ps(XMMRegister dst, XMMRegister src1, const Operand& src2) { \
+    vps(opcode, dst, src1, src2);                                            \
+  }                                                                          \
+  void v##name##pd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {    \
+    vpd(opcode, dst, src1, Operand(src2));                                   \
+  }                                                                          \
+  void v##name##pd(XMMRegister dst, XMMRegister src1, const Operand& src2) { \
+    vpd(opcode, dst, src1, src2);                                            \
+  }
+
+  PACKED_OP_LIST(AVX_PACKED_OP_DECLARE);
+  void vps(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
+  void vps(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
+  void vpd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
+  void vpd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
+
   // Prefetch src position into cache level.
   // Level 1, 2 or 3 specifies CPU cache level. Level 0 specifies a
   // non-temporal
index d13127773aa9869c01fbf2e848d1af1ece8c5df0..80ac52864e04a3720da94b8495cb30a4ec80e490 100644 (file)
@@ -985,6 +985,40 @@ int DisassemblerIA32::AVXInstruction(byte* data) {
       default:
         UnimplementedInstruction();
     }
+  } else if (vex_none() && vex_0f()) {
+    int mod, regop, rm, vvvv = vex_vreg();
+    get_modrm(*current, &mod, &regop, &rm);
+    switch (opcode) {
+      case 0x54:
+        AppendToBuffer("vandps %s,%s,", NameOfXMMRegister(regop),
+                       NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0x57:
+        AppendToBuffer("vxorps %s,%s,", NameOfXMMRegister(regop),
+                       NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      default:
+        UnimplementedInstruction();
+    }
+  } else if (vex_66() && vex_0f()) {
+    int mod, regop, rm, vvvv = vex_vreg();
+    get_modrm(*current, &mod, &regop, &rm);
+    switch (opcode) {
+      case 0x54:
+        AppendToBuffer("vandpd %s,%s,", NameOfXMMRegister(regop),
+                       NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0x57:
+        AppendToBuffer("vxorpd %s,%s,", NameOfXMMRegister(regop),
+                       NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      default:
+        UnimplementedInstruction();
+    }
   } else {
     UnimplementedInstruction();
   }
index 7637b3342e489136587d50f246a68826f84efb84..cafa402fd6ca124a5d8e832655d42934d19819c0 100644 (file)
@@ -3510,6 +3510,46 @@ void Assembler::vsd(byte op, XMMRegister dst, XMMRegister src1,
 }
 
 
+void Assembler::vps(byte op, XMMRegister dst, XMMRegister src1,
+                    XMMRegister src2) {
+  DCHECK(IsEnabled(AVX));
+  EnsureSpace ensure_space(this);
+  emit_vex_prefix(dst, src1, src2, kL128, kNone, k0F, kWIG);
+  emit(op);
+  emit_sse_operand(dst, src2);
+}
+
+
+void Assembler::vps(byte op, XMMRegister dst, XMMRegister src1,
+                    const Operand& src2) {
+  DCHECK(IsEnabled(AVX));
+  EnsureSpace ensure_space(this);
+  emit_vex_prefix(dst, src1, src2, kL128, kNone, k0F, kWIG);
+  emit(op);
+  emit_sse_operand(dst, src2);
+}
+
+
+void Assembler::vpd(byte op, XMMRegister dst, XMMRegister src1,
+                    XMMRegister src2) {
+  DCHECK(IsEnabled(AVX));
+  EnsureSpace ensure_space(this);
+  emit_vex_prefix(dst, src1, src2, kL128, k66, k0F, kWIG);
+  emit(op);
+  emit_sse_operand(dst, src2);
+}
+
+
+void Assembler::vpd(byte op, XMMRegister dst, XMMRegister src1,
+                    const Operand& src2) {
+  DCHECK(IsEnabled(AVX));
+  EnsureSpace ensure_space(this);
+  emit_vex_prefix(dst, src1, src2, kL128, k66, k0F, kWIG);
+  emit(op);
+  emit_sse_operand(dst, src2);
+}
+
+
 void Assembler::vucomiss(XMMRegister dst, XMMRegister src) {
   DCHECK(IsEnabled(AVX));
   EnsureSpace ensure_space(this);
index 291ee7fcb4587f2c48b7c7583ac4a669f76569cb..27f04419a3f79abf12e62194ea06496393ac021e 100644 (file)
@@ -1582,6 +1582,30 @@ class Assembler : public AssemblerBase {
   void rorxl(Register dst, Register src, byte imm8);
   void rorxl(Register dst, const Operand& src, byte imm8);
 
+#define PACKED_OP_LIST(V) \
+  V(and, 0x54)            \
+  V(xor, 0x57)
+
+#define AVX_PACKED_OP_DECLARE(name, opcode)                                  \
+  void v##name##ps(XMMRegister dst, XMMRegister src1, XMMRegister src2) {    \
+    vps(opcode, dst, src1, src2);                                            \
+  }                                                                          \
+  void v##name##ps(XMMRegister dst, XMMRegister src1, const Operand& src2) { \
+    vps(opcode, dst, src1, src2);                                            \
+  }                                                                          \
+  void v##name##pd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {    \
+    vpd(opcode, dst, src1, src2);                                            \
+  }                                                                          \
+  void v##name##pd(XMMRegister dst, XMMRegister src1, const Operand& src2) { \
+    vpd(opcode, dst, src1, src2);                                            \
+  }
+
+  PACKED_OP_LIST(AVX_PACKED_OP_DECLARE);
+  void vps(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
+  void vps(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
+  void vpd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
+  void vpd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
+
   // Debugging
   void Print();
 
index 4799a32f23db7027c331a6070968b1cdd0ef7f6e..c70684d99f5da0400ed5ca33d895b8c38348822e 100644 (file)
@@ -876,13 +876,7 @@ int DisassemblerX64::SetCC(byte* data) {
 int DisassemblerX64::AVXInstruction(byte* data) {
   byte opcode = *data;
   byte* current = data + 1;
-  if (vex_0f() && opcode == 0x2e) {
-    int mod, regop, rm;
-    get_modrm(*current, &mod, &regop, &rm);
-    AppendToBuffer("vucomis%c %s,", vex_66() ? 'd' : 's',
-                   NameOfXMMRegister(regop));
-    current += PrintRightXMMOperand(current);
-  } else if (vex_66() && vex_0f38()) {
+  if (vex_66() && vex_0f38()) {
     int mod, regop, rm, vvvv = vex_vreg();
     get_modrm(*current, &mod, &regop, &rm);
     switch (opcode) {
@@ -1137,6 +1131,49 @@ int DisassemblerX64::AVXInstruction(byte* data) {
       default:
         UnimplementedInstruction();
     }
+  } else if (vex_none() && vex_0f()) {
+    int mod, regop, rm, vvvv = vex_vreg();
+    get_modrm(*current, &mod, &regop, &rm);
+    switch (opcode) {
+      case 0x2e:
+        AppendToBuffer("vucomiss %s,", NameOfXMMRegister(regop));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0x54:
+        AppendToBuffer("vandps %s,%s,", NameOfXMMRegister(regop),
+                       NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0x57:
+        AppendToBuffer("vxorps %s,%s,", NameOfXMMRegister(regop),
+                       NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      default:
+        UnimplementedInstruction();
+    }
+  } else if (vex_66() && vex_0f()) {
+    int mod, regop, rm, vvvv = vex_vreg();
+    get_modrm(*current, &mod, &regop, &rm);
+    switch (opcode) {
+      case 0x2e:
+        AppendToBuffer("vucomisd %s,", NameOfXMMRegister(regop));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0x54:
+        AppendToBuffer("vandpd %s,%s,", NameOfXMMRegister(regop),
+                       NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0x57:
+        AppendToBuffer("vxorpd %s,%s,", NameOfXMMRegister(regop),
+                       NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      default:
+        UnimplementedInstruction();
+    }
+
   } else {
     UnimplementedInstruction();
   }
index 52df2fd039b5b82c3dcd894a75ee6389625fd82f..aeaa99538bbfee708099ea913988995d16150c0a 100644 (file)
@@ -525,6 +525,16 @@ TEST(DisasmIa320) {
       __ vminss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
       __ vmaxss(xmm0, xmm1, xmm2);
       __ vmaxss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+
+      __ vandps(xmm0, xmm1, xmm2);
+      __ vandps(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+      __ vxorps(xmm0, xmm1, xmm2);
+      __ vxorps(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+
+      __ vandpd(xmm0, xmm1, xmm2);
+      __ vandpd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+      __ vxorpd(xmm0, xmm1, xmm2);
+      __ vxorpd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
     }
   }
 
index 072b3b8426148c60423cd7ace1eb6f258c2c0e46..bcfe507b25c4bfa755f4bf059c1c600efdeafb28 100644 (file)
@@ -525,6 +525,16 @@ TEST(DisasmX64) {
       __ vmaxsd(xmm9, xmm1, Operand(rbx, rcx, times_1, 10000));
       __ vucomisd(xmm9, xmm1);
       __ vucomisd(xmm8, Operand(rbx, rdx, times_2, 10981));
+
+      __ vandps(xmm0, xmm9, xmm2);
+      __ vandps(xmm9, xmm1, Operand(rbx, rcx, times_4, 10000));
+      __ vxorps(xmm0, xmm1, xmm9);
+      __ vxorps(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
+
+      __ vandpd(xmm0, xmm9, xmm2);
+      __ vandpd(xmm9, xmm1, Operand(rbx, rcx, times_4, 10000));
+      __ vxorpd(xmm0, xmm1, xmm9);
+      __ vxorpd(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
     }
   }
 
index f43de4a4764883d6dce186fe9d5bae620b054dc4..4c8e0c043104ff8b8d12d21a93cb6f46c969f42b 100644 (file)
@@ -640,36 +640,68 @@ TEST_F(InstructionSelectorTest, Int32MulHigh) {
 
 
 TEST_F(InstructionSelectorTest, Float32Abs) {
-  StreamBuilder m(this, kMachFloat32, kMachFloat32);
-  Node* const p0 = m.Parameter(0);
-  Node* const n = m.Float32Abs(p0);
-  m.Return(n);
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(kSSEFloat32Abs, s[0]->arch_opcode());
-  ASSERT_EQ(1U, s[0]->InputCount());
-  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
-  ASSERT_EQ(1U, s[0]->OutputCount());
-  EXPECT_TRUE(s.IsSameAsFirst(s[0]->Output()));
-  EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
-  EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  {
+    StreamBuilder m(this, kMachFloat32, kMachFloat32);
+    Node* const p0 = m.Parameter(0);
+    Node* const n = m.Float32Abs(p0);
+    m.Return(n);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kSSEFloat32Abs, s[0]->arch_opcode());
+    ASSERT_EQ(1U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_TRUE(s.IsSameAsFirst(s[0]->Output()));
+    EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  }
+  {
+    StreamBuilder m(this, kMachFloat32, kMachFloat32);
+    Node* const p0 = m.Parameter(0);
+    Node* const n = m.Float32Abs(p0);
+    m.Return(n);
+    Stream s = m.Build(AVX);
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kAVXFloat32Abs, s[0]->arch_opcode());
+    ASSERT_EQ(1U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  }
 }
 
 
 TEST_F(InstructionSelectorTest, Float64Abs) {
-  StreamBuilder m(this, kMachFloat64, kMachFloat64);
-  Node* const p0 = m.Parameter(0);
-  Node* const n = m.Float64Abs(p0);
-  m.Return(n);
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(kSSEFloat64Abs, s[0]->arch_opcode());
-  ASSERT_EQ(1U, s[0]->InputCount());
-  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
-  ASSERT_EQ(1U, s[0]->OutputCount());
-  EXPECT_TRUE(s.IsSameAsFirst(s[0]->Output()));
-  EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
-  EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  {
+    StreamBuilder m(this, kMachFloat64, kMachFloat64);
+    Node* const p0 = m.Parameter(0);
+    Node* const n = m.Float64Abs(p0);
+    m.Return(n);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kSSEFloat64Abs, s[0]->arch_opcode());
+    ASSERT_EQ(1U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_TRUE(s.IsSameAsFirst(s[0]->Output()));
+    EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  }
+  {
+    StreamBuilder m(this, kMachFloat64, kMachFloat64);
+    Node* const p0 = m.Parameter(0);
+    Node* const n = m.Float64Abs(p0);
+    m.Return(n);
+    Stream s = m.Build(AVX);
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kAVXFloat64Abs, s[0]->arch_opcode());
+    ASSERT_EQ(1U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  }
 }
 
 
@@ -706,34 +738,66 @@ TEST_F(InstructionSelectorTest, Float64BinopArithmetic) {
 
 
 TEST_F(InstructionSelectorTest, Float32SubWithMinusZeroAndParameter) {
-  StreamBuilder m(this, kMachFloat32, kMachFloat32);
-  Node* const p0 = m.Parameter(0);
-  Node* const n = m.Float32Sub(m.Float32Constant(-0.0f), p0);
-  m.Return(n);
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(kSSEFloat32Neg, s[0]->arch_opcode());
-  ASSERT_EQ(1U, s[0]->InputCount());
-  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
-  ASSERT_EQ(1U, s[0]->OutputCount());
-  EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
-  EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  {
+    StreamBuilder m(this, kMachFloat32, kMachFloat32);
+    Node* const p0 = m.Parameter(0);
+    Node* const n = m.Float32Sub(m.Float32Constant(-0.0f), p0);
+    m.Return(n);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kSSEFloat32Neg, s[0]->arch_opcode());
+    ASSERT_EQ(1U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  }
+  {
+    StreamBuilder m(this, kMachFloat32, kMachFloat32);
+    Node* const p0 = m.Parameter(0);
+    Node* const n = m.Float32Sub(m.Float32Constant(-0.0f), p0);
+    m.Return(n);
+    Stream s = m.Build(AVX);
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kAVXFloat32Neg, s[0]->arch_opcode());
+    ASSERT_EQ(1U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  }
 }
 
 
 TEST_F(InstructionSelectorTest, Float64SubWithMinusZeroAndParameter) {
-  StreamBuilder m(this, kMachFloat64, kMachFloat64);
-  Node* const p0 = m.Parameter(0);
-  Node* const n = m.Float64Sub(m.Float64Constant(-0.0), p0);
-  m.Return(n);
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(kSSEFloat64Neg, s[0]->arch_opcode());
-  ASSERT_EQ(1U, s[0]->InputCount());
-  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
-  ASSERT_EQ(1U, s[0]->OutputCount());
-  EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
-  EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  {
+    StreamBuilder m(this, kMachFloat64, kMachFloat64);
+    Node* const p0 = m.Parameter(0);
+    Node* const n = m.Float64Sub(m.Float64Constant(-0.0), p0);
+    m.Return(n);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kSSEFloat64Neg, s[0]->arch_opcode());
+    ASSERT_EQ(1U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  }
+  {
+    StreamBuilder m(this, kMachFloat64, kMachFloat64);
+    Node* const p0 = m.Parameter(0);
+    Node* const n = m.Float64Sub(m.Float64Constant(-0.0), p0);
+    m.Return(n);
+    Stream s = m.Build(AVX);
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kAVXFloat64Neg, s[0]->arch_opcode());
+    ASSERT_EQ(1U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  }
 }
 
 
index 226b55abdfe272814c402dcc3ff8a16859d85c42..0b46b32306b3a26b847e030aa7d8a0d39b54e913 100644 (file)
@@ -997,36 +997,68 @@ TEST_F(InstructionSelectorTest, Int32Shl4BecomesLea) {
 
 
 TEST_F(InstructionSelectorTest, Float32Abs) {
-  StreamBuilder m(this, kMachFloat32, kMachFloat32);
-  Node* const p0 = m.Parameter(0);
-  Node* const n = m.Float32Abs(p0);
-  m.Return(n);
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(kSSEFloat32Abs, s[0]->arch_opcode());
-  ASSERT_EQ(1U, s[0]->InputCount());
-  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
-  ASSERT_EQ(1U, s[0]->OutputCount());
-  EXPECT_TRUE(s.IsSameAsFirst(s[0]->Output()));
-  EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
-  EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  {
+    StreamBuilder m(this, kMachFloat32, kMachFloat32);
+    Node* const p0 = m.Parameter(0);
+    Node* const n = m.Float32Abs(p0);
+    m.Return(n);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kSSEFloat32Abs, s[0]->arch_opcode());
+    ASSERT_EQ(1U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_TRUE(s.IsSameAsFirst(s[0]->Output()));
+    EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  }
+  {
+    StreamBuilder m(this, kMachFloat32, kMachFloat32);
+    Node* const p0 = m.Parameter(0);
+    Node* const n = m.Float32Abs(p0);
+    m.Return(n);
+    Stream s = m.Build(AVX);
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kAVXFloat32Abs, s[0]->arch_opcode());
+    ASSERT_EQ(1U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  }
 }
 
 
 TEST_F(InstructionSelectorTest, Float64Abs) {
-  StreamBuilder m(this, kMachFloat64, kMachFloat64);
-  Node* const p0 = m.Parameter(0);
-  Node* const n = m.Float64Abs(p0);
-  m.Return(n);
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(kSSEFloat64Abs, s[0]->arch_opcode());
-  ASSERT_EQ(1U, s[0]->InputCount());
-  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
-  ASSERT_EQ(1U, s[0]->OutputCount());
-  EXPECT_TRUE(s.IsSameAsFirst(s[0]->Output()));
-  EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
-  EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  {
+    StreamBuilder m(this, kMachFloat64, kMachFloat64);
+    Node* const p0 = m.Parameter(0);
+    Node* const n = m.Float64Abs(p0);
+    m.Return(n);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kSSEFloat64Abs, s[0]->arch_opcode());
+    ASSERT_EQ(1U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_TRUE(s.IsSameAsFirst(s[0]->Output()));
+    EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  }
+  {
+    StreamBuilder m(this, kMachFloat64, kMachFloat64);
+    Node* const p0 = m.Parameter(0);
+    Node* const n = m.Float64Abs(p0);
+    m.Return(n);
+    Stream s = m.Build(AVX);
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kAVXFloat64Abs, s[0]->arch_opcode());
+    ASSERT_EQ(1U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  }
 }
 
 
@@ -1063,34 +1095,66 @@ TEST_F(InstructionSelectorTest, Float64BinopArithmetic) {
 
 
 TEST_F(InstructionSelectorTest, Float32SubWithMinusZeroAndParameter) {
-  StreamBuilder m(this, kMachFloat32, kMachFloat32);
-  Node* const p0 = m.Parameter(0);
-  Node* const n = m.Float32Sub(m.Float32Constant(-0.0f), p0);
-  m.Return(n);
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(kSSEFloat32Neg, s[0]->arch_opcode());
-  ASSERT_EQ(1U, s[0]->InputCount());
-  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
-  ASSERT_EQ(1U, s[0]->OutputCount());
-  EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
-  EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  {
+    StreamBuilder m(this, kMachFloat32, kMachFloat32);
+    Node* const p0 = m.Parameter(0);
+    Node* const n = m.Float32Sub(m.Float32Constant(-0.0f), p0);
+    m.Return(n);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kSSEFloat32Neg, s[0]->arch_opcode());
+    ASSERT_EQ(1U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  }
+  {
+    StreamBuilder m(this, kMachFloat32, kMachFloat32);
+    Node* const p0 = m.Parameter(0);
+    Node* const n = m.Float32Sub(m.Float32Constant(-0.0f), p0);
+    m.Return(n);
+    Stream s = m.Build(AVX);
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kAVXFloat32Neg, s[0]->arch_opcode());
+    ASSERT_EQ(1U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  }
 }
 
 
 TEST_F(InstructionSelectorTest, Float64SubWithMinusZeroAndParameter) {
-  StreamBuilder m(this, kMachFloat64, kMachFloat64);
-  Node* const p0 = m.Parameter(0);
-  Node* const n = m.Float64Sub(m.Float64Constant(-0.0), p0);
-  m.Return(n);
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(kSSEFloat64Neg, s[0]->arch_opcode());
-  ASSERT_EQ(1U, s[0]->InputCount());
-  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
-  ASSERT_EQ(1U, s[0]->OutputCount());
-  EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
-  EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  {
+    StreamBuilder m(this, kMachFloat64, kMachFloat64);
+    Node* const p0 = m.Parameter(0);
+    Node* const n = m.Float64Sub(m.Float64Constant(-0.0), p0);
+    m.Return(n);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kSSEFloat64Neg, s[0]->arch_opcode());
+    ASSERT_EQ(1U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  }
+  {
+    StreamBuilder m(this, kMachFloat64, kMachFloat64);
+    Node* const p0 = m.Parameter(0);
+    Node* const n = m.Float64Sub(m.Float64Constant(-0.0), p0);
+    m.Return(n);
+    Stream s = m.Build(AVX);
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kAVXFloat64Neg, s[0]->arch_opcode());
+    ASSERT_EQ(1U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  }
 }