]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Fix some isel cases pertaining to 1-bit values. This makes lackey
authorJulian Seward <jseward@acm.org>
Thu, 24 Mar 2005 20:40:12 +0000 (20:40 +0000)
committerJulian Seward <jseward@acm.org>
Thu, 24 Mar 2005 20:40:12 +0000 (20:40 +0000)
work on amd64.  Yay!

git-svn-id: svn://svn.valgrind.org/vex/trunk@1078

VEX/priv/host-amd64/hdefs.c
VEX/priv/host-amd64/hdefs.h
VEX/priv/host-amd64/isel.c

index 27629a923681cd24d6014638d6cde64a86cb9906..7dc0cc61b12efc8175fd1f1f26b6c1e42d7d1e69 100644 (file)
@@ -772,13 +772,13 @@ AMD64Instr* AMD64Instr_Store ( UChar sz, HReg src, AMD64AMode* dst ) {
    vassert(sz == 1 || sz == 2 || sz == 4);
    return i;
 }
-//.. AMD64Instr* AMD64Instr_Set32 ( AMD64CondCode cond, HReg dst ) {
-//..    AMD64Instr* i       = LibVEX_Alloc(sizeof(AMD64Instr));
-//..    i->tag            = Xin_Set32;
-//..    i->Xin.Set32.cond = cond;
-//..    i->Xin.Set32.dst  = dst;
-//..    return i;
-//.. }
+AMD64Instr* AMD64Instr_Set64 ( AMD64CondCode cond, HReg dst ) {
+   AMD64Instr* i     = LibVEX_Alloc(sizeof(AMD64Instr));
+   i->tag            = Ain_Set64;
+   i->Ain.Set64.cond = cond;
+   i->Ain.Set64.dst  = dst;
+   return i;
+}
 //.. AMD64Instr* AMD64Instr_Bsfr32 ( Bool isFwds, HReg src, HReg dst ) {
 //..    AMD64Instr* i          = LibVEX_Alloc(sizeof(AMD64Instr));
 //..    i->tag               = Xin_Bsfr32;
@@ -1116,10 +1116,10 @@ void ppAMD64Instr ( AMD64Instr* i )
          vex_printf(",");
          ppAMD64AMode(i->Ain.Store.dst);
          return;
-//..       case Xin_Set32:
-//..          vex_printf("setl%s ", showAMD64CondCode(i->Xin.Set32.cond));
-//..          ppHRegAMD64(i->Xin.Set32.dst);
-//..          return;
+      case Ain_Set64:
+         vex_printf("setq%s ", showAMD64CondCode(i->Ain.Set64.cond));
+         ppHRegAMD64(i->Ain.Set64.dst);
+         return;
 //..       case Xin_Bsfr32:
 //..          vex_printf("bs%cl ", i->Xin.Bsfr32.isFwds ? 'f' : 'r');
 //..          ppHRegAMD64(i->Xin.Bsfr32.src);
@@ -1430,9 +1430,9 @@ void getRegUsage_AMD64Instr ( HRegUsage* u, AMD64Instr* i )
          addHRegUse(u, HRmRead, i->Ain.Store.src);
          addRegUsage_AMD64AMode(u, i->Ain.Store.dst);
          return;
-//..       case Xin_Set32:
-//..          addHRegUse(u, HRmWrite, i->Xin.Set32.dst);
-//..          return;
+      case Ain_Set64:
+         addHRegUse(u, HRmWrite, i->Ain.Set64.dst);
+         return;
 //..       case Xin_Bsfr32:
 //..          addHRegUse(u, HRmRead, i->Xin.Bsfr32.src);
 //..          addHRegUse(u, HRmWrite, i->Xin.Bsfr32.dst);
@@ -1628,9 +1628,9 @@ void mapRegs_AMD64Instr ( HRegRemap* m, AMD64Instr* i )
          mapReg(m, &i->Ain.Store.src);
          mapRegs_AMD64AMode(m, i->Ain.Store.dst);
          return;
-//..       case Xin_Set32:
-//..          mapReg(m, &i->Xin.Set32.dst);
-//..          return;
+      case Ain_Set64:
+         mapReg(m, &i->Ain.Set64.dst);
+         return;
 //..       case Xin_Bsfr32:
 //..          mapReg(m, &i->Xin.Bsfr32.src);
 //..          mapReg(m, &i->Xin.Bsfr32.dst);
@@ -2150,6 +2150,7 @@ Int emit_AMD64Instr ( UChar* buf, Int nbuf, AMD64Instr* i )
 {
    UInt /*irno,*/ opc, opc_rr, subopc_imm, opc_imma, opc_cl, opc_imm, subopc;
    UInt   xtra;
+   UInt   reg;
    UChar  rex;
    UChar* p = &buf[0];
    UChar* ptmp;
@@ -2670,39 +2671,30 @@ Int emit_AMD64Instr ( UChar* buf, Int nbuf, AMD64Instr* i )
       }
       break;
 
-//..    case Xin_Set32:
-//..       /* Make the destination register be 1 or 0, depending on whether
-//..          the relevant condition holds.  We have to dodge and weave
-//..          when the destination is %esi or %edi as we cannot directly
-//..          emit the native 'setb %reg' for those.  Further complication:
-//..          the top 24 bits of the destination should be forced to zero,
-//..          but doing 'xor %r,%r' kills the flag(s) we are about to read.
-//..          Sigh.  So start off my moving $0 into the dest. */
-//.. 
-//..       /* Do we need to swap in %eax? */
-//..       if (iregNo(i->Xin.Set32.dst) >= 4) {
-//..          /* xchg %eax, %dst */
-//..          *p++ = 0x90 + iregNo(i->Xin.Set32.dst);
-//..          /* movl $0, %eax */
-//..          *p++ = 0xB8 + iregNo(hregAMD64_EAX());
-//..          p = emit32(p, 0);
-//..          /* setb lo8(%eax) */
-//..          *p++ = 0x0F; 
-//..          *p++ = 0x90 + (UChar)(i->Xin.Set32.cond);
-//..          p = doAMode_R(p, fake(0), hregAMD64_EAX());
-//..          /* xchg %eax, %dst */
-//..          *p++ = 0x90 + iregNo(i->Xin.Set32.dst);
-//..       } else {
-//..          /* movl $0, %dst */
-//..          *p++ = 0xB8 + iregNo(i->Xin.Set32.dst);
-//..          p = emit32(p, 0);
-//..          /* setb lo8(%dst) */
-//..          *p++ = 0x0F; 
-//..          *p++ = 0x90 + (UChar)(i->Xin.Set32.cond);
-//..          p = doAMode_R(p, fake(0), i->Xin.Set32.dst);
-//..       }
-//..       goto done;
-//.. 
+   case Ain_Set64:
+      /* Make the destination register be 1 or 0, depending on whether
+         the relevant condition holds.  Complication: the top 56 bits
+         of the destination should be forced to zero, but doing 'xorq
+         %r,%r' kills the flag(s) we are about to read.  Sigh.  So
+         start off my moving $0 into the dest. */
+
+      reg = iregNo(i->Ain.Set64.dst);
+      vassert(reg < 16);
+
+      /* movq $0, %dst */
+      *p++ = toUChar(reg >= 8 ? 0x49 : 0x48);
+      *p++ = 0xC7;
+      *p++ = toUChar(0xC0 + (reg & 7));
+      p = emit32(p, 0);
+
+      /* setb lo8(%dst) */
+      /* note, 8-bit register rex trickyness.  Be careful here. */
+      *p++ = toUChar(reg >= 8 ? 0x41 : 0x40);
+      *p++ = 0x0F; 
+      *p++ = toUChar(0x90 + (0x0F & i->Ain.Set64.cond));
+      *p++ = toUChar(0xC0 + (reg & 7));
+      goto done;
+
 //..    case Xin_Bsfr32:
 //..       *p++ = 0x0F;
 //..       if (i->Xin.Bsfr32.isFwds) {
index cf1b006eee78e2fc0da0d0abd089649de0a58249..ed9299f820655c7bc5a7de2fe7d63f4a2c582031 100644 (file)
@@ -369,7 +369,7 @@ typedef
       Ain_MovZLQ,    /* reg-reg move, zeroing out top half */
       Ain_LoadEX,    /* mov{s,z}{b,w,l}q from mem to reg */
       Ain_Store,     /* store 32/16/8 bit value in memory */
-//..       Xin_Set32,     /* convert condition code to 32-bit value */
+      Ain_Set64,     /* convert condition code to 32-bit value */
 //..       Xin_Bsfr32,    /* 32-bit bsf/bsr */
       Ain_MFence,    /* mem fence */
 //.. 
@@ -498,11 +498,11 @@ typedef
             HReg        src;
             AMD64AMode* dst;
          } Store;
-//..          /* Convert a x86 condition code to a 32-bit value (0 or 1). */
-//..          struct {
-//..             X86CondCode cond;
-//..             HReg        dst;
-//..          } Set32;
+         /* Convert an amd64 condition code to a 64-bit value (0 or 1). */
+         struct {
+            AMD64CondCode cond;
+            HReg          dst;
+         } Set64;
 //..          /* 32-bit bsf or bsr. */
 //..          struct {
 //..             Bool isFwds;
@@ -669,7 +669,7 @@ extern AMD64Instr* AMD64Instr_MovZLQ    ( HReg src, HReg dst );
 extern AMD64Instr* AMD64Instr_LoadEX    ( UChar szSmall, Bool syned,
                                           AMD64AMode* src, HReg dst );
 extern AMD64Instr* AMD64Instr_Store     ( UChar sz, HReg src, AMD64AMode* dst );
-//.. extern AMD64Instr* AMD64Instr_Set32     ( AMD64CondCode cond, HReg dst );
+extern AMD64Instr* AMD64Instr_Set64     ( AMD64CondCode cond, HReg dst );
 //.. extern AMD64Instr* AMD64Instr_Bsfr32    ( Bool isFwds, HReg src, HReg dst );
 extern AMD64Instr* AMD64Instr_MFence    ( void );
 //.. 
index 122c2ae494352ff04e636f0828b39ba472092e16..3678be8e2d01b3aef3d3e9b4c09468ede0b89d55 100644 (file)
@@ -1897,15 +1897,15 @@ static AMD64CondCode iselCondCode_wrk ( ISelEnv* env, IRExpr* e )
 //..          default: vpanic("iselCondCode(x86): CmpXX64");
 //..       }
 //..    }
-//.. 
-//..    /* var */
-//..    if (e->tag == Iex_Tmp) {
-//..       HReg r32 = lookupIRTemp(env, e->Iex.Tmp.tmp);
-//..       HReg dst = newVRegI(env);
-//..       addInstr(env, mk_iMOVsd_RR(r32,dst));
-//..       addInstr(env, X86Instr_Alu32R(Xalu_AND,X86RMI_Imm(1),dst));
-//..       return Xcc_NZ;
-//..    }
+
+   /* var */
+   if (e->tag == Iex_Tmp) {
+      HReg r64 = lookupIRTemp(env, e->Iex.Tmp.tmp);
+      HReg dst = newVRegI(env);
+      addInstr(env, mk_iMOVsd_RR(r64,dst));
+      addInstr(env, AMD64Instr_Alu64R(Aalu_AND,AMD64RMI_Imm(1),dst));
+      return Acc_NZ;
+   }
 
    ppIRExpr(e);
    vpanic("iselCondCode(amd64)");
@@ -3545,12 +3545,12 @@ static void iselStmt ( ISelEnv* env, IRStmt* stmt )
          addInstr(env, mk_iMOVsd_RR(rLo,dstLo) );
          return;
       }
-//..       if (ty == Ity_I1) {
-//..          X86CondCode cond = iselCondCode(env, stmt->Ist.Tmp.data);
-//..          HReg dst = lookupIRTemp(env, tmp);
-//..          addInstr(env, X86Instr_Set32(cond, dst));
-//..          return;
-//..       }
+      if (ty == Ity_I1) {
+         AMD64CondCode cond = iselCondCode(env, stmt->Ist.Tmp.data);
+         HReg dst = lookupIRTemp(env, tmp);
+         addInstr(env, AMD64Instr_Set64(cond, dst));
+         return;
+      }
       if (ty == Ity_F64) {
          HReg dst = lookupIRTemp(env, tmp);
          HReg src = iselDblExpr(env, stmt->Ist.Tmp.data);