]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Finish almost all SSE2 integer instructions. (!)
authorJulian Seward <jseward@acm.org>
Fri, 10 Dec 2004 01:48:18 +0000 (01:48 +0000)
committerJulian Seward <jseward@acm.org>
Fri, 10 Dec 2004 01:48:18 +0000 (01:48 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@640

VEX/priv/guest-x86/toIR.c
VEX/priv/host-x86/hdefs.c
VEX/priv/host-x86/hdefs.h
VEX/priv/host-x86/isel.c

index be26775793f543d337e4f64876aed52770bc4c65..7a337517ba3db457bf7392b7b5dd95d6697dcf8c 100644 (file)
@@ -9783,6 +9783,76 @@ static DisResult disInstr ( /*IN*/  Bool    resteerOK,
       goto decode_success;
    }
 
+   /* 66 0F 68 = PUNPCKHBW */
+   if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x68) {
+      delta = dis_SSEint_E_to_G( sorb, delta+2, 
+                                 "punpckhbw",
+                                 Iop_InterleaveHI8x16, True );
+      goto decode_success;
+   }
+
+   /* 66 0F 6A = PUNPCKHDQ */
+   if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x6A) {
+      delta = dis_SSEint_E_to_G( sorb, delta+2, 
+                                 "punpckhdq",
+                                 Iop_InterleaveHI32x4, True );
+      goto decode_success;
+   }
+
+   /* 66 0F 6D = PUNPCKHQDQ */
+   if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x6D) {
+      delta = dis_SSEint_E_to_G( sorb, delta+2, 
+                                 "punpckhqdq",
+                                 Iop_InterleaveHI64x2, True );
+      goto decode_success;
+   }
+
+   /* 66 0F 69 = PUNPCKHWD */
+   if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x69) {
+      delta = dis_SSEint_E_to_G( sorb, delta+2, 
+                                 "punpckhwd",
+                                 Iop_InterleaveHI16x8, True );
+      goto decode_success;
+   }
+
+   /* 66 0F 60 = PUNPCKLBW */
+   if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x60) {
+      delta = dis_SSEint_E_to_G( sorb, delta+2, 
+                                 "punpcklbw",
+                                 Iop_InterleaveLO8x16, True );
+      goto decode_success;
+   }
+
+   /* 66 0F 62 = PUNPCKLDQ */
+   if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x62) {
+      delta = dis_SSEint_E_to_G( sorb, delta+2, 
+                                 "punpckldq",
+                                 Iop_InterleaveLO32x4, True );
+      goto decode_success;
+   }
+
+   /* 66 0F 6C = PUNPCKLQDQ */
+   if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x6C) {
+      delta = dis_SSEint_E_to_G( sorb, delta+2, 
+                                 "punpcklqdq",
+                                 Iop_InterleaveLO64x2, True );
+      goto decode_success;
+   }
+
+   /* 66 0F 61 = PUNPCKLWD */
+   if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x61) {
+      delta = dis_SSEint_E_to_G( sorb, delta+2, 
+                                 "punpcklwd",
+                                 Iop_InterleaveLO16x8, True );
+      goto decode_success;
+   }
+
+   /* 66 0F EF = PXOR */
+   if (sz == 2 && insn[0] == 0x0F && insn[1] == 0xEF) {
+      delta = dis_SSE_E_to_G_all( sorb, delta+2, "pxor", Iop_Xor128 );
+      goto decode_success;
+   }
+
 
 //-- 
 //--    /* FXSAVE/FXRSTOR m32 -- load/store the FPU/MMX/SSE state. */
index 00de9e1262d300a516e761a709c67d12f6b14671..d61f2164715e2e9eaeaf024417b5fac7ddd1a1e4 100644 (file)
@@ -560,12 +560,14 @@ HChar* showX86SseOp ( X86SseOp op ) {
       case Xsse_PACKSSD:  return "packssdw";
       case Xsse_PACKSSW:  return "packsswb";
       case Xsse_PACKUSW:  return "packuswb";
-      case Xsse_PUNPCKHB: return "punpckhb";
-      case Xsse_PUNPCKHW: return "punpckhw";
-      case Xsse_PUNPCKHD: return "punpckhd";
-      case Xsse_PUNPCKLB: return "punpcklb";
-      case Xsse_PUNPCKLW: return "punpcklw";
-      case Xsse_PUNPCKLD: return "punpckld";
+      case Xsse_UNPCKHB:  return "punpckhb";
+      case Xsse_UNPCKHW:  return "punpckhw";
+      case Xsse_UNPCKHD:  return "punpckhd";
+      case Xsse_UNPCKHQ:  return "punpckhq";
+      case Xsse_UNPCKLB:  return "punpcklb";
+      case Xsse_UNPCKLW:  return "punpcklw";
+      case Xsse_UNPCKLD:  return "punpckld";
+      case Xsse_UNPCKLQ:  return "punpcklq";
       default: vpanic("showX86SseOp");
    }
 }
@@ -803,16 +805,6 @@ X86Instr* X86Instr_SseLdzLO  ( Int sz, HReg reg, X86AMode* addr )
    vassert(sz == 4 || sz == 8);
    return i;
 }
-X86Instr* X86Instr_Sse128 ( X86SseOp op, HReg src, HReg dst ) {
-   X86Instr* i       = LibVEX_Alloc(sizeof(X86Instr));
-   i->tag            = Xin_Sse128;
-   i->Xin.Sse128.op  = op;
-   i->Xin.Sse128.src = src;
-   i->Xin.Sse128.dst = dst;
-   vassert(op == Xsse_MOV 
-           || op == Xsse_AND || op == Xsse_OR || op == Xsse_XOR);
-   return i;
-}
 X86Instr* X86Instr_Sse32Fx4 ( X86SseOp op, HReg src, HReg dst ) {
    X86Instr* i         = LibVEX_Alloc(sizeof(X86Instr));
    i->tag              = Xin_Sse32Fx4;
@@ -855,7 +847,6 @@ X86Instr* X86Instr_SseReRg ( X86SseOp op, HReg re, HReg rg ) {
    i->Xin.SseReRg.op  = op;
    i->Xin.SseReRg.src = re;
    i->Xin.SseReRg.dst = rg;
-   vassert(op != Xsse_MOV);
    return i;
 }
 X86Instr* X86Instr_SseCMov ( X86CondCode cond, HReg src, HReg dst ) {
@@ -1071,16 +1062,6 @@ void ppX86Instr ( X86Instr* i ) {
          vex_printf(",");
          ppHRegX86(i->Xin.SseLdzLO.reg);
          return;
-      case Xin_Sse128:
-         if (i->Xin.Sse128.op == Xsse_MOV) {
-            vex_printf("mov ");
-         } else {
-            vex_printf("p%s ", showX86SseOp(i->Xin.Sse128.op));
-         }
-         ppHRegX86(i->Xin.Sse128.src);
-         vex_printf(",");
-         ppHRegX86(i->Xin.Sse128.dst);
-         return;
       case Xin_Sse32Fx4:
          vex_printf("%sps ", showX86SseOp(i->Xin.Sse32Fx4.op));
          ppHRegX86(i->Xin.Sse32Fx4.src);
@@ -1285,11 +1266,6 @@ void getRegUsage_X86Instr (HRegUsage* u, X86Instr* i)
       case Xin_SseConst:
          addHRegUse(u, HRmWrite, i->Xin.SseConst.dst);
          return;
-      case Xin_Sse128:
-         addHRegUse(u, HRmRead, i->Xin.Sse128.src);
-         addHRegUse(u, i->Xin.Sse128.op==Xsse_MOV ? HRmWrite : HRmModify,
-                       i->Xin.Sse128.dst);
-         return;
       case Xin_Sse32Fx4:
          vassert(i->Xin.Sse32Fx4.op != Xsse_MOV);
          unary = i->Xin.Sse32Fx4.op == Xsse_RCPF
@@ -1327,9 +1303,9 @@ void getRegUsage_X86Instr (HRegUsage* u, X86Instr* i)
                        i->Xin.Sse64FLo.dst);
          return;
       case Xin_SseReRg:
-         vassert(i->Xin.SseReRg.op != Xsse_MOV);
-         addHRegUse(u, HRmRead,   i->Xin.SseReRg.src);
-         addHRegUse(u, HRmModify, i->Xin.SseReRg.dst);
+         addHRegUse(u, HRmRead, i->Xin.SseReRg.src);
+         addHRegUse(u, i->Xin.SseReRg.op == Xsse_MOV ? HRmWrite : HRmModify, 
+                       i->Xin.SseReRg.dst);
          return;
       case Xin_SseCMov:
          addHRegUse(u, HRmRead,   i->Xin.SseCMov.src);
@@ -1451,10 +1427,6 @@ void mapRegs_X86Instr (HRegRemap* m, X86Instr* i)
          mapReg(m, &i->Xin.SseLdzLO.reg);
          mapRegs_X86AMode(m, i->Xin.SseLdzLO.addr);
          break;
-      case Xin_Sse128:
-         mapReg(m, &i->Xin.Sse128.src);
-         mapReg(m, &i->Xin.Sse128.dst);
-         return;
       case Xin_Sse32Fx4:
          mapReg(m, &i->Xin.Sse32Fx4.src);
          mapReg(m, &i->Xin.Sse32Fx4.dst);
@@ -1509,11 +1481,11 @@ Bool isMove_X86Instr ( X86Instr* i, HReg* src, HReg* dst )
       *dst = i->Xin.FpUnary.dst;
       return True;
    }
-   if (i->tag == Xin_Sse128) {
-      if (i->Xin.Sse128.op != Xsse_MOV)
+   if (i->tag == Xin_SseReRg) {
+      if (i->Xin.SseReRg.op != Xsse_MOV)
          return False;
-      *src = i->Xin.Sse128.src;
-      *dst = i->Xin.Sse128.dst;
+      *src = i->Xin.SseReRg.src;
+      *dst = i->Xin.SseReRg.dst;
       return True;
    }
    return False;
@@ -2589,19 +2561,6 @@ Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i )
                        i->Xin.SseLdzLO.addr);
       goto done;
 
-   case Xin_Sse128:
-      *p++ = 0x0F;
-      switch (i->Xin.Sse128.op) {
-         case Xsse_OR:  *p++ = 0x56; break;
-         case Xsse_XOR: *p++ = 0x57; break;
-         case Xsse_AND: *p++ = 0x54; break;
-         case Xsse_MOV: *p++ = 0x10; break;
-         default: goto bad;
-      }
-      p = doAMode_R(p, fake(vregNo(i->Xin.Sse128.dst)),
-                       fake(vregNo(i->Xin.Sse128.src)) );
-      goto done;
-
    case Xin_Sse32Fx4:
       xtra = 0;
       *p++ = 0x0F;
@@ -2704,6 +2663,10 @@ Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i )
    case Xin_SseReRg:
 #     define XX(_n) *p++ = (_n)
       switch (i->Xin.SseReRg.op) {
+         case Xsse_MOV:     /*movups*/ XX(0x0F); XX(0x10); break;
+         case Xsse_OR:                 XX(0x0F); XX(0x56); break;
+         case Xsse_XOR:                XX(0x0F); XX(0x57); break;
+         case Xsse_AND:                XX(0x0F); XX(0x54); break;
          case Xsse_PACKSSD:  XX(0x66); XX(0x0F); XX(0x6B); break;
          case Xsse_PACKSSW:  XX(0x66); XX(0x0F); XX(0x63); break;
          case Xsse_PACKUSW:  XX(0x66); XX(0x0F); XX(0x67); break;
@@ -2746,6 +2709,14 @@ Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i )
          case Xsse_QSUB16S:  XX(0x66); XX(0x0F); XX(0xE9); break;
          case Xsse_QSUB8U:   XX(0x66); XX(0x0F); XX(0xD8); break;
          case Xsse_QSUB16U:  XX(0x66); XX(0x0F); XX(0xD9); break;
+         case Xsse_UNPCKHB:  XX(0x66); XX(0x0F); XX(0x68); break;
+         case Xsse_UNPCKHW:  XX(0x66); XX(0x0F); XX(0x69); break;
+         case Xsse_UNPCKHD:  XX(0x66); XX(0x0F); XX(0x6A); break;
+         case Xsse_UNPCKHQ:  XX(0x66); XX(0x0F); XX(0x6D); break;
+         case Xsse_UNPCKLB:  XX(0x66); XX(0x0F); XX(0x60); break;
+         case Xsse_UNPCKLW:  XX(0x66); XX(0x0F); XX(0x61); break;
+         case Xsse_UNPCKLD:  XX(0x66); XX(0x0F); XX(0x62); break;
+         case Xsse_UNPCKLQ:  XX(0x66); XX(0x0F); XX(0x6C); break;
          default: goto bad;
       }
       p = doAMode_R(p, fake(vregNo(i->Xin.SseReRg.dst)),
index 415b1ea6bfab177c2d44c596145bb6c2793b9821..92d21f1925c3aa775b5c94a3685966da1c8d692e 100644 (file)
@@ -337,9 +337,9 @@ typedef
       Xsse_SHL16, Xsse_SHL32, Xsse_SHL64,
       Xsse_SHR16, Xsse_SHR32, Xsse_SHR64,
       Xsse_SAR16, Xsse_SAR32, 
-      Xsse_PACKSSD,  Xsse_PACKSSW, Xsse_PACKUSW,
-      Xsse_PUNPCKHB, Xsse_PUNPCKHW, Xsse_PUNPCKHD,
-      Xsse_PUNPCKLB, Xsse_PUNPCKLW, Xsse_PUNPCKLD
+      Xsse_PACKSSD, Xsse_PACKSSW, Xsse_PACKUSW,
+      Xsse_UNPCKHB, Xsse_UNPCKHW, Xsse_UNPCKHD, Xsse_UNPCKHQ,
+      Xsse_UNPCKLB, Xsse_UNPCKLW, Xsse_UNPCKLD, Xsse_UNPCKLQ
    }
    X86SseOp;
 
@@ -379,7 +379,6 @@ typedef
       Xin_SseConst,  /* Generate restricted SSE literal */
       Xin_SseLdSt,   /* SSE load/store, no alignment constraints */
       Xin_SseLdzLO,  /* SSE load low 32/64 bits, zero remainder of reg */
-      Xin_Sse128,    /* SSE binary typeless (and/or/xor/andn) */
       Xin_Sse32Fx4,  /* SSE binary, 32Fx4 */
       Xin_Sse32FLo,  /* SSE binary, 32F in lowest lane only */
       Xin_Sse64Fx2,  /* SSE binary, 64Fx2 */
@@ -565,11 +564,6 @@ typedef
             HReg      reg;
             X86AMode* addr;
          } SseLdzLO;
-         struct {
-            X86SseOp op;  /* MOV/AND/OR/XOR/ANDN only */
-            HReg     src;
-            HReg     dst;
-         } Sse128;
          struct {
             X86SseOp op;
             HReg     src;
@@ -638,7 +632,6 @@ extern X86Instr* X86Instr_FpCmp     ( HReg srcL, HReg srcR, HReg dst );
 extern X86Instr* X86Instr_SseConst  ( UShort con, HReg dst );
 extern X86Instr* X86Instr_SseLdSt   ( Bool isLoad, HReg, X86AMode* );
 extern X86Instr* X86Instr_SseLdzLO  ( Int sz, HReg, X86AMode* );
-extern X86Instr* X86Instr_Sse128    ( X86SseOp, HReg, HReg );
 extern X86Instr* X86Instr_Sse32Fx4  ( X86SseOp, HReg, HReg );
 extern X86Instr* X86Instr_Sse32FLo  ( X86SseOp, HReg, HReg );
 extern X86Instr* X86Instr_Sse64Fx2  ( X86SseOp, HReg, HReg );
index 11ae76938c821a163b000affe7bde7e3be8efd69..a913691687c88d63aa21dfd5df89afd2989e72da 100644 (file)
@@ -324,7 +324,7 @@ static X86Instr* mk_vMOVsd_RR ( HReg src, HReg dst )
 {
    vassert(hregClass(src) == HRcVec128);
    vassert(hregClass(dst) == HRcVec128);
-   return X86Instr_Sse128(Xsse_MOV, src, dst);
+   return X86Instr_SseReRg(Xsse_MOV, src, dst);
 }
 
 /* Advance/retreat %esp by n. */
@@ -2590,19 +2590,6 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e )
          return dst;
       }
 
-      case Iop_And128: op = Xsse_AND; goto do_128;
-      case Iop_Or128:  op = Xsse_OR;  goto do_128;
-      case Iop_Xor128: op = Xsse_XOR; goto do_128;
-      do_128: 
-      {
-         HReg argL = iselVecExpr(env, e->Iex.Binop.arg1);
-         HReg argR = iselVecExpr(env, e->Iex.Binop.arg2);
-         HReg dst = newVRegV(env);
-         addInstr(env, mk_vMOVsd_RR(argL, dst));
-         addInstr(env, X86Instr_Sse128(op, argR, dst));
-         return dst;
-      }
-
       case Iop_CmpEQ32Fx4: op = Xsse_CMPEQF; goto do_32Fx4;
       case Iop_CmpLT32Fx4: op = Xsse_CMPLTF; goto do_32Fx4;
       case Iop_CmpLE32Fx4: op = Xsse_CMPLEF; goto do_32Fx4;
@@ -2677,12 +2664,34 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e )
          return dst;
       }
 
-      case Iop_QNarrow32Sx4: op = Xsse_PACKSSD; 
-                             arg1isEReg = True; goto do_SseReRg;
-      case Iop_QNarrow16Sx8: op = Xsse_PACKSSW; 
-                             arg1isEReg = True; goto do_SseReRg;
-      case Iop_QNarrow16Ux8: op = Xsse_PACKUSW; 
-                             arg1isEReg = True; goto do_SseReRg;
+      case Iop_QNarrow32Sx4: 
+         op = Xsse_PACKSSD; arg1isEReg = True; goto do_SseReRg;
+      case Iop_QNarrow16Sx8: 
+         op = Xsse_PACKSSW; arg1isEReg = True; goto do_SseReRg;
+      case Iop_QNarrow16Ux8: 
+         op = Xsse_PACKUSW; arg1isEReg = True; goto do_SseReRg;
+
+      case Iop_InterleaveHI8x16: 
+         op = Xsse_UNPCKHB; arg1isEReg = True; goto do_SseReRg;
+      case Iop_InterleaveHI16x8: 
+         op = Xsse_UNPCKHW; arg1isEReg = True; goto do_SseReRg;
+      case Iop_InterleaveHI32x4: 
+         op = Xsse_UNPCKHD; arg1isEReg = True; goto do_SseReRg;
+      case Iop_InterleaveHI64x2: 
+         op = Xsse_UNPCKHQ; arg1isEReg = True; goto do_SseReRg;
+
+      case Iop_InterleaveLO8x16: 
+         op = Xsse_UNPCKLB; arg1isEReg = True; goto do_SseReRg;
+      case Iop_InterleaveLO16x8: 
+         op = Xsse_UNPCKLW; arg1isEReg = True; goto do_SseReRg;
+      case Iop_InterleaveLO32x4: 
+         op = Xsse_UNPCKLD; arg1isEReg = True; goto do_SseReRg;
+      case Iop_InterleaveLO64x2: 
+         op = Xsse_UNPCKLQ; arg1isEReg = True; goto do_SseReRg;
+
+      case Iop_And128:     op = Xsse_AND;      goto do_SseReRg;
+      case Iop_Or128:      op = Xsse_OR;       goto do_SseReRg;
+      case Iop_Xor128:     op = Xsse_XOR;      goto do_SseReRg;
       case Iop_Add8x16:    op = Xsse_ADD8;     goto do_SseReRg;
       case Iop_Add16x8:    op = Xsse_ADD16;    goto do_SseReRg;
       case Iop_Add32x4:    op = Xsse_ADD32;    goto do_SseReRg;