|
From: <sv...@va...> - 2006-01-02 14:41:55
|
Author: cerion
Date: 2006-01-02 14:41:50 +0000 (Mon, 02 Jan 2006)
New Revision: 1527
Log:
Handle ppc64's function ptr's for toIR.c's dirtyhelper calls.
Modified:
trunk/priv/guest-ppc/toIR.c
Modified: trunk/priv/guest-ppc/toIR.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/priv/guest-ppc/toIR.c 2006-01-02 14:09:16 UTC (rev 1526)
+++ trunk/priv/guest-ppc/toIR.c 2006-01-02 14:41:50 UTC (rev 1527)
@@ -148,7 +148,23 @@
disInstr_PPC below. */
static Bool mode64 =3D False;
=20
+// Given a pointer to a function as obtained by "& functionname" in C,
+// produce a pointer to the actual entry point for the function. For
+// most platforms it's the identity function. Unfortunately, on
+// ppc64-linux it isn't (sigh).
+static void* fnptr_to_fnentry( void* f )
+{
+#if defined(__powerpc64__)
+ /* f is a pointer to a 3-word function descriptor, of which
+ the first word is the entry address. */
+ ULong* fdescr =3D (ULong*)f;
+ return (void*)(fdescr[0]);
+#else
+ return f;
+#endif
+}
=20
+
/*------------------------------------------------------------*/
/*--- Debugging output ---*/
/*------------------------------------------------------------*/
@@ -5037,11 +5053,12 @@
case 0x173: { // mftb (Move from Time Base, PPC32 p475)
IRTemp val =3D newTemp(Ity_I64);
IRExpr** args =3D mkIRExprVec_0();
- IRDirty* d =3D unsafeIRDirty_1_N( val,=20
- 0/*regparms*/,=20
- "ppcg_dirtyhelper_MFTB",=20
- &ppcg_dirtyhelper_MFTB,=20
- args );
+ IRDirty* d =3D unsafeIRDirty_1_N(
+ val,=20
+ 0/*regparms*/,=20
+ "ppcg_dirtyhelper_MFTB",=20
+ fnptr_to_fnentry(&ppcg_dirtyhelper_MFTB),=20
+ args );
/* execute the dirty call, dumping the result in val. */
stmt( IRStmt_Dirty(d) );
=20
@@ -6347,15 +6364,17 @@
mkU32(0xF)),
mkU32(0)/*left*/ );
if (!mode64) {
- d =3D unsafeIRDirty_0_N ( 0/*regparms*/,=20
- "ppc32g_dirtyhelper_LVS",
- &ppc32g_dirtyhelper_LVS,
- args );
+ d =3D unsafeIRDirty_0_N (
+ 0/*regparms*/,=20
+ "ppc32g_dirtyhelper_LVS",
+ fnptr_to_fnentry(&ppc32g_dirtyhelper_LVS),
+ args );
} else {
- d =3D unsafeIRDirty_0_N ( 0/*regparms*/,=20
- "ppc64g_dirtyhelper_LVS",
- &ppc64g_dirtyhelper_LVS,
- args );
+ d =3D unsafeIRDirty_0_N (
+ 0/*regparms*/,=20
+ "ppc64g_dirtyhelper_LVS",
+ fnptr_to_fnentry(&ppc64g_dirtyhelper_LVS),
+ args );
}
DIP("lvsl v%d,r%u,r%u\n", vD_addr, rA_addr, rB_addr);
/* declare guest state effects */
@@ -6378,15 +6397,17 @@
mkU32(0xF)),
mkU32(1)/*right*/ );
if (!mode64) {
- d =3D unsafeIRDirty_0_N ( 0/*regparms*/,=20
- "ppc32g_dirtyhelper_LVS",
- &ppc32g_dirtyhelper_LVS,
- args );
+ d =3D unsafeIRDirty_0_N (
+ 0/*regparms*/,=20
+ "ppc32g_dirtyhelper_LVS",
+ fnptr_to_fnentry(&ppc32g_dirtyhelper_LVS),
+ args );
} else {
- d =3D unsafeIRDirty_0_N ( 0/*regparms*/,=20
- "ppc64g_dirtyhelper_LVS",
- &ppc64g_dirtyhelper_LVS,
- args );
+ d =3D unsafeIRDirty_0_N (
+ 0/*regparms*/,=20
+ "ppc64g_dirtyhelper_LVS",
+ fnptr_to_fnentry(&ppc64g_dirtyhelper_LVS),
+ args );
}
DIP("lvsr v%d,r%u,r%u\n", vD_addr, rA_addr, rB_addr);
/* declare guest state effects */
|