duplication.
git-svn-id: svn://svn.valgrind.org/vex/trunk@673
priv/main/vex_util.h \
priv/guest-x86/gdefs.h \
priv/guest-arm/gdefs.h \
+ priv/ir/irmatch.h \
priv/ir/iropt.h
LIB_OBJS = priv/ir/irdefs.o \
+ priv/ir/irmatch.o \
priv/ir/iropt.o \
priv/main/vex_main.o \
priv/main/vex_globals.o \
$(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/ir/irdefs.o \
-c priv/ir/irdefs.c
+priv/ir/irmatch.o: $(ALL_HEADERS) priv/ir/irmatch.c
+ $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/ir/irmatch.o \
+ -c priv/ir/irmatch.c
+
priv/ir/iropt.o: $(ALL_HEADERS) priv/ir/iropt.c
$(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/ir/iropt.o \
-c priv/ir/iropt.c
#include "host-arm/hdefs.h"
-
-/*---------------------------------------------------------*/
-/*--- Stuff for pattern matching on IR. This isn't ---*/
-/*--- arm specific, and should be moved elsewhere. ---*/
-/*---------------------------------------------------------*/
-
-#define DECLARE_PATTERN(_patt) \
- static IRExpr* _patt = NULL
-
-#define DEFINE_PATTERN(_patt,_expr) \
- do { \
- if (!(_patt)) { \
- vassert(LibVEX_GetAllocMode() == AllocModeTEMPORARY); \
- LibVEX_SetAllocMode(AllocModePERMANENT); \
- _patt = (_expr); \
- LibVEX_SetAllocMode(AllocModeTEMPORARY); \
- vassert(LibVEX_GetAllocMode() == AllocModeTEMPORARY); \
- } \
- } while (0)
-
-
-#define N_MATCH_BINDERS 4
-typedef
- struct {
- IRExpr* bindee[N_MATCH_BINDERS];
- }
- MatchInfo;
-
-
-
-static void setBindee ( MatchInfo* mi, Int n, IRExpr* bindee )
-{
- if (n < 0 || n >= N_MATCH_BINDERS)
- vpanic("setBindee: out of range index");
- if (mi->bindee[n] != NULL)
- vpanic("setBindee: bindee already set");
- mi->bindee[n] = bindee;
-}
-
-static Bool matchWrk ( MatchInfo* mi, IRExpr* p/*attern*/, IRExpr* e/*xpr*/ )
-{
- switch (p->tag) {
- case Iex_Binder: /* aha, what we were looking for. */
- setBindee(mi, p->Iex.Binder.binder, e);
- return True;
-#if 0
- case Iex_GetI:
- if (e->tag != Iex_GetI) return False;
- if (p->Iex.GetI.ty != e->Iex.GetI.ty) return False;
- /* we ignore the offset limit hints .. */
- if (!matchWrk(mi, p->Iex.GetI.offset, e->Iex.GetI.offset))
- return False;
- return True;
-#endif
- case Iex_Unop:
- if (e->tag != Iex_Unop) return False;
- if (p->Iex.Unop.op != e->Iex.Unop.op) return False;
- if (!matchWrk(mi, p->Iex.Unop.arg, e->Iex.Unop.arg))
- return False;
- return True;
- case Iex_Binop:
- if (e->tag != Iex_Binop) return False;
- if (p->Iex.Binop.op != e->Iex.Binop.op) return False;
- if (!matchWrk(mi, p->Iex.Binop.arg1, e->Iex.Binop.arg1))
- return False;
- if (!matchWrk(mi, p->Iex.Binop.arg2, e->Iex.Binop.arg2))
- return False;
- return True;
- case Iex_LDle:
- if (e->tag != Iex_LDle) return False;
- if (p->Iex.LDle.ty != e->Iex.LDle.ty) return False;
- if (!matchWrk(mi, p->Iex.LDle.addr, e->Iex.LDle.addr))
- return False;
- return True;
- case Iex_Const:
- if (e->tag != Iex_Const) return False;
- return eqIRConst(p->Iex.Const.con, e->Iex.Const.con);
- default:
- ppIRExpr(p);
- vpanic("match");
- }
-}
-
-#if 0
-static Bool matchIRExpr ( MatchInfo* mi, IRExpr* p/*attern*/, IRExpr* e/*xpr*/ )
-{
- Int i;
- for (i = 0; i < N_MATCH_BINDERS; i++)
- mi->bindee[i] = NULL;
- return matchWrk(mi, p, e);
-}
-#endif
-
-#if 0
-/*-----*/
-/* These are duplicated in guest-arm/toIR.c */
-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* mkU64 ( ULong i )
-{
- return IRExpr_Const(IRConst_U64(i));
-}
-
-static IRExpr* mkU32 ( UInt i )
-{
- return IRExpr_Const(IRConst_U32(i));
-}
-
-static IRExpr* bind ( Int binder )
-{
- return IRExpr_Binder(binder);
-}
-#endif
-
-
-
/*---------------------------------------------------------*/
/*--- ISelEnv ---*/
/*---------------------------------------------------------*/
#include "libvex_ir.h"
#include "libvex.h"
+#include "ir/irmatch.h"
#include "main/vex_util.h"
#include "main/vex_globals.h"
#include "host-generic/h_generic_regs.h"
/*---------------------------------------------------------*/
-/*--- Stuff for pattern matching on IR. This isn't ---*/
-/*--- x86 specific, and should be moved elsewhere. ---*/
+/*--- misc helpers ---*/
/*---------------------------------------------------------*/
-#define DECLARE_PATTERN(_patt) \
- static IRExpr* _patt = NULL
-
-#define DEFINE_PATTERN(_patt,_expr) \
- do { \
- if (!(_patt)) { \
- vassert(LibVEX_GetAllocMode() == AllocModeTEMPORARY); \
- LibVEX_SetAllocMode(AllocModePERMANENT); \
- _patt = (_expr); \
- LibVEX_SetAllocMode(AllocModeTEMPORARY); \
- vassert(LibVEX_GetAllocMode() == AllocModeTEMPORARY); \
- } \
- } while (0)
-
-
-#define N_MATCH_BINDERS 4
-typedef
- struct {
- IRExpr* bindee[N_MATCH_BINDERS];
- }
- MatchInfo;
-
-
-static void setBindee ( MatchInfo* mi, Int n, IRExpr* bindee )
-{
- if (n < 0 || n >= N_MATCH_BINDERS)
- vpanic("setBindee: out of range index");
- if (mi->bindee[n] != NULL)
- vpanic("setBindee: bindee already set");
- mi->bindee[n] = bindee;
-}
-
-static Bool matchWrk ( MatchInfo* mi, IRExpr* p/*attern*/, IRExpr* e/*xpr*/ )
-{
- switch (p->tag) {
- case Iex_Binder: /* aha, what we were looking for. */
- setBindee(mi, p->Iex.Binder.binder, e);
- return True;
-#if 0
- case Iex_GetI:
- if (e->tag != Iex_GetI) return False;
- if (p->Iex.GetI.ty != e->Iex.GetI.ty) return False;
- /* we ignore the offset limit hints .. */
- if (!matchWrk(mi, p->Iex.GetI.offset, e->Iex.GetI.offset))
- return False;
- return True;
-#endif
- case Iex_Unop:
- if (e->tag != Iex_Unop) return False;
- if (p->Iex.Unop.op != e->Iex.Unop.op) return False;
- if (!matchWrk(mi, p->Iex.Unop.arg, e->Iex.Unop.arg))
- return False;
- return True;
- case Iex_Binop:
- if (e->tag != Iex_Binop) return False;
- if (p->Iex.Binop.op != e->Iex.Binop.op) return False;
- if (!matchWrk(mi, p->Iex.Binop.arg1, e->Iex.Binop.arg1))
- return False;
- if (!matchWrk(mi, p->Iex.Binop.arg2, e->Iex.Binop.arg2))
- return False;
- return True;
- case Iex_LDle:
- if (e->tag != Iex_LDle) return False;
- if (p->Iex.LDle.ty != e->Iex.LDle.ty) return False;
- if (!matchWrk(mi, p->Iex.LDle.addr, e->Iex.LDle.addr))
- return False;
- return True;
- case Iex_Const:
- if (e->tag != Iex_Const) return False;
- return eqIRConst(p->Iex.Const.con, e->Iex.Const.con);
- default:
- ppIRExpr(p);
- vpanic("match");
- }
-}
-
-static Bool matchIRExpr ( MatchInfo* mi, IRExpr* p/*attern*/, IRExpr* e/*xpr*/ )
-{
- Int i;
- for (i = 0; i < N_MATCH_BINDERS; i++)
- mi->bindee[i] = NULL;
- return matchWrk(mi, p, e);
-}
-
-/*-----*/
-/* These are duplicated in x86toIR.c */
+/* These are duplicated in guest-x86/toIR.c */
static IRExpr* unop ( IROp op, IRExpr* a )
{
return IRExpr_Unop(op, a);
-
/*---------------------------------------------------------*/
/*--- ISelEnv ---*/
/*---------------------------------------------------------*/
--- /dev/null
+
+/*---------------------------------------------------------------*/
+/*--- ---*/
+/*--- This file (ir/irmatch.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.
+*/
+
+/* Provides a facility for doing IR tree matching. */
+
+#include "main/vex_util.h"
+#include "ir/irmatch.h"
+
+
+/* Assign a value to a binder. Checks for obvious stupidities. */
+
+static
+void setBindee ( MatchInfo* mi, Int n, IRExpr* bindee )
+{
+ if (n < 0 || n >= N_IRMATCH_BINDERS)
+ vpanic("setBindee: out of range index");
+ if (mi->bindee[n] != NULL)
+ vpanic("setBindee: bindee already set");
+ mi->bindee[n] = bindee;
+}
+
+
+/* This is the actual matching function, recursing over the pattern
+ and expression trees in the obvious way, and dumping any matches
+ found into 'mi'. */
+
+static
+Bool matchWrk ( MatchInfo* mi, IRExpr* p/*attern*/, IRExpr* e/*xpr*/ )
+{
+ switch (p->tag) {
+ case Iex_Binder: /* aha, what we were looking for. */
+ setBindee(mi, p->Iex.Binder.binder, e);
+ return True;
+#if 0
+ case Iex_GetI:
+ if (e->tag != Iex_GetI) return False;
+ if (p->Iex.GetI.ty != e->Iex.GetI.ty) return False;
+ /* we ignore the offset limit hints .. */
+ if (!matchWrk(mi, p->Iex.GetI.offset, e->Iex.GetI.offset))
+ return False;
+ return True;
+#endif
+ case Iex_Unop:
+ if (e->tag != Iex_Unop) return False;
+ if (p->Iex.Unop.op != e->Iex.Unop.op) return False;
+ if (!matchWrk(mi, p->Iex.Unop.arg, e->Iex.Unop.arg))
+ return False;
+ return True;
+ case Iex_Binop:
+ if (e->tag != Iex_Binop) return False;
+ if (p->Iex.Binop.op != e->Iex.Binop.op) return False;
+ if (!matchWrk(mi, p->Iex.Binop.arg1, e->Iex.Binop.arg1))
+ return False;
+ if (!matchWrk(mi, p->Iex.Binop.arg2, e->Iex.Binop.arg2))
+ return False;
+ return True;
+ case Iex_LDle:
+ if (e->tag != Iex_LDle) return False;
+ if (p->Iex.LDle.ty != e->Iex.LDle.ty) return False;
+ if (!matchWrk(mi, p->Iex.LDle.addr, e->Iex.LDle.addr))
+ return False;
+ return True;
+ case Iex_Const:
+ if (e->tag != Iex_Const) return False;
+ return eqIRConst(p->Iex.Const.con, e->Iex.Const.con);
+ default:
+ ppIRExpr(p);
+ vpanic("match");
+ }
+}
+
+
+/* Top level entry point to the matcher. */
+
+Bool matchIRExpr ( MatchInfo* mi, IRExpr* p/*attern*/, IRExpr* e/*xpr*/ )
+{
+ Int i;
+ for (i = 0; i < N_IRMATCH_BINDERS; i++)
+ mi->bindee[i] = NULL;
+ return matchWrk(mi, p, e);
+}
+
+
+
+/*---------------------------------------------------------------*/
+/*--- end ir/irmatch.c ---*/
+/*---------------------------------------------------------------*/
--- /dev/null
+
+/*---------------------------------------------------------------*/
+/*--- ---*/
+/*--- This file (ir/irmatch.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.
+*/
+
+/* Provides a facility for doing IR tree matching. */
+
+#ifndef __LIBVEX_IRMATCH_H
+#define __LIBVEX_IRMATCH_H
+
+#include "libvex_basictypes.h"
+#include "libvex_ir.h"
+
+
+/* Patterns are simply IRExpr* trees, with IRExpr_Binder nodes at the
+ leaves, indicating binding points. Use these magic macros to
+ declare and define patterns. */
+
+#define DECLARE_PATTERN(_patt) \
+ static IRExpr* _patt = NULL
+
+#define DEFINE_PATTERN(_patt,_expr) \
+ do { \
+ if (!(_patt)) { \
+ vassert(LibVEX_GetAllocMode() == AllocModeTEMPORARY); \
+ LibVEX_SetAllocMode(AllocModePERMANENT); \
+ _patt = (_expr); \
+ LibVEX_SetAllocMode(AllocModeTEMPORARY); \
+ vassert(LibVEX_GetAllocMode() == AllocModeTEMPORARY); \
+ } \
+ } while (0)
+
+
+/* This type returns the result of a match -- it records what
+ the binders got instantiated to. */
+
+#define N_IRMATCH_BINDERS 4
+
+typedef
+ struct {
+ IRExpr* bindee[N_IRMATCH_BINDERS];
+ }
+ MatchInfo;
+
+
+/* The matching function. p is expected to have zero or more
+ IRExpr_Binds in it, numbered 0, 1, 2 ... Returns True if a match
+ succeeded. */
+
+extern
+Bool matchIRExpr ( MatchInfo* mi, IRExpr* p/*attern*/, IRExpr* e/*xpr*/ );
+
+
+#endif /* ndef __LIBVEX_IRMATCH_H */
+
+
+
+/*---------------------------------------------------------------*/
+/*--- end ir/irmatch.h ---*/
+/*---------------------------------------------------------------*/
USA.
*/
+#ifndef __LIBVEX_IROPT_H
+#define __LIBVEX_IROPT_H
+
#include "libvex_basictypes.h"
#include "libvex_ir.h"
#include "libvex.h"
extern
void do_treebuild_BB ( IRBB* bb );
+#endif /* ndef __LIBVEX_IROPT_H */
+
/*---------------------------------------------------------------*/
/*--- end ir/iropt.h ---*/
/*---------------------------------------------------------------*/