]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
More support for memchecking 128-bit SIMD code.
authorJulian Seward <jseward@acm.org>
Fri, 10 Dec 2004 14:59:57 +0000 (14:59 +0000)
committerJulian Seward <jseward@acm.org>
Fri, 10 Dec 2004 14:59:57 +0000 (14:59 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@644

VEX/priv/host-x86/hdefs.c
VEX/priv/host-x86/isel.c
VEX/priv/ir/irdefs.c
VEX/pub/libvex_guest_x86.h
VEX/pub/libvex_ir.h

index d61f2164715e2e9eaeaf024417b5fac7ddd1a1e4..c6d472fdc56d15c2d341fee603b3fe3c8cefad70 100644 (file)
@@ -1855,6 +1855,8 @@ Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i )
                         subopc_imm = 0; opc_imma = 0x05; break;
          case Xalu_SUB: opc = 0x2B; opc_rr = 0x29; 
                         subopc_imm = 5; opc_imma = 0x2D; break;
+         case Xalu_SBB: opc = 0x1B; opc_rr = 0x19; 
+                        subopc_imm = 3; opc_imma = 0x1D; break;
          case Xalu_AND: opc = 0x23; opc_rr = 0x21; 
                         subopc_imm = 4; opc_imma = 0x25; break;
          case Xalu_XOR: opc = 0x33; opc_rr = 0x31; 
index a913691687c88d63aa21dfd5df89afd2989e72da..7d14df253a914a7d62a8760190642f53867d5b92 100644 (file)
@@ -2450,6 +2450,33 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e )
    if (e->tag == Iex_Unop) {
    switch (e->Iex.Unop.op) {
 
+      case Iop_CmpNEZ32x4: {
+         /* sigh, we have to generate crappy code for SSE1 */
+         /* basically, the idea is: for each lane:
+               movl lane, %r ; negl %r   (now CF = lane==0 ? 0 : 1)
+               sbbl %r, %r               (now %r = 1Sto32(CF))
+               movl %r, lane
+         */
+         Int       i;
+         X86AMode* am;
+         X86AMode* esp0 = X86AMode_IR(0, hregX86_ESP());
+         HReg      arg  = iselVecExpr(env, e->Iex.Unop.arg);
+         HReg      dst  = newVRegV(env);
+         HReg      r32  = newVRegI(env);
+         sub_from_esp(env, 16);
+         addInstr(env, X86Instr_SseLdSt(False/*store*/, arg, esp0));
+         for (i = 0; i < 4; i++) {
+            am = X86AMode_IR(i*4, hregX86_ESP());
+            addInstr(env, X86Instr_Alu32R(Xalu_MOV, X86RMI_Mem(am), r32));
+            addInstr(env, X86Instr_Unary32(Xun_NEG, X86RM_Reg(r32)));
+            addInstr(env, X86Instr_Alu32R(Xalu_SBB, X86RMI_Reg(r32), r32));
+            addInstr(env, X86Instr_Alu32M(Xalu_MOV, X86RI_Reg(r32), am));
+         }
+         addInstr(env, X86Instr_SseLdSt(True/*load*/, dst, esp0));
+         add_to_esp(env, 16);
+         return dst;
+      }
+
       case Iop_Recip32Fx4: op = Xsse_RCPF;   goto do_32Fx4_unary;
       case Iop_RSqrt32Fx4: op = Xsse_RSQRTF; goto do_32Fx4_unary;
       case Iop_Sqrt32Fx4:  op = Xsse_SQRTF;  goto do_32Fx4_unary;
index 1308c64e514f820edf1ec84cbcce2e0ee1e38f96..0f0306ca7eea51ca4f65c613d566960122302280 100644 (file)
@@ -295,9 +295,10 @@ void ppIROp ( IROp op )
       case Iop_Set128lo32: vex_printf("Set128lo32"); return;
       case Iop_Set128lo64: vex_printf("Set128lo64"); return;
 
-      case Iop_And128:  vex_printf("And128"); return;
-      case Iop_Or128:   vex_printf("Or128");  return;
-      case Iop_Xor128:  vex_printf("Xor128"); return;
+      case Iop_And128:     vex_printf("And128"); return;
+      case Iop_Or128:      vex_printf("Or128");  return;
+      case Iop_Xor128:     vex_printf("Xor128"); return;
+      case Iop_CmpNEZ32x4: vex_printf("CmpNEZ32x4"); return;
 
       case Iop_Add8x16:   vex_printf("Add8x16"); return;
       case Iop_Add16x8:   vex_printf("Add16x8"); return;
@@ -1275,6 +1276,7 @@ void typeOfPrimop ( IROp op, IRType* t_dst, IRType* t_arg1, IRType* t_arg2 )
       case Iop_RSqrt64Fx2: case Iop_RSqrt64F0x2:
       case Iop_Sqrt32Fx4:  case Iop_Sqrt32F0x4:
       case Iop_Sqrt64Fx2:  case Iop_Sqrt64F0x2:
+      case Iop_CmpNEZ32x4:
          UNARY(Ity_V128, Ity_V128);
 
       case Iop_ShlN16x8: case Iop_ShlN32x4: case Iop_ShlN64x2:
index 22011945a037a51b5868c6c889b047e002f18402..ac95b045aa479c50fbfddf806aba7ae9f848805f 100644 (file)
 
 typedef
    struct {
-      UInt  guest_EAX;
+      UInt  guest_EAX;         /* 0 */
       UInt  guest_ECX;
       UInt  guest_EDX;
       UInt  guest_EBX;
       UInt  guest_ESP;
       UInt  guest_EBP;
       UInt  guest_ESI;
-      UInt  guest_EDI;
+      UInt  guest_EDI;         /* 28 */
       /* 4-word thunk used to calculate O S Z A C P flags. */
-      UInt  guest_CC_OP;
+      UInt  guest_CC_OP;       /* 32 */
       UInt  guest_CC_DEP1;
       UInt  guest_CC_DEP2;
-      UInt  guest_CC_NDEP;
+      UInt  guest_CC_NDEP;     /* 44 */
       /* The D flag is stored here, encoded as either -1 or +1 */
-      UInt  guest_DFLAG;
+      UInt  guest_DFLAG;       /* 48 */
       /* Bit 21 (ID) of eflags stored here, as either 0 or 1. */
-      UInt  guest_IDFLAG;
+      UInt  guest_IDFLAG;      /* 52 */
       /* EIP */
-      UInt  guest_EIP;
+      UInt  guest_EIP;         /* 56 */
       /* FPU */
-      UInt  guest_FTOP;
-      ULong guest_FPREG[8];
-      UChar guest_FPTAG[8];
-      UInt  guest_FPROUND;
-      UInt  guest_FC3210;
+      UInt  guest_FTOP;        /* 60 */
+      ULong guest_FPREG[8];    /* 64 */
+      UChar guest_FPTAG[8];   /* 128 */
+      UInt  guest_FPROUND;    /* 136 */
+      UInt  guest_FC3210;     /* 140 */
       /* SSE */
-      UInt  guest_SSEROUND;
-      U128  guest_XMM0;
+      UInt  guest_SSEROUND;   /* 144 */
+      U128  guest_XMM0;       /* 148 */
       U128  guest_XMM1;
       U128  guest_XMM2;
       U128  guest_XMM3;
index d8d8cc58ad9f6a1f3189968386340ba8665e8759..d92396213a2d450b04b9c9d5e04681f14e16b66a 100644 (file)
@@ -377,21 +377,27 @@ typedef
 
       /* --- pack / unpack --- */
 
-      /* 64 <-> 128 bit pack/unpack */
+      /* 64 <-> 128 bit */
       Iop_128to64,     // :: V128 -> I64, low half
       Iop_128HIto64,   // :: V128 -> I64, high half
       Iop_64HLto128,   // :: (I64,I64) -> V128
 
-      Iop_32Uto128,
       Iop_64Uto128,
-      Iop_Set128lo32,
       Iop_Set128lo64,
 
+      /* 32 <-> 128 bit */
+      Iop_32Uto128,
+      Iop_128to32,     // :: V128 -> I32, lowest lane
+      Iop_Set128lo32,  // :: (V128,I32) -> V128
+
       /* ------------------ 128-bit SIMD Integer. ------------------ */
 
       /* BITWISE OPS */
       Iop_And128, Iop_Or128, Iop_Xor128, 
 
+      /* MISC (32x4 integer cmp != 0) */
+      Iop_CmpNEZ32x4,
+
       /* ADDITION (normal / unsigned sat / signed sat) */
       Iop_Add8x16,   Iop_Add16x8,   Iop_Add32x4,  Iop_Add64x2,
       Iop_QAdd8Ux16, Iop_QAdd16Ux8,