front end:
- implemented insns: mfvscr, mtvscr, vand, vor, vxor
- fixed default vscr: enable non-java mode
back end:
- implemented enough to satisfy the front end: V128to32, 32UtoV128, not, and, or, xor
- fixed conversions to/from v128 to use quad-word-aligned stack addressing for their vector load/stores
git-svn-id: svn://svn.valgrind.org/vex/trunk@1386 8f6e269a-dfd6-0310-a8e1-e2731360e62c
diff --git a/priv/guest-ppc32/toIR.c b/priv/guest-ppc32/toIR.c
index 8cc01e5..372df22 100644
--- a/priv/guest-ppc32/toIR.c
+++ b/priv/guest-ppc32/toIR.c
@@ -235,7 +235,7 @@
//zz PPC32_SPR_CR, // Condition Register
PPC32_SPR_FPSCR, // Floating Point Status/Control Register
PPC32_SPR_VRSAVE, // Vector Save/Restore Register
-//zz PPC32_SPR_VSCR, // Vector Status and Control Register
+ PPC32_SPR_VSCR, // Vector Status and Control Register
PPC32_SPR_MAX
} PPC32SPR;
@@ -1188,12 +1188,12 @@
//zz case PPC32_SPR_VRSAVE:
//zz assign( val, IRExpr_Get(OFFB_VRSAVE, Ity_I32) );
//zz break;
-//zz
-//zz case PPC32_SPR_VSCR:
-//zz // All other bits are 'Reserved'. Returning zero for these bits.
-//zz mask = mask & 0x00010001;
-//zz assign( val, IRExpr_Get(OFFB_VSCR, Ity_I32) );
-//zz break;
+
+ case PPC32_SPR_VSCR:
+ // All other bits are zero.
+ mask = mask & 0x00010001;
+ assign( val, IRExpr_Get(OFFB_VSCR, Ity_I32) );
+ break;
default:
vpanic("getReg(ppc32)");
@@ -1300,17 +1300,17 @@
//zz vassert(mask == 0xFFFFFFFF); // Only ever need whole reg
//zz stmt( IRStmt_Put( OFFB_VRSAVE, src ) );
//zz break;
-//zz
-//zz case PPC32_SPR_VSCR:
-//zz //CAB: There are only 2 valid bits in VSCR - maybe split into two vars...
-//zz
-//zz // All other bits are 'Reserved'. Ignoring writes to these bits.
-//zz stmt( IRStmt_Put( OFFB_VSCR,
-//zz binop(Iop_Or32,
-//zz binop(Iop_And32, src, mkU32(mask & 0x00010001)),
-//zz getReg_masked( PPC32_SPR_VSCR, (~mask & 0x00010001) ))));
-//zz break;
-//zz }
+
+ case PPC32_SPR_VSCR:
+ // CAB: There are only 2 valid bits in VSCR - maybe split into two vars...
+ // ... or perhaps only 1 bit... is non-java mode bit ever set to zero?
+
+ // All other bits are 'Reserved'. Ignoring writes to these bits.
+ stmt( IRStmt_Put( OFFB_VSCR,
+ binop(Iop_Or32,
+ binop(Iop_And32, src, mkU32(mask & 0x00010001)),
+ getReg_masked( PPC32_SPR_VSCR, (~mask & 0x00010001) ))));
+ break;
default:
vpanic("putReg(ppc32)");
@@ -1341,6 +1341,9 @@
case PPC32_SPR_VRSAVE:
stmt( IRStmt_Put( OFFB_VRSAVE, src ) );
break;
+ case PPC32_SPR_VSCR:
+ putReg_masked( reg, src, 0xFFFFFFFF );
+ break;
default:
vpanic("putSPR(ppc32)");
}
@@ -1355,6 +1358,8 @@
return IRExpr_Get( OFFB_CTR, Ity_I32 );
case PPC32_SPR_VRSAVE:
return IRExpr_Get( OFFB_VRSAVE, Ity_I32 );
+ case PPC32_SPR_VSCR:
+ return getReg_masked( reg, 0xFFFFFFFF );
default:
vpanic("getSPR(ppc32)");
}
@@ -2894,7 +2899,7 @@
case 0x010: // bclr (Branch Cond. to Link Register, PPC32 p365)
if ((BO & 0x14 /* 1z1zz */) == 0x14 && flag_LK == 0) {
- DIP("blr");
+ DIP("blr\n");
} else {
DIP("bclr%s 0x%x, 0x%x\n", flag_LK ? "l" : "", BO, BI);
}
@@ -3427,7 +3432,7 @@
DIP("mcrxr crf%d\n", crfD);
/* Compute XER[0-3] (the top 4 bits of XER) into the bottom
- 4 bits of xer_0to3. */
+ 4 bits of xer_0to3. */
assign(
xer_0to3,
unop(Iop_32to8,
@@ -4815,18 +4820,20 @@
return False;
}
DIP("mfvscr v%d\n", vD_addr);
- DIP(" => not implemented\n");
- return False;
+ putVReg( vD_addr, unop(Iop_32UtoV128, getSPR( PPC32_SPR_VSCR )) );
+ break;
- case 0x644: // mtvscr (Move to VSCR, AV p130)
+ case 0x644: { // mtvscr (Move to VSCR, AV p130)
if (vD_addr != 0 || vA_addr != 0) {
vex_printf("dis_av_procctl(PPC32)(opc2,dst)\n");
return False;
}
DIP("mtvscr v%d\n", vB_addr);
- DIP(" => not implemented\n");
- return False;
-
+ IRTemp vB = newTemp(Ity_V128);
+ assign( vB, getVReg(vB_addr));
+ putSPR( PPC32_SPR_VSCR, unop(Iop_V128to32, mkexpr(vB)) );
+ break;
+ }
default:
vex_printf("dis_av_procctl(PPC32)(opc2)\n");
return False;
@@ -4914,14 +4921,14 @@
UInt opc2 = (theInstr >> 1) & 0x3FF; /* theInstr[1:10] */
UChar b0 = toUChar((theInstr >> 0) & 1); /* theInstr[0] */
- IRTemp rA = newTemp(Ity_I32);
- IRTemp rB = newTemp(Ity_I32);
+ // IRTemp rA = newTemp(Ity_I32);
+ // IRTemp rB = newTemp(Ity_I32);
IRTemp vS = newTemp(Ity_V128);
IRTemp EA = newTemp(Ity_I32);
IRTemp EA_aligned = newTemp(Ity_I32);
- assign( rA, getIReg(rA_addr));
- assign( rB, getIReg(rB_addr));
+ // assign( rA, getIReg(rA_addr));
+ // assign( rB, getIReg(rB_addr));
assign( vS, getVReg(vS_addr));
assign( EA, ea_standard(rA_addr, rB_addr) );
@@ -5283,6 +5290,11 @@
UChar vB_addr = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */
UInt opc2 = (theInstr >> 0) & 0x7FF; /* theInstr[0:10] */
+ 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(PPC32)(opc1 != 0x4)\n");
return False;
@@ -5291,8 +5303,8 @@
switch (opc2) {
case 0x404: // vand (And, AV p147)
DIP("vand v%d,v%d,v%d\n", vD_addr, vA_addr, vB_addr);
- DIP(" => not implemented\n");
- return False;
+ putVReg( vD_addr, binop(Iop_AndV128, mkexpr(vA), mkexpr(vB)) );
+ break;
case 0x444: // vandc (And, AV p148)
DIP("vandc v%d,v%d,v%d\n", vD_addr, vA_addr, vB_addr);
@@ -5301,13 +5313,13 @@
case 0x484: // vor (Or, AV p217)
DIP("vor v%d,v%d,v%d\n", vD_addr, vA_addr, vB_addr);
- DIP(" => not implemented\n");
- return False;
+ putVReg( vD_addr, binop(Iop_OrV128, mkexpr(vA), mkexpr(vB)) );
+ break;
case 0x4C4: // vxor (Xor, AV p282)
DIP("vxor v%d,v%d,v%d\n", vD_addr, vA_addr, vB_addr);
- DIP(" => not implemented\n");
- return False;
+ 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);
@@ -6095,7 +6107,7 @@
opc1 = toUChar(ifieldOPC(theInstr));
opc2 = ifieldOPClo10(theInstr);
-#if PPC32_TOIR_DEBUG
+#if 0 //PPC32_TOIR_DEBUG
vex_printf("\ndisInstr(ppc32): instr: 0x%x\n", theInstr);
vex_printf("disInstr(ppc32): instr: ");
vex_printf_binary( theInstr, 32, True );
@@ -6565,6 +6577,7 @@
default:
decode_failure:
/* All decode failures end up here. */
+ opc2 = (theInstr) & 0x7FF;
vex_printf("disInstr(ppc32): unhandled instruction: "
"0x%x\n", theInstr);
vex_printf(" primary %d(0x%x), secondary %u(0x%x)\n",