switch (op) {
case Pun_NOT: return "not";
case Pun_NEG: return "neg";
+ case Pun_CLZ: return "cntlzw";
default: vpanic("showPPC32UnaryOp");
}
}
i->Pin.Test32.src = src;
return i;
}
-PPC32Instr* PPC32Instr_Unary32 ( PPC32UnaryOp op, HReg dst ) {
+PPC32Instr* PPC32Instr_Unary32 ( PPC32UnaryOp op, HReg dst, HReg src ) {
PPC32Instr* i = LibVEX_Alloc(sizeof(PPC32Instr));
i->tag = Pin_Unary32;
i->Pin.Unary32.op = op;
i->Pin.Unary32.dst = dst;
+ i->Pin.Unary32.src = src;
return i;
}
PPC32Instr* PPC32Instr_MulL ( Bool syned, Bool word, HReg dst,
ppPPC32RI(i->Pin.Test32.src);
return;
case Pin_Unary32:
- vex_printf("%sl ", showPPC32UnaryOp(i->Pin.Unary32.op));
+ vex_printf("%s ", showPPC32UnaryOp(i->Pin.Unary32.op));
ppHRegPPC32(i->Pin.Unary32.dst);
+ vex_printf(",");
+ ppHRegPPC32(i->Pin.Unary32.src);
return;
case Pin_MulL:
if (i->Pin.MulL.src2->tag == Pri_Imm) {
addRegUsage_PPC32RI(u, i->Pin.Test32.src);
return;
case Pin_Unary32:
- addHRegUse(u, HRmModify, i->Pin.Unary32.dst);
+ addHRegUse(u, HRmWrite, i->Pin.Unary32.dst);
+ addHRegUse(u, HRmRead, i->Pin.Unary32.src);
return;
case Pin_MulL:
addHRegUse(u, HRmWrite, i->Pin.MulL.dst);
return;
case Pin_Unary32:
mapReg(m, &i->Pin.Unary32.dst);
+ mapReg(m, &i->Pin.Unary32.src);
return;
case Pin_MulL:
mapReg(m, &i->Pin.MulL.dst);
}
-/* Generate x86 spill/reload instructions under the direction of the
+/* Generate ppc32 spill/reload instructions under the direction of the
register allocator. Note it's critical these don't write the
condition codes. */
PPC32Instr* genSpill_PPC32 ( HReg rreg, Int offsetB )
-{ vassert(0);
-//.. X86AMode* am;
-//.. vassert(offsetB >= 0);
-//.. vassert(!hregIsVirtual(rreg));
-//.. am = X86AMode_IR(offsetB, hregX86_EBP());
-//..
-//.. switch (hregClass(rreg)) {
-//.. case HRcInt32:
-//.. return X86Instr_Alu32M ( Xalu_MOV, X86RI_Reg(rreg), am );
-//.. case HRcFlt64:
-//.. return X86Instr_FpLdSt ( False/*store*/, 8, rreg, am );
-//.. case HRcVec128:
-//.. return X86Instr_SseLdSt ( False/*store*/, rreg, am );
-//.. default:
-//.. ppHRegClass(hregClass(rreg));
-//.. vpanic("genSpill_X86: unimplemented regclass");
-//.. }
+{
+ PPC32AMode* am;
+ vassert(offsetB >= 0);
+ vassert(!hregIsVirtual(rreg));
+ am = PPC32AMode_IR(offsetB, GuestStatePtr);
+
+ switch (hregClass(rreg)) {
+ case HRcInt32:
+ return PPC32Instr_Store( 4, am, rreg);
+ //case HRcFlt64:
+ // return PPC32Instr_FpLdSt ( False/*store*/, 8, rreg, am );
+ //case HRcVec128:
+ // return PPC32Instr_SseLdSt ( False/*store*/, rreg, am );
+ default:
+ ppHRegClass(hregClass(rreg));
+ vpanic("genSpill_PPC32: unimplemented regclass");
+ }
}
PPC32Instr* genReload_PPC32 ( HReg rreg, Int offsetB )
-{ vassert(0);
-//.. X86AMode* am;
-//.. vassert(offsetB >= 0);
-//.. vassert(!hregIsVirtual(rreg));
-//.. am = X86AMode_IR(offsetB, hregX86_EBP());
-//.. switch (hregClass(rreg)) {
-//.. case HRcInt32:
-//.. return X86Instr_Alu32R ( Xalu_MOV, X86RMI_Mem(am), rreg );
-//.. case HRcFlt64:
-//.. return X86Instr_FpLdSt ( True/*load*/, 8, rreg, am );
-//.. case HRcVec128:
-//.. return X86Instr_SseLdSt ( True/*load*/, rreg, am );
-//.. default:
-//.. ppHRegClass(hregClass(rreg));
-//.. vpanic("genReload_X86: unimplemented regclass");
-//.. }
+{
+ PPC32AMode* am;
+ vassert(offsetB >= 0);
+ vassert(!hregIsVirtual(rreg));
+ am = PPC32AMode_IR(offsetB, GuestStatePtr);
+
+ switch (hregClass(rreg)) {
+ case HRcInt32:
+ return PPC32Instr_LoadEX( 4, False, rreg, am );
+ //case HRcFlt64:
+ // return PPC32Instr_FpLdSt ( True/*load*/, 8, rreg, am );
+ //case HRcVec128:
+ // return PPC32Instr_SseLdSt ( True/*load*/, rreg, am );
+ default:
+ ppHRegClass(hregClass(rreg));
+ vpanic("genReload_PPC32: unimplemented regclass");
+ }
}
typedef
enum {
Pun_NEG,
- Pun_NOT
+ Pun_NOT,
+ Pun_CLZ
}
PPC32UnaryOp;
struct {
PPC32UnaryOp op;
HReg dst;
+ HReg src;
} Unary32;
/* DX:AX = AX *s/u r/m16, or EDX:EAX = EAX *s/u r/m32 */
struct {
extern PPC32Instr* PPC32Instr_Alu32 ( PPC32AluOp, HReg, HReg, PPC32RI* );
extern PPC32Instr* PPC32Instr_Sh32 ( PPC32ShiftOp, HReg, HReg, PPC32RI* );
extern PPC32Instr* PPC32Instr_Test32 ( HReg dst, PPC32RI* src );
-extern PPC32Instr* PPC32Instr_Unary32 ( PPC32UnaryOp op, HReg dst );
+extern PPC32Instr* PPC32Instr_Unary32 ( PPC32UnaryOp op, HReg dst, HReg src );
extern PPC32Instr* PPC32Instr_MulL ( Bool syned, Bool word, HReg, HReg, PPC32RI* );
//.. extern X86Instr* X86Instr_Div ( Bool syned, X86ScalarSz, X86RM* );
//.. extern X86Instr* X86Instr_Sh3232 ( X86ShiftOp, UInt amt, HReg src, HReg dst );
case Iop_Not32: {
HReg dst = newVRegI(env);
HReg src = iselIntExpr_R(env, e->Iex.Unop.arg);
- addInstr(env, mk_iMOVds_RR(dst,src) );
- addInstr(env, PPC32Instr_Unary32(Pun_NOT,dst));
+ addInstr(env, PPC32Instr_Unary32(Pun_NOT,dst,src));
return dst;
}
case Iop_64HIto32: {
return rHi; /* and abandon rLo .. poor wee thing :-) */
}
case Iop_64to32: {
+
#if 1
-// CAB: This right?
+// CAB: This right? Need to figure out sign issues...
/* 64to32(MullS32(expr,expr)) */
{
DECLARE_PATTERN(p_MullS32_then_64to32);
return dst;
}
}
-#else
+#endif
+
+#if 0
+// CAB: This right? Need to figure out sign issues...
+ /* 64to32(MullU32(expr,expr)) */
+ {
+ DECLARE_PATTERN(p_MullU32_then_64to32);
+ DEFINE_PATTERN(p_MullU32_then_64to32,
+ unop(Iop_64to32,
+ binop(Iop_MullU32, bind(0), bind(1))));
+ if (matchIRExpr(&mi,p_MullU32_then_64to32,e)) {
+ HReg dst = newVRegI(env);
+ HReg src1 = iselIntExpr_R( env, mi.bindee[0] );
+ PPC32RI* src2 = iselIntExpr_RI( env, mi.bindee[1] );
+ addInstr(env, PPC32Instr_Alu32(Palu_MUL, dst, src1, src2));
+ return dst;
+ }
+ }
+#endif
+
HReg rHi, rLo;
iselInt64Expr(&rHi,&rLo, env, e->Iex.Unop.arg);
return rLo; /* similar stupid comment to the above ... */
-#endif
}
case Iop_16HIto8:
case Iop_32HIto16: {
//.. addInstr(env, X86Instr_Bsfr32(True,src,dst));
//.. return dst;
//.. }
-//.. case Iop_Clz32: {
-//.. /* Count leading zeroes. Do 'bsrl' to establish the index
-//.. of the highest set bit, and subtract that value from
-//.. 31. */
-//.. HReg tmp = newVRegI(env);
-//.. HReg dst = newVRegI(env);
-//.. HReg src = iselIntExpr_R(env, e->Iex.Unop.arg);
-//.. addInstr(env, X86Instr_Bsfr32(False,src,tmp));
-//.. addInstr(env, X86Instr_Alu32R(Xalu_MOV,
-//.. X86RMI_Imm(31), dst));
-//.. addInstr(env, X86Instr_Alu32R(Xalu_SUB,
-//.. X86RMI_Reg(tmp), dst));
-//.. return dst;
-//.. }
+ case Iop_Clz32: {
+ /* Count leading zeroes. */
+ HReg dst = newVRegI(env);
+ HReg src = iselIntExpr_R(env, e->Iex.Unop.arg);
+ addInstr(env, PPC32Instr_Unary32(Pun_CLZ,dst,src));
+ return dst;
+ }
//.. case Iop_128to32: {
//.. HReg dst = newVRegI(env);