2012-02-24 Luis Machado <lgustavo@codesourcery>
authorLuis Machado <luisgpm@br.ibm.com>
Fri, 24 Feb 2012 15:13:37 +0000 (15:13 +0000)
committerLuis Machado <luisgpm@br.ibm.com>
Fri, 24 Feb 2012 15:13:37 +0000 (15:13 +0000)
* server.h: Include tracepoint.h.
(agent_mem_read, agent_get_trace_state_variable_value,
agent_set_trace_state_variable_value,
agent_tsv_read, agent_mem_read_string, get_get_tsv_func_addr,
get_set_tsv_func_addr): New prototypes.

* ax.h: New include file.
* ax.c: New source file.

* tracepoint.c: Include ax.h.
(gdb_agent_op, gdb_agent_op_names, gdb_agent_op_sizes,
agent_expr, eval_result_type): Move to ax.h.
(parse_agent_expr): Rename to ...
(gdb_parse_agent_expr): ... this, make it non-static and move
to ax.h.
(unparse_agent_expr) Rename to ...
(gdb_unparse_agent_expr): ... this, make it non-static and move
to ax.h.
(eval_agent_expr): Rename to ...
(eval_tracepoint_agent_expr): ... this.
(agent_mem_read, agent_mem_read_string, agent_tsv_read): Remove
forward declarations.
(add_tracepoint_action): Call gdb_parse_agent_expr (...).
(agent_get_trace_state_variable_value): New function.
(agent_set_trace_state_variable_value): New function.
(cmd_qtdp): Call gdb_parse_agent_expr (...).
(response_tracepoint): Call gdb_unparse_agent_expr (...).
(do_action_at_tracepoint): Call eval_tracepoint_agent_expr (...).
(condition_true_at_tracepoint): Likewise.
(parse_agent_expr): Rename to ...
(gdb_parse_agent_expr): ... this and move to ax.c.
(unparse_agent_expr): Rename to ...
(gdb_unparse_agent_expr): ... this and move to ax.c.
(gdb_agent_op_name): Move to ax.c.
(eval_agent_expr): Rename to ...
(gdb_eval_agent_expr): ... this, use regcache passed as parameter
and move to ax.c.
(eval_tracepoint_agent_expr): New function.
(agent_mem_read, agent_mem_read_string, agent_tsv_read): Make
non-static.
(current_insn_ptr, emit_error, struct bytecode_address): Move to
ax.c.
(emit_prologue, emit_epilogue, emit_add, emit_sub, emit_mul, emit_lsh,
emit_rsh_signed, emit_rsh_unsigned, emit_ext, emit_log_not,
emit_bit_and, emit_bit_or, emit_bit_xor, emit_bit_not, emit_equal,
emit_less_signed, emit_less_unsigned, emit_ref, emit_if_goto,
emit_goto, write_goto_address, emit_const, emit_reg, emit_pop,
emit_stack, emit_zero_ext, emit_swap, emit_stack_adjust,
emit_int_call_1, emit_void_call_2, emit_eq_goto, emit_ne_goto,
emit_lt_goto, emit_ge_goto, emit_gt_goto, emit_le_goto): Move to ax.c.
(get_get_tsv_func_addr, get_set_tsv_func_addr): New functions.
(compile_bytecodes): Remove forward declaration.
(is_goto_target): Move to ax.c.
(compile_bytecodes): Move to ax.c and call
agent_get_trace_state_variable_value (...) and
agent_set_trace_state_variable_value (...).

* Makefile.in: Update ax.c and IPA dependencies.

gdb/gdbserver/ChangeLog
gdb/gdbserver/Makefile.in
gdb/gdbserver/server.h
gdb/gdbserver/tracepoint.c

index aa9f556297e28d5675d763136cae4b68ba9f0470..c1baa9604b128548adac48bd276b2eb24ed8c8ce 100644 (file)
@@ -1,3 +1,64 @@
+2012-02-24  Luis Machado  <lgustavo@codesourcery>
+
+       * server.h: Include tracepoint.h.
+       (agent_mem_read, agent_get_trace_state_variable_value,
+       agent_set_trace_state_variable_value,
+       agent_tsv_read, agent_mem_read_string, get_get_tsv_func_addr,
+       get_set_tsv_func_addr): New prototypes.
+
+       * ax.h: New include file.
+       * ax.c: New source file.
+
+       * tracepoint.c: Include ax.h.
+       (gdb_agent_op, gdb_agent_op_names, gdb_agent_op_sizes,
+       agent_expr, eval_result_type): Move to ax.h.
+       (parse_agent_expr): Rename to ...
+       (gdb_parse_agent_expr): ... this, make it non-static and move
+       to ax.h.
+       (unparse_agent_expr) Rename to ...
+       (gdb_unparse_agent_expr): ... this, make it non-static and move
+       to ax.h.
+       (eval_agent_expr): Rename to ...
+       (eval_tracepoint_agent_expr): ... this.
+       (agent_mem_read, agent_mem_read_string, agent_tsv_read): Remove
+       forward declarations.
+       (add_tracepoint_action): Call gdb_parse_agent_expr (...).
+       (agent_get_trace_state_variable_value): New function.
+       (agent_set_trace_state_variable_value): New function.
+       (cmd_qtdp): Call gdb_parse_agent_expr (...).
+       (response_tracepoint): Call gdb_unparse_agent_expr (...).
+       (do_action_at_tracepoint): Call eval_tracepoint_agent_expr (...).
+       (condition_true_at_tracepoint): Likewise.
+       (parse_agent_expr): Rename to ...
+       (gdb_parse_agent_expr): ... this and move to ax.c.
+       (unparse_agent_expr): Rename to ...
+       (gdb_unparse_agent_expr): ... this and move to ax.c.
+       (gdb_agent_op_name): Move to ax.c.
+       (eval_agent_expr): Rename to ...
+       (gdb_eval_agent_expr): ... this, use regcache passed as parameter
+       and move to ax.c.
+       (eval_tracepoint_agent_expr): New function.
+       (agent_mem_read, agent_mem_read_string, agent_tsv_read): Make
+       non-static. 
+       (current_insn_ptr, emit_error, struct bytecode_address): Move to
+       ax.c.
+       (emit_prologue, emit_epilogue, emit_add, emit_sub, emit_mul, emit_lsh,
+       emit_rsh_signed, emit_rsh_unsigned, emit_ext, emit_log_not,
+       emit_bit_and, emit_bit_or, emit_bit_xor, emit_bit_not, emit_equal,
+       emit_less_signed, emit_less_unsigned, emit_ref, emit_if_goto,
+       emit_goto, write_goto_address, emit_const, emit_reg, emit_pop,
+       emit_stack, emit_zero_ext, emit_swap, emit_stack_adjust,
+       emit_int_call_1, emit_void_call_2, emit_eq_goto, emit_ne_goto,
+       emit_lt_goto, emit_ge_goto, emit_gt_goto, emit_le_goto): Move to ax.c.
+       (get_get_tsv_func_addr, get_set_tsv_func_addr): New functions.
+       (compile_bytecodes): Remove forward declaration.
+       (is_goto_target): Move to ax.c.
+       (compile_bytecodes): Move to ax.c and call
+       agent_get_trace_state_variable_value (...) and
+       agent_set_trace_state_variable_value (...).
+
+       * Makefile.in: Update ax.c and IPA dependencies.
+
 2012-02-24  Pedro Alves  <palves@redhat.com>
 
        * tracepoint.c (cmd_bigqtbuffer): Rename as ...
index c6a8bff7cbcbe0cd6ea85ab8a772376f2dd20085..b4d2006ee85d80b48381af85bd2dc5a8a2edad8f 100644 (file)
@@ -134,7 +134,7 @@ LIBOBJS = @LIBOBJS@
 SOURCES = $(SFILES)
 TAGFILES = $(SOURCES) ${HFILES} ${ALLPARAM} ${POSSLIBS}
 
-OBS = inferiors.o regcache.o remote-utils.o server.o signals.o target.o \
+OBS = ax.o inferiors.o regcache.o remote-utils.o server.o signals.o target.o \
        utils.o version.o \
        mem-break.o hostio.o event-loop.o tracepoint.o \
        xml-utils.o common-utils.o ptid.o buffer.o \
@@ -237,7 +237,7 @@ gdbreplay$(EXEEXT): $(GDBREPLAY_OBS)
        ${CC-LD} $(INTERNAL_CFLAGS) $(INTERNAL_LDFLAGS) -o gdbreplay$(EXEEXT) $(GDBREPLAY_OBS) \
          $(XM_CLIBS)
 
-IPA_OBJS=tracepoint-ipa.o utils-ipa.o regcache-ipa.o remote-utils-ipa.o common-utils-ipa.o ${IPA_DEPFILES}
+IPA_OBJS=ax-ipa.o tracepoint-ipa.o utils-ipa.o regcache-ipa.o remote-utils-ipa.o common-utils-ipa.o ${IPA_DEPFILES}
 
 IPA_LIB=libinproctrace.so
 
@@ -336,6 +336,7 @@ regcache_h = $(srcdir)/regcache.h
 signals_def = $(srcdir)/../../include/gdb/signals.def
 signals_h = $(srcdir)/../../include/gdb/signals.h $(signals_def)
 ptid_h = $(srcdir)/../common/ptid.h
+ax_h = $(srcdir)/ax.h
 linux_osdata_h = $(srcdir)/../common/linux-osdata.h
 server_h = $(srcdir)/server.h $(regcache_h) config.h $(srcdir)/target.h \
                $(srcdir)/mem-break.h $(srcdir)/../common/gdb_signals.h \
@@ -368,7 +369,9 @@ IPAGENT_CFLAGS = $(CPPFLAGS) $(INTERNAL_CFLAGS) $(UST_CFLAGS) \
        -fvisibility=hidden
 
 # In-process agent object rules
-tracepoint-ipa.o: tracepoint.c $(server_h) $(srcdir)/../common/ax.def
+ax-ipa.o: ax.c $(server_h) $(ax_h) $(srcdir)/../common/ax.def
+       $(CC) -c $(IPAGENT_CFLAGS) $< -o ax-ipa.o
+tracepoint-ipa.o: tracepoint.c $(server_h) ${ax_h}
        $(CC) -c $(IPAGENT_CFLAGS) $< -o tracepoint-ipa.o
 utils-ipa.o: utils.c $(server_h)
        $(CC) -c $(IPAGENT_CFLAGS) $< -o utils-ipa.o
@@ -387,11 +390,12 @@ linux-amd64-ipa.o: linux-amd64-ipa.c $(server_h)
 amd64-linux-ipa.o : amd64-linux.c $(regdef_h)
        $(CC) -c $(IPAGENT_CFLAGS) $< -o amd64-linux-ipa.o
 
+ax.o: ax.c $(server_h) $(ax_h) $(srcdir)/../common/ax.def
 event-loop.o: event-loop.c $(server_h)
 hostio.o: hostio.c $(server_h)
 hostio-errno.o: hostio-errno.c $(server_h)
 inferiors.o: inferiors.c $(server_h)
-mem-break.o: mem-break.c $(server_h)
+mem-break.o: mem-break.c $(server_h) $(ax_h)
 proc-service.o: proc-service.c $(server_h) $(gdb_proc_service_h)
 regcache.o: regcache.c $(server_h) $(regdef_h)
 remote-utils.o: remote-utils.c terminal.h $(server_h)
@@ -399,7 +403,7 @@ server.o: server.c $(server_h)
 target.o: target.c $(server_h)
 thread-db.o: thread-db.c $(server_h) $(linux_low_h) $(gdb_proc_service_h) \
        $(gdb_thread_db_h)
-tracepoint.o: tracepoint.c $(server_h) $(srcdir)/../common/ax.def
+tracepoint.o: tracepoint.c $(server_h) $(ax_h)
 utils.o: utils.c $(server_h)
 gdbreplay.o: gdbreplay.c config.h
 dll.o: dll.c $(server_h)
index d3b4463a2adccf0c5290e3f3e3cefb5d18460b69..30d608cec07c1d0a5780824300f464d4a56356e4 100644 (file)
@@ -102,6 +102,12 @@ int vsnprintf(char *str, size_t size, const char *format, va_list ap);
 #define _(String) (String)
 #endif
 
+#ifdef IN_PROCESS_AGENT
+#  define PROG "ipa"
+#else
+#  define PROG "gdbserver"
+#endif
+
 /* A type used for binary buffers.  */
 typedef unsigned char gdb_byte;
 
@@ -511,6 +517,26 @@ int claim_trampoline_space (ULONGEST used, CORE_ADDR *trampoline);
 int have_fast_tracepoint_trampoline_buffer (char *msgbuf);
 #endif
 
+struct traceframe;
+
+/* Do memory copies for bytecodes.  */
+/* Do the recording of memory blocks for actions and bytecodes.  */
+
+int agent_mem_read (struct traceframe *tframe,
+                   unsigned char *to, CORE_ADDR from,
+                   ULONGEST len);
+
+LONGEST agent_get_trace_state_variable_value (int num);
+void agent_set_trace_state_variable_value (int num, LONGEST val);
+
+/* Record the value of a trace state variable.  */
+
+int agent_tsv_read (struct traceframe *tframe, int n);
+int agent_mem_read_string (struct traceframe *tframe,
+                          unsigned char *to,
+                          CORE_ADDR from,
+                          ULONGEST len);
+
 /* Bytecode compilation function vector.  */
 
 struct emit_ops
@@ -566,6 +592,12 @@ struct emit_ops
 
 /* Returns the address of the get_raw_reg function in the IPA.  */
 CORE_ADDR get_raw_reg_func_addr (void);
+/* Returns the address of the get_trace_state_variable_value
+   function in the IPA.  */
+CORE_ADDR get_get_tsv_func_addr (void);
+/* Returns the address of the set_trace_state_variable_value
+   function in the IPA.  */
+CORE_ADDR get_set_tsv_func_addr (void);
 
 CORE_ADDR current_insn_ptr;
 int emit_error;
index cd58c2d0d445b97334ca111d3c6577679f740dff..dfa48a72e1e9c83067f725cf80ad0c9f6c047462 100644 (file)
@@ -25,6 +25,7 @@
 #if HAVE_STDINT_H
 #include <stdint.h>
 #endif
+#include "ax.h"
 
 /* This file is built for both GDBserver, and the in-process
    agent (IPA), a shared library that includes a tracing agent that is
@@ -63,18 +64,10 @@ trace_vdebug (const char *fmt, ...)
 
   va_start (ap, fmt);
   vsprintf (buf, fmt, ap);
-#ifdef IN_PROCESS_AGENT
-  fprintf (stderr, "ipa/tracepoint: %s\n", buf);
-#else
-  fprintf (stderr, "gdbserver/tracepoint: %s\n", buf);
-#endif
+  fprintf (stderr, PROG "/tracepoint: %s\n", buf);
   va_end (ap);
 }
 
-#ifdef IN_PROCESS_AGENT
-#define debug_threads debug_agent
-#endif
-
 #define trace_debug_1(level, fmt, args...)     \
   do {                                         \
     if (level <= debug_threads)                \
@@ -374,8 +367,6 @@ tracepoint_look_up_symbols (void)
    GDBserver side.  */
 
 #ifdef IN_PROCESS_AGENT
-int debug_agent = 0;
-
 int
 read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
 {
@@ -480,41 +471,6 @@ write_inferior_uinteger (CORE_ADDR symaddr, unsigned int val)
 
 #endif
 
-/* This enum must exactly match what is documented in
-   gdb/doc/agentexpr.texi, including all the numerical values.  */
-
-enum gdb_agent_op
-  {
-#define DEFOP(NAME, SIZE, DATA_SIZE, CONSUMED, PRODUCED, VALUE)  \
-    gdb_agent_op_ ## NAME = VALUE,
-#include "ax.def"
-#undef DEFOP
-    gdb_agent_op_last
-  };
-
-static const char *gdb_agent_op_names [gdb_agent_op_last] =
-  {
-    "?undef?"
-#define DEFOP(NAME, SIZE, DATA_SIZE, CONSUMED, PRODUCED, VALUE)  , # NAME
-#include "ax.def"
-#undef DEFOP
-  };
-
-static const unsigned char gdb_agent_op_sizes [gdb_agent_op_last] =
-  {
-    0
-#define DEFOP(NAME, SIZE, DATA_SIZE, CONSUMED, PRODUCED, VALUE)  , SIZE
-#include "ax.def"
-#undef DEFOP
-  };
-
-struct agent_expr
-{
-  int length;
-
-  unsigned char *bytes;
-};
-
 /* Base action.  Concrete actions inherit this.  */
 
 struct tracepoint_action
@@ -746,22 +702,6 @@ IP_AGENT_EXPORT struct tracepoint *stopping_tracepoint;
 
 IP_AGENT_EXPORT int trace_buffer_is_full;
 
-/* Enumeration of the different kinds of things that can happen during
-   agent expression evaluation.  */
-
-enum eval_result_type
-  {
-    expr_eval_no_error,
-    expr_eval_empty_expression,
-    expr_eval_empty_stack,
-    expr_eval_stack_overflow,
-    expr_eval_stack_underflow,
-    expr_eval_unhandled_opcode,
-    expr_eval_unrecognized_opcode,
-    expr_eval_divide_by_zero,
-    expr_eval_invalid_goto
-  };
-
 static enum eval_result_type expr_eval_result = expr_eval_no_error;
 
 #ifndef IN_PROCESS_AGENT
@@ -1245,21 +1185,11 @@ struct trap_tracepoint_ctx
 
 #endif
 
-#ifndef IN_PROCESS_AGENT
-static struct agent_expr *parse_agent_expr (char **actparm);
-static char *unparse_agent_expr (struct agent_expr *aexpr);
-#endif
-static enum eval_result_type eval_agent_expr (struct tracepoint_hit_ctx *ctx,
-                                             struct traceframe *tframe,
-                                             struct agent_expr *aexpr,
-                                             ULONGEST *rslt);
-
-static int agent_mem_read (struct traceframe *tframe,
-                          unsigned char *to, CORE_ADDR from, ULONGEST len);
-static int agent_mem_read_string (struct traceframe *tframe,
-                                 unsigned char *to, CORE_ADDR from,
-                                 ULONGEST len);
-static int agent_tsv_read (struct traceframe *tframe, int n);
+static enum eval_result_type
+eval_tracepoint_agent_expr (struct tracepoint_hit_ctx *ctx,
+                           struct traceframe *tframe,
+                           struct agent_expr *aexpr,
+                           ULONGEST *rslt);
 
 #ifndef IN_PROCESS_AGENT
 static CORE_ADDR traceframe_get_pc (struct traceframe *tframe);
@@ -1892,7 +1822,7 @@ add_tracepoint_action (struct tracepoint *tpoint, char *packet)
            action = &xaction->base;
 
            trace_debug ("Want to evaluate expression");
-           xaction->expr = parse_agent_expr (&act);
+           xaction->expr = gdb_parse_agent_expr (&act);
            break;
          }
        default:
@@ -2036,6 +1966,18 @@ set_trace_state_variable_value (int num, LONGEST val)
   tsv->value = val;
 }
 
+LONGEST
+agent_get_trace_state_variable_value (int num)
+{
+  return get_trace_state_variable_value (num);
+}
+
+void
+agent_set_trace_state_variable_value (int num, LONGEST val)
+{
+  set_trace_state_variable_value (num, val);
+}
+
 static void
 set_trace_state_variable_name (int num, const char *name)
 {
@@ -2412,7 +2354,7 @@ cmd_qtdp (char *own_buf)
          else if (*packet == 'X')
            {
              actparm = (char *) packet;
-             tpoint->cond = parse_agent_expr (&actparm);
+             tpoint->cond = gdb_parse_agent_expr (&actparm);
              packet = actparm;
            }
          else if (*packet == '-')
@@ -3522,7 +3464,7 @@ response_tracepoint (char *packet, struct tracepoint *tpoint)
 
   if (tpoint->cond)
     {
-      buf = unparse_agent_expr (tpoint->cond);
+      buf = gdb_unparse_agent_expr (tpoint->cond);
       sprintf (packet + strlen (packet), ":X%x,%s",
               tpoint->cond->length, buf);
       free (buf);
@@ -4549,7 +4491,7 @@ do_action_at_tracepoint (struct tracepoint_hit_ctx *ctx,
 
        trace_debug ("Want to evaluate expression");
 
-       err = eval_agent_expr (ctx, tframe, eaction->expr, NULL);
+       err = eval_tracepoint_agent_expr (ctx, tframe, eaction->expr, NULL);
 
        if (err != expr_eval_no_error)
          {
@@ -4602,7 +4544,7 @@ condition_true_at_tracepoint (struct tracepoint_hit_ctx *ctx,
     err = ((condfn) (uintptr_t) (tpoint->compiled_cond)) (ctx, &value);
   else
 #endif
-    err = eval_agent_expr (ctx, NULL, tpoint->cond, &value);
+    err = eval_tracepoint_agent_expr (ctx, NULL, tpoint->cond, &value);
 
   if (err != expr_eval_no_error)
     {
@@ -4617,463 +4559,26 @@ condition_true_at_tracepoint (struct tracepoint_hit_ctx *ctx,
   return (value ? 1 : 0);
 }
 
-#ifndef IN_PROCESS_AGENT
-
-/* The packet form of an agent expression consists of an 'X', number
-   of bytes in expression, a comma, and then the bytes.  */
-
-static struct agent_expr *
-parse_agent_expr (char **actparm)
-{
-  char *act = *actparm;
-  ULONGEST xlen;
-  struct agent_expr *aexpr;
-
-  ++act;  /* skip the X */
-  act = unpack_varlen_hex (act, &xlen);
-  ++act;  /* skip a comma */
-  aexpr = xmalloc (sizeof (struct agent_expr));
-  aexpr->length = xlen;
-  aexpr->bytes = xmalloc (xlen);
-  convert_ascii_to_int (act, aexpr->bytes, xlen);
-  *actparm = act + (xlen * 2);
-  return aexpr;
-}
-
-/* Convert the bytes of an agent expression back into hex digits, so
-   they can be printed or uploaded.  This allocates the buffer,
-   callers should free when they are done with it.  */
-
-static char *
-unparse_agent_expr (struct agent_expr *aexpr)
-{
-  char *rslt;
-
-  rslt = xmalloc (2 * aexpr->length + 1);
-  convert_int_to_ascii (aexpr->bytes, rslt, aexpr->length);
-  return rslt;
-}
-
-#endif
-
-/* A wrapper for gdb_agent_op_names that does some bounds-checking.  */
-
-static const char *
-gdb_agent_op_name (int op)
-{
-  if (op < 0 || op >= gdb_agent_op_last || gdb_agent_op_names[op] == NULL)
-    return "?undef?";
-  return gdb_agent_op_names[op];
-}
-
-/* The agent expression evaluator, as specified by the GDB docs. It
-   returns 0 if everything went OK, and a nonzero error code
-   otherwise.  */
+/* Evaluates a tracepoint agent expression with context CTX,
+   traceframe TFRAME, agent expression AEXPR and store the
+   result in RSLT.  */
 
 static enum eval_result_type
-eval_agent_expr (struct tracepoint_hit_ctx *ctx,
-                struct traceframe *tframe,
-                struct agent_expr *aexpr,
-                ULONGEST *rslt)
-{
-  int pc = 0;
-#define STACK_MAX 100
-  ULONGEST stack[STACK_MAX], top;
-  int sp = 0;
-  unsigned char op;
-  int arg;
-
-  /* This union is a convenient way to convert representations.  For
-     now, assume a standard architecture where the hardware integer
-     types have 8, 16, 32, 64 bit types.  A more robust solution would
-     be to import stdint.h from gnulib.  */
-  union
-  {
-    union
-    {
-      unsigned char bytes[1];
-      unsigned char val;
-    } u8;
-    union
-    {
-      unsigned char bytes[2];
-      unsigned short val;
-    } u16;
-    union
-    {
-      unsigned char bytes[4];
-      unsigned int val;
-    } u32;
-    union
-    {
-      unsigned char bytes[8];
-      ULONGEST val;
-    } u64;
-  } cnv;
-
-  if (aexpr->length == 0)
-    {
-      trace_debug ("empty agent expression");
-      return expr_eval_empty_expression;
-    }
-
-  /* Cache the stack top in its own variable. Much of the time we can
-     operate on this variable, rather than dinking with the stack. It
-     needs to be copied to the stack when sp changes.  */
-  top = 0;
-
-  while (1)
-    {
-      op = aexpr->bytes[pc++];
-
-      trace_debug ("About to interpret byte 0x%x", op);
-
-      switch (op)
-       {
-       case gdb_agent_op_add:
-         top += stack[--sp];
-         break;
-
-       case gdb_agent_op_sub:
-         top = stack[--sp] - top;
-         break;
-
-       case gdb_agent_op_mul:
-         top *= stack[--sp];
-         break;
-
-       case gdb_agent_op_div_signed:
-         if (top == 0)
-           {
-             trace_debug ("Attempted to divide by zero");
-             return expr_eval_divide_by_zero;
-           }
-         top = ((LONGEST) stack[--sp]) / ((LONGEST) top);
-         break;
-
-       case gdb_agent_op_div_unsigned:
-         if (top == 0)
-           {
-             trace_debug ("Attempted to divide by zero");
-             return expr_eval_divide_by_zero;
-           }
-         top = stack[--sp] / top;
-         break;
-
-       case gdb_agent_op_rem_signed:
-         if (top == 0)
-           {
-             trace_debug ("Attempted to divide by zero");
-             return expr_eval_divide_by_zero;
-           }
-         top = ((LONGEST) stack[--sp]) % ((LONGEST) top);
-         break;
-
-       case gdb_agent_op_rem_unsigned:
-         if (top == 0)
-           {
-             trace_debug ("Attempted to divide by zero");
-             return expr_eval_divide_by_zero;
-           }
-         top = stack[--sp] % top;
-         break;
-
-       case gdb_agent_op_lsh:
-         top = stack[--sp] << top;
-         break;
-
-       case gdb_agent_op_rsh_signed:
-         top = ((LONGEST) stack[--sp]) >> top;
-         break;
-
-       case gdb_agent_op_rsh_unsigned:
-         top = stack[--sp] >> top;
-         break;
-
-       case gdb_agent_op_trace:
-         agent_mem_read (tframe,
-                         NULL, (CORE_ADDR) stack[--sp], (ULONGEST) top);
-         if (--sp >= 0)
-           top = stack[sp];
-         break;
-
-       case gdb_agent_op_trace_quick:
-         arg = aexpr->bytes[pc++];
-         agent_mem_read (tframe, NULL, (CORE_ADDR) top, (ULONGEST) arg);
-         break;
-
-       case gdb_agent_op_log_not:
-         top = !top;
-         break;
-
-       case gdb_agent_op_bit_and:
-         top &= stack[--sp];
-         break;
-
-       case gdb_agent_op_bit_or:
-         top |= stack[--sp];
-         break;
-
-       case gdb_agent_op_bit_xor:
-         top ^= stack[--sp];
-         break;
-
-       case gdb_agent_op_bit_not:
-         top = ~top;
-         break;
-
-       case gdb_agent_op_equal:
-         top = (stack[--sp] == top);
-         break;
-
-       case gdb_agent_op_less_signed:
-         top = (((LONGEST) stack[--sp]) < ((LONGEST) top));
-         break;
-
-       case gdb_agent_op_less_unsigned:
-         top = (stack[--sp] < top);
-         break;
-
-       case gdb_agent_op_ext:
-         arg = aexpr->bytes[pc++];
-         if (arg < (sizeof (LONGEST) * 8))
-           {
-             LONGEST mask = 1 << (arg - 1);
-             top &= ((LONGEST) 1 << arg) - 1;
-             top = (top ^ mask) - mask;
-           }
-         break;
-
-       case gdb_agent_op_ref8:
-         agent_mem_read (tframe, cnv.u8.bytes, (CORE_ADDR) top, 1);
-         top = cnv.u8.val;
-         break;
-
-       case gdb_agent_op_ref16:
-         agent_mem_read (tframe, cnv.u16.bytes, (CORE_ADDR) top, 2);
-         top = cnv.u16.val;
-         break;
-
-       case gdb_agent_op_ref32:
-         agent_mem_read (tframe, cnv.u32.bytes, (CORE_ADDR) top, 4);
-         top = cnv.u32.val;
-         break;
-
-       case gdb_agent_op_ref64:
-         agent_mem_read (tframe, cnv.u64.bytes, (CORE_ADDR) top, 8);
-         top = cnv.u64.val;
-         break;
-
-       case gdb_agent_op_if_goto:
-         if (top)
-           pc = (aexpr->bytes[pc] << 8) + (aexpr->bytes[pc + 1]);
-         else
-           pc += 2;
-         if (--sp >= 0)
-           top = stack[sp];
-         break;
-
-       case gdb_agent_op_goto:
-         pc = (aexpr->bytes[pc] << 8) + (aexpr->bytes[pc + 1]);
-         break;
-
-       case gdb_agent_op_const8:
-         /* Flush the cached stack top.  */
-         stack[sp++] = top;
-         top = aexpr->bytes[pc++];
-         break;
-
-       case gdb_agent_op_const16:
-         /* Flush the cached stack top.  */
-         stack[sp++] = top;
-         top = aexpr->bytes[pc++];
-         top = (top << 8) + aexpr->bytes[pc++];
-         break;
-
-       case gdb_agent_op_const32:
-         /* Flush the cached stack top.  */
-         stack[sp++] = top;
-         top = aexpr->bytes[pc++];
-         top = (top << 8) + aexpr->bytes[pc++];
-         top = (top << 8) + aexpr->bytes[pc++];
-         top = (top << 8) + aexpr->bytes[pc++];
-         break;
-
-       case gdb_agent_op_const64:
-         /* Flush the cached stack top.  */
-         stack[sp++] = top;
-         top = aexpr->bytes[pc++];
-         top = (top << 8) + aexpr->bytes[pc++];
-         top = (top << 8) + aexpr->bytes[pc++];
-         top = (top << 8) + aexpr->bytes[pc++];
-         top = (top << 8) + aexpr->bytes[pc++];
-         top = (top << 8) + aexpr->bytes[pc++];
-         top = (top << 8) + aexpr->bytes[pc++];
-         top = (top << 8) + aexpr->bytes[pc++];
-         break;
-
-       case gdb_agent_op_reg:
-         /* Flush the cached stack top.  */
-         stack[sp++] = top;
-         arg = aexpr->bytes[pc++];
-         arg = (arg << 8) + aexpr->bytes[pc++];
-         {
-           int regnum = arg;
-           struct regcache *regcache;
-
-           regcache = get_context_regcache (ctx);
-
-           switch (register_size (regnum))
-             {
-             case 8:
-               collect_register (regcache, regnum, cnv.u64.bytes);
-               top = cnv.u64.val;
-               break;
-             case 4:
-               collect_register (regcache, regnum, cnv.u32.bytes);
-               top = cnv.u32.val;
-               break;
-             case 2:
-               collect_register (regcache, regnum, cnv.u16.bytes);
-               top = cnv.u16.val;
-               break;
-             case 1:
-               collect_register (regcache, regnum, cnv.u8.bytes);
-               top = cnv.u8.val;
-               break;
-             default:
-               internal_error (__FILE__, __LINE__,
-                               "unhandled register size");
-             }
-         }
-         break;
-
-       case gdb_agent_op_end:
-         trace_debug ("At end of expression, sp=%d, stack top cache=0x%s",
-                      sp, pulongest (top));
-         if (rslt)
-           {
-             if (sp <= 0)
-               {
-                 /* This should be an error */
-                 trace_debug ("Stack is empty, nothing to return");
-                 return expr_eval_empty_stack;
-               }
-             *rslt = top;
-           }
-         return expr_eval_no_error;
-
-       case gdb_agent_op_dup:
-         stack[sp++] = top;
-         break;
-
-       case gdb_agent_op_pop:
-         if (--sp >= 0)
-           top = stack[sp];
-         break;
-
-       case gdb_agent_op_pick:
-         arg = aexpr->bytes[pc++];
-         stack[sp] = top;
-         top = stack[sp - arg];
-         ++sp;
-         break;
-
-       case gdb_agent_op_rot:
-         {
-           ULONGEST tem = stack[sp - 1];
-
-           stack[sp - 1] = stack[sp - 2];
-           stack[sp - 2] = top;
-           top = tem;
-         }
-         break;
-
-       case gdb_agent_op_zero_ext:
-         arg = aexpr->bytes[pc++];
-         if (arg < (sizeof (LONGEST) * 8))
-           top &= ((LONGEST) 1 << arg) - 1;
-         break;
-
-       case gdb_agent_op_swap:
-         /* Interchange top two stack elements, making sure top gets
-            copied back onto stack.  */
-         stack[sp] = top;
-         top = stack[sp - 1];
-         stack[sp - 1] = stack[sp];
-         break;
-
-       case gdb_agent_op_getv:
-         /* Flush the cached stack top.  */
-         stack[sp++] = top;
-         arg = aexpr->bytes[pc++];
-         arg = (arg << 8) + aexpr->bytes[pc++];
-         top = get_trace_state_variable_value (arg);
-         break;
-
-       case gdb_agent_op_setv:
-         arg = aexpr->bytes[pc++];
-         arg = (arg << 8) + aexpr->bytes[pc++];
-         set_trace_state_variable_value (arg, top);
-         /* Note that we leave the value on the stack, for the
-            benefit of later/enclosing expressions.  */
-         break;
-
-       case gdb_agent_op_tracev:
-         arg = aexpr->bytes[pc++];
-         arg = (arg << 8) + aexpr->bytes[pc++];
-         agent_tsv_read (tframe, arg);
-         break;
-
-       case gdb_agent_op_tracenz:
-         agent_mem_read_string (tframe, NULL, (CORE_ADDR) stack[--sp],
-                                (ULONGEST) top);
-         if (--sp >= 0)
-           top = stack[sp];
-         break;
-
-         /* GDB never (currently) generates any of these ops.  */
-       case gdb_agent_op_float:
-       case gdb_agent_op_ref_float:
-       case gdb_agent_op_ref_double:
-       case gdb_agent_op_ref_long_double:
-       case gdb_agent_op_l_to_d:
-       case gdb_agent_op_d_to_l:
-       case gdb_agent_op_trace16:
-         trace_debug ("Agent expression op 0x%x valid, but not handled",
-                      op);
-         /* If ever GDB generates any of these, we don't have the
-            option of ignoring.  */
-         return 1;
-
-       default:
-         trace_debug ("Agent expression op 0x%x not recognized", op);
-         /* Don't struggle on, things will just get worse.  */
-         return expr_eval_unrecognized_opcode;
-       }
-
-      /* Check for stack badness.  */
-      if (sp >= (STACK_MAX - 1))
-       {
-         trace_debug ("Expression stack overflow");
-         return expr_eval_stack_overflow;
-       }
-
-      if (sp < 0)
-       {
-         trace_debug ("Expression stack underflow");
-         return expr_eval_stack_underflow;
-       }
+eval_tracepoint_agent_expr (struct tracepoint_hit_ctx *ctx,
+                           struct traceframe *tframe,
+                           struct agent_expr *aexpr,
+                           ULONGEST *rslt)
+{
+  struct regcache *regcache;
+  regcache = get_context_regcache (ctx);
 
-      trace_debug ("Op %s -> sp=%d, top=0x%s",
-                  gdb_agent_op_name (op), sp, pulongest (top));
-    }
+  return gdb_eval_agent_expr (regcache, tframe, aexpr, rslt);
 }
 
 /* Do memory copies for bytecodes.  */
 /* Do the recording of memory blocks for actions and bytecodes.  */
 
-static int
+int
 agent_mem_read (struct traceframe *tframe,
                unsigned char *to, CORE_ADDR from, ULONGEST len)
 {
@@ -5115,7 +4620,7 @@ agent_mem_read (struct traceframe *tframe,
   return 0;
 }
 
-static int
+int
 agent_mem_read_string (struct traceframe *tframe,
                       unsigned char *to, CORE_ADDR from, ULONGEST len)
 {
@@ -5177,7 +4682,7 @@ agent_mem_read_string (struct traceframe *tframe,
 
 /* Record the value of a trace state variable.  */
 
-static int
+int
 agent_tsv_read (struct traceframe *tframe, int n)
 {
   unsigned char *vspace;
@@ -5970,250 +5475,24 @@ gdb_collect (struct tracepoint *tpoint, unsigned char *regs)
 
 #ifndef IN_PROCESS_AGENT
 
-/* Bytecode compilation.  */
-
-CORE_ADDR current_insn_ptr;
-
-int emit_error;
-
-struct bytecode_address
-{
-  int pc;
-  CORE_ADDR address;
-  int goto_pc;
-  /* Offset and size of field to be modified in the goto block.  */
-  int from_offset, from_size;
-  struct bytecode_address *next;
-} *bytecode_address_table;
-
 CORE_ADDR
 get_raw_reg_func_addr (void)
 {
   return ipa_sym_addrs.addr_get_raw_reg;
 }
 
-static void
-emit_prologue (void)
-{
-  target_emit_ops ()->emit_prologue ();
-}
-
-static void
-emit_epilogue (void)
-{
-  target_emit_ops ()->emit_epilogue ();
-}
-
-static void
-emit_add (void)
-{
-  target_emit_ops ()->emit_add ();
-}
-
-static void
-emit_sub (void)
-{
-  target_emit_ops ()->emit_sub ();
-}
-
-static void
-emit_mul (void)
-{
-  target_emit_ops ()->emit_mul ();
-}
-
-static void
-emit_lsh (void)
-{
-  target_emit_ops ()->emit_lsh ();
-}
-
-static void
-emit_rsh_signed (void)
-{
-  target_emit_ops ()->emit_rsh_signed ();
-}
-
-static void
-emit_rsh_unsigned (void)
-{
-  target_emit_ops ()->emit_rsh_unsigned ();
-}
-
-static void
-emit_ext (int arg)
-{
-  target_emit_ops ()->emit_ext (arg);
-}
-
-static void
-emit_log_not (void)
-{
-  target_emit_ops ()->emit_log_not ();
-}
-
-static void
-emit_bit_and (void)
-{
-  target_emit_ops ()->emit_bit_and ();
-}
-
-static void
-emit_bit_or (void)
-{
-  target_emit_ops ()->emit_bit_or ();
-}
-
-static void
-emit_bit_xor (void)
-{
-  target_emit_ops ()->emit_bit_xor ();
-}
-
-static void
-emit_bit_not (void)
-{
-  target_emit_ops ()->emit_bit_not ();
-}
-
-static void
-emit_equal (void)
-{
-  target_emit_ops ()->emit_equal ();
-}
-
-static void
-emit_less_signed (void)
-{
-  target_emit_ops ()->emit_less_signed ();
-}
-
-static void
-emit_less_unsigned (void)
-{
-  target_emit_ops ()->emit_less_unsigned ();
-}
-
-static void
-emit_ref (int size)
-{
-  target_emit_ops ()->emit_ref (size);
-}
-
-static void
-emit_if_goto (int *offset_p, int *size_p)
-{
-  target_emit_ops ()->emit_if_goto (offset_p, size_p);
-}
-
-static void
-emit_goto (int *offset_p, int *size_p)
-{
-  target_emit_ops ()->emit_goto (offset_p, size_p);
-}
-
-static void
-write_goto_address (CORE_ADDR from, CORE_ADDR to, int size)
-{
-  target_emit_ops ()->write_goto_address (from, to, size);
-}
-
-static void
-emit_const (LONGEST num)
-{
-  target_emit_ops ()->emit_const (num);
-}
-
-static void
-emit_reg (int reg)
-{
-  target_emit_ops ()->emit_reg (reg);
-}
-
-static void
-emit_pop (void)
-{
-  target_emit_ops ()->emit_pop ();
-}
-
-static void
-emit_stack_flush (void)
-{
-  target_emit_ops ()->emit_stack_flush ();
-}
-
-static void
-emit_zero_ext (int arg)
-{
-  target_emit_ops ()->emit_zero_ext (arg);
-}
-
-static void
-emit_swap (void)
-{
-  target_emit_ops ()->emit_swap ();
-}
-
-static void
-emit_stack_adjust (int n)
-{
-  target_emit_ops ()->emit_stack_adjust (n);
-}
-
-/* FN's prototype is `LONGEST(*fn)(int)'.  */
-
-static void
-emit_int_call_1 (CORE_ADDR fn, int arg1)
-{
-  target_emit_ops ()->emit_int_call_1 (fn, arg1);
-}
-
-/* FN's prototype is `void(*fn)(int,LONGEST)'.  */
-
-static void
-emit_void_call_2 (CORE_ADDR fn, int arg1)
-{
-  target_emit_ops ()->emit_void_call_2 (fn, arg1);
-}
-
-static void
-emit_eq_goto (int *offset_p, int *size_p)
-{
-  target_emit_ops ()->emit_eq_goto (offset_p, size_p);
-}
-
-static void
-emit_ne_goto (int *offset_p, int *size_p)
-{
-  target_emit_ops ()->emit_ne_goto (offset_p, size_p);
-}
-
-static void
-emit_lt_goto (int *offset_p, int *size_p)
-{
-  target_emit_ops ()->emit_lt_goto (offset_p, size_p);
-}
-
-static void
-emit_ge_goto (int *offset_p, int *size_p)
-{
-  target_emit_ops ()->emit_ge_goto (offset_p, size_p);
-}
-
-static void
-emit_gt_goto (int *offset_p, int *size_p)
+CORE_ADDR
+get_get_tsv_func_addr (void)
 {
-  target_emit_ops ()->emit_gt_goto (offset_p, size_p);
+  return ipa_sym_addrs.addr_get_trace_state_variable_value;
 }
 
-static void
-emit_le_goto (int *offset_p, int *size_p)
+CORE_ADDR
+get_set_tsv_func_addr (void)
 {
-  target_emit_ops ()->emit_le_goto (offset_p, size_p);
+  return ipa_sym_addrs.addr_set_trace_state_variable_value;
 }
 
-static enum eval_result_type compile_bytecodes (struct agent_expr *aexpr);
-
 static void
 compile_tracepoint_condition (struct tracepoint *tpoint,
                              CORE_ADDR *jump_entry)
@@ -6261,436 +5540,6 @@ compile_tracepoint_condition (struct tracepoint *tpoint,
   *jump_entry += 16;
 }
 
-/* Scan an agent expression for any evidence that the given PC is the
-   target of a jump bytecode in the expression.  */
-
-int
-is_goto_target (struct agent_expr *aexpr, int pc)
-{
-  int i;
-  unsigned char op;
-
-  for (i = 0; i < aexpr->length; i += 1 + gdb_agent_op_sizes[op])
-    {
-      op = aexpr->bytes[i];
-
-      if (op == gdb_agent_op_goto || op == gdb_agent_op_if_goto)
-       {
-         int target = (aexpr->bytes[i + 1] << 8) + aexpr->bytes[i + 2];
-         if (target == pc)
-           return 1;
-       }
-    }
-
-  return 0;
-}
-
-/* Given an agent expression, turn it into native code.  */
-
-static enum eval_result_type
-compile_bytecodes (struct agent_expr *aexpr)
-{
-  int pc = 0;
-  int done = 0;
-  unsigned char op, next_op;
-  int arg;
-  /* This is only used to build 64-bit value for constants.  */
-  ULONGEST top;
-  struct bytecode_address *aentry, *aentry2;
-
-#define UNHANDLED                                      \
-  do                                                   \
-    {                                                  \
-      trace_debug ("Cannot compile op 0x%x\n", op);    \
-      return expr_eval_unhandled_opcode;               \
-    } while (0)
-
-  if (aexpr->length == 0)
-    {
-      trace_debug ("empty agent expression\n");
-      return expr_eval_empty_expression;
-    }
-
-  bytecode_address_table = NULL;
-
-  while (!done)
-    {
-      op = aexpr->bytes[pc];
-
-      trace_debug ("About to compile op 0x%x, pc=%d\n", op, pc);
-
-      /* Record the compiled-code address of the bytecode, for use by
-        jump instructions.  */
-      aentry = xmalloc (sizeof (struct bytecode_address));
-      aentry->pc = pc;
-      aentry->address = current_insn_ptr;
-      aentry->goto_pc = -1;
-      aentry->from_offset = aentry->from_size = 0;
-      aentry->next = bytecode_address_table;
-      bytecode_address_table = aentry;
-
-      ++pc;
-
-      emit_error = 0;
-
-      switch (op)
-       {
-       case gdb_agent_op_add:
-         emit_add ();
-         break;
-
-       case gdb_agent_op_sub:
-         emit_sub ();
-         break;
-
-       case gdb_agent_op_mul:
-         emit_mul ();
-         break;
-
-       case gdb_agent_op_div_signed:
-         UNHANDLED;
-         break;
-
-       case gdb_agent_op_div_unsigned:
-         UNHANDLED;
-         break;
-
-       case gdb_agent_op_rem_signed:
-         UNHANDLED;
-         break;
-
-       case gdb_agent_op_rem_unsigned:
-         UNHANDLED;
-         break;
-
-       case gdb_agent_op_lsh:
-         emit_lsh ();
-         break;
-
-       case gdb_agent_op_rsh_signed:
-         emit_rsh_signed ();
-         break;
-
-       case gdb_agent_op_rsh_unsigned:
-         emit_rsh_unsigned ();
-         break;
-
-       case gdb_agent_op_trace:
-         UNHANDLED;
-         break;
-
-       case gdb_agent_op_trace_quick:
-         UNHANDLED;
-         break;
-
-       case gdb_agent_op_log_not:
-         emit_log_not ();
-         break;
-
-       case gdb_agent_op_bit_and:
-         emit_bit_and ();
-         break;
-
-       case gdb_agent_op_bit_or:
-         emit_bit_or ();
-         break;
-
-       case gdb_agent_op_bit_xor:
-         emit_bit_xor ();
-         break;
-
-       case gdb_agent_op_bit_not:
-         emit_bit_not ();
-         break;
-
-       case gdb_agent_op_equal:
-         next_op = aexpr->bytes[pc];
-         if (next_op == gdb_agent_op_if_goto
-             && !is_goto_target (aexpr, pc)
-             && target_emit_ops ()->emit_eq_goto)
-           {
-             trace_debug ("Combining equal & if_goto");
-             pc += 1;
-             aentry->pc = pc;
-             arg = aexpr->bytes[pc++];
-             arg = (arg << 8) + aexpr->bytes[pc++];
-             aentry->goto_pc = arg;
-             emit_eq_goto (&(aentry->from_offset), &(aentry->from_size));
-           }
-         else if (next_op == gdb_agent_op_log_not
-                  && (aexpr->bytes[pc + 1] == gdb_agent_op_if_goto)
-                  && !is_goto_target (aexpr, pc + 1)
-                  && target_emit_ops ()->emit_ne_goto)
-           {
-             trace_debug ("Combining equal & log_not & if_goto");
-             pc += 2;
-             aentry->pc = pc;
-             arg = aexpr->bytes[pc++];
-             arg = (arg << 8) + aexpr->bytes[pc++];
-             aentry->goto_pc = arg;
-             emit_ne_goto (&(aentry->from_offset), &(aentry->from_size));
-           }
-         else
-           emit_equal ();
-         break;
-
-       case gdb_agent_op_less_signed:
-         next_op = aexpr->bytes[pc];
-         if (next_op == gdb_agent_op_if_goto
-             && !is_goto_target (aexpr, pc))
-           {
-             trace_debug ("Combining less_signed & if_goto");
-             pc += 1;
-             aentry->pc = pc;
-             arg = aexpr->bytes[pc++];
-             arg = (arg << 8) + aexpr->bytes[pc++];
-             aentry->goto_pc = arg;
-             emit_lt_goto (&(aentry->from_offset), &(aentry->from_size));
-           }
-         else if (next_op == gdb_agent_op_log_not
-                  && !is_goto_target (aexpr, pc)
-                  && (aexpr->bytes[pc + 1] == gdb_agent_op_if_goto)
-                  && !is_goto_target (aexpr, pc + 1))
-           {
-             trace_debug ("Combining less_signed & log_not & if_goto");
-             pc += 2;
-             aentry->pc = pc;
-             arg = aexpr->bytes[pc++];
-             arg = (arg << 8) + aexpr->bytes[pc++];
-             aentry->goto_pc = arg;
-             emit_ge_goto (&(aentry->from_offset), &(aentry->from_size));
-           }
-         else
-           emit_less_signed ();
-         break;
-
-       case gdb_agent_op_less_unsigned:
-         emit_less_unsigned ();
-         break;
-
-       case gdb_agent_op_ext:
-         arg = aexpr->bytes[pc++];
-         if (arg < (sizeof (LONGEST) * 8))
-           emit_ext (arg);
-         break;
-
-       case gdb_agent_op_ref8:
-         emit_ref (1);
-         break;
-
-       case gdb_agent_op_ref16:
-         emit_ref (2);
-         break;
-
-       case gdb_agent_op_ref32:
-         emit_ref (4);
-         break;
-
-       case gdb_agent_op_ref64:
-         emit_ref (8);
-         break;
-
-       case gdb_agent_op_if_goto:
-         arg = aexpr->bytes[pc++];
-         arg = (arg << 8) + aexpr->bytes[pc++];
-         aentry->goto_pc = arg;
-         emit_if_goto (&(aentry->from_offset), &(aentry->from_size));
-         break;
-
-       case gdb_agent_op_goto:
-         arg = aexpr->bytes[pc++];
-         arg = (arg << 8) + aexpr->bytes[pc++];
-         aentry->goto_pc = arg;
-         emit_goto (&(aentry->from_offset), &(aentry->from_size));
-         break;
-
-       case gdb_agent_op_const8:
-         emit_stack_flush ();
-         top = aexpr->bytes[pc++];
-         emit_const (top);
-         break;
-
-       case gdb_agent_op_const16:
-         emit_stack_flush ();
-         top = aexpr->bytes[pc++];
-         top = (top << 8) + aexpr->bytes[pc++];
-         emit_const (top);
-         break;
-
-       case gdb_agent_op_const32:
-         emit_stack_flush ();
-         top = aexpr->bytes[pc++];
-         top = (top << 8) + aexpr->bytes[pc++];
-         top = (top << 8) + aexpr->bytes[pc++];
-         top = (top << 8) + aexpr->bytes[pc++];
-         emit_const (top);
-         break;
-
-       case gdb_agent_op_const64:
-         emit_stack_flush ();
-         top = aexpr->bytes[pc++];
-         top = (top << 8) + aexpr->bytes[pc++];
-         top = (top << 8) + aexpr->bytes[pc++];
-         top = (top << 8) + aexpr->bytes[pc++];
-         top = (top << 8) + aexpr->bytes[pc++];
-         top = (top << 8) + aexpr->bytes[pc++];
-         top = (top << 8) + aexpr->bytes[pc++];
-         top = (top << 8) + aexpr->bytes[pc++];
-         emit_const (top);
-         break;
-
-       case gdb_agent_op_reg:
-         emit_stack_flush ();
-         arg = aexpr->bytes[pc++];
-         arg = (arg << 8) + aexpr->bytes[pc++];
-         emit_reg (arg);
-         break;
-
-       case gdb_agent_op_end:
-         trace_debug ("At end of expression\n");
-
-         /* Assume there is one stack element left, and that it is
-            cached in "top" where emit_epilogue can get to it.  */
-         emit_stack_adjust (1);
-
-         done = 1;
-         break;
-
-       case gdb_agent_op_dup:
-         /* In our design, dup is equivalent to stack flushing.  */
-         emit_stack_flush ();
-         break;
-
-       case gdb_agent_op_pop:
-         emit_pop ();
-         break;
-
-       case gdb_agent_op_zero_ext:
-         arg = aexpr->bytes[pc++];
-         if (arg < (sizeof (LONGEST) * 8))
-           emit_zero_ext (arg);
-         break;
-
-       case gdb_agent_op_swap:
-         next_op = aexpr->bytes[pc];
-         /* Detect greater-than comparison sequences.  */
-         if (next_op == gdb_agent_op_less_signed
-             && !is_goto_target (aexpr, pc)
-             && (aexpr->bytes[pc + 1] == gdb_agent_op_if_goto)
-             && !is_goto_target (aexpr, pc + 1))
-           {
-             trace_debug ("Combining swap & less_signed & if_goto");
-             pc += 2;
-             aentry->pc = pc;
-             arg = aexpr->bytes[pc++];
-             arg = (arg << 8) + aexpr->bytes[pc++];
-             aentry->goto_pc = arg;
-             emit_gt_goto (&(aentry->from_offset), &(aentry->from_size));
-           }
-         else if (next_op == gdb_agent_op_less_signed
-                  && !is_goto_target (aexpr, pc)
-                  && (aexpr->bytes[pc + 1] == gdb_agent_op_log_not)
-                  && !is_goto_target (aexpr, pc + 1)
-                  && (aexpr->bytes[pc + 2] == gdb_agent_op_if_goto)
-                  && !is_goto_target (aexpr, pc + 2))
-           {
-             trace_debug ("Combining swap & less_signed & log_not & if_goto");
-             pc += 3;
-             aentry->pc = pc;
-             arg = aexpr->bytes[pc++];
-             arg = (arg << 8) + aexpr->bytes[pc++];
-             aentry->goto_pc = arg;
-             emit_le_goto (&(aentry->from_offset), &(aentry->from_size));
-           }
-         else
-           emit_swap ();
-         break;
-
-       case gdb_agent_op_getv:
-         emit_stack_flush ();
-         arg = aexpr->bytes[pc++];
-         arg = (arg << 8) + aexpr->bytes[pc++];
-         emit_int_call_1 (ipa_sym_addrs.addr_get_trace_state_variable_value,
-                          arg);
-         break;
-
-       case gdb_agent_op_setv:
-         arg = aexpr->bytes[pc++];
-         arg = (arg << 8) + aexpr->bytes[pc++];
-         emit_void_call_2 (ipa_sym_addrs.addr_set_trace_state_variable_value,
-                           arg);
-         break;
-
-       case gdb_agent_op_tracev:
-         UNHANDLED;
-         break;
-
-         /* GDB never (currently) generates any of these ops.  */
-       case gdb_agent_op_float:
-       case gdb_agent_op_ref_float:
-       case gdb_agent_op_ref_double:
-       case gdb_agent_op_ref_long_double:
-       case gdb_agent_op_l_to_d:
-       case gdb_agent_op_d_to_l:
-       case gdb_agent_op_trace16:
-         UNHANDLED;
-         break;
-
-       default:
-         trace_debug ("Agent expression op 0x%x not recognized\n", op);
-         /* Don't struggle on, things will just get worse.  */
-         return expr_eval_unrecognized_opcode;
-       }
-
-      /* This catches errors that occur in target-specific code
-        emission.  */
-      if (emit_error)
-       {
-         trace_debug ("Error %d while emitting code for %s\n",
-                      emit_error, gdb_agent_op_name (op));
-         return expr_eval_unhandled_opcode;
-       }
-
-      trace_debug ("Op %s compiled\n", gdb_agent_op_name (op));
-    }
-
-  /* Now fill in real addresses as goto destinations.  */
-  for (aentry = bytecode_address_table; aentry; aentry = aentry->next)
-    {
-      int written = 0;
-
-      if (aentry->goto_pc < 0)
-       continue;
-
-      /* Find the location that we are going to, and call back into
-        target-specific code to write the actual address or
-        displacement.  */
-      for (aentry2 = bytecode_address_table; aentry2; aentry2 = aentry2->next)
-       {
-         if (aentry2->pc == aentry->goto_pc)
-           {
-             trace_debug ("Want to jump from %s to %s\n",
-                          paddress (aentry->address),
-                          paddress (aentry2->address));
-             write_goto_address (aentry->address + aentry->from_offset,
-                                 aentry2->address, aentry->from_size);
-             written = 1;
-             break;
-           }
-       }
-
-      /* Error out if we didn't find a destination.  */
-      if (!written)
-       {
-         trace_debug ("Destination of goto %d not found\n",
-                      aentry->goto_pc);
-         return expr_eval_invalid_goto;
-       }
-    }
-
-  return expr_eval_no_error;
-}
-
 /* We'll need to adjust these when we consider bi-arch setups, and big
    endian machines.  */
 
This page took 0.046693 seconds and 4 git commands to generate.