From: Julian Seward Date: Fri, 20 Apr 2012 23:58:17 +0000 (+0000) Subject: Merge branches/TCHAIN from r2271 (its creation point) into trunk. X-Git-Tag: svn/VALGRIND_3_8_1^2~182 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4a6004e4e5e723c622d5b200d2933f33e8de046e;p=thirdparty%2Fvalgrind.git Merge branches/TCHAIN from r2271 (its creation point) into trunk. git-svn-id: svn://svn.valgrind.org/vex/trunk@2296 --- 4a6004e4e5e723c622d5b200d2933f33e8de046e diff --cc VEX/priv/host_ppc_defs.c index 9974b7bf46,263f5bc534..f8ff79c0a8 --- a/VEX/priv/host_ppc_defs.c +++ b/VEX/priv/host_ppc_defs.c @@@ -1034,40 -1027,21 +1054,53 @@@ PPCInstr* PPCInstr_Dfp128Binary(PPCFpO i->Pin.Dfp128Binary.srcR_lo = srcR_lo; return i; } - +PPCInstr* PPCInstr_DfpShift128 ( PPCFpOp op, HReg dst_hi, HReg dst_lo, + HReg src_hi, HReg src_lo, + PPCRI* shift ) { + PPCInstr* i = LibVEX_Alloc(sizeof(PPCInstr)); + i->tag = Pin_DfpShift128; + i->Pin.DfpShift128.op = op; + i->Pin.DfpShift128.shift = shift; + i->Pin.DfpShift128.src_hi = src_hi; + i->Pin.DfpShift128.src_lo = src_lo; + i->Pin.DfpShift128.dst_hi = dst_hi; + i->Pin.DfpShift128.dst_lo = dst_lo; + return i; +} +PPCInstr* PPCInstr_DfpD128toD64 ( PPCFpOp op, HReg dst, + HReg src_hi, HReg src_lo ) { + PPCInstr* i = LibVEX_Alloc(sizeof(PPCInstr)); + i->tag = Pin_DfpD128toD64; + i->Pin.DfpD128toD64.op = op; + i->Pin.DfpD128toD64.src_hi = src_hi; + i->Pin.DfpD128toD64.src_lo = src_lo; + i->Pin.DfpD128toD64.dst = dst; + return i; +} - +PPCInstr* PPCInstr_DfpI64StoD128 ( PPCFpOp op, HReg dst_hi, + HReg dst_lo, HReg src ) { + PPCInstr* i = LibVEX_Alloc(sizeof(PPCInstr)); + i->tag = Pin_DfpI64StoD128; + i->Pin.DfpI64StoD128.op = op; + i->Pin.DfpI64StoD128.src = src; + i->Pin.DfpI64StoD128.dst_hi = dst_hi; + i->Pin.DfpI64StoD128.dst_lo = dst_lo; + return i; +} + PPCInstr* PPCInstr_EvCheck ( PPCAMode* amCounter, + PPCAMode* amFailAddr ) { + PPCInstr* i = LibVEX_Alloc(sizeof(PPCInstr)); + i->tag = Pin_EvCheck; + i->Pin.EvCheck.amCounter = amCounter; + i->Pin.EvCheck.amFailAddr = amFailAddr; + return i; + } + PPCInstr* PPCInstr_ProfInc ( void ) { + PPCInstr* i = LibVEX_Alloc(sizeof(PPCInstr)); + i->tag = Pin_ProfInc; + return i; + } + /* Valid combo | fromI | int32 | syned | flt64 | @@@ -1850,31 -1835,30 +1910,55 @@@ void ppPPCInstr ( PPCInstr* i, Bool mod ppHRegPPC(i->Pin.Dfp128Binary.srcR_hi); return; + case Pin_DfpShift128: + vex_printf("%s ", showPPCFpOp(i->Pin.DfpShift128.op)); + ppHRegPPC(i->Pin.DfpShift128.dst_hi); + vex_printf(","); + ppHRegPPC(i->Pin.DfpShift128.src_hi); + vex_printf(","); + ppPPCRI(i->Pin.DfpShift128.shift); + return; + + case Pin_DfpD128toD64: + vex_printf("%s ", showPPCFpOp(i->Pin.DfpD128toD64.op)); + ppHRegPPC(i->Pin.DfpD128toD64.dst); + vex_printf(","); + ppHRegPPC(i->Pin.DfpD128toD64.src_hi); + vex_printf(","); + return; + + case Pin_DfpI64StoD128: + vex_printf("%s ", showPPCFpOp(i->Pin.DfpI64StoD128.op)); + ppHRegPPC(i->Pin.DfpI64StoD128.dst_hi); + vex_printf(","); + ppHRegPPC(i->Pin.DfpI64StoD128.src); + vex_printf(","); + return; + + case Pin_EvCheck: + /* Note that the counter dec is 32 bit even in 64-bit mode. */ + vex_printf("(evCheck) "); + vex_printf("lwz r30,"); + ppPPCAMode(i->Pin.EvCheck.amCounter); + vex_printf("; addic. r30,r30,-1; "); + vex_printf("stw r30,"); + ppPPCAMode(i->Pin.EvCheck.amCounter); + vex_printf("; bge nofail; lwz r30,"); + ppPPCAMode(i->Pin.EvCheck.amFailAddr); + vex_printf("; mtctr r30; bctr; nofail:"); + return; + + case Pin_ProfInc: + if (mode64) { + vex_printf("(profInc) imm64-fixed5 r30,$NotKnownYet; "); + vex_printf("ld r29,(r30); addi r29,r29,1; std r29,(r30)"); + } else { + vex_printf("(profInc) imm32-fixed2 r30,$NotKnownYet; "); + vex_printf("lwz r29,4(r30); addic. r29,r29,1; stw r29,4(r30)"); + vex_printf("lwz r29,0(r30); addze r29,r29; stw r29,0(r30)"); + } + break; + default: vex_printf("\nppPPCInstr: No such tag(%d)\n", (Int)i->tag); vpanic("ppPPCInstr"); @@@ -2168,24 -2145,18 +2256,35 @@@ void getRegUsage_PPCInstr ( HRegUsage* addHRegUse(u, HRmRead, i->Pin.Dfp128Binary.srcR_hi); addHRegUse(u, HRmRead, i->Pin.Dfp128Binary.srcR_lo); return; + case Pin_DfpShift128: + addRegUsage_PPCRI(u, i->Pin.DfpShift128.shift); + addHRegUse(u, HRmWrite, i->Pin.DfpShift128.src_hi); + addHRegUse(u, HRmWrite, i->Pin.DfpShift128.src_lo); + addHRegUse(u, HRmWrite, i->Pin.DfpShift128.dst_hi); + addHRegUse(u, HRmWrite, i->Pin.DfpShift128.dst_lo); + return; + case Pin_DfpD128toD64: + addHRegUse(u, HRmWrite, i->Pin.DfpD128toD64.src_hi); + addHRegUse(u, HRmWrite, i->Pin.DfpD128toD64.src_lo); + addHRegUse(u, HRmWrite, i->Pin.DfpD128toD64.dst); + return; + case Pin_DfpI64StoD128: + addHRegUse(u, HRmWrite, i->Pin.DfpI64StoD128.src); + addHRegUse(u, HRmWrite, i->Pin.DfpI64StoD128.dst_hi); + addHRegUse(u, HRmWrite, i->Pin.DfpI64StoD128.dst_lo); + return; - + case Pin_EvCheck: + /* We expect both amodes only to mention the GSP (r31), so this + is in fact pointless, since GSP isn't allocatable, but + anyway.. */ + addRegUsage_PPCAMode(u, i->Pin.EvCheck.amCounter); + addRegUsage_PPCAMode(u, i->Pin.EvCheck.amFailAddr); + addHRegUse(u, HRmWrite, hregPPC_GPR30(mode64)); /* also unavail to RA */ + return; + case Pin_ProfInc: + addHRegUse(u, HRmWrite, hregPPC_GPR29(mode64)); + addHRegUse(u, HRmWrite, hregPPC_GPR30(mode64)); + return; default: ppPPCInstr(i, mode64); vpanic("getRegUsage_PPCInstr"); @@@ -2407,24 -2375,16 +2514,33 @@@ void mapRegs_PPCInstr ( HRegRemap* m, P mapReg(m, &i->Pin.Dfp128Binary.srcR_hi); mapReg(m, &i->Pin.Dfp128Binary.srcR_lo); return; + case Pin_DfpShift128: + mapRegs_PPCRI(m, i->Pin.DfpShift128.shift); + mapReg(m, &i->Pin.DfpShift128.src_hi); + mapReg(m, &i->Pin.DfpShift128.src_lo); + mapReg(m, &i->Pin.DfpShift128.dst_hi); + mapReg(m, &i->Pin.DfpShift128.dst_lo); + return; + case Pin_DfpD128toD64: + mapReg(m, &i->Pin.DfpD128toD64.src_hi); + mapReg(m, &i->Pin.DfpD128toD64.src_lo); + mapReg(m, &i->Pin.DfpD128toD64.dst); + return; + case Pin_DfpI64StoD128: + mapReg(m, &i->Pin.DfpI64StoD128.src); + mapReg(m, &i->Pin.DfpI64StoD128.dst_hi); + mapReg(m, &i->Pin.DfpI64StoD128.dst_lo); + return; - + case Pin_EvCheck: + /* We expect both amodes only to mention the GSP (r31), so this + is in fact pointless, since GSP isn't allocatable, but + anyway.. */ + mapRegs_PPCAMode(m, i->Pin.EvCheck.amCounter); + mapRegs_PPCAMode(m, i->Pin.EvCheck.amFailAddr); + return; + case Pin_ProfInc: + /* hardwires r29 and r30 -- nothing to modify. */ + return; default: ppPPCInstr(i, mode64); vpanic("mapRegs_PPCInstr"); @@@ -4361,93 -4562,6 +4796,94 @@@ Int emit_PPCInstr ( /*MB_MOD*/Bool* is_ * reference the first of the two registers in the pair. */ p = mkFormX(p, 63, fr_dstHi, 0, 10, 72, 0); + p = mkFormX(p, 63, fr_dstLo, 0, 11, 72, 0); + goto done; + } + + case Pin_DfpShift128: { + UInt fr_src_hi = fregNo(i->Pin.DfpShift128.src_hi); + UInt fr_src_lo = fregNo(i->Pin.DfpShift128.src_lo); + UInt fr_dst_hi = fregNo(i->Pin.DfpShift128.dst_hi); + UInt fr_dst_lo = fregNo(i->Pin.DfpShift128.dst_lo); + UInt shift; + + shift = i->Pin.DfpShift128.shift->Pri.Imm; + + /* setup source operand in register 12, 13 pair */ + p = mkFormX(p, 63, 12, 0, fr_src_hi, 72, 0); + p = mkFormX(p, 63, 13, 0, fr_src_lo, 72, 0); + + /* execute instruction putting result in register 10, 11 pair */ + switch (i->Pin.DfpShift128.op) { + case Pfp_DSCLIQ: /* dscliq, DFP shift left, fr_srcR is the integer + * shift amount. + */ + p = mkFormZ22( p, 63, 10, 12, shift, 66, 0 ); + break; + case Pfp_DSCRIQ: /* dscriq, DFP shift right, fr_srcR is the integer + * shift amount. + */ + p = mkFormZ22( p, 63, 10, 12, shift, 98, 0 ); + break; + default: + vex_printf("ERROR: emit_PPCInstr quad default case %d \n", + i->Pin.DfpShift128.op); + goto bad; + } + + /* The instruction put the 128-bit result in registers (10,11). + * Note, the operand in the instruction only reference the first of + * the two registers in the pair. + */ + p = mkFormX(p, 63, fr_dst_hi, 0, 10, 72, 0); + p = mkFormX(p, 63, fr_dst_lo, 0, 11, 72, 0); + goto done; + } + + case Pin_DfpD128toD64: { + UInt fr_dst = fregNo( i->Pin.DfpD128toD64.dst ); + UInt fr_srcHi = fregNo( i->Pin.DfpD128toD64.src_hi ); + UInt fr_srcLo = fregNo( i->Pin.DfpD128toD64.src_lo ); + + /* Setup the upper and lower registers of the source operand + * register pair. + */ + p = mkFormX( p, 63, 10, 0, fr_dst, 72, 0 ); + p = mkFormX( p, 63, 12, 0, fr_srcHi, 72, 0 ); + p = mkFormX( p, 63, 13, 0, fr_srcLo, 72, 0 ); + + /* Do instruction with 128-bit source operands in registers (10,11) */ + switch (i->Pin.Dfp128Binary.op) { + case Pfp_DRDPQ: + p = mkFormX( p, 63, 10, 0, 12, 770, 0 ); + break; + case Pfp_DCTFIXQ: + p = mkFormX( p, 63, 10, 0, 12, 290, 0 ); + break; + default: + goto bad; + } + + /* The instruction will put the 64-bit result in registers 10. */ + p = mkFormX(p, 63, fr_dst, 0, 10, 72, 0); + goto done; + } ++ + case Pin_DfpI64StoD128: { + UInt fr_dstHi = fregNo( i->Pin.DfpI64StoD128.dst_hi ); + UInt fr_dstLo = fregNo( i->Pin.DfpI64StoD128.dst_lo ); + UInt fr_src = fregNo( i->Pin.DfpI64StoD128.src ); + + switch (i->Pin.Dfp128Binary.op) { + case Pfp_DCFFIXQ: + p = mkFormX( p, 63, 10, 11, fr_src, 802, 0 ); + break; + default: + goto bad; + } + + /* The instruction will put the 64-bit result in registers 10, 11. */ + p = mkFormX(p, 63, fr_dstHi, 0, 10, 72, 0); p = mkFormX(p, 63, fr_dstLo, 0, 11, 72, 0); goto done; } diff --cc VEX/priv/host_ppc_defs.h index c09d74825d,6a8542bb6b..1a1f90217b --- a/VEX/priv/host_ppc_defs.h +++ b/VEX/priv/host_ppc_defs.h @@@ -495,14 -494,11 +497,16 @@@ typede Pin_AvLdVSCR, /* mtvscr */ Pin_AvCMov, /* AV conditional move */ Pin_Dfp64Unary, /* DFP64 unary op */ - Pin_Dfp128nary, /* DFP128 unary op */ + Pin_Dfp128Unary, /* DFP128 unary op */ + Pin_DfpShift, /* Decimal floating point shift by immediate value */ Pin_Dfp64Binary, /* DFP64 binary op */ - Pin_Dfp128Binary, /* DFP128 binary op */ + Pin_Dfp128Binary, /* DFP128 binary op */ + Pin_DfpShift128, /* 128-bit Decimal floating point shift by + * immediate value */ + Pin_DfpD128toD64, /* DFP 128 to DFP 64 op */ + Pin_DfpI64StoD128, /* DFP signed integer to DFP 128 */ + Pin_EvCheck, /* Event check */ + Pin_ProfInc /* 64-bit profile counter increment */ } PPCInstrTag; @@@ -834,26 -841,17 +855,35 @@@ typede HReg srcR_hi; HReg srcR_lo; } Dfp128Binary; - + struct { + PPCFpOp op; + HReg dst_hi; + HReg dst_lo; + HReg src_hi; + HReg src_lo; + PPCRI* shift; + } DfpShift128; + struct { + PPCFpOp op; + HReg dst; + HReg src_hi; + HReg src_lo; + } DfpD128toD64; + struct { + PPCFpOp op; + HReg dst_hi; + HReg dst_lo; + HReg src; + } DfpI64StoD128; + struct { + PPCAMode* amCounter; + PPCAMode* amFailAddr; + } EvCheck; + struct { + /* No fields. The address of the counter to inc is + installed later, post-translation, by patching it in, + as it is not known at translation time. */ + } ProfInc; - } Pin; } PPCInstr; @@@ -915,19 -918,11 +950,22 @@@ extern PPCInstr* PPCInstr_AvLdVSCR ( extern PPCInstr* PPCInstr_Dfp64Unary ( PPCFpOp op, HReg dst, HReg src ); extern PPCInstr* PPCInstr_Dfp64Binary ( PPCFpOp op, HReg dst, HReg srcL, HReg srcR ); -extern PPCInstr* PPCInstr_Dfp128Binary( PPCFpOp op, HReg dst_hi, HReg dst_lo, - HReg srcR_hi, HReg srcR_lo ); +extern PPCInstr* PPCInstr_DfpShift ( PPCFpOp op, HReg dst, HReg src, + PPCRI* shift ); +extern PPCInstr* PPCInstr_Dfp128Unary ( PPCFpOp op, HReg dst_hi, HReg dst_lo, + HReg srcR_hi, HReg srcR_lo ); +extern PPCInstr* PPCInstr_Dfp128Binary ( PPCFpOp op, HReg dst_hi, HReg dst_lo, + HReg srcR_hi, HReg srcR_lo ); +extern PPCInstr* PPCInstr_DfpShift128 ( PPCFpOp op, HReg dst_hi, HReg src_hi, + HReg dst_lo, HReg src_lo, + PPCRI* shift ); +extern PPCInstr* PPCInstr_DfpD128toD64 ( PPCFpOp op, HReg dst, + HReg dst_lo, HReg src_lo); +extern PPCInstr* PPCInstr_DfpI64StoD128 ( PPCFpOp op, HReg dst_hi, + HReg dst_lo, HReg src); + extern PPCInstr* PPCInstr_EvCheck ( PPCAMode* amCounter, + PPCAMode* amFailAddr ); + extern PPCInstr* PPCInstr_ProfInc ( void ); extern void ppPPCInstr(PPCInstr*, Bool mode64);