|
From: <sv...@va...> - 2005-04-06 20:02:02
|
Author: sewardj
Date: 2005-04-06 21:01:56 +0100 (Wed, 06 Apr 2005)
New Revision: 1125
Modified:
trunk/priv/guest-amd64/toIR.c
trunk/priv/host-amd64/hdefs.c
trunk/priv/host-amd64/hdefs.h
trunk/priv/host-amd64/isel.c
trunk/priv/ir/irdefs.c
trunk/pub/libvex_ir.h
Log:
More AMD64 instructions: sfence, movnti, bsf{w,l,q}
Modified: trunk/priv/guest-amd64/toIR.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/priv/guest-amd64/toIR.c 2005-04-06 10:27:11 UTC (rev 1124)
+++ trunk/priv/guest-amd64/toIR.c 2005-04-06 20:01:56 UTC (rev 1125)
@@ -771,7 +771,8 @@
case 2: return Ity_I16;
case 4: return Ity_I32;
case 8: return Ity_I64;
- default: vpanic("szToITy(amd64)");
+ default: vex_printf("\nszToITy(%d)\n", n);
+ vpanic("szToITy(amd64)");
}
}
=20
@@ -6696,114 +6697,125 @@
//.. =20
//.. return delta;
//.. }
-//..=20
-//..=20
-//..=20
-//.. /* Handle BSF/BSR. Only v-size seems necessary. */
-//.. static
-//.. UInt dis_bs_E_G ( UChar sorb, Int sz, ULong delta, Bool fwds )
-//.. {
-//.. Bool isReg;
-//.. UChar modrm;
-//.. HChar dis_buf[50];
-//.. =20
-//.. IRType ty =3D szToITy(sz);
-//.. IRTemp src =3D newTemp(ty);
-//.. IRTemp dst =3D newTemp(ty);
-//..=20
-//.. IRTemp src32 =3D newTemp(Ity_I32);
-//.. IRTemp dst32 =3D newTemp(Ity_I32);
-//.. IRTemp src8 =3D newTemp(Ity_I8);
-//..=20
-//.. vassert(sz =3D=3D 4 || sz =3D=3D 2);
-//..=20
-//.. modrm =3D getUChar(delta);
-//..=20
-//.. isReg =3D epartIsReg(modrm);
-//.. if (isReg) {
-//.. delta++;
-//.. assign( src, getIReg(sz, eregOfRM(modrm)) );
-//.. } else {
-//.. Int len;
-//.. IRTemp addr =3D disAMode( &len, sorb, delta, dis_buf );
-//.. delta +=3D len;
-//.. assign( src, loadLE(ty, mkexpr(addr)) );
-//.. }
-//..=20
-//.. DIP("bs%c%c %s, %s\n",
-//.. fwds ? 'f' : 'r', nameISize(sz),=20
-//.. ( isReg ? nameIReg(sz, eregOfRM(modrm)) : dis_buf ),=20
-//.. nameIReg(sz, gregOfRM(modrm)));
-//..=20
-//.. /* Generate an 8-bit expression which is zero iff the=20
-//.. original is zero, and nonzero otherwise */
-//.. assign( src8,
-//.. unop(Iop_1Uto8, binop(mkSizedOp(ty,Iop_CmpNE8),
-//.. mkexpr(src), mkU(ty,0))) );
-//..=20
-//.. /* Flags: Z is 1 iff source value is zero. All others=20
-//.. are undefined -- we force them to zero. */
-//.. stmt( IRStmt_Put( OFFB_CC_OP, mkU32(X86G_CC_OP_COPY) ));
-//.. stmt( IRStmt_Put( OFFB_CC_DEP2, mkU32(0) ));
-//.. stmt( IRStmt_Put(=20
-//.. OFFB_CC_DEP1,
-//.. IRExpr_Mux0X( mkexpr(src8),
-//.. /* src=3D=3D0 */
-//.. mkU32(X86G_CC_MASK_Z),
-//.. /* src!=3D0 */
-//.. mkU32(0)
-//.. )
-//.. ));
-//..=20
-//.. /* Result: iff source value is zero, we can't use
-//.. Iop_Clz32/Iop_Ctz32 as they have no defined result in that ca=
se.
-//.. But anyway, Intel x86 semantics say the result is undefined i=
n
-//.. such situations. Hence handle the zero case specially. */
-//..=20
-//.. /* Bleh. What we compute:
-//..=20
-//.. bsf32: if src =3D=3D 0 then 0 else Ctz32(src)
-//.. bsr32: if src =3D=3D 0 then 0 else 31 - Clz32(src)
-//..=20
-//.. bsf16: if src =3D=3D 0 then 0 else Ctz32(16Uto32(src))
-//.. bsr16: if src =3D=3D 0 then 0 else 31 - Clz32(16Uto32(s=
rc))
-//..=20
-//.. First, widen src to 32 bits if it is not already.
-//..=20
-//.. Postscript 15 Oct 04: it seems that at least VIA Nehemiah lea=
ves the
-//.. dst register unchanged when src =3D=3D 0. Hence change accor=
dingly.
-//.. */
-//.. if (sz =3D=3D 2)
-//.. assign( src32, unop(Iop_16Uto32, mkexpr(src)) );
-//.. else
-//.. assign( src32, mkexpr(src) );
-//..=20
-//.. /* The main computation, guarding against zero. */
-//.. assign( dst32, =20
-//.. IRExpr_Mux0X(=20
-//.. mkexpr(src8),
-//.. /* src =3D=3D 0 -- leave dst unchanged */
-//.. widenUto32( getIReg( sz, gregOfRM(modrm) ) ),
-//.. /* src !=3D 0 */
-//.. fwds ? unop(Iop_Ctz32, mkexpr(src32))
-//.. : binop(Iop_Sub32,=20
-//.. mkU32(31),=20
-//.. unop(Iop_Clz32, mkexpr(src32)))
-//.. )
-//.. );
-//..=20
-//.. if (sz =3D=3D 2)
-//.. assign( dst, unop(Iop_32to16, mkexpr(dst32)) );
-//.. else
-//.. assign( dst, mkexpr(dst32) );
-//..=20
-//.. /* dump result back */
-//.. putIReg( sz, gregOfRM(modrm), mkexpr(dst) );
-//..=20
-//.. return delta;
-//.. }
=20
=20
+
+/* Handle BSF/BSR. Only v-size seems necessary. */
+static
+ULong dis_bs_E_G ( Prefix pfx, Int sz, ULong delta, Bool fwds )
+{
+ Bool isReg;
+ UChar modrm;
+ HChar dis_buf[50];
+
+ IRType ty =3D szToITy(sz);
+ IRTemp src =3D newTemp(ty);
+ IRTemp dst =3D newTemp(ty);
+ IRTemp src64 =3D newTemp(Ity_I64);
+ IRTemp dst64 =3D newTemp(Ity_I64);
+ IRTemp src8 =3D newTemp(Ity_I8);
+
+ vassert(sz =3D=3D 8 || sz =3D=3D 4 || sz =3D=3D 2);
+
+ modrm =3D getUChar(delta);
+ isReg =3D epartIsReg(modrm);
+ if (isReg) {
+ delta++;
+ assign( src, getIRegE(sz, pfx, modrm) );
+ } else {
+ Int len;
+ IRTemp addr =3D disAMode( &len, pfx, delta, dis_buf, 0 );
+ delta +=3D len;
+ assign( src, loadLE(ty, mkexpr(addr)) );
+ }
+
+ DIP("bs%c%c %s, %s\n",
+ fwds ? 'f' : 'r', nameISize(sz),=20
+ ( isReg ? nameIRegE(sz, pfx, modrm) : dis_buf ),=20
+ nameIRegG(sz, pfx, modrm));
+
+ /* First, widen src to 64 bits if it is not already. */
+ assign( src64, widenUto64(mkexpr(src)) );
+
+ /* Generate an 8-bit expression which is zero iff the=20
+ original is zero, and nonzero otherwise */
+ assign( src8,
+ unop(Iop_1Uto8,=20
+ binop(Iop_CmpNE64,
+ mkexpr(src64), mkU64(0))) );
+
+ /* Flags: Z is 1 iff source value is zero. All others=20
+ are undefined -- we force them to zero. */
+ stmt( IRStmt_Put( OFFB_CC_OP, mkU64(AMD64G_CC_OP_COPY) ));
+ stmt( IRStmt_Put( OFFB_CC_DEP2, mkU64(0) ));
+ stmt( IRStmt_Put(=20
+ OFFB_CC_DEP1,
+ IRExpr_Mux0X( mkexpr(src8),
+ /* src=3D=3D0 */
+ mkU64(AMD64G_CC_MASK_Z),
+ /* src!=3D0 */
+ mkU64(0)
+ )
+ ));
+ /* Set NDEP even though it isn't used. This makes redundant-PUT
+ elimination of previous stores to this field work better. */
+ stmt( IRStmt_Put( OFFB_CC_NDEP, mkU64(0) ));
+
+ /* Result: iff source value is zero, we can't use
+ Iop_Clz64/Iop_Ctz64 as they have no defined result in that case.
+ But anyway, amd64 semantics say the result is undefined in
+ such situations. Hence handle the zero case specially. */
+
+ /* Bleh. What we compute:
+
+ bsf64: if src =3D=3D 0 then {dst is unchanged}=20
+ else Ctz64(src)
+
+ bsr64: if src =3D=3D 0 then {dst is unchanged}=20
+ else 63 - Clz64(src)
+
+ bsf32: if src =3D=3D 0 then {dst is unchanged}=20
+ else Ctz64(32Uto64(src))
+
+ bsr32: if src =3D=3D 0 then {dst is unchanged}
+ else 63 - Clz64(32Uto64(src))
+
+ bsf16: if src =3D=3D 0 then {dst is unchanged}=20
+ else Ctz64(32Uto64(16Uto32(src)))
+
+ bsr16: if src =3D=3D 0 then {dst is unchanged}=20
+ else 63 - Clz64(32Uto64(16Uto32(src)))
+ */
+
+ /* The main computation, guarding against zero. */
+ assign( dst64,
+ IRExpr_Mux0X(=20
+ mkexpr(src8),
+ /* src =3D=3D 0 -- leave dst unchanged */
+ widenUto64( getIRegG( sz, pfx, modrm ) ),
+ /* src !=3D 0 */
+ fwds ? unop(Iop_Ctz64, mkexpr(src64))
+ : binop(Iop_Sub64,=20
+ mkU64(63),=20
+ unop(Iop_Clz64, mkexpr(src64)))
+ )
+ );
+
+ if (sz =3D=3D 2)
+ assign( dst, unop(Iop_32to16, unop(Iop_64to32, mkexpr(dst64))) );
+ else
+ if (sz =3D=3D 4)
+ assign( dst, unop(Iop_64to32, mkexpr(dst64)) );
+ else
+ assign( dst, mkexpr(dst64) );
+
+ /* dump result back */
+ putIRegG( sz, pfx, modrm, mkexpr(dst) );
+
+ return delta;
+}
+
+
/* swap rAX with the reg specified by reg and REX.B */
static=20
void codegen_xchg_rAX_Reg ( Prefix pfx, Int sz, UInt regLo3 )
@@ -8975,19 +8987,20 @@
//.. "rsqrtss", Iop_RSqrt32F0x4=
);
//.. goto decode_success;
//.. }
-//..=20
-//.. /* 0F AE /7 =3D SFENCE -- flush pending operations to memory */
-//.. if (insn[0] =3D=3D 0x0F && insn[1] =3D=3D 0xAE
-//.. && epartIsReg(insn[2]) && gregOfRM(insn[2]) =3D=3D 7) {
-//.. vassert(sz =3D=3D 4);
-//.. delta +=3D 3;
-//.. /* Insert a memory fence. It's sometimes important that thes=
e
-//.. are carried through to the generated code. */
-//.. stmt( IRStmt_MFence() );
-//.. DIP("sfence\n");
-//.. goto decode_success;
-//.. }
-//..=20
+
+ /* 0F AE /7 =3D SFENCE -- flush pending operations to memory */
+ if (haveNo66noF2noF3(pfx)=20
+ && insn[0] =3D=3D 0x0F && insn[1] =3D=3D 0xAE
+ && epartIsReg(insn[2]) && gregLO3ofRM(insn[2]) =3D=3D 7
+ && sz =3D=3D 4) {
+ delta +=3D 3;
+ /* Insert a memory fence. It's sometimes important that these
+ are carried through to the generated code. */
+ stmt( IRStmt_MFence() );
+ DIP("sfence\n");
+ goto decode_success;
+ }
+
//.. /* 0F C6 /r ib =3D SHUFPS -- shuffle packed F32s */
//.. if (sz =3D=3D 4 && insn[0] =3D=3D 0x0F && insn[1] =3D=3D 0xC6) {
//.. Int select;
@@ -10124,22 +10137,23 @@
//.. }
//.. /* else fall through */
//.. }
-//..=20
-//.. /* 0F C3 =3D MOVNTI -- for us, just a plain ireg store. */
-//.. if (insn[0] =3D=3D 0x0F && insn[1] =3D=3D 0xC3) {
-//.. vassert(sz =3D=3D 4);
-//.. modrm =3D getUChar(delta+2);
-//.. if (!epartIsReg(modrm)) {
-//.. addr =3D disAMode ( &alen, sorb, delta+2, dis_buf );
-//.. storeLE( mkexpr(addr), getIReg(4, gregOfRM(modrm)) );
-//.. DIP("movnti %s,%s\n", dis_buf,
-//.. nameIReg(4, gregOfRM(modrm)));
-//.. delta +=3D 2+alen;
-//.. goto decode_success;
-//.. }
-//.. /* else fall through */
-//.. }
=20
+ /* 0F C3 =3D MOVNTI -- for us, just a plain ireg store. */
+ if (haveNo66noF2noF3(pfx) &&
+ insn[0] =3D=3D 0x0F && insn[1] =3D=3D 0xC3) {
+ vassert(sz =3D=3D 4 || sz =3D=3D 8);
+ modrm =3D getUChar(delta+2);
+ if (!epartIsReg(modrm)) {
+ addr =3D disAMode ( &alen, pfx, delta+2, dis_buf, 0 );
+ storeLE( mkexpr(addr), getIRegG(sz, pfx, modrm) );
+ DIP("movnti %s,%s\n", dis_buf,
+ nameIRegG(sz, pfx, modrm));
+ delta +=3D 2+alen;
+ goto decode_success;
+ }
+ /* else fall through */
+ }
+
/* 66 0F D6 =3D MOVQ -- move 64 bits from G (lo half xmm) to E (mem
or lo half xmm). */
if (have66noF2noF3(pfx) && insn[0] =3D=3D 0x0F && insn[1] =3D=3D 0xD6=
) {
@@ -12843,11 +12857,12 @@
break;
}
=20
-//.. /* =3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- BSF/BSR -=3D-=3D-=3D-=
=3D-=3D-=3D-=3D-=3D-=3D-=3D */
-//..=20
-//.. case 0xBC: /* BSF Gv,Ev */
-//.. delta =3D dis_bs_E_G ( sorb, sz, delta, True );
-//.. break;
+ /* =3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- BSF/BSR -=3D-=3D-=3D-=3D-=3D=
-=3D-=3D-=3D-=3D-=3D */
+
+ case 0xBC: /* BSF Gv,Ev */
+ if (haveF2orF3(pfx)) goto decode_failure;
+ delta =3D dis_bs_E_G ( pfx, sz, delta, True );
+ break;
//.. case 0xBD: /* BSR Gv,Ev */
//.. delta =3D dis_bs_E_G ( sorb, sz, delta, False );
//.. break;
Modified: trunk/priv/host-amd64/hdefs.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/priv/host-amd64/hdefs.c 2005-04-06 10:27:11 UTC (rev 1124)
+++ trunk/priv/host-amd64/hdefs.c 2005-04-06 20:01:56 UTC (rev 1125)
@@ -779,14 +779,14 @@
i->Ain.Set64.dst =3D dst;
return i;
}
-//.. AMD64Instr* AMD64Instr_Bsfr32 ( Bool isFwds, HReg src, HReg dst ) {
-//.. AMD64Instr* i =3D LibVEX_Alloc(sizeof(AMD64Instr));
-//.. i->tag =3D Xin_Bsfr32;
-//.. i->Xin.Bsfr32.isFwds =3D isFwds;
-//.. i->Xin.Bsfr32.src =3D src;
-//.. i->Xin.Bsfr32.dst =3D dst;
-//.. return i;
-//.. }
+AMD64Instr* AMD64Instr_Bsfr64 ( Bool isFwds, HReg src, HReg dst ) {
+ AMD64Instr* i =3D LibVEX_Alloc(sizeof(AMD64Instr));
+ i->tag =3D Ain_Bsfr64;
+ i->Ain.Bsfr64.isFwds =3D isFwds;
+ i->Ain.Bsfr64.src =3D src;
+ i->Ain.Bsfr64.dst =3D dst;
+ return i;
+}
AMD64Instr* AMD64Instr_MFence ( void )
{
AMD64Instr* i =3D LibVEX_Alloc(sizeof(AMD64Instr));
@@ -1120,12 +1120,12 @@
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);
-//.. vex_printf(",");
-//.. ppHRegAMD64(i->Xin.Bsfr32.dst);
-//.. return;
+ case Ain_Bsfr64:
+ vex_printf("bs%cq ", i->Ain.Bsfr64.isFwds ? 'f' : 'r');
+ ppHRegAMD64(i->Ain.Bsfr64.src);
+ vex_printf(",");
+ ppHRegAMD64(i->Ain.Bsfr64.dst);
+ return;
case Ain_MFence:
vex_printf("mfence" );
return;
@@ -1433,10 +1433,10 @@
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);
-//.. return;
+ case Ain_Bsfr64:
+ addHRegUse(u, HRmRead, i->Ain.Bsfr64.src);
+ addHRegUse(u, HRmWrite, i->Ain.Bsfr64.dst);
+ return;
case Ain_MFence:
return;
//.. case Xin_FpUnary:
@@ -1631,10 +1631,10 @@
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);
-//.. return;
+ case Ain_Bsfr64:
+ mapReg(m, &i->Ain.Bsfr64.src);
+ mapReg(m, &i->Ain.Bsfr64.dst);
+ return;
case Ain_MFence:
return;
//.. case Xin_FpUnary:
@@ -2695,15 +2695,16 @@
*p++ =3D toUChar(0xC0 + (reg & 7));
goto done;
=20
-//.. case Xin_Bsfr32:
-//.. *p++ =3D 0x0F;
-//.. if (i->Xin.Bsfr32.isFwds) {
-//.. *p++ =3D 0xBC;
-//.. } else {
-//.. *p++ =3D 0xBD;
-//.. }
-//.. p =3D doAMode_R(p, i->Xin.Bsfr32.dst, i->Xin.Bsfr32.src);
-//.. goto done;
+ case Ain_Bsfr64:
+ *p++ =3D rexAMode_R(i->Ain.Bsfr64.dst, i->Ain.Bsfr64.src);
+ *p++ =3D 0x0F;
+ if (i->Ain.Bsfr64.isFwds) {
+ *p++ =3D 0xBC;
+ } else {
+ *p++ =3D 0xBD;
+ }
+ p =3D doAMode_R(p, i->Ain.Bsfr64.dst, i->Ain.Bsfr64.src);
+ goto done;
=20
case Ain_MFence:
/* mfence */
Modified: trunk/priv/host-amd64/hdefs.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/priv/host-amd64/hdefs.h 2005-04-06 10:27:11 UTC (rev 1124)
+++ trunk/priv/host-amd64/hdefs.h 2005-04-06 20:01:56 UTC (rev 1125)
@@ -370,7 +370,7 @@
Ain_LoadEX, /* mov{s,z}{b,w,l}q from mem to reg */
Ain_Store, /* store 32/16/8 bit value in memory */
Ain_Set64, /* convert condition code to 32-bit value */
-//.. Xin_Bsfr32, /* 32-bit bsf/bsr */
+ Ain_Bsfr64, /* 64-bit bsf/bsr */
Ain_MFence, /* mem fence */
//..=20
//.. Xin_FpUnary, /* FP fake unary op */
@@ -503,12 +503,12 @@
AMD64CondCode cond;
HReg dst;
} Set64;
-//.. /* 32-bit bsf or bsr. */
-//.. struct {
-//.. Bool isFwds;
-//.. HReg src;
-//.. HReg dst;
-//.. } Bsfr32;
+ /* 64-bit bsf or bsr. */
+ struct {
+ Bool isFwds;
+ HReg src;
+ HReg dst;
+ } Bsfr64;
/* Mem fence. In short, an insn which flushes all preceding
loads and stores as much as possible before continuing.
On AMD64 we emit a real "mfence". */
@@ -670,7 +670,7 @@
AMD64AMode* src, HReg dst );
extern AMD64Instr* AMD64Instr_Store ( UChar sz, HReg src, AMD64AMode=
* dst );
extern AMD64Instr* AMD64Instr_Set64 ( AMD64CondCode cond, HReg dst )=
;
-//.. extern AMD64Instr* AMD64Instr_Bsfr32 ( Bool isFwds, HReg src, HR=
eg dst );
+extern AMD64Instr* AMD64Instr_Bsfr64 ( Bool isFwds, HReg src, HReg ds=
t );
extern AMD64Instr* AMD64Instr_MFence ( void );
//..=20
//.. extern AMD64Instr* AMD64Instr_FpUnary ( AMD64FpOp op, HReg src, H=
Reg dst );
Modified: trunk/priv/host-amd64/isel.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/priv/host-amd64/isel.c 2005-04-06 10:27:11 UTC (rev 1124)
+++ trunk/priv/host-amd64/isel.c 2005-04-06 20:01:56 UTC (rev 1125)
@@ -1276,12 +1276,12 @@
return dst;
}
//.. case Iop_1Uto32:
-//.. case Iop_1Uto8: {
-//.. HReg dst =3D newVRegI(env);
-//.. X86CondCode cond =3D iselCondCode(env, e->Iex.Unop.arg)=
;
-//.. addInstr(env, X86Instr_Set32(cond,dst));
-//.. return dst;
-//.. }
+ case Iop_1Uto8: {
+ HReg dst =3D newVRegI(env);
+ AMD64CondCode cond =3D iselCondCode(env, e->Iex.Unop.arg);
+ addInstr(env, AMD64Instr_Set64(cond,dst));
+ return dst;
+ }
//.. case Iop_1Sto8:
//.. case Iop_1Sto16:
//.. case Iop_1Sto32: {
@@ -1293,13 +1293,13 @@
//.. addInstr(env, X86Instr_Sh32(Xsh_SAR, 31, X86RM_Reg(dst)=
));
//.. return dst;
//.. }
-//.. case Iop_Ctz32: {
-//.. /* Count trailing zeroes, implemented by x86 'bsfl' */
-//.. HReg dst =3D newVRegI(env);
-//.. HReg src =3D iselIntExpr_R(env, e->Iex.Unop.arg);
-//.. addInstr(env, X86Instr_Bsfr32(True,src,dst));
-//.. return dst;
-//.. }
+ case Iop_Ctz64: {
+ /* Count trailing zeroes, implemented by amd64 'bsfq' */
+ HReg dst =3D newVRegI(env);
+ HReg src =3D iselIntExpr_R(env, e->Iex.Unop.arg);
+ addInstr(env, AMD64Instr_Bsfr64(True,src,dst));
+ return dst;
+ }
//.. case Iop_Clz32: {
//.. /* Count leading zeroes. Do 'bsrl' to establish the in=
dex
//.. of the highest set bit, and subtract that value from
Modified: trunk/priv/ir/irdefs.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/priv/ir/irdefs.c 2005-04-06 10:27:11 UTC (rev 1124)
+++ trunk/priv/ir/irdefs.c 2005-04-06 20:01:56 UTC (rev 1125)
@@ -161,7 +161,9 @@
case Iop_MullU32: vex_printf("MullU32"); return;
case Iop_MullU64: vex_printf("MullU64"); return;
=20
+ case Iop_Clz64: vex_printf("Clz64"); return;
case Iop_Clz32: vex_printf("Clz32"); return;
+ case Iop_Ctz64: vex_printf("Ctz64"); return;
case Iop_Ctz32: vex_printf("Ctz32"); return;
=20
case Iop_CmpLT32S: vex_printf("CmpLT32S"); return;
@@ -1283,6 +1285,9 @@
case Iop_Clz32: case Iop_Ctz32:
UNARY(Ity_I32,Ity_I32);
=20
+ case Iop_Clz64: case Iop_Ctz64:
+ UNARY(Ity_I64,Ity_I64);
+
case Iop_DivU32: case Iop_DivS32:
BINARY(Ity_I32, Ity_I32,Ity_I32);
=20
Modified: trunk/pub/libvex_ir.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/pub/libvex_ir.h 2005-04-06 10:27:11 UTC (rev 1124)
+++ trunk/pub/libvex_ir.h 2005-04-06 20:01:56 UTC (rev 1125)
@@ -223,10 +223,10 @@
Iop_MullU8, Iop_MullU16, Iop_MullU32, Iop_MullU64,
=20
/* Wierdo integer stuff */
- Iop_Clz32, /* count leading zeroes */
- Iop_Ctz32, /* count trailing zeros */
- /* Ctz32/Clz32 are UNDEFINED when given arguments of zero.
- You must ensure they are never given a zero argument.=20
+ Iop_Clz64, Iop_Clz32, /* count leading zeroes */
+ Iop_Ctz64, Iop_Ctz32, /* count trailing zeros */
+ /* Ctz64/Ctz32/Clz64/Clz32 are UNDEFINED when given arguments of
+ zero. You must ensure they are never given a zero argument.
*/
=20
/* Ordering not important after here. */
|