|
From: Sergey G. <Ser...@as...> - 2013-06-04 07:41:57
|
diff -upNr ../valgrind-3.8.1.orig/VEX/priv/guest_ppc_toIR.c ./VEX/priv/guest_ppc_toIR.c
--- ../valgrind-3.8.1.orig/VEX/priv/guest_ppc_toIR.c 2013-04-26 09:21:03.375809664 +0200
+++ ./VEX/priv/guest_ppc_toIR.c 2013-04-26 09:49:17.833852413 +0200
@@ -6563,7 +6563,7 @@ static Bool dis_proc_ctl ( VexAbiInfo* v
putIReg( rD_addr, mkWidenFrom32(ty, getGST( PPC_GST_XER ),
/* Signed */False) );
break;
- case 0x8:
+ case 0x8: case 0x200:
DIP("mflr r%u\n", rD_addr);
putIReg( rD_addr, getGST( PPC_GST_LR ) );
break;
@@ -6729,7 +6729,7 @@ static Bool dis_proc_ctl ( VexAbiInfo* v
DIP("mtlr r%u\n", rS_addr);
putGST( PPC_GST_LR, mkexpr(rS) );
break;
- case 0x9:
+ case 0x9: case 0x200:
DIP("mtctr r%u\n", rS_addr);
putGST( PPC_GST_CTR, mkexpr(rS) );
break;
@@ -8118,14 +8118,14 @@ static Bool dis_fp_cmp ( UInt theInstr )
UChar frB_addr = ifieldRegB(theInstr);
UInt opc2 = ifieldOPClo10(theInstr);
UChar b0 = ifieldBIT0(theInstr);
-
+ UInt opc2_ = IFIELD( theInstr, 0, 11 );
IRTemp ccIR = newTemp(Ity_I32);
IRTemp ccPPC32 = newTemp(Ity_I32);
IRTemp frA = newTemp(Ity_F64);
IRTemp frB = newTemp(Ity_F64);
- if (opc1 != 0x3F || b21to22 != 0 || b0 != 0) {
+ if ((opc1 != 0x3F || b21to22 != 0 || b0 != 0) && opc1 != 0x4) {
vex_printf("dis_fp_cmp(ppc)(instr)\n");
return False;
}
@@ -8179,6 +8179,17 @@ static Bool dis_fp_cmp ( UInt theInstr )
);
putGST_field( PPC_GST_CR, mkexpr(ccPPC32), crfD );
+
+ if (opc1 == 0x4){
+ switch (opc2_){
+ case 0x2EE:
+ DIP("efdcmpeq crf%d,r%u,r%u\n", crfD, frA_addr, frB_addr);
+ return True;
+ default:
+ return False;
+ }
+ }
+
/* CAB: TODO?: Support writing cc to FPSCR->FPCC ?
putGST_field( PPC_GST_FPSCR, mkexpr(ccPPC32), 4 );
@@ -8214,6 +8225,7 @@ static Bool dis_fp_round ( UInt theInstr
UChar b16to20 = ifieldRegA(theInstr);
UChar frD_addr = ifieldRegDS(theInstr);
UChar frB_addr = ifieldRegB(theInstr);
+ UInt opc2_ = IFIELD( theInstr, 0, 11 );
UInt opc2 = ifieldOPClo10(theInstr);
UChar flag_rC = ifieldBIT0(theInstr);
@@ -8233,7 +8245,7 @@ static Bool dis_fp_round ( UInt theInstr
simulating exceptions, the exception status will appear to be
zero. Hence cr1 should be cleared if this is a . form insn. */
Bool clear_CR1 = True;
- if ((!(opc1 == 0x3F || opc1 == 0x3B)) || b16to20 != 0) {
+ if ((!(opc1 == 0x3F || opc1 == 0x3B || opc1==0x4)) || b16to20 != 0) {
vex_printf("dis_fp_round(ppc)(instr)\n");
return False;
}
@@ -8260,6 +8272,18 @@ static Bool dis_fp_round ( UInt theInstr
}
}
+ if (opc1 == 0x4) {
+ switch (opc2_) {
+ case 0x2CF:
+ vex_printf("\n0x2CF\n");
+ DIP("efscfd r%u r%u\n", frD_addr, frB_addr);
+ assign(frD, binop(Iop_RoundF64toF32, rm, mkexpr(frB)));
+ goto putFR;
+ default:
+ break;
+ }
+ }
+
switch (opc2) {
case 0x00C: // frsp (Float Round to Single, PPC32 p423)
@@ -8394,8 +8418,9 @@ static Bool dis_fp_round ( UInt theInstr
return False;
}
putFR:
+ vex_printf("fP_pre_put\n");
putFReg( frD_addr, mkexpr(frD) );
-
+ vex_printf("fp_post_put\n");
if (set_FPRF) {
// XXX XXX XXX FIXME
// set FPRF from frD
@@ -8409,6 +8434,70 @@ putFR:
return True;
}
+Bool dis_fp_conv2 ( UInt theInstr )
+{
+ UChar opc1 = ifieldOPC(theInstr);
+ IRType ty = mode64 ? Ity_I64 : Ity_I32;
+ UChar b16to20 = ifieldRegA(theInstr);
+ UChar frD_addr = ifieldRegDS(theInstr);
+ UChar frB_addr = ifieldRegB(theInstr);
+ UInt opc2_ = IFIELD( theInstr, 0, 11 );
+ UChar flag_rC = ifieldBIT0(theInstr);
+
+ IRTemp frD = newTemp(Ity_F64);
+ IRTemp frB = newTemp(Ity_I32);
+ IRTemp r_tmp32 = newTemp(Ity_I32);
+ IRTemp r_tmp64 = newTemp(Ity_I32);
+ IRTemp f_tmp32 = newTemp(Ity_F32);
+ IRTemp f_tmp32_1;
+ IRTemp f_tmp64 = newTemp(Ity_F64);
+ IRExpr* rm = get_IR_roundingmode();
+
+ /* By default, we will examine the results of the operation and set
+ fpscr[FPRF] accordingly. */
+ vex_printf("fp1_\n");
+ Bool set_FPRF = True;
+
+ /* By default, if flag_RC is set, we will clear cr1 after the
+ operation. In reality we should set cr1 to indicate the
+ exception status of the operation, but since we're not
+ simulating exceptions, the exception status will appear to be
+ zero. Hence cr1 should be cleared if this is a . form insn. */
+ Bool clear_CR1 = True;
+ if ((!(opc1==0x4)) || b16to20 != 0) {
+ vex_printf("dis_fp_round(ppc)(instr)\n");
+ return False;
+ }
+
+ assign( frB, getIReg(frB_addr));
+
+ switch (opc2_) {
+ case 0x2F1:
+ DIP("efdcfsi r%u r%u\n", frD_addr, frB_addr);
+ assign(frD, unop (Iop_I32StoF64, mkexpr(frB)));
+
+ break;
+ break;
+ case 0x2F0:
+
+ DIP("efdcfsi r%u r%u\n", frD_addr, frB_addr);
+ assign(frD, unop (Iop_I32UtoF64, mkexpr(frB)));
+
+ break;
+ default:
+ vex_printf("dis_fp_round(ppc)(opc2)\n");
+ return False;
+ }
+ putFReg( frD_addr, mkexpr(frD) );
+
+
+// if (flag_rC && clear_CR1) {
+// putCR321( 1, mkU8(0) );
+// putCR0( 1, mkU8(0) );
+//}
+ return True;
+}
+
/*
Floating Point Pair Instructions
*/
@@ -15067,6 +15156,8 @@ static Bool dis_av_arith ( UInt theInstr
return True;
}
+
+
/*
AltiVec Logic Instructions
*/
@@ -15110,7 +15201,6 @@ static Bool dis_av_logic ( UInt theInstr
DIP("vxor v%d,v%d,v%d\n", vD_addr, vA_addr, vB_addr);
putVReg( vD_addr, binop(Iop_XorV128, mkexpr(vA), mkexpr(vB)) );
break;
-
case 0x504: // vnor (Nor, AV p216)
DIP("vnor v%d,v%d,v%d\n", vD_addr, vA_addr, vB_addr);
putVReg( vD_addr,
@@ -15124,6 +15214,39 @@ static Bool dis_av_logic ( UInt theInstr
return True;
}
+static Bool dis_evect_logic ( UInt theInstr )
+{
+ UChar opc1 = ifieldOPC(theInstr);
+ UChar vD_addr = ifieldRegDS(theInstr);
+ UChar vA_addr = ifieldRegA(theInstr);
+ UChar vB_addr = ifieldRegB(theInstr);
+ UInt opc2 = IFIELD( theInstr, 0, 11 );
+
+ IRTemp vA = newTemp(Ity_V128);
+ IRTemp vB = newTemp(Ity_V128);
+ assign( vA, getVReg(vA_addr));
+ assign( vB, getVReg(vB_addr));
+
+ if (opc1 != 0x4) {
+ vex_printf("dis_av_logic(ppc)(opc1 != 0x4)\n");
+ return False;
+ }
+
+ switch (opc2){
+ case 0x216: //evxor
+ DIP("evxor r%d, r%d, r%d", vD_addr, vA_addr, vB_addr);
+ putVReg(vD_addr, binop(Iop_XorV128, mkexpr(vA), mkexpr(vB)));
+ break;
+ default:
+ vex_printf("dis_evect_logic(ppc)(opc2=0x%x)\n", opc2);
+ return False;
+
+ }
+ return True;
+
+}
+
+
/*
AltiVec Compare Instructions
*/
@@ -16509,11 +16632,23 @@ static Bool dis_sp_fp ( UInt theInstr )
assign( frD, triop( Iop_SubF64r32,
rm, mkexpr(frA), mkexpr(frB) ));
break;
+ case 0x2E8:
+ DIP("efddiv r%u,r%u,r%u\n", rD_addr, rA_addr, rB_addr);
+ assign( frD, triop( Iop_DivF64,
+ rm, mkexpr(frA), mkexpr(frB) ));
+ break;
+ case 0x2E0:
+ DIP("efdadd r%u,r%u,r%u\n", rD_addr, rA_addr, rB_addr);
+ assign( frD, triop( Iop_AddF64, rm,
+ mkexpr(frA), mkexpr(frB) ));
+
+ break;
default:
vex_printf("dis_sp_fp(ppc)(opc2)\n");
return False;
}
putSPReg(rD_addr, unop(Iop_TruncF64asF32, mkexpr(frD)) );
+
return True;
}
@@ -16579,6 +16714,37 @@ static Bool dis_sp_cvt ( UInt theInstr )
return True;
}
+static Bool dis_sp_logic ( UInt theInstr )
+{
+ UChar opc1 = ifieldOPC(theInstr);
+ UChar vD_addr = ifieldRegDS(theInstr);
+ UChar vA_addr = ifieldRegA(theInstr);
+ UChar vB_addr = ifieldRegB(theInstr);
+ UInt opc2 = IFIELD( theInstr, 0, 11 );
+
+ IRTemp vA = newTemp(Ity_I32);
+ IRTemp vB = newTemp(Ity_I32);
+ assign( vA, getIReg(vA_addr));
+ assign( vB, getIReg(vB_addr));
+
+ if (opc1 != 0x4) {
+ vex_printf("dis_sp_logic(ppc)(opc1 != 0x4)\n");
+ return False;
+ }
+
+ switch (opc2) {
+ case 0x216: // evxor
+ DIP("evxor v%d,v%d,v%d\n", vD_addr, vA_addr, vB_addr);
+ putIReg( vD_addr, binop(Iop_Xor32, mkexpr(vA), mkexpr(vB)) );
+ break;
+ default:
+ vex_printf("dis_sp_logic(ppc)(opc2=0x%x)\n", opc2);
+ return False;
+
+ }
+
+ return True;
+}
/* The 0x3C primary opcode (VSX category) uses several different forms of
* extended opcodes:
@@ -17856,10 +18021,11 @@ DisResult disInstr_PPC_WRK (
/* SPE Arith */
case 0x2C0: case 0x2C1: // efsadd, efssub
- case 0x2C8: case 0x2C9: // efsmul, efsdiv
+ case 0x2C8: case 0x2C9: case 0x2E8: case 0x2E0: // efsmul, efsdiv, eddiv, efdadd
if (dis_sp_fp( theInstr )) goto decode_success;
goto decode_failure;
+
/* SPE Convert */
case 0x2D4: case 0x2D5: // efsctui, efsctsi
case 0x2D6: case 0x2D7: // efsctuf, efsctsf
@@ -17867,6 +18033,23 @@ DisResult disInstr_PPC_WRK (
if (dis_sp_cvt( theInstr )) goto decode_success;
goto decode_failure;
+ //0x216
+ case 0x216:
+ if (dis_sp_logic( theInstr )) goto decode_success;
+ goto decode_failure;
+ case 0x2CF:
+ if ( dis_fp_round( theInstr )) goto decode_success;
+ goto decode_failure;
+ case 0x2F1:
+ if (dis_fp_conv2( theInstr )) goto decode_success;
+ goto decode_failure;
+ case 0x2F0:
+ if (dis_fp_conv2( theInstr )) goto decode_success;
+ goto decode_failure;
+ case 0x2EE:
+ if (dis_fp_cmp( theInstr )) goto decode_success;
+ goto decode_failure;
+
default:
vex_printf("disInstr(ppc): "
"declined to decode a SignalProcessing-Optional insn.\n");
@@ -17942,7 +18125,7 @@ DisResult disInstr_PPC_WRK (
/* AV Logic */
case 0x404: case 0x444: case 0x484: // vand, vandc, vor
- case 0x4C4: case 0x504: // vxor, vnor
+ case 0x4C4: case 0x504: // vxor, vnor
if (!allow_V) goto decode_noV;
if (dis_av_logic( theInstr )) goto decode_success;
goto decode_failure;
diff -upNr ../valgrind-3.8.1.orig/VEX/priv/host_ppc_defs.c ./VEX/priv/host_ppc_defs.c
--- ../valgrind-3.8.1.orig/VEX/priv/host_ppc_defs.c 2013-04-26 09:21:03.313813327 +0200
+++ ./VEX/priv/host_ppc_defs.c 2013-04-26 09:52:35.892954399 +0200
@@ -1238,7 +1238,7 @@ PPCInstr* PPCInstr_FpCftI ( Bool fromI,
switch (conversion) {
// Supported conversion operations
case 1: case 3: case 5: case 7:
- case 8: case 9: case 11:
+ case 8: case 9: case 11: case 15: case 13:
break;
default:
vpanic("PPCInstr_FpCftI(ppc_host)");
@@ -1780,6 +1780,10 @@ void ppPPCInstr ( PPCInstr* i, Bool mode
str = "fcfidus";
}
}
+ if (i->Pin.FpCftI.fromI == True && i->Pin.FpCftI.int32 == True && i->Pin.FpCftI.syned == True && i->Pin.FpCftI.flt64 == True)
+ str = "efdcfsi";
+ if (i->Pin.FpCftI.fromI == True && i->Pin.FpCftI.int32 == True && i->Pin.FpCftI.syned == False && i->Pin.FpCftI.flt64 == True)
+ str = "efdcfui";
vex_printf("%s ", str);
ppHRegPPC(i->Pin.FpCftI.dst);
vex_printf(",");
@@ -3033,6 +3037,7 @@ static UChar* mkFormX ( UChar* p, UInt o
theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) |
(r3<<11) | (opc2<<1) | (b0));
return emit32(p, theInstr);
+
}
static UChar* mkFormXO ( UChar* p, UInt opc1, UInt r1, UInt r2,
@@ -4515,7 +4520,19 @@ Int emit_PPCInstr ( /*MB_MOD*/Bool* is_p
p = mkFormX(p, 59, fr_dst, 0, fr_src, 974, 0);
goto done;
}
+
+ }
+ if (i->Pin.FpCftI.fromI == True && i->Pin.FpCftI.int32 == True && i->Pin.FpCftI.syned == True && i->Pin.FpCftI.flt64 == True){
+ p = mkFormVX(p, 4, fr_dst, 0 , fr_src, 753);
+
+ goto done;
}
+ if (i->Pin.FpCftI.fromI == True && i->Pin.FpCftI.int32 == True && i->Pin.FpCftI.syned == False && i->Pin.FpCftI.flt64 == True){
+ p = mkFormVX(p, 4, fr_dst, 0 , fr_src, 752);
+
+ goto done;
+ }
+
goto bad;
}
diff -upNr ../valgrind-3.8.1.orig/VEX/priv/host_ppc_isel.c ./VEX/priv/host_ppc_isel.c
--- ../valgrind-3.8.1.orig/VEX/priv/host_ppc_isel.c 2013-04-26 09:21:03.400808187 +0200
+++ ./VEX/priv/host_ppc_isel.c 2013-04-26 09:26:03.866704097 +0200
@@ -1998,7 +1998,7 @@ static HReg iselWordExpr_R_wrk ( ISelEnv
/* ReinterpF32asI32(e) */
/* Given an IEEE754 float, produce an I32 with the same bit
pattern. */
- case Iop_ReinterpF32asI32: {
+ case Iop_ReinterpF32asI32: case Iop_ReinterpF64asI32: {
/* I believe this generates correct code for both 32- and
64-bit hosts. */
PPCAMode *am_addr;
@@ -3547,7 +3547,7 @@ static HReg iselDblExpr_wrk ( ISelEnv* e
Bool mode64 = env->mode64;
IRType ty = typeOfIRExpr(env->type_env,e);
vassert(e);
- vassert(ty == Ity_F64);
+// vassert(ty == Ity_F64);
if (e->tag == Iex_RdTmp) {
return lookupIRTemp(env, e->Iex.RdTmp.tmp);
@@ -3715,6 +3715,7 @@ static HReg iselDblExpr_wrk ( ISelEnv* e
///* Restore default FPU rounding. */
//set_FPU_rounding_default( env );
return fdst;
+
} else {
/* 32-bit mode */
HReg fdst = newVRegF(env);
@@ -3746,6 +3747,8 @@ static HReg iselDblExpr_wrk ( ISelEnv* e
}
}
+
+
}
if (e->tag == Iex_Unop) {
@@ -3815,6 +3818,29 @@ static HReg iselDblExpr_wrk ( ISelEnv* e
default:
break;
}
+ if (e->Iex.Unop.op == Iop_I32StoF64 || e->Iex.Unop.op == Iop_I32UtoF64) {
+ HReg fdst = newVRegF(env);
+ vex_printf("arg2 %d", e->Iex.Unop.arg->tag);
+ HReg isrc = iselWordExpr_R(env, e->Iex.Unop.arg);
+ HReg r1 = StackFramePtr(env->mode64);
+ HReg is1, is2;
+ PPCAMode* four_r1 = PPCAMode_IR( 4, r1 );
+
+ /* Set host rounding mode */
+ // set_FPU_rounding_mode( env, get_IR_roundingmode() );
+
+ sub_from_sp( env, 16 );
+ addInstr(env, PPCInstr_Store(4, four_r1, isrc, mode64/*mode64*/));
+ addInstr(env, PPCInstr_FpLdSt(True/*load*/, 4, fdst, four_r1));
+ addInstr(env, PPCInstr_FpCftI(True/*I->F*/, True/*int64*/,
+ e->Iex.Unop.op == Iop_I32StoF64,
+ True/*fdst is 64 bit*/,
+ fdst, fdst));
+
+ add_to_sp( env, 16 );
+ return fdst;
+
+ }
}
/* --------- MULTIPLEX --------- */
@@ -4809,7 +4835,7 @@ static void iselStmt ( ISelEnv* env, IRS
PPCInstr_AvLdSt(False/*store*/, 16, v_src, am_addr));
return;
}
- if (ty == Ity_F64) {
+ if (ty == Ity_F64 || ty == Ity_F32) {
HReg fr_src = iselDblExpr(env, stmt->Ist.Put.data);
PPCAMode* am_addr = PPCAMode_IR( stmt->Ist.Put.offset,
GuestStatePtr(mode64) );
@@ -5134,6 +5160,8 @@ static void iselStmt ( ISelEnv* env, IRS
}
stmt_fail:
ppIRStmt(stmt);
+IRType ty = typeOfIRExpr(env->type_env, stmt->Ist.Put.data);
+ vex_printf("tyy - %d\n", ty);
vpanic("iselStmt(ppc)");
}
Binary files ../valgrind-3.8.1.orig/VEX/priv/.host_ppc_isel.c.swp and ./VEX/priv/.host_ppc_isel.c.swp differ
diff -upNr ../valgrind-3.8.1.orig/VEX/priv/ir_defs.c ./VEX/priv/ir_defs.c
--- ../valgrind-3.8.1.orig/VEX/priv/ir_defs.c 2013-04-26 09:21:03.437806003 +0200
+++ ./VEX/priv/ir_defs.c 2013-04-26 09:26:03.986696967 +0200
@@ -165,7 +165,7 @@ void ppIROp ( IROp op )
case Iop_8Sto64: vex_printf("8Sto64"); return;
case Iop_64to16: vex_printf("64to16"); return;
case Iop_64to8: vex_printf("64to8"); return;
-
+ case Iop_XorF32: vex_printf("evxor"); return;
case Iop_Not1: vex_printf("Not1"); return;
case Iop_32to1: vex_printf("32to1"); return;
case Iop_64to1: vex_printf("64to1"); return;
@@ -389,6 +389,7 @@ void ppIROp ( IROp op )
case Iop_RoundF64toF32: vex_printf("RoundF64toF32"); return;
case Iop_ReinterpF64asI64: vex_printf("ReinterpF64asI64"); return;
+ case Iop_ReinterpF64asI32: vex_printf("Iop_ReinterpF64asI32"); return;
case Iop_ReinterpI64asF64: vex_printf("ReinterpI64asF64"); return;
case Iop_ReinterpF32asI32: vex_printf("ReinterpF32asI32"); return;
case Iop_ReinterpI32asF32: vex_printf("ReinterpI32asF32"); return;
@@ -2160,6 +2161,9 @@ void typeOfPrimop ( IROp op,
case Iop_Sad8Ux4:
BINARY(Ity_I32,Ity_I32, Ity_I32);
+ case Iop_XorF32:
+ BINARY(Ity_F32, Ity_F32, Ity_F32);
+
case Iop_Add64: case Iop_Sub64: case Iop_Mul64:
case Iop_Or64: case Iop_And64: case Iop_Xor64:
case Iop_CmpORD64U:
@@ -2440,6 +2444,7 @@ void typeOfPrimop ( IROp op,
case Iop_ReinterpI64asF64: UNARY(Ity_I64, Ity_F64);
case Iop_ReinterpF64asI64: UNARY(Ity_F64, Ity_I64);
+ case Iop_ReinterpF64asI32: UNARY(Ity_F64, Ity_I32);
case Iop_ReinterpI32asF32: UNARY(Ity_I32, Ity_F32);
case Iop_ReinterpF32asI32: UNARY(Ity_F32, Ity_I32);
diff -upNr ../valgrind-3.8.1.orig/VEX/pub/libvex_ir.h ./VEX/pub/libvex_ir.h
--- ../valgrind-3.8.1.orig/VEX/pub/libvex_ir.h 2013-04-26 09:21:03.513801514 +0200
+++ ./VEX/pub/libvex_ir.h 2013-04-26 09:26:05.642598556 +0200
@@ -1469,7 +1469,8 @@ typedef
Iop_Recip32Fx8,
Iop_Max32Fx8, Iop_Min32Fx8,
- Iop_Max64Fx4, Iop_Min64Fx4
+ Iop_Max64Fx4, Iop_Min64Fx4,
+ Iop_XorF32, Iop_ReinterpF64asI32
}
IROp;
|