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 |
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");
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");
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");
* 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;
}
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;
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;
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);