i->tag = Pin_MulL;
i->Pin.MulL.syned = syned;
i->Pin.MulL.word = word;
- i->Pin.MulL.dst = dst;
+ i->Pin.MulL.dst = dst;
i->Pin.MulL.src1 = src1;
i->Pin.MulL.src2 = src2;
return i;
}
-//.. X86Instr* X86Instr_Div ( Bool syned, X86ScalarSz ssz, X86RM* src ) {
-//.. X86Instr* i = LibVEX_Alloc(sizeof(X86Instr));
-//.. i->tag = Xin_Div;
-//.. i->Xin.Div.syned = syned;
-//.. i->Xin.Div.ssz = ssz;
-//.. i->Xin.Div.src = src;
-//.. return i;
-//.. }
+PPC32Instr* PPC32Instr_Div ( Bool syned, HReg dst,
+ HReg src1, PPC32RI* src2 ) {
+ PPC32Instr* i = LibVEX_Alloc(sizeof(PPC32Instr));
+ i->tag = Pin_Div;
+ i->Pin.Div.syned = syned;
+ i->Pin.Div.dst = dst;
+ i->Pin.Div.src1 = src1;
+ i->Pin.Div.src2 = src2;
+ return i;
+}
//.. X86Instr* X86Instr_Sh3232 ( X86ShiftOp op, UInt amt, HReg src, HReg dst ) {
//.. X86Instr* i = LibVEX_Alloc(sizeof(X86Instr));
//.. i->tag = Xin_Sh3232;
vex_printf(",");
ppPPC32RI(i->Pin.MulL.src2);
return;
-//.. case Xin_Div:
-//.. vex_printf("%cdiv%s ",
-//.. i->Xin.Div.syned ? 's' : 'u',
-//.. showX86ScalarSz(i->Xin.Div.ssz));
-//.. ppX86RM(i->Xin.Div.src);
-//.. return;
+ case Pin_Div:
+ vex_printf("divw%s ",
+ i->Pin.Div.syned ? "" : "u");
+ ppHRegPPC32(i->Pin.MulL.dst);
+ vex_printf(",");
+ ppHRegPPC32(i->Pin.MulL.src1);
+ vex_printf(",");
+ ppPPC32RI(i->Pin.MulL.src2);
+ return;
//.. case Xin_Sh3232:
//.. vex_printf("%sdl ", showX86ShiftOp(i->Xin.Sh3232.op));
//.. if (i->Xin.Sh3232.amt == 0)
addHRegUse(u, HRmRead, i->Pin.MulL.src1);
addRegUsage_PPC32RI(u, i->Pin.MulL.src2);
return;
-//.. case Xin_Div:
-//.. addRegUsage_X86RM(u, i->Xin.Div.src, HRmRead);
-//.. addHRegUse(u, HRmModify, hregX86_EAX());
-//.. addHRegUse(u, HRmModify, hregX86_EDX());
-//.. return;
+ case Pin_Div:
+ addHRegUse(u, HRmWrite, i->Pin.Div.dst);
+ addHRegUse(u, HRmRead, i->Pin.Div.src1);
+ addRegUsage_PPC32RI(u, i->Pin.Div.src2);
+ return;
//.. case Xin_Sh3232:
//.. addHRegUse(u, HRmRead, i->Xin.Sh3232.src);
//.. addHRegUse(u, HRmModify, i->Xin.Sh3232.dst);
mapReg(m, &i->Pin.MulL.src1);
mapRegs_PPC32RI(m, i->Pin.MulL.src2);
return;
-//.. case Xin_Div:
-//.. mapRegs_X86RM(m, i->Xin.Div.src);
-//.. return;
+ case Pin_Div:
+ mapReg(m, &i->Pin.Div.dst);
+ mapReg(m, &i->Pin.Div.src1);
+ mapRegs_PPC32RI(m, i->Pin.Div.src2);
+ return;
//.. case Xin_Sh3232:
//.. mapReg(m, &i->Xin.Sh3232.src);
//.. mapReg(m, &i->Xin.Sh3232.dst);
Pin_Alu32, /* 32-bit mov/arith/logical */
Pin_Sh32, /* 32-bit shift/rotate */
Pin_Test32, /* 32-bit test (AND, set flags, discard result) */
- Pin_Unary32, /* 32-bit not and neg */
+ Pin_Unary32, /* 32-bit not, neg, clz */
Pin_MulL, /* widening multiply */
-//.. Xin_Div, /* div and mod */
+ Pin_Div, /* div */
//.. Xin_Sh3232, /* shldl or shrdl */
//.. Xin_Push, /* push (32-bit?) value on stack */
Pin_Call, /* call to address in register */
HReg src1;
PPC32RI* src2;
} MulL;
-//.. /* x86 div/idiv instruction. Modifies EDX and EAX and reads src. */
-//.. struct {
-//.. Bool syned;
-//.. X86ScalarSz ssz;
-//.. X86RM* src;
-//.. } Div;
+ /* ppc32 div/idiv instruction. Modifies EDX and EAX and reads src. */
+ struct {
+ Bool syned;
+ HReg dst;
+ HReg src1;
+ PPC32RI* src2;
+ } Div;
//.. /* shld/shrd. op may only be Xsh_SHL or Xsh_SHR */
//.. struct {
//.. X86ShiftOp op;
extern PPC32Instr* PPC32Instr_Test32 ( HReg dst, PPC32RI* src );
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 PPC32Instr* PPC32Instr_Div ( Bool syned, HReg, HReg, PPC32RI* );
//.. extern X86Instr* X86Instr_Sh3232 ( X86ShiftOp, UInt amt, HReg src, HReg dst );
//.. extern X86Instr* X86Instr_Push ( X86RMI* );
extern PPC32Instr* PPC32Instr_Call ( PPC32CondCode, Addr32, Int );
//.. movl %vr104,%vr70
//.. */
+ /* How about a div? */
+ if (e->Iex.Binop.op == Iop_DivU32) {
+ vex_printf(" *HERE\n\n");
+ HReg dst = newVRegI(env);
+ HReg src1 = iselIntExpr_R(env, e->Iex.Binop.arg1);
+ PPC32RI* ri_src2 = iselIntExpr_RI(env, e->Iex.Binop.arg2);
+ addInstr(env, PPC32Instr_Div(False, dst, src1, ri_src2));
+ return dst;
+ }
+ if (e->Iex.Binop.op == Iop_DivS32) {
+ HReg dst = newVRegI(env);
+ HReg src1 = iselIntExpr_R(env, e->Iex.Binop.arg1);
+ PPC32RI* ri_src2 = iselIntExpr_RI(env, e->Iex.Binop.arg2);
+ addInstr(env, PPC32Instr_Div(True, dst, src1, ri_src2));
+ return dst;
+ }
+
/* Perhaps a shift op? */
switch (e->Iex.Binop.op) {
case Iop_Shl32: case Iop_Shl16: case Iop_Shl8: