//.. return i;
//.. }
+/* Read/Write Link Register */
+PPC32Instr* PPC32Instr_RdWrLR ( Bool wrLR, HReg gpr )
+{
+ PPC32Instr* i = LibVEX_Alloc(sizeof(PPC32Instr));
+ i->tag = Pin_RdWrLR;
+ i->Pin.RdWrLR.wrLR = wrLR;
+ i->Pin.RdWrLR.gpr = gpr;
+ return i;
+}
+
void ppPPC32Instr ( PPC32Instr* i )
{
switch (i->tag) {
//.. ppHRegX86(i->Xin.SseShuf.dst);
//.. return;
+ case Pin_RdWrLR:
+ vex_printf("%s ", i->Pin.RdWrLR.wrLR ? "mtlr" : "mflr");
+ ppHRegPPC32(i->Pin.RdWrLR.gpr);
+ return;
+
default:
vex_printf("\nppPPC32Instr(ppc32): No such tag(%d)\n", i->tag);
vpanic("ppPPC32Instr(ppc32)");
//.. addHRegUse(u, HRmRead, i->Xin.SseShuf.src);
//.. addHRegUse(u, HRmWrite, i->Xin.SseShuf.dst);
//.. return;
+
+ case Pin_RdWrLR:
+ addHRegUse(u, (i->Pin.RdWrLR.wrLR ? HRmRead : HRmWrite),
+ i->Pin.RdWrLR.gpr);
+ return;
+
default:
ppPPC32Instr(i);
vpanic("getRegUsage_PPC32Instr");
//.. mapReg(m, &i->Xin.SseShuf.src);
//.. mapReg(m, &i->Xin.SseShuf.dst);
//.. return;
+
+ case Pin_RdWrLR:
+ mapReg(m, &i->Pin.RdWrLR.gpr);
+ return;
+
default:
ppPPC32Instr(i);
vpanic("mapRegs_PPC32Instr");
//.. *p++ = (UChar)(i->Xin.SseShuf.order);
//.. goto done;
+ case Pin_RdWrLR: {
+ UInt reg = iregNo(i->Pin.RdWrLR.gpr);
+ /* wrLR==True ? mtlr r4 : mflr r4 */
+ p = mkFormXFX(p, reg, 8, (i->Pin.RdWrLR.wrLR==True) ? 467 : 339);
+ goto done;
+ }
+
default:
goto bad;
}
//.. Xin_FpLdStCW, /* fldcw / fstcw */
//.. Xin_FpStSW_AX, /* fstsw %ax */
//.. Xin_FpCmp, /* FP compare, generating a C320 value into int reg */
- Pin_Nada // Nix
+
+ Pin_RdWrLR /* Read/Write Link Register */
}
PPC32InstrTag;
//.. HReg dst;
//.. } FpCmp;
+ /* Read/Write Link Register */
+ struct {
+ Bool wrLR;
+ HReg gpr;
+ } RdWrLR;
} Pin;
}
PPC32Instr;
//.. extern X86Instr* X86Instr_FpStSW_AX ( void );
//.. extern X86Instr* X86Instr_FpCmp ( HReg srcL, HReg srcR, HReg dst );
+extern PPC32Instr* PPC32Instr_RdWrLR ( Bool wrLR, HReg gpr );
+
extern void ppPPC32Instr ( PPC32Instr* );
IRTemps. It holds the identity of a second
32-bit virtual HReg, which holds the high half
of the value.
-
+
+ - A copy of the link reg, so helper functions don't kill it.
+
- The code array, that is, the insns selected so far.
- A counter, for generating new virtual registers.
HReg* vregmapHI;
Int n_vregmap;
+ HReg savedLR;
+
HInstrArray* code;
Int vreg_ctr;
vpanic("isel_ppc32: Ist_Exit: dst is not a 32-bit value");
dst = iselIntExpr_RI(env, IRExpr_Const(stmt->Ist.Exit.dst));
cc = iselCondCode(env,stmt->Ist.Exit.guard);
+ addInstr(env, PPC32Instr_RdWrLR(True, env->savedLR));
addInstr(env, PPC32Instr_Goto(stmt->Ist.Exit.jk, cc, dst));
return;
}
}
cond = mk_PPCCondCode( Pct_ALWAYS, Pcf_EQ );
ri = iselIntExpr_RI(env, next);
+ addInstr(env, PPC32Instr_RdWrLR(True, env->savedLR));
addInstr(env, PPC32Instr_Goto(jk, cond, ri));
}
}
env->vreg_ctr = j;
+ /* Keep a copy of the link reg, so helper functions don't kill it. */
+ env->savedLR = newVRegI(env);
+ addInstr(env, PPC32Instr_RdWrLR(False, env->savedLR));
+
/* Ok, finally we can iterate over the statements. */
for (i = 0; i < bb->stmts_used; i++)
if (bb->stmts[i])
sb_helper2 = LibVEX_GuestPPC32_get_flags(&gst);
/* stay sane ... */
- assert(p[0] == 24<<26);
+ assert(p[0] == 24<<26); /* nop */
#if 0
printf("addr of first nop = 0x%x\n", addr_of_nop);
LibVEX_default_VexControl(&vcon);
vcon.guest_max_insns=1;
vcon.guest_chase_thresh=0;
+// vcon.iropt_level=2;
LibVEX_Init( failure_exit, log_bytes, 1, False, &vcon );
LibVEX_Guest_initialise(&gst);