From: Julian Seward Date: Thu, 24 Mar 2005 20:40:12 +0000 (+0000) Subject: Fix some isel cases pertaining to 1-bit values. This makes lackey X-Git-Tag: svn/VALGRIND_3_0_1^2~256 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=bac80480a0c1d0175d938cf7d27888c7900e1aba;p=thirdparty%2Fvalgrind.git Fix some isel cases pertaining to 1-bit values. This makes lackey work on amd64. Yay! git-svn-id: svn://svn.valgrind.org/vex/trunk@1078 --- diff --git a/VEX/priv/host-amd64/hdefs.c b/VEX/priv/host-amd64/hdefs.c index 27629a9236..7dc0cc61b1 100644 --- a/VEX/priv/host-amd64/hdefs.c +++ b/VEX/priv/host-amd64/hdefs.c @@ -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) { diff --git a/VEX/priv/host-amd64/hdefs.h b/VEX/priv/host-amd64/hdefs.h index cf1b006eee..ed9299f820 100644 --- a/VEX/priv/host-amd64/hdefs.h +++ b/VEX/priv/host-amd64/hdefs.h @@ -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 ); //.. diff --git a/VEX/priv/host-amd64/isel.c b/VEX/priv/host-amd64/isel.c index 122c2ae494..3678be8e2d 100644 --- a/VEX/priv/host-amd64/isel.c +++ b/VEX/priv/host-amd64/isel.c @@ -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);