]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Initial file setup for guest-ppc
authorCerion Armour-Brown <cerion@valgrind.org>
Tue, 25 Jan 2005 12:24:25 +0000 (12:24 +0000)
committerCerion Armour-Brown <cerion@valgrind.org>
Tue, 25 Jan 2005 12:24:25 +0000 (12:24 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@742

VEX/Makefile
VEX/priv/guest-ppc/gdefs.h [new file with mode: 0644]
VEX/priv/guest-ppc/ghelpers.c [new file with mode: 0644]
VEX/priv/guest-ppc/toIR.c [new file with mode: 0644]
VEX/pub/libvex.h
VEX/pub/libvex_guest_ppc.h [new file with mode: 0644]

index e9c063b344b1954e0e418b686b4ec1e833aedbba..b703ba5b8b74ff99b0de2453497614397dd7f730 100644 (file)
@@ -6,7 +6,8 @@ PUB_HEADERS =   pub/libvex_basictypes.h                 \
                pub/libvex_emwarn.h                     \
                pub/libvex_guest_x86.h                  \
                pub/libvex_guest_amd64.h                \
-               pub/libvex_guest_arm.h
+               pub/libvex_guest_arm.h                  \
+               pub/libvex_guest_ppc.h
 
 PRIV_HEADERS =         priv/host-x86/hdefs.h                   \
                priv/host-arm/hdefs.h                   \
@@ -17,6 +18,7 @@ PRIV_HEADERS =        priv/host-x86/hdefs.h                   \
                priv/guest-x86/gdefs.h                  \
                priv/guest-amd64/gdefs.h                \
                priv/guest-arm/gdefs.h                  \
+               priv/guest-ppc/gdefs.h                  \
                priv/ir/irmatch.h                       \
                priv/ir/iropt.h
 
@@ -36,9 +38,11 @@ LIB_OBJS =   priv/ir/irdefs.o                        \
                priv/guest-x86/ghelpers.o               \
                priv/guest-amd64/ghelpers.o             \
                priv/guest-arm/ghelpers.o               \
+               priv/guest-ppc/ghelpers.o               \
                priv/guest-x86/toIR.o                   \
                priv/guest-amd64/toIR.o                 \
-               priv/guest-arm/toIR.o
+               priv/guest-arm/toIR.o                   \
+               priv/guest-ppc/toIR.o
 
 PUB_INCLUDES = -Ipub
 
@@ -182,3 +186,11 @@ priv/guest-arm/ghelpers.o: $(ALL_HEADERS) priv/guest-arm/ghelpers.c
 priv/guest-arm/toIR.o: $(ALL_HEADERS) priv/guest-arm/toIR.c
        $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/guest-arm/toIR.o \
                                         -c priv/guest-arm/toIR.c
+
+priv/guest-ppc/ghelpers.o: $(ALL_HEADERS) priv/guest-ppc/ghelpers.c
+       $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/guest-ppc/ghelpers.o \
+                                        -c priv/guest-ppc/ghelpers.c
+
+priv/guest-ppc/toIR.o: $(ALL_HEADERS) priv/guest-ppc/toIR.c
+       $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/guest-ppc/toIR.o \
+                                        -c priv/guest-ppc/toIR.c
diff --git a/VEX/priv/guest-ppc/gdefs.h b/VEX/priv/guest-ppc/gdefs.h
new file mode 100644 (file)
index 0000000..0ed3899
--- /dev/null
@@ -0,0 +1,106 @@
+
+/*---------------------------------------------------------------*/
+/*---                                                         ---*/
+/*--- This file (guest-ppc/gdefs.h) is                        ---*/
+/*--- Copyright (c) 2004 OpenWorks LLP.  All rights reserved. ---*/
+/*---                                                         ---*/
+/*---------------------------------------------------------------*/
+
+/*
+   This file is part of LibVEX, a library for dynamic binary
+   instrumentation and translation.
+
+   Copyright (C) 2004 OpenWorks, LLP.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; Version 2 dated June 1991 of the
+   license.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or liability
+   for damages.  See the GNU General Public License for more details.
+
+   Neither the names of the U.S. Department of Energy nor the
+   University of California nor the names of its contributors may be
+   used to endorse or promote products derived from this software
+   without prior written permission.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+   USA.
+*/
+
+/* Only to be used within the guest-ppc directory. */
+
+
+#ifndef __LIBVEX_GUEST_PPC_DEFS_H
+#define __LIBVEX_GUEST_PPC_DEFS_H
+
+
+/*---------------------------------------------------------*/
+/*--- ppc to IR conversion                              ---*/
+/*---------------------------------------------------------*/
+
+extern
+IRBB* bbToIR_PPC ( UChar*     ppcCode, 
+                   Addr64     eip, 
+                   Int*       guest_bytes_read, 
+                   Bool       (*byte_accessible)(Addr64),
+                   Bool       (*resteerOkFn)(Addr64),
+                   Bool       host_bigendian,
+                   VexSubArch subarch_guest );
+
+/* Used by the optimiser to specialise calls to helpers. */
+extern
+IRExpr* guest_ppc_spechelper ( Char* function_name,
+                               IRExpr** args );
+
+/* Describes to the optimser which part of the guest state require
+   precise memory exceptions.  This is logically part of the guest
+   state description. */
+extern 
+Bool guest_ppc_state_requires_precise_mem_exns ( Int, Int );
+
+extern
+VexGuestLayout ppcGuest_layout;
+
+
+/*---------------------------------------------------------*/
+/*--- ppc guest helpers                                 ---*/
+/*---------------------------------------------------------*/
+
+/* --- CLEAN HELPERS --- */
+
+// Calculate CR0[0,1,2] (neg,pos,zero) from result
+extern UInt  ppcg_calculate_flags_cr0 ( UInt result );
+
+
+
+
+/* Defines conditions which we can ask for */
+
+/*
+neg(lt):  CR0[0]==1
+pos(gt):  CR0[1]==1
+zero(eq): CR0[2]==1
+
+summary overflow: XER[0]
+overflow:         XER[1]
+carry:            XER[2]
+*/
+
+#if 0
+typedef
+   enum {
+   }
+   PPCCondcode;
+#endif
+
+#endif /* ndef __LIBVEX_GUEST_PPC_DEFS_H */
+
+/*---------------------------------------------------------------*/
+/*--- end                                   guest-ppc/gdefs.h ---*/
+/*---------------------------------------------------------------*/
diff --git a/VEX/priv/guest-ppc/ghelpers.c b/VEX/priv/guest-ppc/ghelpers.c
new file mode 100644 (file)
index 0000000..00c0d4a
--- /dev/null
@@ -0,0 +1,212 @@
+
+/*---------------------------------------------------------------*/
+/*---                                                         ---*/
+/*--- This file (guest-ppc/ghelpers.c) is                     ---*/
+/*--- Copyright (c) 2004 OpenWorks LLP.  All rights reserved. ---*/
+/*---                                                         ---*/
+/*---------------------------------------------------------------*/
+
+/*
+   This file is part of LibVEX, a library for dynamic binary
+   instrumentation and translation.
+
+   Copyright (C) 2004 OpenWorks, LLP.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; Version 2 dated June 1991 of the
+   license.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or liability
+   for damages.  See the GNU General Public License for more details.
+
+   Neither the names of the U.S. Department of Energy nor the
+   University of California nor the names of its contributors may be
+   used to endorse or promote products derived from this software
+   without prior written permission.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+   USA.
+*/
+
+#include "libvex_basictypes.h"
+#include "libvex_guest_ppc.h"
+#include "libvex_ir.h"
+#include "libvex.h"
+
+#include "main/vex_util.h"
+#include "guest-ppc/gdefs.h"
+
+
+/* This file contains helper functions for ppc guest code.
+   Calls to these functions are generated by the back end.
+   These calls are of course in the host machine code and 
+   this file will be compiled to host machine code, so that
+   all makes sense.  
+
+   Only change the signatures of these helper functions very
+   carefully.  If you change the signature here, you'll have to change
+   the parameters passed to it in the IR calls constructed by
+   guest-ppc/toIR.c.
+*/
+
+
+
+
+
+/* CALLED FROM GENERATED CODE: CLEAN HELPER */
+/* Calculate all the 4 flags from the supplied thunk parameters. */
+UInt ppcg_calculate_flags_cr0 ( UInt result )
+{
+    return 0;
+}
+
+
+
+
+
+/* Used by the optimiser to try specialisations.  Returns an
+   equivalent expression, or NULL if none. */
+
+#if 0
+/* temporarily unused */
+static Bool isU32 ( IRExpr* e, UInt n )
+{
+   return e->tag == Iex_Const
+          && e->Iex.Const.con->tag == Ico_U32
+          && e->Iex.Const.con->Ico.U32 == n;
+}
+#endif
+IRExpr* guest_ppc_spechelper ( Char* function_name,
+                               IRExpr** args )
+{
+   return NULL;
+}
+
+
+/*----------------------------------------------*/
+/*--- The exported fns ..                    ---*/
+/*----------------------------------------------*/
+
+/* VISIBLE TO LIBVEX CLIENT */
+#if 0
+void LibVEX_GuestPPC_put_flags ( UInt flags_native,
+                                 /*OUT*/VexGuestPPCState* vex_state )
+{
+   vassert(0); // FIXME
+}
+#endif
+
+/* VISIBLE TO LIBVEX CLIENT */
+UInt LibVEX_GuestPPC_get_flags ( /*IN*/VexGuestPPCState* vex_state )
+{
+   UInt flags;
+   vassert(0); // FIXME
+
+   flags = ppcg_calculate_flags_cr0( vex_state->guest_Result );
+   return flags;
+}
+
+/* VISIBLE TO LIBVEX CLIENT */
+void LibVEX_GuestPPC_initialise ( /*OUT*/VexGuestPPCState* vex_state )
+{
+   vex_state->guest_GPR0  = 0;
+   vex_state->guest_GPR1  = 0;
+   vex_state->guest_GPR2  = 0;
+   vex_state->guest_GPR3  = 0;
+   vex_state->guest_GPR4  = 0;
+   vex_state->guest_GPR5  = 0;
+   vex_state->guest_GPR6  = 0;
+   vex_state->guest_GPR7  = 0;
+   vex_state->guest_GPR8  = 0;
+   vex_state->guest_GPR9  = 0;
+   vex_state->guest_GPR10 = 0;
+   vex_state->guest_GPR11 = 0;
+   vex_state->guest_GPR12 = 0;
+   vex_state->guest_GPR13 = 0;
+   vex_state->guest_GPR14 = 0;
+   vex_state->guest_GPR15 = 0;
+   vex_state->guest_GPR16 = 0;
+   vex_state->guest_GPR17 = 0;
+   vex_state->guest_GPR18 = 0;
+   vex_state->guest_GPR19 = 0;
+   vex_state->guest_GPR20 = 0;
+   vex_state->guest_GPR21 = 0;
+   vex_state->guest_GPR22 = 0;
+   vex_state->guest_GPR23 = 0;
+   vex_state->guest_GPR24 = 0;
+   vex_state->guest_GPR25 = 0;
+   vex_state->guest_GPR26 = 0;
+   vex_state->guest_GPR27 = 0;
+   vex_state->guest_GPR28 = 0;
+   vex_state->guest_GPR29 = 0;
+   vex_state->guest_GPR30 = 0;
+   vex_state->guest_GPR31 = 0;
+
+   vex_state->guest_LR  = 0;
+   vex_state->guest_CTR = 0;
+
+   vex_state->guest_Result = 0;
+
+   vex_state->guest_XER_SO = 0;
+   vex_state->guest_XER_OV = 0;
+   vex_state->guest_XER_CA = 0;
+
+   vex_state->guest_EMWARN = 0;
+}
+
+
+/*-----------------------------------------------------------*/
+/*--- Describing the ppc guest state, for the benefit     ---*/
+/*--- of iropt and instrumenters.                         ---*/
+/*-----------------------------------------------------------*/
+
+/* Figure out if any part of the guest state contained in minoff
+   .. maxoff requires precise memory exceptions.  If in doubt return
+   True (but this is generates significantly slower code).  
+*/
+Bool guest_ppc_state_requires_precise_mem_exns ( Int minoff, 
+                                                 Int maxoff)
+{
+   return True; // FIXME (also comment above)
+}
+
+
+
+#define ALWAYSDEFD(field)                           \
+    { offsetof(VexGuestPPCState, field),            \
+      (sizeof ((VexGuestPPCState*)0)->field) }
+
+VexGuestLayout
+   ppcGuest_layout 
+      = { 
+          /* Total size of the guest state, in bytes. */
+          .total_sizeB = sizeof(VexGuestPPCState),
+
+          /* Describe the stack pointer. */
+          .offset_SP = offsetof(VexGuestPPCState,guest_GPR1),
+          .sizeof_SP = 4,
+
+// CAB: There isn't a PC on the PPC!
+          /* Describe the instruction pointer. */
+//          .offset_IP = offsetof(VexGuestPPCState,guest_R15),
+//          .sizeof_IP = 4,
+
+          /* Describe any sections to be regarded by Memcheck as
+             'always-defined'. */
+          .n_alwaysDefd = 1,
+          /* flags thunk: only using last_result, which is always defd. */
+
+          .alwaysDefd 
+             = { /*  0 */ ALWAYSDEFD(guest_Result)
+               }
+        };
+
+
+/*---------------------------------------------------------------*/
+/*--- end                                guest-ppc/ghelpers.c ---*/
+/*---------------------------------------------------------------*/
diff --git a/VEX/priv/guest-ppc/toIR.c b/VEX/priv/guest-ppc/toIR.c
new file mode 100644 (file)
index 0000000..f8c8e19
--- /dev/null
@@ -0,0 +1,852 @@
+
+/*--------------------------------------------------------------------*/
+/*---                                                              ---*/
+/*--- This file (guest-ppc/toIR.c) is                              ---*/
+/*--- Copyright (c) 2004 OpenWorks LLP.  All rights reserved.      ---*/
+/*---                                                              ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+   This file is part of LibVEX, a library for dynamic binary
+   instrumentation and translation.
+
+   Copyright (C) 2004 OpenWorks, LLP.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; Version 2 dated June 1991 of the
+   license.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or liability
+   for damages.  See the GNU General Public License for more details.
+
+   Neither the names of the U.S. Department of Energy nor the
+   University of California nor the names of its contributors may be
+   used to endorse or promote products derived from this software
+   without prior written permission.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+   USA.
+*/
+
+/* Translates PPC(v4) code to IR. */
+
+#include "libvex_basictypes.h"
+#include "libvex_ir.h"
+#include "libvex.h"
+#include "libvex_guest_ppc.h"
+
+#include "main/vex_util.h"
+#include "main/vex_globals.h"
+#include "guest-ppc/gdefs.h"
+
+
+/*------------------------------------------------------------*/
+/*--- Globals                                              ---*/
+/*------------------------------------------------------------*/
+
+/* These are set at the start of the translation of a BB, so that we
+   don't have to pass them around endlessly.  CONST means does not
+   change during translation of a bb. 
+*/
+
+/* We need to know this to do sub-register accesses correctly. */
+/* CONST */
+static Bool host_is_bigendian;
+
+/* Pointer to the guest code area. */
+/* CONST */
+static UChar* guest_code;
+
+/* The guest address corresponding to guest_code[0]. */
+/* CONST */
+static Addr32 guest_pc_bbstart;
+
+/* The IRBB* into which we're generating code. */
+static IRBB* irbb;
+
+
+/*------------------------------------------------------------*/
+/*--- Debugging output                                     ---*/
+/*------------------------------------------------------------*/
+
+#define DIP(format, args...)           \
+   if (vex_traceflags & VEX_TRACE_FE)  \
+      vex_printf(format, ## args)
+
+#define DIS(buf, format, args...)      \
+   if (vex_traceflags & VEX_TRACE_FE)  \
+      vex_sprintf(buf, format, ## args)
+
+
+
+
+/*------------------------------------------------------------*/
+/*--- Offsets of various parts of the ppc guest state.     ---*/
+/*------------------------------------------------------------*/
+
+#define OFFB_GPR0       offsetof(VexGuestPPCState,guest_GPR0)
+#define OFFB_GPR1       offsetof(VexGuestPPCState,guest_GPR1)
+#define OFFB_GPR2       offsetof(VexGuestPPCState,guest_GPR2)
+#define OFFB_GPR3       offsetof(VexGuestPPCState,guest_GPR3)
+#define OFFB_GPR4       offsetof(VexGuestPPCState,guest_GPR4)
+#define OFFB_GPR5       offsetof(VexGuestPPCState,guest_GPR5)
+#define OFFB_GPR6       offsetof(VexGuestPPCState,guest_GPR6)
+#define OFFB_GPR7       offsetof(VexGuestPPCState,guest_GPR7)
+#define OFFB_GPR8       offsetof(VexGuestPPCState,guest_GPR8)
+#define OFFB_GPR9       offsetof(VexGuestPPCState,guest_GPR9)
+#define OFFB_GPR10      offsetof(VexGuestPPCState,guest_GPR10)
+#define OFFB_GPR11      offsetof(VexGuestPPCState,guest_GPR11)
+#define OFFB_GPR12      offsetof(VexGuestPPCState,guest_GPR12)
+#define OFFB_GPR13      offsetof(VexGuestPPCState,guest_GPR13)
+#define OFFB_GPR14      offsetof(VexGuestPPCState,guest_GPR14)
+#define OFFB_GPR15      offsetof(VexGuestPPCState,guest_GPR15)
+#define OFFB_GPR16      offsetof(VexGuestPPCState,guest_GPR16)
+#define OFFB_GPR17      offsetof(VexGuestPPCState,guest_GPR17)
+#define OFFB_GPR18      offsetof(VexGuestPPCState,guest_GPR18)
+#define OFFB_GPR19      offsetof(VexGuestPPCState,guest_GPR19)
+#define OFFB_GPR20      offsetof(VexGuestPPCState,guest_GPR20)
+#define OFFB_GPR21      offsetof(VexGuestPPCState,guest_GPR21)
+#define OFFB_GPR22      offsetof(VexGuestPPCState,guest_GPR22)
+#define OFFB_GPR23      offsetof(VexGuestPPCState,guest_GPR23)
+#define OFFB_GPR24      offsetof(VexGuestPPCState,guest_GPR24)
+#define OFFB_GPR25      offsetof(VexGuestPPCState,guest_GPR25)
+#define OFFB_GPR26      offsetof(VexGuestPPCState,guest_GPR26)
+#define OFFB_GPR27      offsetof(VexGuestPPCState,guest_GPR27)
+#define OFFB_GPR28      offsetof(VexGuestPPCState,guest_GPR28)
+#define OFFB_GPR29      offsetof(VexGuestPPCState,guest_GPR29)
+#define OFFB_GPR30      offsetof(VexGuestPPCState,guest_GPR30)
+#define OFFB_GPR31      offsetof(VexGuestPPCState,guest_GPR31)
+
+#define OFFB_RESULT    offsetof(VexGuestPPCState,guest_Result)
+
+
+/*------------------------------------------------------------*/
+/*--- Disassemble an entire basic block                    ---*/
+/*------------------------------------------------------------*/
+
+/* The results of disassembling an instruction.  There are three
+   possible outcomes.  For Dis_Resteer, the disassembler _must_
+   continue at the specified address.  For Dis_StopHere, the
+   disassembler _must_ terminate the BB.  For Dis_Continue, we may at
+   our option either disassemble the next insn, or terminate the BB;
+   but in the latter case we must set the bb's ->next field to point
+   to the next instruction.  */
+
+typedef
+   enum { 
+      Dis_StopHere, /* this insn terminates the BB; we must stop. */
+      Dis_Continue, /* we can optionally continue into the next insn */
+      Dis_Resteer   /* followed a branch; continue at the spec'd addr */
+   }
+   DisResult;
+
+
+/* forward decls .. */
+static IRExpr* mkU32 ( UInt i );
+static void stmt ( IRStmt* st );
+
+
+/* disInstr disassembles an instruction located at &guest_code[delta],
+   and sets *size to its size.  If the returned value is Dis_Resteer,
+   the next guest address is assigned to *whereNext.  disInstr is not
+   permitted to return Dis_Resteer if either (1) resteerOK is False,
+   or (2) resteerOkFn, when applied to the address which it wishes to
+   resteer into, returns False.  */
+   
+static DisResult disInstr ( /*IN*/  Bool    resteerOK,
+                            /*IN*/  Bool    (*resteerOkFn) ( Addr64 ),
+                            /*IN*/  UInt    delta, 
+                            /*OUT*/ UInt*   size,
+                            /*OUT*/ Addr64* whereNext );
+
+
+/* This is the main (only, in fact) entry point for this module. */
+
+/* Disassemble a complete basic block, starting at guest_pc_start, and
+   dumping the IR into global irbb.  Returns the size, in bytes, of
+   the basic block.  
+*/
+IRBB* bbToIR_PPC ( UChar*     ppcCode, 
+                   Addr64     guest_pc_start, 
+                   Int*       guest_bytes_read, 
+                   Bool       (*byte_accessible)(Addr64),
+                   Bool       (*chase_into_ok)(Addr64),
+                   Bool       host_bigendian,
+                   VexSubArch subarch_guest )
+{
+   UInt       delta;
+   Int        i, n_instrs, size, first_stmt_idx;
+   Addr64     guest_next;
+   Bool       resteerOK;
+   DisResult  dres;
+   static Int n_resteers = 0;
+   Int        d_resteers = 0;
+
+   /* check sanity .. */
+   vassert(vex_control.guest_max_insns >= 1);
+   vassert(vex_control.guest_max_insns < 1000);
+   vassert(vex_control.guest_chase_thresh >= 0);
+   vassert(vex_control.guest_chase_thresh < vex_control.guest_max_insns);
+
+//   vassert(subarch_guest == VexSubArchPPC_32);
+
+   /* Set up globals. */
+   host_is_bigendian = host_bigendian;
+   guest_code        = ppcCode;
+   guest_pc_bbstart  = (Addr32)guest_pc_start;
+   irbb              = emptyIRBB();
+
+   vassert((guest_pc_start >> 32) == 0);
+
+   /* Delta keeps track of how far along the x86code array we
+      have so far gone. */
+   delta             = 0;
+   n_instrs          = 0;
+   *guest_bytes_read = 0;
+
+   while (True) {
+      vassert(n_instrs < vex_control.guest_max_insns);
+
+      guest_next = 0;
+      resteerOK = n_instrs < vex_control.guest_chase_thresh;
+      first_stmt_idx = irbb->stmts_used;
+
+      if (n_instrs > 0) {
+         /* for the first insn, the dispatch loop will have set
+            GPR1, but for all the others we have to do it ourselves. */
+         stmt( IRStmt_Put( OFFB_GPR1, mkU32(guest_pc_bbstart + delta)) );
+      }
+
+      dres = disInstr( resteerOK, chase_into_ok, 
+                       delta, &size, &guest_next );
+
+      /* Print the resulting IR, if needed. */
+      if (vex_traceflags & VEX_TRACE_FE) {
+         for (i = first_stmt_idx; i < irbb->stmts_used; i++) {
+            vex_printf("              ");
+            ppIRStmt(irbb->stmts[i]);
+            vex_printf("\n");
+         }
+      }
+   
+      if (dres == Dis_StopHere) {
+         vassert(irbb->next != NULL);
+         if (vex_traceflags & VEX_TRACE_FE) {
+            vex_printf("              ");
+            vex_printf( "goto {");
+            ppIRJumpKind(irbb->jumpkind);
+            vex_printf( "} ");
+            ppIRExpr( irbb->next );
+            vex_printf( "\n");
+         }
+      }
+
+      delta += size;
+      *guest_bytes_read += size;
+      n_instrs++;
+      DIP("\n");
+
+      vassert(size > 0 && size <= 18);
+      if (!resteerOK) 
+         vassert(dres != Dis_Resteer);
+      if (dres != Dis_Resteer) 
+         vassert(guest_next == 0);
+
+      switch (dres) {
+         case Dis_Continue:
+            vassert(irbb->next == NULL);
+            if (n_instrs < vex_control.guest_max_insns) {
+               /* keep going */
+            } else {
+               irbb->next = mkU32(((Addr32)guest_pc_start)+delta);
+               return irbb;
+            }
+            break;
+         case Dis_StopHere:
+            vassert(irbb->next != NULL);
+            return irbb;
+         case Dis_Resteer:
+            vassert(irbb->next == NULL);
+            /* figure out a new delta to continue at. */
+            vassert(chase_into_ok(guest_next));
+            delta = (UInt)(guest_next - guest_pc_start);
+            n_resteers++;
+            d_resteers++;
+            if (0 && (n_resteers & 0xFF) == 0)
+            vex_printf("resteer[%d,%d] to %p (delta = %d)\n",
+                       n_resteers, d_resteers,
+                       (void*)(UInt)(guest_next), delta);
+            break;
+      }
+   }
+}
+
+
+/*------------------------------------------------------------*/
+/*--- Helper bits and pieces for deconstructing the        ---*/
+/*--- x86 insn stream.                                     ---*/
+/*------------------------------------------------------------*/
+
+/* Add a statement to the list held by "irbb". */
+static void stmt ( IRStmt* st )
+{
+   addStmtToIRBB( irbb, st );
+}
+
+#if 0
+/* Generate a new temporary of the given type. */
+static IRTemp newTemp ( IRType ty )
+{
+   vassert(isPlausibleType(ty));
+   return newIRTemp( irbb->tyenv, ty );
+}
+#endif
+
+#if 0
+/* Bomb out if we can't handle something. */
+__attribute__ ((noreturn))
+static void unimplemented ( Char* str )
+{
+   vex_printf("ppcToIR: unimplemented feature\n");
+   vpanic(str);
+}
+#endif
+
+/* Various simple conversions */
+
+#if 0
+static UInt extend_s_8to32( UInt x )
+{
+   return (UInt)((((Int)x) << 24) >> 24);
+}
+
+static UInt extend_s_16to32 ( UInt x )
+{
+   return (UInt)((((Int)x) << 16) >> 16);
+}
+#endif
+
+#if 0
+static UInt extend_s_24to32 ( UInt x )
+{
+   return (UInt)((((Int)x) << 8) >> 8);
+}
+#endif
+
+#if 0
+/* Fetch a byte from the guest insn stream. */
+static UChar getIByte ( UInt delta )
+{
+   return guest_code[delta];
+}
+#endif
+
+/* Get a 8/16/32-bit unsigned value out of the insn stream. */
+
+#if 0
+static UInt getUChar ( UInt delta )
+{
+   UInt v = guest_code[delta+0];
+   return v & 0xFF;
+}
+#endif
+
+#if 0
+static UInt getUDisp16 ( UInt delta )
+{
+   UInt v = guest_code[delta+1]; v <<= 8;
+   v |= guest_code[delta+0];
+   return v & 0xFFFF;
+}
+#endif
+
+#if 0
+static UInt getUDisp32 ( UInt delta )
+{
+   UInt v = guest_code[delta+3]; v <<= 8;
+   v |= guest_code[delta+2]; v <<= 8;
+   v |= guest_code[delta+1]; v <<= 8;
+   v |= guest_code[delta+0];
+   return v;
+}
+#endif
+
+#if 0
+static UInt getUDisp ( Int size, UInt delta )
+{
+   switch (size) {
+      case 4: return getUDisp32(delta);
+      case 2: return getUDisp16(delta);
+      case 1: return getUChar(delta);
+      default: vpanic("getUDisp(PPC)");
+   }
+   return 0; /*notreached*/
+}
+#endif
+
+#if 0
+/* Get a byte value out of the insn stream and sign-extend to 32
+   bits. */
+static UInt getSDisp8 ( UInt delta )
+{
+   return extend_s_8to32( (UInt) (guest_code[delta]) );
+}
+#endif
+
+#if 0
+static UInt getSDisp16 ( UInt delta0 )
+{
+   UChar* eip = (UChar*)(&guest_code[delta0]);
+   UInt d = *eip++;
+   d |= ((*eip++) << 8);
+   return extend_s_16to32(d);
+}
+#endif
+
+#if 0
+static UInt getSDisp ( Int size, UInt delta )
+{
+   switch (size) {
+      case 4: return getUDisp32(delta);
+      case 2: return getSDisp16(delta);
+      case 1: return getSDisp8(delta);
+      default: vpanic("getSDisp(PPC)");
+  }
+  return 0; /*notreached*/
+}
+#endif
+
+
+/*------------------------------------------------------------*/
+/*--- Helpers for constructing IR.                         ---*/
+/*------------------------------------------------------------*/
+
+/* Create a 1/2/4 byte read of an x86 integer registers.  For 16/8 bit
+   register references, we need to take the host endianness into
+   account.  Supplied value is 0 .. 7 and in the Intel instruction
+   encoding. */
+
+#if 0
+static IRType szToITy ( Int n )
+{
+   switch (n) {
+      case 1: return Ity_I8;
+      case 2: return Ity_I16;
+      case 4: return Ity_I32;
+      default: vpanic("szToITy(PPC)");
+   }
+}
+#endif
+
+#if 0
+static Int integerGuestRegOffset ( UInt archreg )
+{
+   vassert(archreg < 32);
+
+   vassert(!host_is_bigendian);   //TODO: is this necessary?
+   // jrs: probably not; only matters if we reference sub-parts
+   // of the ppc registers, but that isn't the case
+   switch (archreg) {
+      case  0: return offsetof(VexGuestPPCState, guest_GPR0);
+      case  1: return offsetof(VexGuestPPCState, guest_GPR1);
+      case  2: return offsetof(VexGuestPPCState, guest_GPR2);
+      case  3: return offsetof(VexGuestPPCState, guest_GPR3);
+      case  4: return offsetof(VexGuestPPCState, guest_GPR4);
+      case  5: return offsetof(VexGuestPPCState, guest_GPR5);
+      case  6: return offsetof(VexGuestPPCState, guest_GPR6);
+      case  7: return offsetof(VexGuestPPCState, guest_GPR7);
+      case  8: return offsetof(VexGuestPPCState, guest_GPR8);
+      case  9: return offsetof(VexGuestPPCState, guest_GPR9);
+      case 10: return offsetof(VexGuestPPCState, guest_GPR10);
+      case 11: return offsetof(VexGuestPPCState, guest_GPR11);
+      case 12: return offsetof(VexGuestPPCState, guest_GPR12);
+      case 13: return offsetof(VexGuestPPCState, guest_GPR13);
+      case 14: return offsetof(VexGuestPPCState, guest_GPR14);
+      case 15: return offsetof(VexGuestPPCState, guest_GPR15);
+      case 16: return offsetof(VexGuestPPCState, guest_GPR16);
+      case 17: return offsetof(VexGuestPPCState, guest_GPR17);
+      case 18: return offsetof(VexGuestPPCState, guest_GPR18);
+      case 19: return offsetof(VexGuestPPCState, guest_GPR19);
+      case 20: return offsetof(VexGuestPPCState, guest_GPR20);
+      case 21: return offsetof(VexGuestPPCState, guest_GPR21);
+      case 22: return offsetof(VexGuestPPCState, guest_GPR22);
+      case 23: return offsetof(VexGuestPPCState, guest_GPR23);
+      case 24: return offsetof(VexGuestPPCState, guest_GPR24);
+      case 25: return offsetof(VexGuestPPCState, guest_GPR25);
+      case 26: return offsetof(VexGuestPPCState, guest_GPR26);
+      case 27: return offsetof(VexGuestPPCState, guest_GPR27);
+      case 28: return offsetof(VexGuestPPCState, guest_GPR28);
+      case 29: return offsetof(VexGuestPPCState, guest_GPR29);
+      case 30: return offsetof(VexGuestPPCState, guest_GPR30);
+      case 31: return offsetof(VexGuestPPCState, guest_GPR31);
+   }
+
+   vpanic("integerGuestRegOffset(ppc,le)"); /*notreached*/
+}
+#endif
+
+#if 0
+static IRExpr* getIReg ( UInt archreg )
+{
+   vassert(archreg < 32);
+   return IRExpr_Get( integerGuestRegOffset(archreg), Ity_I32 );
+}
+
+/* Ditto, but write to a reg instead. */
+static void putIReg ( UInt archreg, IRExpr* e )
+{
+   vassert(archreg < 32);
+   stmt( IRStmt_Put(integerGuestRegOffset(archreg), e) );
+}
+
+static void assign ( IRTemp dst, IRExpr* e )
+{
+   stmt( IRStmt_Tmp(dst, e) );
+}
+
+static void storeLE ( IRExpr* addr, IRExpr* data )
+{
+   stmt( IRStmt_STle(addr,data) );
+}
+
+static IRExpr* unop ( IROp op, IRExpr* a )
+{
+   return IRExpr_Unop(op, a);
+}
+
+static IRExpr* binop ( IROp op, IRExpr* a1, IRExpr* a2 )
+{
+   return IRExpr_Binop(op, a1, a2);
+}
+
+static IRExpr* mkexpr ( IRTemp tmp )
+{
+   return IRExpr_Tmp(tmp);
+}
+
+static IRExpr* mkU8 ( UInt i )
+{
+   vassert(i < 256);
+   return IRExpr_Const(IRConst_U8(i));
+}
+#endif
+
+#if 0
+static IRExpr* mkU16 ( UInt i )
+{
+   vassert(i < 65536);
+   return IRExpr_Const(IRConst_U16(i));
+}
+#endif
+
+static IRExpr* mkU32 ( UInt i )
+{
+   return IRExpr_Const(IRConst_U32(i));
+}
+
+#if 0
+static IRExpr* mkU ( IRType ty, UInt i )
+{
+   if (ty == Ity_I8)  return mkU8(i);
+   if (ty == Ity_I16) return mkU16(i);
+   if (ty == Ity_I32) return mkU32(i);
+   /* If this panics, it usually means you passed a size (1,2,4)
+      value as the IRType, rather than a real IRType. */
+   vpanic("mkU(PPC)");
+}
+#endif
+
+#if 0
+static IRExpr* loadLE ( IRType ty, IRExpr* data )
+{
+   return IRExpr_LDle(ty,data);
+}
+#endif
+
+#if 0
+static IROp mkSizedOp ( IRType ty, IROp op8 )
+{
+   Int adj;
+   vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32);
+   vassert(op8 == Iop_Add8 || op8 == Iop_Sub8 
+           || op8 == Iop_Mul8 
+           || op8 == Iop_Or8 || op8 == Iop_And8 || op8 == Iop_Xor8
+           || op8 == Iop_Shl8 || op8 == Iop_Shr8 || op8 == Iop_Sar8
+           || op8 == Iop_CmpEQ8 || op8 == Iop_CmpNE8
+           || op8 == Iop_Not8 );
+   adj = ty==Ity_I8 ? 0 : (ty==Ity_I16 ? 1 : 2);
+   return adj + op8;
+}
+#endif
+
+#if 0
+static IROp mkWidenOp ( Int szSmall, Int szBig, Bool signd )
+{
+   if (szSmall == 1 && szBig == 4) {
+      return signd ? Iop_8Sto32 : Iop_8Uto32;
+   }
+   if (szSmall == 1 && szBig == 2) {
+      return signd ? Iop_8Sto16 : Iop_8Uto16;
+   }
+   if (szSmall == 2 && szBig == 4) {
+      return signd ? Iop_16Sto32 : Iop_16Uto32;
+   }
+   vpanic("mkWidenOp(PPC,guest)");
+}
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*------------------------------------------------------------*/
+/*--- Helpers for %flags.                                 ---*/
+/*------------------------------------------------------------*/
+
+/* -------------- Evaluating the flags-thunk. -------------- */
+
+#if 0
+static IRExpr* mk_ppcg_calculate_flags_cr0 ( void )
+{
+   IRExpr** args
+      = mkIRExprVec_1( IRExpr_Get(OFFB_RESULT,  Ity_I32) );
+
+   IRExpr* call
+      = mkIRExprCCall(
+           Ity_I32,
+           0/*regpppc*/, 
+           "ppcg_calculate_flags_all", &ppcg_calculate_flags_all,
+           args
+        );
+
+   /* Exclude OP from definedness checking.  We're only
+      interested in DEP1 and DEP2. */
+   call->Iex.CCall.cee->mcx_mask = 1;
+   return call;
+}
+#endif
+
+
+
+
+
+
+
+#if 0
+
+/* -------------- Building the flags-thunk. -------------- */
+
+/* The machinery in this section builds the flag-thunk following a
+   flag-setting operation.  Hence the various setFlags_* functions.
+*/
+
+/* U-widen 8/16/32 bit int expr to 32. */
+static IRExpr* widenUto32 ( IRExpr* e )
+{
+   switch (typeOfIRExpr(irbb->tyenv,e)) {
+      case Ity_I32: return e;
+      case Ity_I16: return unop(Iop_16Uto32,e);
+      case Ity_I8:  return unop(Iop_8Uto32,e);
+      default: vpanic("widenUto32");
+   }
+}
+
+/* Narrow 8/16/32 bit int expr to 8/16/32.  Clearly only some
+   of these combinations make sense. */
+static IRExpr* narrowTo ( IRType dst_ty, IRExpr* e )
+{
+   IRType src_ty = typeOfIRExpr(irbb->tyenv,e);
+   if (src_ty == dst_ty)
+      return e;
+   if (src_ty == Ity_I32 && dst_ty == Ity_I16)
+      return unop(Iop_32to16, e);
+   if (src_ty == Ity_I32 && dst_ty == Ity_I8)
+      return unop(Iop_32to8, e);
+
+   vex_printf("\nsrc, dst tys are: ");
+   ppIRType(src_ty);
+   vex_printf(", ");
+   ppIRType(dst_ty);
+   vex_printf("\n");
+   vpanic("narrowTo(PPC)");
+}
+
+
+/* Set the flags thunk OP, DEP1 and DEP2 fields.  The supplied op is
+   auto-sized up to the real op. */
+
+static 
+void setFlags_DEP1_DEP2 ( IRTemp result )
+{
+   stmt( IRStmt_Put( OFFB_RESULT, mkU32(result)) );
+}
+
+#endif
+
+
+
+
+
+
+
+
+/* -------------- Condition codes. -------------- */
+
+#if 0
+/* Condition codes, using the PPC encoding.  */
+static HChar* name_PPCCondcode ( PPCCondcode cond )
+{
+   switch (cond) {
+       default: vpanic("name_PPCCondcode");
+   }
+}
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*------------------------------------------------------------*/
+/*--- Disassemble a single instruction                     ---*/
+/*------------------------------------------------------------*/
+
+/* Disassemble a single instruction into IR.  The instruction
+   is located in host memory at &guest_code[delta].
+   Set *size to be the size of the instruction.
+   If the returned value is Dis_Resteer,
+   the next guest address is assigned to *whereNext.  If resteerOK
+   is False, disInstr may not return Dis_Resteer. */
+   
+static DisResult disInstr ( /*IN*/  Bool    resteerOK,
+                            /*IN*/  Bool    (*resteerOkFn) ( Addr64 ),
+                            /*IN*/  UInt    delta, 
+                            /*OUT*/ UInt*   size,
+                            /*OUT*/ Addr64* whereNext )
+{
+  //   IRType    ty;
+  //  IRTemp    addr, t1, t2;
+  //   Int       alen;
+   UChar opc;
+//   PPCCondcode cond;
+   //  UInt      d32;
+   // UChar     dis_buf[50];
+   // Int       am_sz, d_sz;
+   DisResult whatNext = Dis_Continue;
+   UInt      theInstr;
+
+
+   /* At least this is simple on PPC: insns are all 4 bytes long, and
+      4-aligned.  So just fish the whole thing out of memory right now
+      and have done. */
+
+   /* We will set *size to 4 if the insn is successfully decoded.
+      Setting it to 0 by default makes bbToIR_PPC abort if we fail the
+      decode. */
+   *size = 0;
+
+   theInstr = *(UInt*)(&guest_code[delta]);
+
+//   vex_printf("START: 0x%x, %,b\n", theInstr, theInstr );
+
+   DIP("\t0x%x:  ", guest_pc_bbstart+delta);
+
+
+
+   // TODO: fix the client-request stuff, else nothing will work
+
+   /* Spot the client-request magic sequence. */
+   // Essentially a v. unlikely sequence of noops that we can catch
+   {
+      UInt* code = (UInt*)(guest_code + delta);
+
+      // CAB: easy way to rotate left?
+
+      /* Spot this:                                       
+         E1A00EE0                   mov  r0, r0, ror #29
+        E1A001E0                   mov  r0, r0, ror #3
+        E1A00DE0                   mov  r0, r0, ror #27
+        E1A002E0                   mov  r0, r0, ror #5
+        E1A006E0                   mov  r0, r0, ror #13
+        E1A009E0                   mov  r0, r0, ror #19
+      */
+      /* I suspect these will have to be turned the other way round to
+        work on little-endian ppc. */
+      if (code[0] == 0xE1A00EE0 &&
+          code[1] == 0xE1A001E0 &&
+          code[2] == 0xE1A00DE0 &&
+          code[3] == 0xE1A002E0 &&
+          code[4] == 0xE1A006E0 &&
+         code[5] == 0xE1A009E0) {
+
+         // uh ... I'll figure this out later.  possibly r0 = client_request(r0) */
+         DIP("?CAB? = client_request ( ?CAB? )\n");
+
+        *size = 24;
+
+        irbb->next     = mkU32(guest_pc_bbstart+delta);
+        irbb->jumpkind = Ijk_ClientReq;
+
+         whatNext = Dis_StopHere;
+         goto decode_success;
+      }
+   }
+
+
+
+   
+
+   opc = 0;//(theInstr >> 20) & 0xFF;    /* opcode1: bits 27:20 */
+//   vex_printf("disInstr(ppc): opcode: 0x%2x, %,09b\n", opc, opc );
+
+
+
+   switch (opc) {
+   case 0:
+       goto decode_failure;
+
+   default:
+   decode_failure:
+   /* All decode failures end up here. */
+   vex_printf("disInstr(ppc): unhandled instruction: "
+              "0x%x\n", theInstr);
+   vpanic("ppcToIR: unimplemented insn");
+
+   } /* switch (opc) for the main (primary) opcode switch. */
+
+  decode_success:
+   /* All decode successes end up here. */
+//   vex_printf("disInstr(ppc): success");
+   DIP("\n");
+
+   *size = 4;
+   return whatNext;
+}
+
+#undef DIP
+#undef DIS
+
+/*--------------------------------------------------------------------*/
+/*--- end                                         guest-ppc/toIR.c ---*/
+/*--------------------------------------------------------------------*/
index ead8076b4d3d31c55a9c52baa7e3948b35e46e4a..e4a475be162027593dc49fc0e25b2e4301624639 100644 (file)
@@ -54,7 +54,8 @@ typedef
       VexArch_INVALID,
       VexArchX86, 
       VexArchAMD64, 
-      VexArchARM 
+      VexArchARM,
+      VexArchPPC
    }
    VexArch;
 
@@ -65,7 +66,8 @@ typedef
       VexSubArchX86_sse0, /* has SSE state but no insns (Pentium II) */
       VexSubArchX86_sse1, /* SSE1 support (Pentium III) */
       VexSubArchX86_sse2, /* SSE2 support (Pentium 4) */
-      VexSubArchARM_v4    /* ARM version 4 */
+      VexSubArchARM_v4,   /* ARM version 4 */
+      VexSubArchPPC_32    /* 32 bit */
    }
    VexSubArch;
 
diff --git a/VEX/pub/libvex_guest_ppc.h b/VEX/pub/libvex_guest_ppc.h
new file mode 100644 (file)
index 0000000..67dd73d
--- /dev/null
@@ -0,0 +1,128 @@
+
+/*---------------------------------------------------------------*/
+/*---                                                         ---*/
+/*--- This file (libvex_guest_ppc.h) is                       ---*/
+/*--- Copyright (c) 2005 OpenWorks LLP.  All rights reserved. ---*/
+/*---                                                         ---*/
+/*---------------------------------------------------------------*/
+
+/*
+   This file is part of LibVEX, a library for dynamic binary
+   instrumentation and translation.
+
+   Copyright (C) 2005 OpenWorks, LLP.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; Version 2 dated June 1991 of the
+   license.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or liability
+   for damages.  See the GNU General Public License for more details.
+
+   Neither the names of the U.S. Department of Energy nor the
+   University of California nor the names of its contributors may be
+   used to endorse or promote products derived from this software
+   without prior written permission.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+   USA.
+*/
+
+#ifndef __LIBVEX_PUB_GUEST_PPC_H
+#define __LIBVEX_PUB_GUEST_PPC_H
+
+#include "libvex_basictypes.h"
+#include "libvex_emwarn.h"
+
+
+/*---------------------------------------------------------------*/
+/*--- Vex's representation of the PPC CPU state (32 bit)      ---*/
+/*---------------------------------------------------------------*/
+
+typedef
+   struct {
+      // General Purpose Registers
+      UInt guest_GPR0;
+      UInt guest_GPR1;
+      UInt guest_GPR2;
+      UInt guest_GPR3;
+      UInt guest_GPR4;
+      UInt guest_GPR5;
+      UInt guest_GPR6;
+      UInt guest_GPR7;
+      UInt guest_GPR8;
+      UInt guest_GPR9;
+      UInt guest_GPR10;
+      UInt guest_GPR11;
+      UInt guest_GPR12;
+      UInt guest_GPR13;
+      UInt guest_GPR14;
+      UInt guest_GPR15;
+      UInt guest_GPR16;
+      UInt guest_GPR17;
+      UInt guest_GPR18;
+      UInt guest_GPR19;
+      UInt guest_GPR20;
+      UInt guest_GPR21;
+      UInt guest_GPR22;
+      UInt guest_GPR23;
+      UInt guest_GPR24;
+      UInt guest_GPR25;
+      UInt guest_GPR26;
+      UInt guest_GPR27;
+      UInt guest_GPR28;
+      UInt guest_GPR29;
+      UInt guest_GPR30;
+      UInt guest_GPR31;
+
+      UInt guest_LR;     // Link Register
+      UInt guest_CTR;    // Count Register
+
+      // CR0: Use last result for delayed calc of CR0[0,1,2] (neg,pos,zero)
+      // (bit3 is just a redundant copy of XER_SO)
+      UInt guest_Result; // Result of last op
+
+      // XER: Simpler representation:
+      Bool guest_XER_SO; // Summary Overflow
+      Bool guest_XER_OV; // Overflow
+      Bool guest_XER_CA; // Carry
+//      UChar guest_XER_ByteCount;
+
+      /* Emulation warnings */
+      UInt guest_EMWARN;
+
+      /* Padding to make it have an 8-aligned size */
+      UChar padding_1b;
+      UInt  padding_4b;
+   }
+   VexGuestPPCState;
+
+
+/*---------------------------------------------------------------*/
+/*--- Utility functions for PPC guest stuff.                  ---*/
+/*---------------------------------------------------------------*/
+
+/* ALL THE FOLLOWING ARE VISIBLE TO LIBRARY CLIENT */
+
+/* Initialise all guest PPC state. */
+
+extern
+void LibVEX_GuestPPC_initialise ( /*OUT*/VexGuestPPCState* vex_state );
+
+/* Calculate the PPC flag state from the saved data. */
+
+extern
+UInt LibVEX_GuestPPC_get_flags ( /*IN*/VexGuestPPCState* vex_state );
+
+
+#endif /* ndef __LIBVEX_PUB_GUEST_PPC_H */
+
+
+/*---------------------------------------------------------------*/
+/*---                                      libvex_guest_ppc.h ---*/
+/*---------------------------------------------------------------*/