i->Pin.Unary32.dst = dst;
return i;
}
-//.. X86Instr* X86Instr_MulL ( Bool syned, X86ScalarSz ssz , X86RM* src ) {
-//.. X86Instr* i = LibVEX_Alloc(sizeof(X86Instr));
-//.. i->tag = Xin_MulL;
-//.. i->Xin.MulL.syned = syned;
-//.. i->Xin.MulL.ssz = ssz;
-//.. i->Xin.MulL.src = src;
-//.. return i;
-//.. }
+PPC32Instr* PPC32Instr_MulL ( Bool syned, Bool word, HReg dst,
+ HReg src1, PPC32RI* src2 ) {
+ PPC32Instr* i = LibVEX_Alloc(sizeof(PPC32Instr));
+ i->tag = Pin_MulL;
+ i->Pin.MulL.syned = syned;
+ i->Pin.MulL.word = word;
+ 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.Bsfr32.dst = dst;
//.. return i;
//.. }
-//.. X86Instr* X86Instr_MFence ( VexSubArch subarch )
-//.. {
-//.. X86Instr* i = LibVEX_Alloc(sizeof(X86Instr));
-//.. i->tag = Xin_MFence;
-//.. i->Xin.MFence.subarch = subarch;
-//.. vassert(subarch == VexSubArchX86_sse0
-//.. || subarch == VexSubArchX86_sse1
-//.. || subarch == VexSubArchX86_sse2);
-//.. return i;
-//.. }
+PPC32Instr* PPC32Instr_MFence ( VexSubArch subarch )
+{
+ PPC32Instr* i = LibVEX_Alloc(sizeof(PPC32Instr));
+ i->tag = Pin_MFence;
+ i->Pin.MFence.subarch = subarch;
+ vassert(subarch == VexSubArchPPC32_AV
+ || subarch == VexSubArchPPC32_noAV);
+ return i;
+}
//.. X86Instr* X86Instr_FpUnary ( X86FpOp op, HReg src, HReg dst ) {
//.. X86Instr* i = LibVEX_Alloc(sizeof(X86Instr));
vex_printf("%sl ", showPPC32UnaryOp(i->Pin.Unary32.op));
ppHRegPPC32(i->Pin.Unary32.dst);
return;
-//.. case Xin_MulL:
-//.. vex_printf("%cmul%s ",
-//.. i->Xin.MulL.syned ? 's' : 'u',
-//.. showX86ScalarSz(i->Xin.MulL.ssz));
-//.. ppX86RM(i->Xin.MulL.src);
-//.. return;
+ case Pin_MulL:
+ if (i->Pin.MulL.src2->tag == Pri_Imm) {
+ vex_printf("mulli ");
+ } else {
+ vex_printf("mul%s%c ",
+ i->Pin.MulL.word ? "hw" : "lw",
+ i->Pin.MulL.syned ? 's' : 'u');
+ }
+ ppHRegPPC32(i->Pin.MulL.dst);
+ vex_printf(",");
+ ppHRegPPC32(i->Pin.MulL.src1);
+ vex_printf(",");
+ ppPPC32RI(i->Pin.MulL.src2);
+ return;
//.. case Xin_Div:
//.. vex_printf("%cdiv%s ",
//.. i->Xin.Div.syned ? 's' : 'u',
//.. vex_printf(",");
//.. ppHRegX86(i->Xin.Bsfr32.dst);
//.. return;
-//.. case Xin_MFence:
-//.. vex_printf("mfence(%s)",
-//.. LibVEX_ppVexSubArch(i->Xin.MFence.subarch));
-//.. return;
+ case Pin_MFence:
+ vex_printf("mfence(%s)",
+ LibVEX_ppVexSubArch(i->Pin.MFence.subarch));
+ return;
//.. case Xin_FpUnary:
//.. vex_printf("g%sD ", showX86FpOp(i->Xin.FpUnary.op));
//.. ppHRegX86(i->Xin.FpUnary.src);
case Pin_Unary32:
addHRegUse(u, HRmModify, i->Pin.Unary32.dst);
return;
-//.. case Xin_MulL:
-//.. addRegUsage_X86RM(u, i->Xin.MulL.src, HRmRead);
-//.. addHRegUse(u, HRmModify, hregX86_EAX());
-//.. addHRegUse(u, HRmWrite, hregX86_EDX());
-//.. return;
+ case Pin_MulL:
+ addHRegUse(u, HRmWrite, i->Pin.MulL.dst);
+ 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, HRmRead, i->Xin.Bsfr32.src);
//.. addHRegUse(u, HRmWrite, i->Xin.Bsfr32.dst);
//.. return;
-//.. case Xin_MFence:
-//.. return;
+ case Pin_MFence:
+ return;
//.. case Xin_FpUnary:
//.. addHRegUse(u, HRmRead, i->Xin.FpUnary.src);
//.. addHRegUse(u, HRmWrite, i->Xin.FpUnary.dst);
case Pin_Unary32:
mapReg(m, &i->Pin.Unary32.dst);
return;
-//.. case Xin_MulL:
-//.. mapRegs_X86RM(m, i->Xin.MulL.src);
-//.. return;
+ case Pin_MulL:
+ mapReg(m, &i->Pin.MulL.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;
//.. mapReg(m, &i->Xin.Bsfr32.src);
//.. mapReg(m, &i->Xin.Bsfr32.dst);
//.. return;
-//.. case Xin_MFence:
-//.. return;
+ case Pin_MFence:
+ return;
//.. case Xin_FpUnary:
//.. mapReg(m, &i->Xin.FpUnary.src);
//.. mapReg(m, &i->Xin.FpUnary.dst);
Pin_Sh32, /* 32-bit shift/rotate */
Pin_Test32, /* 32-bit test (AND, set flags, discard result) */
Pin_Unary32, /* 32-bit not and neg */
-//.. Xin_MulL, /* widening multiply */
+ Pin_MulL, /* widening multiply */
//.. Xin_Div, /* div and mod */
//.. Xin_Sh3232, /* shldl or shrdl */
//.. Xin_Push, /* push (32-bit?) value on stack */
Pin_Store, /* store a 8|16|32 bit value to mem */
Pin_Set32, /* convert condition code to 32-bit value */
//.. Xin_Bsfr32, /* 32-bit bsf/bsr */
-//.. Xin_MFence, /* mem fence (not just sse2, but sse0 and 1 too) */
+ Pin_MFence, /* mem fence (not just sse2, but sse0 and 1 too) */
//.. Xin_FpUnary, /* FP fake unary op */
//.. Xin_FpBinary, /* FP fake binary op */
PPC32UnaryOp op;
HReg dst;
} Unary32;
-//.. /* DX:AX = AX *s/u r/m16, or EDX:EAX = EAX *s/u r/m32 */
-//.. struct {
-//.. Bool syned;
-//.. X86ScalarSz ssz;
-//.. X86RM* src;
-//.. } MulL;
+ /* DX:AX = AX *s/u r/m16, or EDX:EAX = EAX *s/u r/m32 */
+ struct {
+ Bool syned;
+ Bool word; /* low=0, hi=1 */
+ HReg dst;
+ HReg src1;
+ PPC32RI* src2;
+ } MulL;
//.. /* x86 div/idiv instruction. Modifies EDX and EAX and reads src. */
//.. struct {
//.. Bool syned;
//.. HReg src;
//.. HReg dst;
//.. } Bsfr32;
-//.. /* Mem fence (not just sse2, but sse0 and 1 too). In short,
-//.. an insn which flushes all preceding loads and stores as
-//.. much as possible before continuing. On SSE2 we emit a
-//.. real "mfence", on SSE1 "sfence ; lock addl $0,0(%esp)" and
-//.. on SSE0 "lock addl $0,0(%esp)". This insn therefore
-//.. carries the subarch so the assembler knows what to
-//.. emit. */
-//.. struct {
-//.. VexSubArch subarch;
-//.. } MFence;
+ /* Mem fence (not just sse2, but sse0 and 1 too). In short,
+ an insn which flushes all preceding loads and stores as
+ much as possible before continuing. On SSE2 we emit a
+ real "mfence", on SSE1 "sfence ; lock addl $0,0(%esp)" and
+ on SSE0 "lock addl $0,0(%esp)". This insn therefore
+ carries the subarch so the assembler knows what to
+ emit. */
+ struct {
+ VexSubArch subarch;
+ } MFence;
//.. /* X86 Floating point (fake 3-operand, "flat reg file" insns) */
//.. struct {
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 X86Instr* X86Instr_MulL ( Bool syned, X86ScalarSz, X86RM* );
+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 );
//.. extern X86Instr* X86Instr_Push ( X86RMI* );
extern PPC32Instr* PPC32Instr_Store ( UChar sz, PPC32AMode* dst, HReg src );
extern PPC32Instr* PPC32Instr_Set32 ( PPC32CondCode cond, HReg dst );
//.. extern X86Instr* X86Instr_Bsfr32 ( Bool isFwds, HReg src, HReg dst );
-//.. extern X86Instr* X86Instr_MFence ( VexSubArch );
+extern PPC32Instr* PPC32Instr_MFence ( VexSubArch );
//..
//.. extern X86Instr* X86Instr_FpUnary ( X86FpOp op, HReg src, HReg dst );
//.. extern X86Instr* X86Instr_FpBinary ( X86FpOp op, HReg srcL, HReg srcR, HReg dst );
return env->vregmap[tmp];
}
-#if 0
static void lookupIRTemp64 ( HReg* vrHI, HReg* vrLO, ISelEnv* env, IRTemp tmp )
{
vassert(tmp >= 0);
*vrLO = env->vregmap[tmp];
*vrHI = env->vregmapHI[tmp];
}
-#endif
static void addInstr ( ISelEnv* env, PPC32Instr* instr )
{
static PPC32AMode* iselIntExpr_AMode_wrk ( ISelEnv* env, IRExpr* e );
static PPC32AMode* iselIntExpr_AMode ( ISelEnv* env, IRExpr* e );
-#if 0
static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo,
ISelEnv* env, IRExpr* e );
static void iselInt64Expr ( HReg* rHi, HReg* rLo,
ISelEnv* env, IRExpr* e );
-#endif
static PPC32CondCode iselCondCode_wrk ( ISelEnv* env, IRExpr* e );
static PPC32CondCode iselCondCode ( ISelEnv* env, IRExpr* e );
return dst;
}
case Iop_64HIto32: {
-
- /* 64HIto32(MullU32(expr,expr)) */
+ HReg rHi, rLo;
+ iselInt64Expr(&rHi,&rLo, env, e->Iex.Unop.arg);
+ return rHi; /* and abandon rLo .. poor wee thing :-) */
+ }
+ case Iop_64to32: {
+#if 1
+// CAB: This right?
+ /* 64to32(MullS32(expr,expr)) */
{
- DECLARE_PATTERN(p_MullU32_then_64HIto32);
- DEFINE_PATTERN(p_MullU32_then_64HIto32,
- unop(Iop_64HIto32,
- binop(Iop_MullU32, bind(0), bind(1))));
- if (matchIRExpr(&mi,p_MullU32_then_64HIto32,e)) {
+ DECLARE_PATTERN(p_MullS32_then_64to32);
+ DEFINE_PATTERN(p_MullS32_then_64to32,
+ unop(Iop_64to32,
+ binop(Iop_MullS32, bind(0), bind(1))));
+ if (matchIRExpr(&mi,p_MullS32_then_64to32,e)) {
HReg dst = newVRegI(env);
HReg src1 = iselIntExpr_R( env, mi.bindee[0] );
PPC32RI* src2 = iselIntExpr_RI( env, mi.bindee[1] );
return dst;
}
}
-
-#if 0
- HReg rHi, rLo;
- iselInt64Expr(&rHi,&rLo, env, e->Iex.Unop.arg);
- return rHi; /* and abandon rLo .. poor wee thing :-) */
-#endif
- }
-#if 0
- case Iop_64to32: {
+#else
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: {
HReg dst = newVRegI(env);
}
-#if 0
/*---------------------------------------------------------*/
/*--- ISEL: Integer expressions (64 bit) ---*/
/*---------------------------------------------------------*/
vassert(e);
vassert(typeOfIRExpr(env->type_env,e) == Ity_I64);
- vex_printf("@iselInt64Expr_wrk: tag=%d\n", e->tag);
+// vex_printf("@iselInt64Expr_wrk: tag=%d\n", e->tag);
//.. /* 64-bit literal */
//.. if (e->tag == Iex_Const) {
/* 32 x 32 -> 64 multiply */
case Iop_MullU32:
case Iop_MullS32: {
-#if 0
/* get one operand into %r3, and the other into a R/I.
Need to make an educated guess about which is better in
which. */
- HReg tLo = newVRegI(env);
- HReg tHi = newVRegI(env);
- Bool syned = e->Iex.Binop.op == Iop_MullS32;
- PPC32RI* rmLeft = iselIntExpr_RI(env, e->Iex.Binop.arg1);
- HReg rRight = iselIntExpr_R(env, e->Iex.Binop.arg2);
- addInstr(env, mk_iMOVsd_RR(rRight, hregPPC32_GPR3()));
-
- addInstr(env, PPC32Instr_MulL(syned, Pss_32, rmLeft));
-
- /* Result is now in EDX:EAX. Tell the caller. */
- addInstr(env, mk_iMOVds_RR(tHi, hregPPC32_EDX()));
- addInstr(env, mk_iMOVds_RR(tLo, hregPPC32_EAX()));
+ HReg tLo = newVRegI(env);
+ HReg tHi = newVRegI(env);
+ Bool syned = e->Iex.Binop.op == Iop_MullS32;
+ HReg rLeft = iselIntExpr_R(env, e->Iex.Binop.arg1);
+ PPC32RI* riRight = iselIntExpr_RI(env, e->Iex.Binop.arg2);
+ addInstr(env, PPC32Instr_MulL(syned, 0, tLo, rLeft, riRight));
+ addInstr(env, PPC32Instr_MulL(syned, 1, tHi, rLeft, riRight));
*rHi = tHi;
*rLo = tLo;
return;
-#endif
}
//.. /* 64 x 32 -> (32(rem),32(div)) division */
ppIRExpr(e);
vpanic("iselInt64Expr(ppc32)");
}
-#endif
//.. /*---------------------------------------------------------*/
//.. break;
//.. }
-//.. /* --------- MEM FENCE --------- */
-//.. case Ist_MFence:
-//.. addInstr(env, X86Instr_MFence(env->subarch));
-//.. return;
+ /* --------- MEM FENCE --------- */
+ case Ist_MFence:
+ addInstr(env, PPC32Instr_MFence(env->subarch));
+ return;
/* --------- EXIT --------- */
case Ist_Exit: {