/* This machine-generated file includes source code from GNU Jitter.

   Copyright (C) 2016-2021 Luca Saiu
   Written by Luca Saiu

   GNU Jitter 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, either version 3 of the License,
   or (at your option) any later version.

   GNU Jitter 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.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with GNU Jitter.  If not, see <https://www.gnu.org/licenses/>.

This generated code also is also derived from a user VM specification.

*/

/* User-specified code, initial header part: beginning. */
#line 176 "../../libpoke/pvm.jitter"
#line 176 "../../libpoke/pvm.jitter"

#   include <config.h>
  
/* User-specified code, initial header part: end */

/* VM library: main header file.

   Copyright (C) 2016, 2017, 2018, 2019, 2020, 2021 Luca Saiu
   Written by Luca Saiu

   This file is part of GNU Jitter.

   GNU Jitter 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, either version 3 of the License, or
   (at your option) any later version.

   GNU Jitter 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.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with GNU Jitter.  If not, see <https://www.gnu.org/licenses/>. */


/* Generated file warning.
 * ************************************************************************** */

/* Unless this file is named exactly "vm.h" , without any prefix, you are
   looking at a machine-generated derived file.  The original source is the vm.h
   template from Jitter, with added code implementing the pvm VM. */




/* This multiple-inclusion guard is opened here in the template, and will be
   closed at the end of the generated code.  It is normal to find no matching
   #endif in the template file.  */
#ifndef PVM_VM_H_
#define PVM_VM_H_


/* This is the main VM header to use from hand-written code.
 * ************************************************************************** */

#include <jitter/jitter-early-header.h>

#include <stdio.h>
#include <stdbool.h>

#include <jitter/jitter.h>
#include <jitter/jitter-hash.h>
#include <jitter/jitter-stack.h>
#include <jitter/jitter-instruction.h>
#include <jitter/jitter-mutable-routine.h>
#include <jitter/jitter-print.h>
#include <jitter/jitter-routine.h>
//#include <jitter/jitter-specialize.h> // FIXME: what about only declaring jitter_specialize in another header, and not including this?
#include <jitter/jitter-disassemble.h>
#include <jitter/jitter-vm.h>
#include <jitter/jitter-profile.h>
#include <jitter/jitter-data-locations.h>
#include <jitter/jitter-arithmetic.h>
#include <jitter/jitter-bitwise.h>
#include <jitter/jitter-signals.h>
#include <jitter/jitter-list.h>




/* Initialization and finalization.
 * ************************************************************************** */

/* Initialize the runtime state for the pvm VM.  This needs to be called
   before using VM routines or VM states in any way. */
void
pvm_initialize (void);

/* Finalize the runtime state, freeing some resources.  After calling this no
   use of VM routines or states is allowed.  It is possible to re-initialize
   after finalizing; these later re-initializations might be more efficient than
   the first initialization. */
void
pvm_finalize (void);




/* State data structure initialization and finalization.
 * ************************************************************************** */

/* The machine state is separated into the backing and the more compact runtime
   data structures, to be allocated in registers as far as possible.  These are
   just a forward-declarations: the actual definitions are machine-generated. */
struct pvm_state_backing;
struct pvm_state_runtime;

/* A data structure containing both the backing and the runtime state.  This is
   a forward-declaration: the actual definition will come after both are
   defined. */
struct pvm_state;

/* Initialize the pointed VM state data structure, or fail fatally.  The
   function definition is machine-generated, even if it may include user code.
   The state backing and runtime are initialized at the same time, and in fact
   the distinction between them is invisible to the VM user.
   The version not specifying a given number of slow registers per class
   sets slow registers to be initially zero. */
void
pvm_state_initialize (struct pvm_state *state)
  __attribute__ ((nonnull (1)));
void
pvm_state_initialize_with_slow_registers (struct pvm_state *state,
                                               jitter_uint
                                               slow_register_no_per_class)
  __attribute__ ((nonnull (1)));

/* Finalize the pointed VM state data structure, or fail fatally.  The function
   definition is machine-generated, even if it may include user code.  The state
   backing and runtime are finalized at the same time. */
void
pvm_state_finalize (struct pvm_state *state)
  __attribute__ ((nonnull (1)));

/* The make/destroy counterparts of the initialize/finalize functions above. */
struct pvm_state *
pvm_state_make (void)
  __attribute__ ((returns_nonnull));
struct pvm_state *
pvm_state_make_with_slow_registers (jitter_uint slow_register_no_per_class)
  __attribute__ ((returns_nonnull));
void
pvm_state_destroy (struct pvm_state *state)
  __attribute__ ((nonnull (1)));

/* Reset the pointed VM state, restoring its initial content.  This is cheaper
   than finalising and re-initialising a state. */
void
pvm_state_reset (struct pvm_state *state)
  __attribute__ ((nonnull (1)));




/* State data structure: iteration.
 * ************************************************************************** */

/* The header of a doubly-linked list linking every state for the pvm VM
   together.  This global is automatically wrapped, and therefore also
   accessible from VM instruction code. */
extern struct jitter_list_header * const
pvm_states;

/* A pointer to the current state, only accessible from VM code.  This is usable
   for pointer comparison when iterating over states. */
#define PVM_OWN_STATE                           \
  ((struct pvm_state *) jitter_original_state)

/* Given an l-value of type struct pvm_state * (usually a variable name)
   expand to a for loop statement iterating over every existing pvm state
   using the l-value as iteration variable.  The expansion will execute the
   statement immediately following the macro call with the l-value in scope;
   in order words the loop body is not a macro argument, but follows the macro
   use.
   The l-value may be evaluated an unspecified number of times.
   This macro is safe to use within VM instruction code.
   For example:
     struct pvm_state *s;
     PVM_FOR_EACH_STATE (s)
       printf ("This is a state: %p\n", s); // (but printf unsafe in VM code) */
#define PVM_FOR_EACH_STATE(jitter_state_iteration_lvalue)     \
  for ((jitter_state_iteration_lvalue)                             \
          = pvm_states->first;                                \
       (jitter_state_iteration_lvalue)                             \
          != NULL;                                                 \
       (jitter_state_iteration_lvalue)                             \
         = (jitter_state_iteration_lvalue)->links.next)            \
    /* Here comes the body supplied by the user: no semicolon. */




/* Mutable routine initialization.
 * ************************************************************************** */

/* Return a freshly-allocated empty mutable routine for the pvm VM. */
struct jitter_mutable_routine*
pvm_make_mutable_routine (void)
  __attribute__ ((returns_nonnull));

/* Mutable routine finalization is actually VM-independent, but a definition of
   pvm_destroy_mutable_routine is provided below as a macro, for cosmetic
   reasons. */


/* Mutable routines: code generation C API.
 * ************************************************************************** */

/* This is the preferred way of adding a new VM instruction to a pointed
   routine, more efficient than pvm_mutable_routine_append_instruction_name
   even if only usable when the VM instruction opcode is known at compile time.
   The unspecialized instruction name must be explicitly mangled by the user as
   per the rules in jitterc_mangle.c .  For example an instruction named foo_bar
   can be added to the routine pointed by p with any one of
     pvm_mutable_routine_append_instruction_name (p, "foo_bar");
   ,
     PVM_MUTABLE_ROUTINE_APPEND_INSTRUCTION (p, foo_ubar);
   , and
     PVM_MUTABLE_ROUTINE_APPEND_INSTRUCTION_ID 
        (p, pvm_meta_instruction_id_foo_ubar);
   .
   The string "foo_bar" is not mangled, but the token foo_ubar is. */
#define PVM_MUTABLE_ROUTINE_APPEND_INSTRUCTION(                 \
          routine_p, instruction_mangled_name_root)                  \
  do                                                                 \
    {                                                                \
      jitter_mutable_routine_append_meta_instruction                 \
         ((routine_p),                                               \
          pvm_meta_instructions                                 \
          + JITTER_CONCATENATE_TWO(pvm_meta_instruction_id_,    \
                                   instruction_mangled_name_root));  \
    }                                                                \
  while (false)

/* Append the unspecialized instruction whose id is given to the pointed routine.
   The id must be a case of enum pvm_meta_instruction_id ; such cases have
   a name starting with pvm_meta_instruction_id_ .
   This is slightly less convenient to use than PVM_MUTABLE_ROUTINE_APPEND_INSTRUCTION
   but more general, as the instruction id is allowed to be a non-constant C
   expression. */
#define PVM_MUTABLE_ROUTINE_APPEND_INSTRUCTION_ID(_jitter_routine_p,       \
                                                       _jitter_instruction_id)  \
  do                                                                            \
    {                                                                           \
      jitter_mutable_routine_append_instruction_id                              \
         ((_jitter_routine_p),                                                  \
          pvm_meta_instructions,                                           \
          PVM_META_INSTRUCTION_NO,                                         \
          (_jitter_instruction_id));                                            \
    }                                                                           \
  while (false)

/* This is the preferred way of appending a register argument to the instruction
   being added to the pointed routine, more convenient than directly using
   pvm_mutable_routine_append_register_id_parameter , even if only usable
   when the register class is known at compile time.  Here the register class is
   only provided as a letter, but both the routine pointer and the register
   index are arbitrary C expressions.
   For example, in
     PVM_MUTABLE_ROUTINE_APPEND_REGISTER_PARAMETER (p, r,
                                                         variable_to_index (x));
   the second macro argument "r" represents the register class named "r", and
   not the value of a variable named r. */
#define PVM_MUTABLE_ROUTINE_APPEND_REGISTER_PARAMETER(routine_p,     \
                                                           class_letter,  \
                                                           index)         \
  do                                                                      \
    {                                                                     \
      pvm_mutable_routine_append_register_parameter                  \
         ((routine_p),                                                    \
          & JITTER_CONCATENATE_TWO(pvm_register_class_,              \
                                   class_letter),                         \
          (index));                                                       \
    }                                                                     \
  while (false)




/* Routine unified API: initialization.
 * ************************************************************************** */

/* See the comments above in "Mutable routines: initialization", and the
   implementation of the unified routine API in <jitter/jitter-routine.h> . */

#define pvm_make_routine pvm_make_mutable_routine




/* Routine unified API: code generation C API.
 * ************************************************************************** */

/* See the comments above in "Mutable routines: code generation C API". */

#define PVM_ROUTINE_APPEND_INSTRUCTION  \
  PVM_MUTABLE_ROUTINE_APPEND_INSTRUCTION
#define PVM_ROUTINE_APPEND_INSTRUCTION_ID  \
  PVM_MUTABLE_ROUTINE_APPEND_INSTRUCTION_ID
#define PVM_ROUTINE_APPEND_REGISTER_PARAMETER  \
  PVM_MUTABLE_ROUTINE_APPEND_REGISTER_PARAMETER




/* Array: special-purpose data.
 * ************************************************************************** */

/* The Array is a convenient place to store special-purpose data, accessible in
   an efficient way from a VM routine.
   Every item in special-purpose data is thread-local. */

/* The special-purpose data struct.  Every Array contains one of these at unbiased
   offset PVM_SPECIAL_PURPOSE_STATE_DATA_UNBIASED_OFFSET from the unbiased
   beginning of the array.
   This entire struct is aligned to at least sizeof (jitter_int) bytes.  The
   entire struct is meant to be always accessed through a pointer-to-volatile,
   as its content may be altered from signal handlers and from different
   threads.  In particualar the user should use the macro
     PVM_ARRAY_TO_SPECIAL_PURPOSE_STATE_DATA
   defined below and the macros defined from it as accessors.
   VM code accessing special-purpose data for its own state should use
     PVM_SPECIAL_PURPOSE_STATE_DATA
   and the macros defined from it. */
struct jitter_special_purpose_state_data
{
  /* Notification fields.
   * ***************************************************************** */

  /* This is a Boolean flag, held as a word-sized datum so as to ensure
     atomicity in access.  It is also aligned to at least sizeof (jitter_int)
     bytes.
     Non-zero means that there is at least one notification pending, zero means
     that there are no notifications.  The flag specifies no other details: it
     is meant to be fast to check, with detailed information about each pending
     notification available elsewhere.
     It is the receiver's responsibility to periodically poll for notifications
     in application-specific "safe-points":
     A check can be inserted, for example, in all of these program points:
     a) at every backward branch;
     b) at every procedure entry;
     c) right after a call to each blocking primitive (as long as primitives
       can be interrupted).
     Safe-point checks are designed to be short and fast in the common case.  In
     the common case no action is required, and the VM routine should simply
     fall through.  If an action is required then control should branch off to a
     handler, where the user may implement the required behavior.
     It is mandatory that, as long as notifications can arrive, this field
     is reset to zero (when handling pending notifications) only by a thread
     running VM code in the state containing this struct.
     Other threads are allowed to set this to non-zero, in order to send a
     notification.  */
  jitter_int pending_notifications;

  /* Information about pending signal notifications.  If any signal is pending
     then pending_notifications must also be set, so that a notification check
     can always just quickly check pending_notifications, and then look at more
     details (including in pending_signal_notifications) only in the rare case
     of pending_notifications being true. */
  struct jitter_signal_notification *pending_signal_notifications;


  /* Profiling instrumentation fields.
   * ***************************************************************** */
  struct jitter_profile_runtime profile_runtime;
};




/* The Array and volatility.
 * ************************************************************************** */

/* Some fields of The Array, seen from VM code, are meant to be volatile, since
   they can be set by signal handlers or by other threads.  However it is
   acceptable to not see such changes immediately after they occur (notifications
   will get delayed, but not lost) and always accessing such data through a
   volatile struct is suboptimal.

   Non-VM code does need a volatile qualifier.

   Advanced dispatches already need a trick using inline assembly to make the
   base pointer (a biased pointer to The Array beginning) appear to
   spontaneously change beween instruction.  That is sufficient to express the
   degree of volatility required for this purpose.
   Simple dispatches, on targets where inline assembly may not be available at
   all, will use an actual volatile qualifier. */
#if defined (JITTER_DISPATCH_SWITCH)               \
    || defined (JITTER_DISPATCH_DIRECT_THREADING)
# define PVM_ARRAY_VOLATILE_QUALIFIER volatile
#elif defined (JITTER_DISPATCH_MINIMAL_THREADING)  \
      || defined (JITTER_DISPATCH_NO_THREADING)
# define PVM_ARRAY_VOLATILE_QUALIFIER /* nothing */
#else
# error "unknown dispatch: this should not happen"
#endif /* dispatch conditional */




/* Array element access: residuals, transfers, slow registers, and more.
 * ************************************************************************** */

/* In order to cover a wider range of addresses with simple base + register
   addressing the base does not necessarily point to the beginning of the Array;
   instead the base points to the beginning of the Array plus JITTER_ARRAY_BIAS
   bytes.
   FIXME: define the bias as a value appropriate to each architecture.  I think
   I should just move the definition to jitter-machine.h and provide a default
   here, in case the definition is missing on some architecture. */

/* FIXME: Horrible, horrible, horrible temporary workaround!

   This is a temporary workaround, very ugly and fragile, to compensate
   a limitation in jitter-specialize.c , which I will need to rewrite anyway.
   The problem is that jitter-specialize.c patches snippets to load non-label
   residuals in a VM-independent way based only on slow-register/memory residual
   indices, which is incorrect.  By using this particular bias I am cancelling
   that error.
   Test case, on a machine having only one register residual and a VM having just
     one fast register:
     [luca@moore ~/repos/jitter/_build/native-gcc-9]$ Q=bin/uninspired--no-threading; make $Q && echo 'mov 2, %r1' | libtool --mode=execute valgrind $Q --disassemble - --print-locations
   If this bias is wrong the slow-register accesses in mov/nR/%rR will use two
   different offsets, one for reading and another for writing.  With this
   workaround they will be the same.
   Good, with workadound (biased offset 0x0 from the base in %rbx):
    # 0x4a43d38: mov/nR/%rR 0x2, 0x20 (21 bytes):
        0x0000000004effb30 41 bc 02 00 00 00    	movl   $0x2,%r12d
        0x0000000004effb36 48 c7 43 00 20 00 00 00 	movq   $0x20,0x0(%rbx)
        0x0000000004effb3e 48 8b 13             	movq   (%rbx),%rdx
        0x0000000004effb41 4c 89 24 13          	movq   %r12,(%rbx,%rdx,1)
   Bad, with JITTER_ARRAY_BIAS defined as zero: first write at 0x0(%rbx)
                                                then read at 0x10(%rbx):
    # 0x4a43d38: mov/nR/%rR 0x2, 0x30 (22 bytes):
        0x0000000004effb30 41 bc 02 00 00 00    	movl   $0x2,%r12d
        0x0000000004effb36 48 c7 43 00 30 00 00 00 	movq   $0x30,0x0(%rbx)
        0x0000000004effb3e 48 8b 53 10          	movq   0x10(%rbx),%rdx
        0x0000000004effb42 4c 89 24 13          	movq   %r12,(%rbx,%rdx,1) */
#define JITTER_ARRAY_BIAS \
  (sizeof (struct jitter_special_purpose_state_data))
//#define JITTER_ARRAY_BIAS //0//(((jitter_int) 1 << 15))//(((jitter_int) 1 << 31))//0//0//16//0

/* Array-based globals are not implemented yet.  For the purpose of computing
   Array offsets I will say they are zero. */
#define PVM_GLOBAL_NO 0

/* Transfer registers are not implemented yet.  For the purpose of computing
   Array offsets I will say they are zero. */
#define PVM_TRANSFER_REGISTER_NO 0

/* Define macros holding offsets in bytes for the first global, memory residual
   and transfer register, from an initial Array pointer.
   In general we have to keep into account:
   - globals (word-sized);
   - special-purpose state data;
   - memory residuals (word-sized);
   - transfer registers (word-sized);
   - slow registers (pvm_any_register-sized and aligned).
   Notice that memory
   residuals (meaning residuals stored in The Array) are zero on dispatching
   modes different from no-threading.  This relies on
   PVM_MAX_MEMORY_RESIDUAL_ARITY , defined below, which in its turn depends
   on PVM_MAX_RESIDUAL_ARITY, which is machine-generated. */
#define PVM_FIRST_GLOBAL_UNBIASED_OFFSET  \
  0
#define PVM_SPECIAL_PURPOSE_STATE_DATA_UNBIASED_OFFSET  \
  (PVM_FIRST_GLOBAL_UNBIASED_OFFSET                     \
   + sizeof (jitter_int) * PVM_GLOBAL_NO)
#define PVM_FIRST_MEMORY_RESIDUAL_UNBIASED_OFFSET   \
  (PVM_SPECIAL_PURPOSE_STATE_DATA_UNBIASED_OFFSET   \
   + sizeof (struct jitter_special_purpose_state_data))
#define PVM_FIRST_TRANSFER_REGISTER_UNBIASED_OFFSET        \
  (PVM_FIRST_MEMORY_RESIDUAL_UNBIASED_OFFSET               \
   + sizeof (jitter_int) * PVM_MAX_MEMORY_RESIDUAL_ARITY)
#define PVM_FIRST_SLOW_REGISTER_UNBIASED_OFFSET          \
  JITTER_NEXT_MULTIPLE_OF_POSITIVE                            \
     (PVM_FIRST_TRANSFER_REGISTER_UNBIASED_OFFSET        \
      + sizeof (jitter_int) * PVM_TRANSFER_REGISTER_NO,  \
      sizeof (union pvm_any_register))

/* Expand to the offset of the special-purpose data struct from the Array
   biased beginning. */
#define PVM_SPECIAL_PURPOSE_STATE_DATA_OFFSET       \
  (PVM_SPECIAL_PURPOSE_STATE_DATA_UNBIASED_OFFSET   \
   - JITTER_ARRAY_BIAS)

/* Given an expression evaluating to the Array unbiased beginning, expand to
   an expression evaluating to a pointer to its special-purpose data.
   This is convenient for accessing special-purpose data from outside the
   state -- for example, to set the pending notification flag for another
   thread.
   There are two versions of this feature:
     PVM_ARRAY_TO_SPECIAL_PURPOSE_STATE_DATA
   is meant to be used to access state data for some other thread, or in
   general out of VM code.
     PVM_OWN_SPECIAL_PURPOSE_STATE_DATA
   is for VM code accessing its own special-purpose data. */
#define PVM_ARRAY_TO_SPECIAL_PURPOSE_STATE_DATA_PRIVATE(qualifier,      \
                                                             array_address)  \
  ((qualifier struct jitter_special_purpose_state_data *)                    \
   (((char *) (array_address))                                               \
    + PVM_SPECIAL_PURPOSE_STATE_DATA_UNBIASED_OFFSET))
#define PVM_ARRAY_TO_SPECIAL_PURPOSE_STATE_DATA(array_address)       \
  PVM_ARRAY_TO_SPECIAL_PURPOSE_STATE_DATA_PRIVATE (volatile,         \
                                                        (array_address))
#define PVM_OWN_SPECIAL_PURPOSE_STATE_DATA          \
  PVM_ARRAY_TO_SPECIAL_PURPOSE_STATE_DATA_PRIVATE   \
     (PVM_ARRAY_VOLATILE_QUALIFIER,                 \
      ((char *) jitter_array_base) - JITTER_ARRAY_BIAS)

/* Given a state pointer, expand to an expression evaluating to a pointer to
   the state's special-purpose data.  This is meant for threads accessing
   other threads' special-purpose data, typically to set notifications. */
#define PVM_STATE_TO_SPECIAL_PURPOSE_STATE_DATA(state_p)  \
  (PVM_ARRAY_TO_SPECIAL_PURPOSE_STATE_DATA                \
     ((state_p)->pvm_state_backing.jitter_array))

/* Given a state pointer, expand to an expression evaluating to the
   pending_notification field for the state as an l-value.  This is meant for
   threads sending notifications to other threads. */
#define PVM_STATE_TO_PENDING_NOTIFICATIONS(state_p)   \
  (PVM_STATE_TO_SPECIAL_PURPOSE_STATE_DATA (state_p)  \
     ->pending_notifications)

/* Given a state pointer and a signal, expand to an l-value evaluating to a the
   pending field of the struct jitter_signal_notification element for the given
   signal in the pointed state.  This is meant for threads sending signal
   notifications to other threads and for C handler function. */
#define PVM_STATE_AND_SIGNAL_TO_PENDING_SIGNAL_NOTIFICATION(state_p,    \
                                                                 signal_id)  \
  (((PVM_STATE_TO_SPECIAL_PURPOSE_STATE_DATA (state_p)                   \
       ->pending_signal_notifications)                                        \
    + (signal_id))->pending)


/* Expand to the offset of the i-th register of class c in bytes from the Array
   beginning.
   The c argument must be a literal C (one-character) identifier.
   The i argument should always be a compile-time constant for performance, and
   it is in generated code.
   The i-th c-class register must be slow, otherwise the offset will be
   incorrect -- in fact fast registers are, hopefully, not in memory at all.

   Slow registers come in the Array ordered first by index, then by class.  For
   example if there are three classes "r" with 4 fast registers, "f" with 7 fast
   registers and "q" with 2 fast registers, slow registers can be accessed in
   this order:
     r4, f7, q2, r5, r8, q3, r6, r9, q4, and so on.
   Each contiguous group of slow registers spanning every class and starting
   from the first class (here for example <r5, r6, q3>) is called a "rank".
   This organization is convenient since changing the number of slow registers
   doesn't invalidate any offset computed in the past: the Array can simply be
   resized and its base pointer updated, without changing the code accessing it.

   This relies on macro such as PVM_REGISTER_CLASS_NO and
   PVM_REGISTER_?_FAST_REGISTER_NO and , defined below in machine-generated
   code. */
#define PVM_SLOW_REGISTER_UNBIASED_OFFSET(c, i)                     \
  (PVM_FIRST_SLOW_REGISTER_UNBIASED_OFFSET                          \
   + (sizeof (union pvm_any_register)                               \
      * (PVM_REGISTER_CLASS_NO                                      \
         * ((i) - JITTER_CONCATENATE_THREE(PVM_REGISTER_, c,        \
                                           _FAST_REGISTER_NO))           \
         + JITTER_CONCATENATE_THREE(PVM_REGISTER_, c, _CLASS_ID))))

/* Expand to the offset of the i-th register of class c in bytes from the base,
   keeping the bias into account. */
#define PVM_SLOW_REGISTER_OFFSET(c, i)                              \
  (PVM_SLOW_REGISTER_UNBIASED_OFFSET(c, i) - JITTER_ARRAY_BIAS)

/* Expand to the Array size in bytes, assuming the given number of slow
   registers per class.  This is an allocation size, ignoring the bias. */
#define PVM_ARRAY_SIZE(slow_register_per_class_no)                  \
  (PVM_FIRST_SLOW_REGISTER_UNBIASED_OFFSET                          \
   + (sizeof (union pvm_any_register)                               \
      * PVM_REGISTER_CLASS_NO                                       \
      * (slow_register_per_class_no)))




/* Residual access.
 * ************************************************************************** */

/* How many residuals we can have at most in memory, which is to say,
   without counting residuals kept in reserved registers.

   Implementation note: it would be wrong here to use a CPP conditional based on
   the value of PVM_MAX_RESIDUAL_ARITY , as I was doing in a preliminary
   version.  That lead to a tricky bug, since PVM_MAX_RESIDUAL_ARITY ,
   which is defined below but is not yet available here, simply counted as 0
   for the purposes of evaluating the CPP condititional. */
#ifdef JITTER_DISPATCH_NO_THREADING
  /* We are using no-threading dispatch.  If there are no more residuals
     than reserved residual registers then we never need to keep any in
     memory.  Otherwise we need to keep as many residuals in memory as the
     total number of residuals minus how many registers are reserved for
     them. */
# define PVM_MAX_MEMORY_RESIDUAL_ARITY                          \
    ((PVM_MAX_RESIDUAL_ARITY <= JITTER_RESIDUAL_REGISTER_NO)    \
     ? 0                                                             \
     : (PVM_MAX_RESIDUAL_ARITY - JITTER_RESIDUAL_REGISTER_NO))
#else // Not no-threading.
  /* No registers are reserved for residuals in this dispatch; even if
     in fact all residuals are memory residuals they don't count here, since
     residuals are not held in The Array in this dispatch. */
# define PVM_MAX_MEMORY_RESIDUAL_ARITY  \
  0
#endif // #ifdef JITTER_DISPATCH_NO_THREADING

#ifdef JITTER_DISPATCH_NO_THREADING
/* Expand to the offset from the base, in bytes, of the i-th residual.  The
   given index must be greater than or equal to JITTER_RESIDUAL_REGISTER_NO;
   residuals with indices lower than that number are not stored in The Array
   at all.
   This is not useful with any of the other dispatches, where residuals
   directly follow each VM instruction opcode or thread.  For good performance i
   should always be a compile-time constant, as it is in machine-generated
   code.
   Residuals always have the size of a jitter word, even if some register class
   may be wider. */
/* FIXME: if later I use a different policy than simply checking
   JITTER_RESIDUAL_REGISTER_NO to decide how many residuals to keep in
   registers, then I have to change this or meet very nasty bugs. */
# define PVM_RESIDUAL_UNBIASED_OFFSET(i)                      \
    (PVM_FIRST_MEMORY_RESIDUAL_UNBIASED_OFFSET                \
     + (sizeof (jitter_int) * (i - JITTER_RESIDUAL_REGISTER_NO)))
# define PVM_RESIDUAL_OFFSET(i)  \
    (PVM_RESIDUAL_UNBIASED_OFFSET(i) - JITTER_ARRAY_BIAS)
#endif // #ifdef JITTER_DISPATCH_NO_THREADING



/* Mutable routine text frontend.
 * ************************************************************************** */

/* An enum type. */
#define pvm_routine_edit_status  \
  jitter_routine_edit_status
/* Cases for an enum type. */
#define pvm_routine_edit_status_success  \
  jitter_routine_edit_status_success
#define pvm_routine_edit_status_label_defined_twice  \
  jitter_routine_edit_status_label_defined_twice
#define pvm_routine_edit_status_invalid_instruction  \
  jitter_routine_edit_status_invalid_instruction
#define pvm_routine_edit_status_invalid_register  \
  jitter_routine_edit_status_invalid_register
#define pvm_routine_edit_status_register_class_mismatch  \
  jitter_routine_edit_status_register_class_mismatch
#define pvm_routine_edit_status_nonexisting_register_class  \
  jitter_routine_edit_status_nonexisting_register_class
#define pvm_routine_edit_status_invalid_parameter_kind  \
  jitter_routine_edit_status_invalid_parameter_kind
#define pvm_routine_edit_status_too_many_parameters  \
  jitter_routine_edit_status_too_many_parameters
#define pvm_routine_edit_status_last_instruction_incomplete  \
  jitter_routine_edit_status_last_instruction_incomplete
#define pvm_routine_edit_status_other_parse_error  \
  jitter_routine_edit_status_other_parse_error

/* Given a parse status of type enum jitter_routine_edit_status return its
   written C representation. */
#define pvm_routine_edit_status_to_string  \
  jitter_routine_edit_status_to_string

/* The name of the struct returned by parsers. */
#define pvm_routine_parse_error  \
  jitter_routine_parse_error

/* The name of the function destroying a pointer to pvm_routine_parse_error
   , returned by routine parsers in case of error. */
#define pvm_routine_parse_error_destroy  \
  jitter_routine_parse_error_destroy

/* Parse VM code from the given file or string into the pointed VM routine,
   which is allowed but not required to be empty.
   These are simple wrappers around functions implemented in the Bison file. */
struct pvm_routine_parse_error *
pvm_parse_mutable_routine_from_file_star (FILE *input_file,
                                               struct jitter_mutable_routine *p)
  __attribute__ ((nonnull (1, 2)));
struct pvm_routine_parse_error *
pvm_parse_mutable_routine_from_file (const char *input_file_name,
                                          struct jitter_mutable_routine *p)
  __attribute__ ((nonnull (1, 2)));
struct pvm_routine_parse_error *
pvm_parse_mutable_routine_from_string (const char *string,
                                            struct jitter_mutable_routine *p)
  __attribute__ ((nonnull (1, 2)));




/* Unified routine text frontend.
 * ************************************************************************** */

/* The C wrappers for the ordinary API can be reused for the unified API, since
   it internally works with mutable routines. */
#define pvm_parse_routine_from_file_star  \
  pvm_parse_mutable_routine_from_file_star
#define pvm_parse_routine_from_file  \
  pvm_parse_mutable_routine_from_file
#define pvm_parse_routine_from_string  \
  pvm_parse_mutable_routine_from_string




/* Machine-generated data structures.
 * ************************************************************************** */

/* Declare a few machine-generated data structures, which together define a VM. */

/* Threads or pointers to native code blocks of course don't exist with
   switch-dispatching. */
#ifndef JITTER_DISPATCH_SWITCH
/* Every possible thread, indexed by enum jitter_specialized_instruction_opcode .
   This is used at specialization time, and the user shouldn't need to touch
   it. */
extern const jitter_thread *
pvm_threads;

/* VM instruction end label.  These are not all reachable at run time, but
   having them in a global array might prevent older GCCs from being too clever
   in reordering blocks. */
extern const jitter_thread *
pvm_thread_ends;

/* The size, in chars, of each thread's native code.  The elements are in the
   same order of pvm_threads.  Sizes could conceptually be of type size_t ,
   but in order to be defensive I'm storing pointer differences as signed
   values, so that we may catch compilation problems: if any VM instruction end
   *precedes* its VM instruction beginning, then the compiler has reordered
   labels, which would have disastrous effects with replicated code. */
extern const long *
pvm_thread_sizes;
#endif // #ifndef JITTER_DISPATCH_SWITCH

/* This is defined in the machine-generated vm/meta-instructions.c . */
extern struct jitter_hash_table
pvm_meta_instruction_hash;

/* An array specifying every existing meta-instruction, defined in the order of
   enum pvm_meta_instruction_id .  This is defined in vm/meta-instructions.c ,
   which is machine-generated. */
extern const struct jitter_meta_instruction
pvm_meta_instructions [];

/* An array whose indices are specialised instruction opcodes, and
   whose elements are the corresponding unspecialised instructions
   opcodes -- or -1 when there is no mapping mapping having */
extern const int
pvm_specialized_instruction_to_unspecialized_instruction [];

/* How many residual parameters each specialized instruction has.  The
   actual array definition is machine-generated. */
extern const size_t
pvm_specialized_instruction_residual_arities [];

/* An array of bitmasks, one per specialized instruction.  Each bitmask holds
   one bit per residual argument, counting from the least significant (the first
   residual arg maps to element & (1 << 0), the second to element & (1 << 1),
   and so on).
   Each bit is 1 if and only if the corresponding residual argument is a label
   or a fast label.
   Only residual arguments are counted: for example a specialized instruction
   foo_n1_lR_r2 would have a mask with the *first* bit set. */
extern const unsigned long // FIXME: possibly use a shorter type when possible
pvm_specialized_instruction_label_bitmasks [];

/* Like pvm_specialized_instruction_label_bitmasks , but for fast labels
   only.
   The actual definition is conditionalized so as to appear only when
   needed according to the dispatch. */
extern const unsigned long // FIXME: possibly use a shorter type when possible
pvm_specialized_instruction_fast_label_bitmasks [];

/* An array of booleans in which each element is true iff the specialized
   instruction whose opcode is the index is relocatable. */
extern const bool
pvm_specialized_instruction_relocatables [];

/* An array of booleans in which each element is true iff the specialized
   instruction whose opcode is the index is a caller. */
extern const bool
pvm_specialized_instruction_callers [];

/* An array of booleans in which each element is true iff the specialized
   instruction whose opcode is the index is a callee. */
extern const bool
pvm_specialized_instruction_callees [];

/* This big array of strings contains the name of each specialized instruction,
   in the order of enum pvm_specialized_instruction_opcode . */
extern const char* const
pvm_specialized_instruction_names [];


/* A pointer to a struct containing const pointers to the structures above, plus
   sizes; there will be only one instance of this per VM, machine-generated.
   Each program data structure contains a pointer to that instance, so that
   VM-independent functions, given a program, will have everything needed to
   work.  The one instance of struct jitter_vm for the pvm VM. */
extern struct jitter_vm * const
pvm_vm;

/* A pointer to a struct containing VM-specific parameters set in part when
   calling jitterc and in part when compiling the generated C code, such as the
   dispatch and the number of fast registers.  The data is fully
   initialized only after a call to pvm_initialize . */
extern const
struct jitter_vm_configuration * const
pvm_vm_configuration;




/* Compatibility macros.
 * ************************************************************************** */

/* It is convenient, for future extensibility, to expose an interface in which
   some VM-independent functions and data structures actually look as if they
   were specific to the user VM. */

/* What the user refers to as struct pvm_mutable_routine is actually a
   struct jitter_mutable_routine , whose definition is VM-independent. */
#define pvm_mutable_routine jitter_mutable_routine

/* Same for executable routines. */
#define pvm_executable_routine jitter_executable_routine

/* Same for unified routines. */
#define pvm_routine jitter_routine

/* Destroy a non-executable routine (routine initialization is actually
   VM-specific). */
#define pvm_destroy_mutable_routine jitter_destroy_mutable_routine

/* Destroy a unified routine. */
#define pvm_destroy_routine jitter_destroy_routine

/* Pin a unified routine. */
#define pvm_pin_routine jitter_pin_routine

/* Unpin a unified routine. */
#define pvm_unpin_routine jitter_unpin_routine

/* Print VM configuration. */
#define pvm_print_vm_configuration jitter_print_vm_configuration

/* Generic routine construction API. */
#define pvm_label \
  jitter_label
#define pvm_fresh_label \
  jitter_fresh_label

/* Mutable routine option API. */
#define pvm_set_mutable_routine_option_slow_literals_only \
  jitter_set_mutable_routine_option_slow_literals_only
#define pvm_set_mutable_routine_option_slow_registers_only \
  jitter_set_mutable_routine_option_slow_registers_only
#define pvm_set_mutable_routine_option_slow_literals_and_registers_only \
  jitter_set_mutable_routine_option_slow_literals_and_registers_only
#define pvm_set_mutable_routine_option_add_final_exitvm \
  jitter_set_mutable_routine_option_add_final_exitvm
#define pvm_set_mutable_routine_option_optimization_rewriting \
  jitter_set_mutable_routine_option_optimization_rewriting

/* Printing and disassembling: ordinary API. */
#define pvm_mutable_routine_print \
  jitter_mutable_routine_print
#define pvm_executable_routine_disassemble \
  jitter_executable_routine_disassemble

/* Mutable routine construction API: unsafe API */
#define pvm_mutable_routine_append_instruction_name \
  jitter_mutable_routine_append_instruction_name
#define pvm_mutable_routine_append_meta_instruction \
  jitter_mutable_routine_append_meta_instruction
#define pvm_mutable_routine_append_label \
  jitter_mutable_routine_append_label
#define pvm_mutable_routine_append_symbolic_label \
  jitter_mutable_routine_append_symbolic_label
#define pvm_mutable_routine_append_register_parameter \
  jitter_mutable_routine_append_register_parameter
#define pvm_mutable_routine_append_symbolic_register_parameter \
  jitter_mutable_routine_append_symbolic_register_parameter
#define pvm_mutable_routine_append_literal_parameter \
  jitter_mutable_routine_append_literal_parameter
#define pvm_mutable_routine_append_signed_literal_parameter \
  jitter_mutable_routine_append_signed_literal_parameter
#define pvm_mutable_routine_append_unsigned_literal_parameter \
  jitter_mutable_routine_append_unsigned_literal_parameter
#define pvm_mutable_routine_append_pointer_literal_parameter \
  jitter_mutable_routine_append_pointer_literal_parameter
#define pvm_mutable_routine_append_label_parameter \
  jitter_mutable_routine_append_label_parameter
#define pvm_mutable_routine_append_symbolic_label_parameter \
  jitter_mutable_routine_append_symbolic_label_parameter

/* Mutable routine construction API: safe API */
#define pvm_mutable_routine_append_label_safe  \
  jitter_mutable_routine_append_label_safe
#define pvm_mutable_routine_append_symbolic_label_safe  \
  jitter_mutable_routine_append_symbolic_label_safe
#define pvm_mutable_routine_append_instruction_name_safe  \
  jitter_mutable_routine_append_instruction_name_safe
#define pvm_mutable_routine_append_instruction_id_safe  \
  jitter_mutable_routine_append_instruction_id_safe
#define pvm_mutable_routine_append_meta_instruction_safe  \
  jitter_mutable_routine_append_meta_instruction_safe
#define pvm_mutable_routine_append_literal_parameter_safe  \
  jitter_mutable_routine_append_literal_parameter_safe
#define pvm_mutable_routine_append_signed_literal_parameter_safe  \
  jitter_mutable_routine_append_signed_literal_parameter_safe
#define pvm_mutable_routine_append_unsigned_literal_parameter_safe  \
  jitter_mutable_routine_append_unsigned_literal_parameter_safe
#define pvm_mutable_routine_append_pointer_literal_parameter_safe  \
  jitter_mutable_routine_append_pointer_literal_parameter_safe
#define pvm_mutable_routine_append_register_parameter_safe  \
  jitter_mutable_routine_append_register_parameter_safe
#define pvm_mutable_routine_append_symbolic_register_parameter_safe  \
  jitter_mutable_routine_append_symbolic_register_parameter_safe
#define pvm_mutable_routine_append_symbolic_label_parameter_safe  \
  jitter_mutable_routine_append_symbolic_label_parameter_safe
#define pvm_mutable_routine_append_label_parameter_safe  \
  jitter_mutable_routine_append_label_parameter_safe

/* Mutable routine destruction. */
#define pvm_destroy_executable_routine \
  jitter_destroy_executable_routine

/* Making executable routines from mutable routines. */
#define pvm_make_executable_routine \
  jitter_make_executable_routine

/* Unified routine option API. */
#define pvm_set_routine_option_slow_literals_only \
  jitter_set_mutable_routine_option_slow_literals_only
#define pvm_set_routine_option_slow_registers_only \
  jitter_set_mutable_routine_option_slow_registers_only
#define pvm_set_routine_option_slow_literals_and_registers_only \
  jitter_set_mutable_routine_option_slow_literals_and_registers_only
#define pvm_set_routine_option_add_final_exitvm \
  jitter_set_mutable_routine_option_add_final_exitvm
#define pvm_set_routine_option_optimization_rewriting \
  jitter_set_mutable_routine_option_optimization_rewriting

/* Printing and disassembling: unified API.  These do not follow the pattern of
   the rest: wrapped identifiers here are the names of C functions specific to
   the unified API */
#define pvm_routine_print \
  jitter_routine_print
#define pvm_routine_disassemble \
  jitter_routine_disassemble

/* Unified routine construction API. */
#define pvm_routine_append_instruction_name \
  jitter_mutable_routine_append_instruction_name
#define pvm_routine_append_meta_instruction \
  jitter_mutable_routine_append_meta_instruction
#define pvm_routine_append_label \
  jitter_mutable_routine_append_label
#define pvm_routine_append_symbolic_label \
  jitter_mutable_routine_append_symbolic_label
#define pvm_routine_append_register_parameter \
  jitter_mutable_routine_append_register_parameter
#define pvm_routine_append_literal_parameter \
  jitter_mutable_routine_append_literal_parameter
#define pvm_routine_append_signed_literal_parameter \
  jitter_mutable_routine_append_signed_literal_parameter
#define pvm_routine_append_unsigned_literal_parameter \
  jitter_mutable_routine_append_unsigned_literal_parameter
#define pvm_routine_append_pointer_literal_parameter \
  jitter_mutable_routine_append_pointer_literal_parameter
#define pvm_routine_append_label_parameter \
  jitter_mutable_routine_append_label_parameter
#define pvm_routine_append_symbolic_label_parameter \
  jitter_mutable_routine_append_symbolic_label_parameter

/* Mutable routine destruction. */
#define pvm_destroy_routine                                           \
  /* This does not follow the pattern of the rest: the wrapped identifier  \
     here is the name of a C function specific to the unified API. */      \
  jitter_destroy_routine

/* The unified API has no facility to explicitly make executable routines: their
   very existence is hidden.  For this reason some of the macros above, such
   pvm_make_executable_routine, have no unified counterpart here. */

/* Defects and replacements. */
void
pvm_defect_print_summary (jitter_print_context cx)
  __attribute__ ((nonnull (1)));
void
pvm_defect_print (jitter_print_context cx,
                       unsigned indentation_column_no)
  __attribute__ ((nonnull (1)));
void
pvm_defect_print_replacement_table (jitter_print_context cx,
                                         unsigned indentation_column_no)
  __attribute__ ((nonnull (1)));

/* Profiling.  Apart from pvm_state_profile, which returns a pointer to
   the profile within a pointed state structure, everything else here has the
   same API as the functionality in jitter/jitter-profile.h , without the VM
   pointer.
   Notice that this API does nothing useful onless at least one of the CPP
   macros PVM_PROFILE_COUNT or PVM_PROFILE_SAMPLE is defined. */
#define pvm_profile_runtime  \
  jitter_profile_runtime /* the struct name */
#define pvm_profile  \
  jitter_profile /* the struct name */
// FIXME: no: distinguish between struct jitter_profile_runtime and its user-friendly variant
struct jitter_profile_runtime *
pvm_state_profile_runtime (struct pvm_state *s)
  __attribute__ ((returns_nonnull, nonnull (1)));
struct pvm_profile_runtime*
pvm_profile_runtime_make (void)
  __attribute__ ((returns_nonnull));
void
pvm_profile_runtime_destroy (struct pvm_profile_runtime *p)
  __attribute__ ((nonnull (1)));
#define pvm_profile_destroy jitter_profile_destroy
void
pvm_profile_runtime_clear (struct pvm_profile_runtime *p)
  __attribute__ ((nonnull (1)));
void
pvm_profile_runtime_merge_from (struct pvm_profile_runtime *to,
                                     const struct pvm_profile_runtime *from)
  __attribute__ ((nonnull (1, 2)));
void
pvm_profile_runtime_merge_from_state (struct pvm_profile_runtime *to,
                                   const struct pvm_state *from_state)
  __attribute__ ((nonnull (1, 2)));
struct pvm_profile *
pvm_profile_unspecialized_from_runtime
   (const struct pvm_profile_runtime *p)
  __attribute__ ((returns_nonnull, nonnull (1)));
struct pvm_profile *
pvm_profile_specialized_from_runtime (const struct pvm_profile_runtime
                                           *p)
  __attribute__ ((returns_nonnull, nonnull (1)));
void
pvm_profile_runtime_print_unspecialized
   (jitter_print_context ct,
    const struct pvm_profile_runtime *p)
  __attribute__ ((nonnull (1, 2)));
void
pvm_profile_runtime_print_specialized (jitter_print_context ct,
                                            const struct pvm_profile_runtime
                                            *p)
  __attribute__ ((nonnull (1, 2)));




/* Register class types.
 * ************************************************************************** */

/* Return a pointer to a statically allocated register class descriptor, given
   the register class character, or NULL if the character does not represent a
   valid register class.

   A constant array indexed by a character would have been more efficient, but
   relying on character ordering is not portable, at least in theory.  A
   non-constant array could be initialized in a portable way, but that would
   probably not be worth the trouble. */
const struct jitter_register_class *
pvm_register_class_character_to_register_class (char c)
  __attribute__ ((pure));


/* A constant array of constant pointers to every existing register class
   descriptor, ordered by class id; each pointer within the array refers the
   only existing class descriptor for its class.  The number of elements is
   PVM_REGISTER_CLASS_NO , but that is not declared because the definition
   of PVM_REGISTER_CLASS_NO comes later in generated code.

   This is useful when the user code enumerates every existing register class,
   particularly for debugging. */
extern const struct jitter_register_class * const
pvm_regiter_classes [];




/* Array re-allocation.
 * ************************************************************************** */

/* Make the Array in the pointed state large enough to accommodate the given
   number of slow reigsters per class, adjusting the Array pointer as needed
   and recording information about the new size in the state; change nothing
   if the array is already large enough.  Return the new base.
   For example passing 3 as the value of slow_register_no would make
   place for three slow registers per register class: if the current VM had two
   classes 'r' and 'f' than the function would ensure that the Array can hold
   three 'r' and three 'f' slow registers, independently from the number
   of fast 'r' or 'f' registers.
   Any new elements allocated in the Array are left uninitialized, but its old
   content remains valid. */
char *
pvm_make_place_for_slow_registers (struct pvm_state *s,
                                        jitter_int slow_register_no_per_class)
  __attribute__ ((noinline));




/* **************************************************************************
 * Evrything following this point is for internal use only.
 * ************************************************************************** */




/* Replacement tables.
 * ************************************************************************** */

/* It is harmless to declare these unconditionally, even if they only used when
   defect replacement is available.  See jitter/jitter-defect.h . */

/* The worst-case replacement table.  This is a global constant array, having
   one element per specialised instruction. */
extern const jitter_uint
pvm_worst_case_replacement_table [];

/* An array whose first defective_specialized_instruction_no elements contain
   the specialized_instruction_ids of defective instructions; the remaining
   elements are set to -1.  This array is initialised by
   jitter_fill_replacement_table . */
extern jitter_int
pvm_defective_specialized_instructions [];

/* The actual replacement table, to be filled at initialization time. */
extern jitter_uint
pvm_replacement_table [];

/* An array of specialized instruction ids, holding the specialized instruction
   ids of any non-replacement specialized instruction which is "call-related",
   which is to say any of caller, callee or returning.  These are useful for
   defect replacements, since any defect in even just one of them requires
   replacing them all. */
extern const jitter_uint
pvm_call_related_specialized_instruction_ids [];

/* The size of pvm_call_related_specialized_instruction_ids in elements. */
extern const jitter_uint
pvm_call_related_specialized_instruction_id_no;

/* An array of Booleans in which each element is true iff the specialized
   instruction whose opcode is the index is call-related. */
extern const bool
pvm_specialized_instruction_call_relateds [];




/* Instruction rewriter.
 * ************************************************************************** */

/* Try to apply each rewrite rule in order and run the first one that matches,
   if any, on the pointed program.  When a rule fires the following ones are not
   checked but if a rule, after removing the last few instructions, adds another
   one, the addition will trigger another rewrite in its turn, and so on until
   no more rewriting is possible.  The rewriting process is inherently
   recursive.

   The implementation of this function is machine-generated, but the user can
   add her own code in the rewriter-c block, which ends up near the beginning of
   this function body, right after JITTTER_REWRITE_FUNCTION_PROLOG_ .  The
   formal argument seen from the body is named jitter_mutable_routine_p .

   Rationale: the argument is named differently in the body in order to keep
   the namespace conventions and, more importantly, to encourage the user to
   read this comment.

   The user must *not* append labels to the VM routines during rewriting: that
   would break it.  The user is responsible for destroying any instruction she
   removes, including their arguments.  The user can assume that
   jitter_rewritable_instruction_no is strictly greater than zero. */
void
pvm_rewrite (struct jitter_mutable_routine *jitter_mutable_routine_p);




/* Program points at run time in executable routines.
 * ************************************************************************** */

/* Provide a nice name for a program point type which looks VM-dependent. */
typedef jitter_program_point
pvm_program_point;

/* Again, provide a VM-dependent alias for an actually VM-independent macro. */
#define PVM_EXECUTABLE_ROUTINE_BEGINNING(_jitter_executable_routine_ptr)  \
  JITTER_EXECUTABLE_ROUTINE_BEGINNING(_jitter_executable_routine_ptr)




/* Program points at run time in routines: unified routine API.
 * ************************************************************************** */

/* Like PVM_EXECUTABLE_ROUTINE_BEGINNING for the unified routine API. */
#define PVM_ROUTINE_BEGINNING(_jitter_routine)                \
  JITTER_EXECUTABLE_ROUTINE_BEGINNING                              \
     (jitter_routine_make_executable_if_needed (_jitter_routine))



/* Executing code from an executable routine.
 * ************************************************************************** */

/* Make sure that the pointed state has enough slow registers to run the pointed
   executable routine; if that is not the case, allocate more slow registers. */
void
pvm_ensure_enough_slow_registers_for_executable_routine
   (const struct jitter_executable_routine *er, struct pvm_state *s)
  __attribute__ ((nonnull (1, 2)));

/* Run VM code starting from the given program point (which must belong to some
   executable routine), in the pointed VM state.
   Return the VM execution state at the end.

   Since no executable routine is given this cannot automatically guarantee that
   the slow registers in the pointed state are in sufficient number; it is the
   user's responsibility to check, if needed.

   This function is also usable with the unified routine API. */
enum pvm_exit_status
pvm_branch_to_program_point (pvm_program_point p,
                                  struct pvm_state *s)
  __attribute__ ((nonnull (1, 2)));

/* Run VM code starting from the beginning of the pointed executable routine,
   in the pointed VM state.
   Return the VM execution state at the end.
   This does ensure that the slow registers in the pointed state are in
   sufficient number, by calling pvm_ensure_enough_slow_registers_for .
   This function is slightly less efficient than
   pvm_branch_to_program_point , and pvm_branch_to_program_point
   should be preferred in contexts where C code repeatedly calls VM code. */
enum pvm_exit_status
pvm_execute_executable_routine (const struct jitter_executable_routine *er,
                                     struct pvm_state *s)
  __attribute__ ((nonnull (1, 2)));




/* Executing code: unified routine API.
 * ************************************************************************** */

/* Like pvm_ensure_enough_slow_registers_for_executable_routine , with the
   unified API. */
void
pvm_ensure_enough_slow_registers_for_routine
   (jitter_routine r, struct pvm_state *s)
  __attribute__ ((nonnull (1, 2)));

/* pvm_branch_to_program_point , declared above, is also usable with the
   unified routine API. */

/* Like pvm_execute_executable_routine, for a unified routine. */
enum pvm_exit_status
pvm_execute_routine (jitter_routine r,
                          struct pvm_state *s)
  __attribute__ ((nonnull (1, 2)));




/* VM exit status.
 * ************************************************************************** */

/* A value of this type is returned by a VM after execution, and the last
   returned value is also held in the VM state in order to make consistency
   checks. */
enum pvm_exit_status
  {
    /* This state has never been used for execution.  This is the initial value
       within the state, and is never returned after execution. */
    pvm_exit_status_never_executed = 0,

    /* The state is being used in execution right now; this is never returned by
       the executor.  It is an error (checked for) to execute code with a VM
       state containing this exit status, which shows that there has been a
       problem -- likely VM code was exited via longjmp, skipping the proper
       cleanup. */
    pvm_exit_status_being_executed = 1,

    /* Some VM code has been executed.  It is now possible to execute more code
       (including the same code again) in the same state. */
    pvm_exit_status_exited = 2,

    /* Code execution has been interrupted for debugging, but can be resumed. */
    pvm_exit_status_debug = 3,
  };




/* Low-level debugging features relying on assembly: data locations.
 * ************************************************************************** */

/* Dump human-readable information about data locations to the given print
   context.
   This is a trivial VM-dependent wrapper around jitter_dump_data_locations,
   which does not require a struct jitter_vm pointer as input. */
void
pvm_dump_data_locations (jitter_print_context output)
  __attribute__ ((nonnull (1)));




/* Sample profiling: internal API.
 * ************************************************************************** */

/* The functions in this sections are used internally by vm2.c, only when
   sample-profiling is enabled.  In fact these functions are not defined at all
   otherwise. */

/* Initialise global sampling-related structures. */
// FIXME: no: distinguish struct jitter_profile_runtime and struct jitter_profile
void
pvm_profile_sample_initialize (void);

/* Begin sampling. */
void
pvm_profile_sample_start (struct pvm_state *state)
  __attribute__ ((nonnull (1)));

/* Stop sampling. */
void
pvm_profile_sample_stop (void);




/* User macros to access VM state data structures (out of VM instructions).
 * ************************************************************************** */

/* Notice that these macros are to be used out of VM instruction code blocks:
   for use within instructions see the alternative definitions of
   _JITTER_STATE_RUNTIME_FIELD and _JITTER_STATE_BACKING_FIELD in
   jitter-executor.h .  The alternative definitions are *not* compatible: the
   macros defined here have one more argument, the VM state structure. */

/* Given a VM state pointer and a state runtime field name expand to an l-value
   referring the named field in the given VM state runtime.
   This macro is not usable within VM instruction code blocks: see the commmnt
   above. */
#define PVM_STATE_RUNTIME_FIELD(state_p /* see the comment above */,  \
                                     field_name)                           \
  ((state_p)->_pvm_Vv9tlAxnoJ_state_runtime.field_name)

/* Given a VM state pointer and a state backing field name expand to an l-value
   referring the named field in the given VM state backing.
   This macro is not usable within VM instruction code blocks: see the commmnt
   above. */
#define PVM_STATE_BACKING_FIELD(state_p /* see the comment above */,  \
                                     field_name)                           \
  ((state_p)->pvm_state_backing.field_name)




/* Machine-generated code.
 * ************************************************************************** */

/* What follows could be conceptually split into several generated header files,
   but having too many files would be inconvenient for the user to compile and
   link.  For this reason we generate a single header. */

/* User-specified code, early header part: beginning. */
#line 182 "../../libpoke/pvm.jitter"
#line 182 "../../libpoke/pvm.jitter"

#   include "pvm.h"
#   include "pvm-val.h"
#   include "ios.h"
#   include "pkt.h"
#   include "pk-utils.h"

    /* Exception handlers, that are installed in the "exceptionstack".

       EXCEPTION is the exception type, either one of the E_* values defined
       above, or any integer >= 256 for user-defined exceptions.

       MAIN_STACK_HEIGHT and RETURN_STACK_HEIGHT are the heights of
       the main and return stacks, to restore before transferring
       control to the exception handler.

       CODE is the program point where the exception handler starts.

       ENV is the run-time environment to restore before transferring
       control to the exception handler.  */

    struct pvm_exception_handler
    {
      int exception;
      jitter_stack_height main_stack_height;
      jitter_stack_height return_stack_height;
      pvm_program_point code;
      pvm_env env;
    };
  
/* User-specified code, early header part: end */

/* Configuration data for struct jitter_vm_configuration. */
#define PVM_VM_NAME JITTER_STRINGIFY(Pvm)
#define PVM_LOWER_CASE_PREFIX "pvm"
#define PVM_UPPER_CASE_PREFIX "PVM"
#define PVM_HASH_PREFIX "_pvm_Vv9tlAxnoJ"
#define PVM_DISPATCH_HUMAN_READABLE \
  JITTER_DISPATCH_NAME_STRING
#define PVM_MAX_FAST_REGISTER_NO_PER_CLASS -1
#define PVM_MAX_NONRESIDUAL_LITERAL_NO -1


/* For each register class define the register type, a unique index, and the
   number of fast registers.  Indices are useful for computing slow register
   offsets.  For each register class declare a global register class
   descriptor, convenient to use when generating unspecialized instructions
   from the C API.*/
typedef
pvm_val pvm_register_r;
#define PVM_REGISTER_r_CLASS_ID 0
#define PVM_REGISTER_r_FAST_REGISTER_NO 0
extern const struct jitter_register_class
pvm_register_class_r;

/* How many register classes we have. */
#define PVM_REGISTER_CLASS_NO  1

/* A union large enough to hold a register of any class, or a machine word. */
union pvm_any_register
{
  /* In any case the union must be at least as large as a machine word. */
  jitter_int jitter_unused_field;

  pvm_register_r r /* A r-class register */;
};

/* An enumeration of all pvm register classes. */
enum pvm_register_class_id
  {
    pvm_register_class_id_r = PVM_REGISTER_r_CLASS_ID,

    /* The number of register class ids, not valid as a class id itself. */
    pvm_register_class_id_no = PVM_REGISTER_CLASS_NO
  };

/* A macro expanding to a statement initialising a rank of slow
   registers.  The argument has type union pvm_any_register *
   and points to the first register in a rank. */
#define PVM_INITIALIZE_SLOW_REGISTER_RANK(rank) \
  do \
    { \
      union pvm_any_register *_jitter_rank __attribute__ ((unused)) \
        = (rank); \
      /* r-class registers need no initialisation. */ \
    } \
  while (false)


#ifndef PVM_STATE_H_
#define PVM_STATE_H_

//#include <jitter/jitter.h>

/* Early C code from the user for the state definition. */
/* End of the early C code from the user for the state definition. */

/* The VM state backing. */
struct pvm_state_backing
{
  /* The Array.  This initial pointer is kept in the backing, since it is
     not normally needed at run time.  By subtracting JITTER_ARRAY_BIAS from
     it (as a pointer to char) we get the base pointer. */
  char *jitter_array;

  /* How many slow registers per class the Array can hold, without being
     reallocated.  This number is always the same for evey class. */
  jitter_int jitter_slow_register_no_per_class;

  /* The initial VM program point.  This is not part of the runtime,
     in fact with no-threading dispatch there is not even a copy of this
     datum being kept up to date during execution, anywhere; this field
     serves to keep track of where execution should *continue* from at the
     next execution.  It will become more useful when debubbing is
     implemented. */
  pvm_program_point initial_program_point;

  /* The exit status. */
  enum pvm_exit_status exit_status;

  /* Stack backing data structures. */
  struct jitter_stack_backing jitter_stack_stack_backing;
  struct jitter_stack_backing jitter_stack_returnstack_backing;
  struct jitter_stack_backing jitter_stack_exceptionstack_backing;

  /* State backing fields added in C by the user. */
#line 1089 "../../libpoke/pvm.jitter"
#line 1089 "../../libpoke/pvm.jitter"

      enum pvm_exit_code exit_code;
      pvm_val result_value;
      pvm_val exit_exception_value;
      jitter_stack_height canary_stack;
      jitter_stack_height canary_returnstack;
      jitter_stack_height canary_exceptionstack;
      pvm vm;
  
  /* End of the state backing fields added in C by the user. */
};

/* The VM state runtime data structure, using memory from the VM state backing. */
struct pvm_state_runtime
{
  /* A link register for branch-and-link operations.  This field must *not*
     be accessed from user code, as it may not exist on all dispatches.
     It is only used internally for JITTER_PROCEDURE_PROLOG .

     With no-threading on arthitectures supporting procedures some
     hardware-dependent resource such as a designed register (general-
     purpose or not, reserved or not) or a stack location will be used
     instead of this, normally; however even with no-threading we need
     this for defect replacement: if any call-related instruction turns
     out to be defective they will all be replaced in order to keep their
     calling conventions compatible, and the replacement will use
     this. */
  union jitter_word _jitter_link;

  /* With recent GCC versions (as of Summer 2017) the *last* declared fields
     are the most likely to be allocated in registers; this is why VM registers
     are in reverse order here.  The first few fast registers will be the "fastest"
     ones, allocated in hardware registers; they may be followed by other fast
     fast allocated on the stack at known offsets, with intermediate performance; then
     come the slow registers.  In critical code the users should prefer a register with as
     small an index as possible for best performance. */

  /* Stack runtime data structures. */
  JITTER_STACK_TOS_DECLARATION(pvm_val, stack);
  JITTER_STACK_NTOS_DECLARATION(pvm_val, returnstack);
  JITTER_STACK_NTOS_DECLARATION(struct pvm_exception_handler, exceptionstack);

  /* State runtime fields added in C by the user. */
#line 1101 "../../libpoke/pvm.jitter"
#line 1101 "../../libpoke/pvm.jitter"

      pvm_env env;
      uint32_t push_hi;
      uint32_t endian;
      uint32_t nenc;
      uint32_t pretty_print;
      enum pvm_omode omode;
      int obase;
      int omaps;
      uint32_t odepth;
      uint32_t oindent;
      uint32_t oacutoff;
      uint32_t autoremap;
  
  /* End of the state runtime fields added in C by the user. */
};

/* A struct holding both the backing and the runtime part of the VM state. */
struct pvm_state
{
  /* Pointers to the previous and next VM state for this VM. */
  struct jitter_list_links links;

  /* Each state data structure contains its backing. */
  struct pvm_state_backing pvm_state_backing;

  /* Each state data structure contains its runtime data structures,
     which the compiler will try to keep in registers as far as
     possible.  Runtime structures are allowed to point to memory
     from the backing (which is particularly important for stacks),
     but the backing itself is not copied into registers at
     execution time.
     It is important for this identifier not to be directly used in
     user code, since at some points during execution the data stored
     struct field may be out of date.  In order to prevent this kind
     of mistakes this field has a hard-to-predict name. */
  struct pvm_state_runtime _pvm_Vv9tlAxnoJ_state_runtime;
};
#endif // #ifndef PVM_STATE_H_
#ifndef PVM_META_INSTRUCTIONS_H_
#define PVM_META_INSTRUCTIONS_H_

enum pvm_meta_instruction_id
  {
    pvm_meta_instruction_id_addi = 0,
    pvm_meta_instruction_id_addiu = 1,
    pvm_meta_instruction_id_addl = 2,
    pvm_meta_instruction_id_addlu = 3,
    pvm_meta_instruction_id_ains = 4,
    pvm_meta_instruction_id_and = 5,
    pvm_meta_instruction_id_aref = 6,
    pvm_meta_instruction_id_arefo = 7,
    pvm_meta_instruction_id_arem = 8,
    pvm_meta_instruction_id_aset = 9,
    pvm_meta_instruction_id_asettb = 10,
    pvm_meta_instruction_id_atr = 11,
    pvm_meta_instruction_id_ba = 12,
    pvm_meta_instruction_id_bandi = 13,
    pvm_meta_instruction_id_bandiu = 14,
    pvm_meta_instruction_id_bandl = 15,
    pvm_meta_instruction_id_bandlu = 16,
    pvm_meta_instruction_id_beghl = 17,
    pvm_meta_instruction_id_begsc = 18,
    pvm_meta_instruction_id_bn = 19,
    pvm_meta_instruction_id_bnn = 20,
    pvm_meta_instruction_id_bnoti = 21,
    pvm_meta_instruction_id_bnotiu = 22,
    pvm_meta_instruction_id_bnotl = 23,
    pvm_meta_instruction_id_bnotlu = 24,
    pvm_meta_instruction_id_bnzi = 25,
    pvm_meta_instruction_id_bnziu = 26,
    pvm_meta_instruction_id_bnzl = 27,
    pvm_meta_instruction_id_bnzlu = 28,
    pvm_meta_instruction_id_bori = 29,
    pvm_meta_instruction_id_boriu = 30,
    pvm_meta_instruction_id_borl = 31,
    pvm_meta_instruction_id_borlu = 32,
    pvm_meta_instruction_id_bsli = 33,
    pvm_meta_instruction_id_bsliu = 34,
    pvm_meta_instruction_id_bsll = 35,
    pvm_meta_instruction_id_bsllu = 36,
    pvm_meta_instruction_id_bsri = 37,
    pvm_meta_instruction_id_bsriu = 38,
    pvm_meta_instruction_id_bsrl = 39,
    pvm_meta_instruction_id_bsrlu = 40,
    pvm_meta_instruction_id_bxori = 41,
    pvm_meta_instruction_id_bxoriu = 42,
    pvm_meta_instruction_id_bxorl = 43,
    pvm_meta_instruction_id_bxorlu = 44,
    pvm_meta_instruction_id_bzi = 45,
    pvm_meta_instruction_id_bziu = 46,
    pvm_meta_instruction_id_bzl = 47,
    pvm_meta_instruction_id_bzlu = 48,
    pvm_meta_instruction_id_call = 49,
    pvm_meta_instruction_id_canary = 50,
    pvm_meta_instruction_id_close = 51,
    pvm_meta_instruction_id_ctos = 52,
    pvm_meta_instruction_id_disas = 53,
    pvm_meta_instruction_id_divi = 54,
    pvm_meta_instruction_id_diviu = 55,
    pvm_meta_instruction_id_divl = 56,
    pvm_meta_instruction_id_divlu = 57,
    pvm_meta_instruction_id_drop = 58,
    pvm_meta_instruction_id_drop2 = 59,
    pvm_meta_instruction_id_drop3 = 60,
    pvm_meta_instruction_id_drop4 = 61,
    pvm_meta_instruction_id_duc = 62,
    pvm_meta_instruction_id_dup = 63,
    pvm_meta_instruction_id_endhl = 64,
    pvm_meta_instruction_id_endsc = 65,
    pvm_meta_instruction_id_eqc = 66,
    pvm_meta_instruction_id_eqi = 67,
    pvm_meta_instruction_id_eqiu = 68,
    pvm_meta_instruction_id_eql = 69,
    pvm_meta_instruction_id_eqlu = 70,
    pvm_meta_instruction_id_eqs = 71,
    pvm_meta_instruction_id_exit = 72,
    pvm_meta_instruction_id_exitvm = 73,
    pvm_meta_instruction_id_flush = 74,
    pvm_meta_instruction_id_formatf32 = 75,
    pvm_meta_instruction_id_formatf64 = 76,
    pvm_meta_instruction_id_formati = 77,
    pvm_meta_instruction_id_formatiu = 78,
    pvm_meta_instruction_id_formatl = 79,
    pvm_meta_instruction_id_formatlu = 80,
    pvm_meta_instruction_id_fromr = 81,
    pvm_meta_instruction_id_gei = 82,
    pvm_meta_instruction_id_geiu = 83,
    pvm_meta_instruction_id_gel = 84,
    pvm_meta_instruction_id_gelu = 85,
    pvm_meta_instruction_id_ges = 86,
    pvm_meta_instruction_id_getenv = 87,
    pvm_meta_instruction_id_gti = 88,
    pvm_meta_instruction_id_gtiu = 89,
    pvm_meta_instruction_id_gtl = 90,
    pvm_meta_instruction_id_gtlu = 91,
    pvm_meta_instruction_id_gts = 92,
    pvm_meta_instruction_id_ioflags = 93,
    pvm_meta_instruction_id_iogetb = 94,
    pvm_meta_instruction_id_iohandler = 95,
    pvm_meta_instruction_id_ionum = 96,
    pvm_meta_instruction_id_ioref = 97,
    pvm_meta_instruction_id_iosetb = 98,
    pvm_meta_instruction_id_iosize = 99,
    pvm_meta_instruction_id_isa = 100,
    pvm_meta_instruction_id_isty = 101,
    pvm_meta_instruction_id_itoi = 102,
    pvm_meta_instruction_id_itoiu = 103,
    pvm_meta_instruction_id_itol = 104,
    pvm_meta_instruction_id_itolu = 105,
    pvm_meta_instruction_id_iutoi = 106,
    pvm_meta_instruction_id_iutoiu = 107,
    pvm_meta_instruction_id_iutol = 108,
    pvm_meta_instruction_id_iutolu = 109,
    pvm_meta_instruction_id_lei = 110,
    pvm_meta_instruction_id_leiu = 111,
    pvm_meta_instruction_id_lel = 112,
    pvm_meta_instruction_id_lelu = 113,
    pvm_meta_instruction_id_les = 114,
    pvm_meta_instruction_id_lti = 115,
    pvm_meta_instruction_id_ltiu = 116,
    pvm_meta_instruction_id_ltl = 117,
    pvm_meta_instruction_id_ltlu = 118,
    pvm_meta_instruction_id_ltoi = 119,
    pvm_meta_instruction_id_ltoiu = 120,
    pvm_meta_instruction_id_ltol = 121,
    pvm_meta_instruction_id_ltolu = 122,
    pvm_meta_instruction_id_lts = 123,
    pvm_meta_instruction_id_lutoi = 124,
    pvm_meta_instruction_id_lutoiu = 125,
    pvm_meta_instruction_id_lutol = 126,
    pvm_meta_instruction_id_lutolu = 127,
    pvm_meta_instruction_id_map = 128,
    pvm_meta_instruction_id_mgetios = 129,
    pvm_meta_instruction_id_mgetm = 130,
    pvm_meta_instruction_id_mgeto = 131,
    pvm_meta_instruction_id_mgets = 132,
    pvm_meta_instruction_id_mgetsel = 133,
    pvm_meta_instruction_id_mgetsiz = 134,
    pvm_meta_instruction_id_mgetw = 135,
    pvm_meta_instruction_id_mka = 136,
    pvm_meta_instruction_id_mko = 137,
    pvm_meta_instruction_id_mksct = 138,
    pvm_meta_instruction_id_mktya = 139,
    pvm_meta_instruction_id_mktyc = 140,
    pvm_meta_instruction_id_mktyi = 141,
    pvm_meta_instruction_id_mktyo = 142,
    pvm_meta_instruction_id_mktys = 143,
    pvm_meta_instruction_id_mktysct = 144,
    pvm_meta_instruction_id_mktyv = 145,
    pvm_meta_instruction_id_mm = 146,
    pvm_meta_instruction_id_modi = 147,
    pvm_meta_instruction_id_modiu = 148,
    pvm_meta_instruction_id_modl = 149,
    pvm_meta_instruction_id_modlu = 150,
    pvm_meta_instruction_id_msetios = 151,
    pvm_meta_instruction_id_msetm = 152,
    pvm_meta_instruction_id_mseto = 153,
    pvm_meta_instruction_id_msets = 154,
    pvm_meta_instruction_id_msetsel = 155,
    pvm_meta_instruction_id_msetsiz = 156,
    pvm_meta_instruction_id_msetw = 157,
    pvm_meta_instruction_id_muli = 158,
    pvm_meta_instruction_id_muliu = 159,
    pvm_meta_instruction_id_mull = 160,
    pvm_meta_instruction_id_mullu = 161,
    pvm_meta_instruction_id_muls = 162,
    pvm_meta_instruction_id_nec = 163,
    pvm_meta_instruction_id_negi = 164,
    pvm_meta_instruction_id_negiu = 165,
    pvm_meta_instruction_id_negl = 166,
    pvm_meta_instruction_id_neglu = 167,
    pvm_meta_instruction_id_nei = 168,
    pvm_meta_instruction_id_neiu = 169,
    pvm_meta_instruction_id_nel = 170,
    pvm_meta_instruction_id_nelu = 171,
    pvm_meta_instruction_id_nes = 172,
    pvm_meta_instruction_id_nip = 173,
    pvm_meta_instruction_id_nip2 = 174,
    pvm_meta_instruction_id_nip3 = 175,
    pvm_meta_instruction_id_nn = 176,
    pvm_meta_instruction_id_nnn = 177,
    pvm_meta_instruction_id_nop = 178,
    pvm_meta_instruction_id_not = 179,
    pvm_meta_instruction_id_note = 180,
    pvm_meta_instruction_id_nrot = 181,
    pvm_meta_instruction_id_ogetbt = 182,
    pvm_meta_instruction_id_ogetm = 183,
    pvm_meta_instruction_id_ogetu = 184,
    pvm_meta_instruction_id_oover = 185,
    pvm_meta_instruction_id_open = 186,
    pvm_meta_instruction_id_or = 187,
    pvm_meta_instruction_id_osetm = 188,
    pvm_meta_instruction_id_over = 189,
    pvm_meta_instruction_id_pec = 190,
    pvm_meta_instruction_id_peekdi = 191,
    pvm_meta_instruction_id_peekdiu = 192,
    pvm_meta_instruction_id_peekdl = 193,
    pvm_meta_instruction_id_peekdlu = 194,
    pvm_meta_instruction_id_peeki = 195,
    pvm_meta_instruction_id_peekiu = 196,
    pvm_meta_instruction_id_peekl = 197,
    pvm_meta_instruction_id_peeklu = 198,
    pvm_meta_instruction_id_peeks = 199,
    pvm_meta_instruction_id_pokedi = 200,
    pvm_meta_instruction_id_pokediu = 201,
    pvm_meta_instruction_id_pokedl = 202,
    pvm_meta_instruction_id_pokedlu = 203,
    pvm_meta_instruction_id_pokei = 204,
    pvm_meta_instruction_id_pokeiu = 205,
    pvm_meta_instruction_id_pokel = 206,
    pvm_meta_instruction_id_pokelu = 207,
    pvm_meta_instruction_id_pokes = 208,
    pvm_meta_instruction_id_poparem = 209,
    pvm_meta_instruction_id_pope = 210,
    pvm_meta_instruction_id_popend = 211,
    pvm_meta_instruction_id_popexite = 212,
    pvm_meta_instruction_id_popf = 213,
    pvm_meta_instruction_id_popios = 214,
    pvm_meta_instruction_id_popoac = 215,
    pvm_meta_instruction_id_popob = 216,
    pvm_meta_instruction_id_popobc = 217,
    pvm_meta_instruction_id_popoc = 218,
    pvm_meta_instruction_id_popod = 219,
    pvm_meta_instruction_id_popoi = 220,
    pvm_meta_instruction_id_popom = 221,
    pvm_meta_instruction_id_popoo = 222,
    pvm_meta_instruction_id_popopp = 223,
    pvm_meta_instruction_id_popr = 224,
    pvm_meta_instruction_id_popvar = 225,
    pvm_meta_instruction_id_powi = 226,
    pvm_meta_instruction_id_powiu = 227,
    pvm_meta_instruction_id_powl = 228,
    pvm_meta_instruction_id_powlu = 229,
    pvm_meta_instruction_id_printi = 230,
    pvm_meta_instruction_id_printiu = 231,
    pvm_meta_instruction_id_printl = 232,
    pvm_meta_instruction_id_printlu = 233,
    pvm_meta_instruction_id_prints = 234,
    pvm_meta_instruction_id_prolog = 235,
    pvm_meta_instruction_id_push = 236,
    pvm_meta_instruction_id_push32 = 237,
    pvm_meta_instruction_id_pusharem = 238,
    pvm_meta_instruction_id_pushe = 239,
    pvm_meta_instruction_id_pushend = 240,
    pvm_meta_instruction_id_pushf = 241,
    pvm_meta_instruction_id_pushhi = 242,
    pvm_meta_instruction_id_pushios = 243,
    pvm_meta_instruction_id_pushlo = 244,
    pvm_meta_instruction_id_pushoac = 245,
    pvm_meta_instruction_id_pushob = 246,
    pvm_meta_instruction_id_pushobc = 247,
    pvm_meta_instruction_id_pushoc = 248,
    pvm_meta_instruction_id_pushod = 249,
    pvm_meta_instruction_id_pushoi = 250,
    pvm_meta_instruction_id_pushom = 251,
    pvm_meta_instruction_id_pushoo = 252,
    pvm_meta_instruction_id_pushopp = 253,
    pvm_meta_instruction_id_pushr = 254,
    pvm_meta_instruction_id_pushtopvar = 255,
    pvm_meta_instruction_id_pushvar = 256,
    pvm_meta_instruction_id_quake = 257,
    pvm_meta_instruction_id_raise = 258,
    pvm_meta_instruction_id_rand = 259,
    pvm_meta_instruction_id_regvar = 260,
    pvm_meta_instruction_id_reloc = 261,
    pvm_meta_instruction_id_restorer = 262,
    pvm_meta_instruction_id_return = 263,
    pvm_meta_instruction_id_revn = 264,
    pvm_meta_instruction_id_rot = 265,
    pvm_meta_instruction_id_saver = 266,
    pvm_meta_instruction_id_sconc = 267,
    pvm_meta_instruction_id_sel = 268,
    pvm_meta_instruction_id_setr = 269,
    pvm_meta_instruction_id_siz = 270,
    pvm_meta_instruction_id_sleep = 271,
    pvm_meta_instruction_id_smodi = 272,
    pvm_meta_instruction_id_spropc = 273,
    pvm_meta_instruction_id_sproph = 274,
    pvm_meta_instruction_id_sprops = 275,
    pvm_meta_instruction_id_sref = 276,
    pvm_meta_instruction_id_srefi = 277,
    pvm_meta_instruction_id_srefia = 278,
    pvm_meta_instruction_id_srefin = 279,
    pvm_meta_instruction_id_srefio = 280,
    pvm_meta_instruction_id_srefmnt = 281,
    pvm_meta_instruction_id_srefnt = 282,
    pvm_meta_instruction_id_srefo = 283,
    pvm_meta_instruction_id_sset = 284,
    pvm_meta_instruction_id_sseti = 285,
    pvm_meta_instruction_id_strace = 286,
    pvm_meta_instruction_id_strref = 287,
    pvm_meta_instruction_id_strset = 288,
    pvm_meta_instruction_id_subi = 289,
    pvm_meta_instruction_id_subiu = 290,
    pvm_meta_instruction_id_subl = 291,
    pvm_meta_instruction_id_sublu = 292,
    pvm_meta_instruction_id_substr = 293,
    pvm_meta_instruction_id_swap = 294,
    pvm_meta_instruction_id_swapgti = 295,
    pvm_meta_instruction_id_swapgtiu = 296,
    pvm_meta_instruction_id_swapgtl = 297,
    pvm_meta_instruction_id_swapgtlu = 298,
    pvm_meta_instruction_id_sync = 299,
    pvm_meta_instruction_id_time = 300,
    pvm_meta_instruction_id_tor = 301,
    pvm_meta_instruction_id_tuck = 302,
    pvm_meta_instruction_id_tyagetb = 303,
    pvm_meta_instruction_id_tyagett = 304,
    pvm_meta_instruction_id_tyigetsg = 305,
    pvm_meta_instruction_id_tyigetsz = 306,
    pvm_meta_instruction_id_tyisa = 307,
    pvm_meta_instruction_id_tyisc = 308,
    pvm_meta_instruction_id_tyisi = 309,
    pvm_meta_instruction_id_tyisiu = 310,
    pvm_meta_instruction_id_tyisl = 311,
    pvm_meta_instruction_id_tyislu = 312,
    pvm_meta_instruction_id_tyiso = 313,
    pvm_meta_instruction_id_tyiss = 314,
    pvm_meta_instruction_id_tyissct = 315,
    pvm_meta_instruction_id_tyisv = 316,
    pvm_meta_instruction_id_tyogetm = 317,
    pvm_meta_instruction_id_tyogetu = 318,
    pvm_meta_instruction_id_typof = 319,
    pvm_meta_instruction_id_tysctgetfn = 320,
    pvm_meta_instruction_id_tysctgetft = 321,
    pvm_meta_instruction_id_tysctgetn = 322,
    pvm_meta_instruction_id_tysctgetnf = 323,
    pvm_meta_instruction_id_unmap = 324,
    pvm_meta_instruction_id_unreachable = 325,
    pvm_meta_instruction_id_ureloc = 326,
    pvm_meta_instruction_id_vmdisp = 327,
    pvm_meta_instruction_id_write = 328
  };

#define PVM_META_INSTRUCTION_NO 329

/* The longest meta-instruction name length, not mangled, without
   counting the final '\0' character. */
#define PVM_MAX_META_INSTRUCTION_NAME_LENGTH 11

#endif // #ifndef PVM_META_INSTRUCTIONS_H_
#ifndef PVM_SPECIALIZED_INSTRUCTIONS_H_
#define PVM_SPECIALIZED_INSTRUCTIONS_H_

enum pvm_specialized_instruction_opcode
  {
    pvm_specialized_instruction_opcode__eINVALID = 0,
    pvm_specialized_instruction_opcode__eBEGINBASICBLOCK = 1,
    pvm_specialized_instruction_opcode__eEXITVM = 2,
    pvm_specialized_instruction_opcode__eDATALOCATIONS = 3,
    pvm_specialized_instruction_opcode__eNOP = 4,
    pvm_specialized_instruction_opcode__eUNREACHABLE0 = 5,
    pvm_specialized_instruction_opcode__eUNREACHABLE1 = 6,
    pvm_specialized_instruction_opcode__ePRETENDTOJUMPANYWHERE = 7,
    pvm_specialized_instruction_opcode_addi = 8,
    pvm_specialized_instruction_opcode_addiu = 9,
    pvm_specialized_instruction_opcode_addl = 10,
    pvm_specialized_instruction_opcode_addlu = 11,
    pvm_specialized_instruction_opcode_ains = 12,
    pvm_specialized_instruction_opcode_and = 13,
    pvm_specialized_instruction_opcode_aref = 14,
    pvm_specialized_instruction_opcode_arefo = 15,
    pvm_specialized_instruction_opcode_arem = 16,
    pvm_specialized_instruction_opcode_aset = 17,
    pvm_specialized_instruction_opcode_asettb = 18,
    pvm_specialized_instruction_opcode_atr = 19,
    pvm_specialized_instruction_opcode_ba__fR = 20,
    pvm_specialized_instruction_opcode_bandi = 21,
    pvm_specialized_instruction_opcode_bandiu = 22,
    pvm_specialized_instruction_opcode_bandl = 23,
    pvm_specialized_instruction_opcode_bandlu = 24,
    pvm_specialized_instruction_opcode_beghl__retR = 25,
    pvm_specialized_instruction_opcode_begsc__retR = 26,
    pvm_specialized_instruction_opcode_bn__fR = 27,
    pvm_specialized_instruction_opcode_bnn__fR = 28,
    pvm_specialized_instruction_opcode_bnoti = 29,
    pvm_specialized_instruction_opcode_bnotiu = 30,
    pvm_specialized_instruction_opcode_bnotl = 31,
    pvm_specialized_instruction_opcode_bnotlu = 32,
    pvm_specialized_instruction_opcode_bnzi__fR = 33,
    pvm_specialized_instruction_opcode_bnziu__fR = 34,
    pvm_specialized_instruction_opcode_bnzl__fR = 35,
    pvm_specialized_instruction_opcode_bnzlu__fR = 36,
    pvm_specialized_instruction_opcode_bori = 37,
    pvm_specialized_instruction_opcode_boriu = 38,
    pvm_specialized_instruction_opcode_borl = 39,
    pvm_specialized_instruction_opcode_borlu = 40,
    pvm_specialized_instruction_opcode_bsli = 41,
    pvm_specialized_instruction_opcode_bsliu = 42,
    pvm_specialized_instruction_opcode_bsll = 43,
    pvm_specialized_instruction_opcode_bsllu = 44,
    pvm_specialized_instruction_opcode_bsri = 45,
    pvm_specialized_instruction_opcode_bsriu = 46,
    pvm_specialized_instruction_opcode_bsrl = 47,
    pvm_specialized_instruction_opcode_bsrlu = 48,
    pvm_specialized_instruction_opcode_bxori = 49,
    pvm_specialized_instruction_opcode_bxoriu = 50,
    pvm_specialized_instruction_opcode_bxorl = 51,
    pvm_specialized_instruction_opcode_bxorlu = 52,
    pvm_specialized_instruction_opcode_bzi__fR = 53,
    pvm_specialized_instruction_opcode_bziu__fR = 54,
    pvm_specialized_instruction_opcode_bzl__fR = 55,
    pvm_specialized_instruction_opcode_bzlu__fR = 56,
    pvm_specialized_instruction_opcode_call__retR = 57,
    pvm_specialized_instruction_opcode_canary = 58,
    pvm_specialized_instruction_opcode_close = 59,
    pvm_specialized_instruction_opcode_ctos = 60,
    pvm_specialized_instruction_opcode_disas__retR = 61,
    pvm_specialized_instruction_opcode_divi__retR = 62,
    pvm_specialized_instruction_opcode_diviu__retR = 63,
    pvm_specialized_instruction_opcode_divl__retR = 64,
    pvm_specialized_instruction_opcode_divlu__retR = 65,
    pvm_specialized_instruction_opcode_drop = 66,
    pvm_specialized_instruction_opcode_drop2 = 67,
    pvm_specialized_instruction_opcode_drop3 = 68,
    pvm_specialized_instruction_opcode_drop4 = 69,
    pvm_specialized_instruction_opcode_duc = 70,
    pvm_specialized_instruction_opcode_dup = 71,
    pvm_specialized_instruction_opcode_endhl__retR = 72,
    pvm_specialized_instruction_opcode_endsc__retR = 73,
    pvm_specialized_instruction_opcode_eqc = 74,
    pvm_specialized_instruction_opcode_eqi = 75,
    pvm_specialized_instruction_opcode_eqiu = 76,
    pvm_specialized_instruction_opcode_eql = 77,
    pvm_specialized_instruction_opcode_eqlu = 78,
    pvm_specialized_instruction_opcode_eqs = 79,
    pvm_specialized_instruction_opcode_exit = 80,
    pvm_specialized_instruction_opcode_exitvm = 81,
    pvm_specialized_instruction_opcode_flush = 82,
    pvm_specialized_instruction_opcode_formatf32__n0 = 83,
    pvm_specialized_instruction_opcode_formatf32__n1 = 84,
    pvm_specialized_instruction_opcode_formatf32__n2 = 85,
    pvm_specialized_instruction_opcode_formatf32__nR = 86,
    pvm_specialized_instruction_opcode_formatf64__n0 = 87,
    pvm_specialized_instruction_opcode_formatf64__n1 = 88,
    pvm_specialized_instruction_opcode_formatf64__n2 = 89,
    pvm_specialized_instruction_opcode_formatf64__nR = 90,
    pvm_specialized_instruction_opcode_formati__nR__retR = 91,
    pvm_specialized_instruction_opcode_formatiu__nR__retR = 92,
    pvm_specialized_instruction_opcode_formatl__nR__retR = 93,
    pvm_specialized_instruction_opcode_formatlu__nR__retR = 94,
    pvm_specialized_instruction_opcode_fromr = 95,
    pvm_specialized_instruction_opcode_gei = 96,
    pvm_specialized_instruction_opcode_geiu = 97,
    pvm_specialized_instruction_opcode_gel = 98,
    pvm_specialized_instruction_opcode_gelu = 99,
    pvm_specialized_instruction_opcode_ges = 100,
    pvm_specialized_instruction_opcode_getenv = 101,
    pvm_specialized_instruction_opcode_gti = 102,
    pvm_specialized_instruction_opcode_gtiu = 103,
    pvm_specialized_instruction_opcode_gtl = 104,
    pvm_specialized_instruction_opcode_gtlu = 105,
    pvm_specialized_instruction_opcode_gts = 106,
    pvm_specialized_instruction_opcode_ioflags = 107,
    pvm_specialized_instruction_opcode_iogetb__retR = 108,
    pvm_specialized_instruction_opcode_iohandler = 109,
    pvm_specialized_instruction_opcode_ionum = 110,
    pvm_specialized_instruction_opcode_ioref = 111,
    pvm_specialized_instruction_opcode_iosetb = 112,
    pvm_specialized_instruction_opcode_iosize = 113,
    pvm_specialized_instruction_opcode_isa = 114,
    pvm_specialized_instruction_opcode_isty = 115,
    pvm_specialized_instruction_opcode_itoi__nR = 116,
    pvm_specialized_instruction_opcode_itoiu__nR = 117,
    pvm_specialized_instruction_opcode_itol__nR = 118,
    pvm_specialized_instruction_opcode_itolu__nR = 119,
    pvm_specialized_instruction_opcode_iutoi__nR = 120,
    pvm_specialized_instruction_opcode_iutoiu__nR = 121,
    pvm_specialized_instruction_opcode_iutol__nR = 122,
    pvm_specialized_instruction_opcode_iutolu__nR = 123,
    pvm_specialized_instruction_opcode_lei = 124,
    pvm_specialized_instruction_opcode_leiu = 125,
    pvm_specialized_instruction_opcode_lel = 126,
    pvm_specialized_instruction_opcode_lelu = 127,
    pvm_specialized_instruction_opcode_les = 128,
    pvm_specialized_instruction_opcode_lti = 129,
    pvm_specialized_instruction_opcode_ltiu = 130,
    pvm_specialized_instruction_opcode_ltl = 131,
    pvm_specialized_instruction_opcode_ltlu = 132,
    pvm_specialized_instruction_opcode_ltoi__nR = 133,
    pvm_specialized_instruction_opcode_ltoiu__nR = 134,
    pvm_specialized_instruction_opcode_ltol__nR = 135,
    pvm_specialized_instruction_opcode_ltolu__nR = 136,
    pvm_specialized_instruction_opcode_lts = 137,
    pvm_specialized_instruction_opcode_lutoi__nR = 138,
    pvm_specialized_instruction_opcode_lutoiu__nR = 139,
    pvm_specialized_instruction_opcode_lutol__nR = 140,
    pvm_specialized_instruction_opcode_lutolu__nR = 141,
    pvm_specialized_instruction_opcode_map = 142,
    pvm_specialized_instruction_opcode_mgetios = 143,
    pvm_specialized_instruction_opcode_mgetm = 144,
    pvm_specialized_instruction_opcode_mgeto = 145,
    pvm_specialized_instruction_opcode_mgets = 146,
    pvm_specialized_instruction_opcode_mgetsel = 147,
    pvm_specialized_instruction_opcode_mgetsiz = 148,
    pvm_specialized_instruction_opcode_mgetw = 149,
    pvm_specialized_instruction_opcode_mka = 150,
    pvm_specialized_instruction_opcode_mko = 151,
    pvm_specialized_instruction_opcode_mksct = 152,
    pvm_specialized_instruction_opcode_mktya = 153,
    pvm_specialized_instruction_opcode_mktyc = 154,
    pvm_specialized_instruction_opcode_mktyi = 155,
    pvm_specialized_instruction_opcode_mktyo = 156,
    pvm_specialized_instruction_opcode_mktys = 157,
    pvm_specialized_instruction_opcode_mktysct = 158,
    pvm_specialized_instruction_opcode_mktyv = 159,
    pvm_specialized_instruction_opcode_mm = 160,
    pvm_specialized_instruction_opcode_modi__retR = 161,
    pvm_specialized_instruction_opcode_modiu__retR = 162,
    pvm_specialized_instruction_opcode_modl__retR = 163,
    pvm_specialized_instruction_opcode_modlu__retR = 164,
    pvm_specialized_instruction_opcode_msetios = 165,
    pvm_specialized_instruction_opcode_msetm = 166,
    pvm_specialized_instruction_opcode_mseto = 167,
    pvm_specialized_instruction_opcode_msets = 168,
    pvm_specialized_instruction_opcode_msetsel = 169,
    pvm_specialized_instruction_opcode_msetsiz = 170,
    pvm_specialized_instruction_opcode_msetw = 171,
    pvm_specialized_instruction_opcode_muli = 172,
    pvm_specialized_instruction_opcode_muliu = 173,
    pvm_specialized_instruction_opcode_mull = 174,
    pvm_specialized_instruction_opcode_mullu = 175,
    pvm_specialized_instruction_opcode_muls = 176,
    pvm_specialized_instruction_opcode_nec = 177,
    pvm_specialized_instruction_opcode_negi = 178,
    pvm_specialized_instruction_opcode_negiu = 179,
    pvm_specialized_instruction_opcode_negl = 180,
    pvm_specialized_instruction_opcode_neglu = 181,
    pvm_specialized_instruction_opcode_nei = 182,
    pvm_specialized_instruction_opcode_neiu = 183,
    pvm_specialized_instruction_opcode_nel = 184,
    pvm_specialized_instruction_opcode_nelu = 185,
    pvm_specialized_instruction_opcode_nes = 186,
    pvm_specialized_instruction_opcode_nip = 187,
    pvm_specialized_instruction_opcode_nip2 = 188,
    pvm_specialized_instruction_opcode_nip3 = 189,
    pvm_specialized_instruction_opcode_nn = 190,
    pvm_specialized_instruction_opcode_nnn = 191,
    pvm_specialized_instruction_opcode_nop = 192,
    pvm_specialized_instruction_opcode_not = 193,
    pvm_specialized_instruction_opcode_note__nR = 194,
    pvm_specialized_instruction_opcode_nrot = 195,
    pvm_specialized_instruction_opcode_ogetbt = 196,
    pvm_specialized_instruction_opcode_ogetm = 197,
    pvm_specialized_instruction_opcode_ogetu = 198,
    pvm_specialized_instruction_opcode_oover = 199,
    pvm_specialized_instruction_opcode_open = 200,
    pvm_specialized_instruction_opcode_or = 201,
    pvm_specialized_instruction_opcode_osetm = 202,
    pvm_specialized_instruction_opcode_over = 203,
    pvm_specialized_instruction_opcode_pec = 204,
    pvm_specialized_instruction_opcode_peekdi__nR = 205,
    pvm_specialized_instruction_opcode_peekdiu__nR = 206,
    pvm_specialized_instruction_opcode_peekdl__nR = 207,
    pvm_specialized_instruction_opcode_peekdlu__nR = 208,
    pvm_specialized_instruction_opcode_peeki__nR__nR__nR = 209,
    pvm_specialized_instruction_opcode_peekiu__nR__nR = 210,
    pvm_specialized_instruction_opcode_peekl__nR__nR__nR = 211,
    pvm_specialized_instruction_opcode_peeklu__nR__nR = 212,
    pvm_specialized_instruction_opcode_peeks = 213,
    pvm_specialized_instruction_opcode_pokedi__nR = 214,
    pvm_specialized_instruction_opcode_pokediu__nR = 215,
    pvm_specialized_instruction_opcode_pokedl__nR = 216,
    pvm_specialized_instruction_opcode_pokedlu__nR = 217,
    pvm_specialized_instruction_opcode_pokei__nR__nR__nR = 218,
    pvm_specialized_instruction_opcode_pokeiu__nR__nR = 219,
    pvm_specialized_instruction_opcode_pokel__nR__nR__nR = 220,
    pvm_specialized_instruction_opcode_pokelu__nR__nR = 221,
    pvm_specialized_instruction_opcode_pokes = 222,
    pvm_specialized_instruction_opcode_poparem = 223,
    pvm_specialized_instruction_opcode_pope = 224,
    pvm_specialized_instruction_opcode_popend = 225,
    pvm_specialized_instruction_opcode_popexite = 226,
    pvm_specialized_instruction_opcode_popf__nR = 227,
    pvm_specialized_instruction_opcode_popios = 228,
    pvm_specialized_instruction_opcode_popoac = 229,
    pvm_specialized_instruction_opcode_popob = 230,
    pvm_specialized_instruction_opcode_popobc = 231,
    pvm_specialized_instruction_opcode_popoc = 232,
    pvm_specialized_instruction_opcode_popod = 233,
    pvm_specialized_instruction_opcode_popoi = 234,
    pvm_specialized_instruction_opcode_popom = 235,
    pvm_specialized_instruction_opcode_popoo = 236,
    pvm_specialized_instruction_opcode_popopp = 237,
    pvm_specialized_instruction_opcode_popr___rrR = 238,
    pvm_specialized_instruction_opcode_popvar__nR__nR = 239,
    pvm_specialized_instruction_opcode_powi = 240,
    pvm_specialized_instruction_opcode_powiu = 241,
    pvm_specialized_instruction_opcode_powl = 242,
    pvm_specialized_instruction_opcode_powlu = 243,
    pvm_specialized_instruction_opcode_printi__nR__retR = 244,
    pvm_specialized_instruction_opcode_printiu__nR__retR = 245,
    pvm_specialized_instruction_opcode_printl__nR__retR = 246,
    pvm_specialized_instruction_opcode_printlu__nR__retR = 247,
    pvm_specialized_instruction_opcode_prints__retR = 248,
    pvm_specialized_instruction_opcode_prolog = 249,
    pvm_specialized_instruction_opcode_push__nR = 250,
    pvm_specialized_instruction_opcode_push__lR = 251,
    pvm_specialized_instruction_opcode_push32__nR = 252,
    pvm_specialized_instruction_opcode_push32__lR = 253,
    pvm_specialized_instruction_opcode_pusharem = 254,
    pvm_specialized_instruction_opcode_pushe__lR = 255,
    pvm_specialized_instruction_opcode_pushend = 256,
    pvm_specialized_instruction_opcode_pushf__nR = 257,
    pvm_specialized_instruction_opcode_pushhi__nR = 258,
    pvm_specialized_instruction_opcode_pushhi__lR = 259,
    pvm_specialized_instruction_opcode_pushios = 260,
    pvm_specialized_instruction_opcode_pushlo__nR = 261,
    pvm_specialized_instruction_opcode_pushlo__lR = 262,
    pvm_specialized_instruction_opcode_pushoac = 263,
    pvm_specialized_instruction_opcode_pushob = 264,
    pvm_specialized_instruction_opcode_pushobc = 265,
    pvm_specialized_instruction_opcode_pushoc = 266,
    pvm_specialized_instruction_opcode_pushod = 267,
    pvm_specialized_instruction_opcode_pushoi = 268,
    pvm_specialized_instruction_opcode_pushom = 269,
    pvm_specialized_instruction_opcode_pushoo = 270,
    pvm_specialized_instruction_opcode_pushopp = 271,
    pvm_specialized_instruction_opcode_pushr___rrR = 272,
    pvm_specialized_instruction_opcode_pushtopvar__nR = 273,
    pvm_specialized_instruction_opcode_pushvar__n0__n0 = 274,
    pvm_specialized_instruction_opcode_pushvar__n0__n1 = 275,
    pvm_specialized_instruction_opcode_pushvar__n0__n2 = 276,
    pvm_specialized_instruction_opcode_pushvar__n0__n3 = 277,
    pvm_specialized_instruction_opcode_pushvar__n0__n4 = 278,
    pvm_specialized_instruction_opcode_pushvar__n0__n5 = 279,
    pvm_specialized_instruction_opcode_pushvar__n0__nR = 280,
    pvm_specialized_instruction_opcode_pushvar__nR__n0 = 281,
    pvm_specialized_instruction_opcode_pushvar__nR__n1 = 282,
    pvm_specialized_instruction_opcode_pushvar__nR__n2 = 283,
    pvm_specialized_instruction_opcode_pushvar__nR__n3 = 284,
    pvm_specialized_instruction_opcode_pushvar__nR__n4 = 285,
    pvm_specialized_instruction_opcode_pushvar__nR__n5 = 286,
    pvm_specialized_instruction_opcode_pushvar__nR__nR = 287,
    pvm_specialized_instruction_opcode_quake = 288,
    pvm_specialized_instruction_opcode_raise = 289,
    pvm_specialized_instruction_opcode_rand = 290,
    pvm_specialized_instruction_opcode_regvar = 291,
    pvm_specialized_instruction_opcode_reloc = 292,
    pvm_specialized_instruction_opcode_restorer___rrR = 293,
    pvm_specialized_instruction_opcode_return = 294,
    pvm_specialized_instruction_opcode_revn__n3 = 295,
    pvm_specialized_instruction_opcode_revn__n4 = 296,
    pvm_specialized_instruction_opcode_revn__nR = 297,
    pvm_specialized_instruction_opcode_rot = 298,
    pvm_specialized_instruction_opcode_saver___rrR = 299,
    pvm_specialized_instruction_opcode_sconc = 300,
    pvm_specialized_instruction_opcode_sel = 301,
    pvm_specialized_instruction_opcode_setr___rrR = 302,
    pvm_specialized_instruction_opcode_siz = 303,
    pvm_specialized_instruction_opcode_sleep = 304,
    pvm_specialized_instruction_opcode_smodi = 305,
    pvm_specialized_instruction_opcode_spropc = 306,
    pvm_specialized_instruction_opcode_sproph = 307,
    pvm_specialized_instruction_opcode_sprops = 308,
    pvm_specialized_instruction_opcode_sref = 309,
    pvm_specialized_instruction_opcode_srefi = 310,
    pvm_specialized_instruction_opcode_srefia = 311,
    pvm_specialized_instruction_opcode_srefin = 312,
    pvm_specialized_instruction_opcode_srefio = 313,
    pvm_specialized_instruction_opcode_srefmnt = 314,
    pvm_specialized_instruction_opcode_srefnt = 315,
    pvm_specialized_instruction_opcode_srefo = 316,
    pvm_specialized_instruction_opcode_sset = 317,
    pvm_specialized_instruction_opcode_sseti = 318,
    pvm_specialized_instruction_opcode_strace__nR__retR = 319,
    pvm_specialized_instruction_opcode_strref = 320,
    pvm_specialized_instruction_opcode_strset = 321,
    pvm_specialized_instruction_opcode_subi = 322,
    pvm_specialized_instruction_opcode_subiu = 323,
    pvm_specialized_instruction_opcode_subl = 324,
    pvm_specialized_instruction_opcode_sublu = 325,
    pvm_specialized_instruction_opcode_substr = 326,
    pvm_specialized_instruction_opcode_swap = 327,
    pvm_specialized_instruction_opcode_swapgti = 328,
    pvm_specialized_instruction_opcode_swapgtiu = 329,
    pvm_specialized_instruction_opcode_swapgtl = 330,
    pvm_specialized_instruction_opcode_swapgtlu = 331,
    pvm_specialized_instruction_opcode_sync = 332,
    pvm_specialized_instruction_opcode_time = 333,
    pvm_specialized_instruction_opcode_tor = 334,
    pvm_specialized_instruction_opcode_tuck = 335,
    pvm_specialized_instruction_opcode_tyagetb = 336,
    pvm_specialized_instruction_opcode_tyagett = 337,
    pvm_specialized_instruction_opcode_tyigetsg = 338,
    pvm_specialized_instruction_opcode_tyigetsz = 339,
    pvm_specialized_instruction_opcode_tyisa = 340,
    pvm_specialized_instruction_opcode_tyisc = 341,
    pvm_specialized_instruction_opcode_tyisi = 342,
    pvm_specialized_instruction_opcode_tyisiu = 343,
    pvm_specialized_instruction_opcode_tyisl = 344,
    pvm_specialized_instruction_opcode_tyislu = 345,
    pvm_specialized_instruction_opcode_tyiso = 346,
    pvm_specialized_instruction_opcode_tyiss = 347,
    pvm_specialized_instruction_opcode_tyissct = 348,
    pvm_specialized_instruction_opcode_tyisv = 349,
    pvm_specialized_instruction_opcode_tyogetm = 350,
    pvm_specialized_instruction_opcode_tyogetu = 351,
    pvm_specialized_instruction_opcode_typof = 352,
    pvm_specialized_instruction_opcode_tysctgetfn = 353,
    pvm_specialized_instruction_opcode_tysctgetft = 354,
    pvm_specialized_instruction_opcode_tysctgetn = 355,
    pvm_specialized_instruction_opcode_tysctgetnf = 356,
    pvm_specialized_instruction_opcode_unmap = 357,
    pvm_specialized_instruction_opcode_unreachable = 358,
    pvm_specialized_instruction_opcode_ureloc = 359,
    pvm_specialized_instruction_opcode_vmdisp = 360,
    pvm_specialized_instruction_opcode_write__retR = 361,
    pvm_specialized_instruction_opcode__eREPLACEMENT_maddi__retR = 362,
    pvm_specialized_instruction_opcode__eREPLACEMENT_maddl__retR = 363,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mains__retR = 364,
    pvm_specialized_instruction_opcode__eREPLACEMENT_maref__retR = 365,
    pvm_specialized_instruction_opcode__eREPLACEMENT_marefo__retR = 366,
    pvm_specialized_instruction_opcode__eREPLACEMENT_marem__retR = 367,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mba__fR__retR = 368,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mbn__fR__retR = 369,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mbnn__fR__retR = 370,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mbnzi__fR__retR = 371,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mbnziu__fR__retR = 372,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mbnzl__fR__retR = 373,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mbnzlu__fR__retR = 374,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mbsli__retR = 375,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mbsliu__retR = 376,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mbsll__retR = 377,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mbsllu__retR = 378,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mbzi__fR__retR = 379,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mbziu__fR__retR = 380,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mbzl__fR__retR = 381,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mbzlu__fR__retR = 382,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mcall__retR = 383,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mclose__retR = 384,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mdivi__retR = 385,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mdiviu__retR = 386,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mdivl__retR = 387,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mdivlu__retR = 388,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mendhl__retR = 389,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mendsc__retR = 390,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mexit__retR = 391,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mexitvm__retR = 392,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mflush__retR = 393,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mformatf32__n0__retR = 394,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mformatf32__n1__retR = 395,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mformatf32__n2__retR = 396,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mformatf32__nR__retR = 397,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mformatf64__n0__retR = 398,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mformatf64__n1__retR = 399,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mformatf64__n2__retR = 400,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mformatf64__nR__retR = 401,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mioflags__retR = 402,
    pvm_specialized_instruction_opcode__eREPLACEMENT_miogetb__retR = 403,
    pvm_specialized_instruction_opcode__eREPLACEMENT_miohandler__retR = 404,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mioref__retR = 405,
    pvm_specialized_instruction_opcode__eREPLACEMENT_miosetb__retR = 406,
    pvm_specialized_instruction_opcode__eREPLACEMENT_miosize__retR = 407,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mmodi__retR = 408,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mmodiu__retR = 409,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mmodl__retR = 410,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mmodlu__retR = 411,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mmuli__retR = 412,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mmull__retR = 413,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mnegi__retR = 414,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mnegiu__retR = 415,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mnegl__retR = 416,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mneglu__retR = 417,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mpeekdi__nR__retR = 418,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mpeekdiu__nR__retR = 419,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mpeekdl__nR__retR = 420,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mpeekdlu__nR__retR = 421,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mpeeki__nR__nR__nR__retR = 422,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mpeekiu__nR__nR__retR = 423,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mpeekl__nR__nR__nR__retR = 424,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mpeeklu__nR__nR__retR = 425,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mpeeks__retR = 426,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mpokedi__nR__retR = 427,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mpokediu__nR__retR = 428,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mpokedl__nR__retR = 429,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mpokedlu__nR__retR = 430,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mpokei__nR__nR__nR__retR = 431,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mpokeiu__nR__nR__retR = 432,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mpokel__nR__nR__nR__retR = 433,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mpokelu__nR__nR__retR = 434,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mpokes__retR = 435,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mpopios__retR = 436,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mpopob__retR = 437,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mpopom__retR = 438,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mpowi__retR = 439,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mpowiu__retR = 440,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mpowl__retR = 441,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mpowlu__retR = 442,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mprolog__retR = 443,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mpushtopvar__nR__retR = 444,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mraise__retR = 445,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mreloc__retR = 446,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mreturn__retR = 447,
    pvm_specialized_instruction_opcode__eREPLACEMENT_msmodi__retR = 448,
    pvm_specialized_instruction_opcode__eREPLACEMENT_msref__retR = 449,
    pvm_specialized_instruction_opcode__eREPLACEMENT_msrefi__retR = 450,
    pvm_specialized_instruction_opcode__eREPLACEMENT_msrefia__retR = 451,
    pvm_specialized_instruction_opcode__eREPLACEMENT_msrefin__retR = 452,
    pvm_specialized_instruction_opcode__eREPLACEMENT_msrefio__retR = 453,
    pvm_specialized_instruction_opcode__eREPLACEMENT_msrefo__retR = 454,
    pvm_specialized_instruction_opcode__eREPLACEMENT_msset__retR = 455,
    pvm_specialized_instruction_opcode__eREPLACEMENT_msseti__retR = 456,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mstrref__retR = 457,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mstrset__retR = 458,
    pvm_specialized_instruction_opcode__eREPLACEMENT_msubi__retR = 459,
    pvm_specialized_instruction_opcode__eREPLACEMENT_msubl__retR = 460,
    pvm_specialized_instruction_opcode__eREPLACEMENT_msubstr__retR = 461,
    pvm_specialized_instruction_opcode__eREPLACEMENT_msync__retR = 462,
    pvm_specialized_instruction_opcode__eREPLACEMENT_munreachable__retR = 463,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mureloc__retR = 464,
    pvm_specialized_instruction_opcode__eREPLACEMENT_mwrite__retR = 465
  };

#define PVM_SPECIALIZED_INSTRUCTION_NO 466

#endif // #ifndef PVM_SPECIALIZED_INSTRUCTIONS_H_
/* How many residuals we can have at most.  This, with some dispatches,
   is needed to compute a slow register offset from the base. */
#define PVM_MAX_RESIDUAL_ARITY  4

/* Stack operations.
 * ************************************************************************** */

/* The following stack operations (with the initial state
   pointer argument) can be used *out* of instruction code
   blocks, in non-VM code.
   Macros with the same names are available from instruction
   code blocks, but those alternative definitions lack the first
   argument: the state they operate on is always the current
   state -- in particular, its runtime. */

/* Wrapper definition of the top operation for the
   TOS-optimized stack "stack". */
#define PVM_TOP_STACK(state_p)  \
  JITTER_STACK_TOS_TOP (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    stack  \
    )
/* Wrapper definition of the under_top operation for the
   TOS-optimized stack "stack". */
#define PVM_UNDER_TOP_STACK(state_p)  \
  JITTER_STACK_TOS_UNDER_TOP (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    stack  \
    )
/* Wrapper definition of the at_depth operation for the
   TOS-optimized stack "stack". */
#define PVM_AT_DEPTH_STACK(state_p, x0)  \
  JITTER_STACK_TOS_AT_DEPTH (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    stack  \
    , x0)
/* Wrapper definition of the at_nonzero_depth operation for the
   TOS-optimized stack "stack". */
#define PVM_AT_NONZERO_DEPTH_STACK(state_p, x0)  \
  JITTER_STACK_TOS_AT_NONZERO_DEPTH (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    stack  \
    , x0)
/* Wrapper definition of the set_at_depth operation for the
   TOS-optimized stack "stack". */
#define PVM_SET_AT_DEPTH_STACK(state_p, x0, x1)  \
  JITTER_STACK_TOS_SET_AT_DEPTH (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    stack  \
    , x0, x1)
/* Wrapper definition of the set_at_nonzero_depth operation for the
   TOS-optimized stack "stack". */
#define PVM_SET_AT_NONZERO_DEPTH_STACK(state_p, x0, x1)  \
  JITTER_STACK_TOS_SET_AT_NONZERO_DEPTH (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    stack  \
    , x0, x1)
/* Wrapper definition of the push_unspecified operation for the
   TOS-optimized stack "stack". */
#define PVM_PUSH_UNSPECIFIED_STACK(state_p)  \
  JITTER_STACK_TOS_PUSH_UNSPECIFIED (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    stack  \
    )
/* Wrapper definition of the push operation for the
   TOS-optimized stack "stack". */
#define PVM_PUSH_STACK(state_p, x0)  \
  JITTER_STACK_TOS_PUSH (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    stack  \
    , x0)
/* Wrapper definition of the under_push_unspecified operation for the
   TOS-optimized stack "stack". */
#define PVM_UNDER_PUSH_UNSPECIFIED_STACK(state_p)  \
  JITTER_STACK_TOS_UNDER_PUSH_UNSPECIFIED (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    stack  \
    )
/* Wrapper definition of the under_push operation for the
   TOS-optimized stack "stack". */
#define PVM_UNDER_PUSH_STACK(state_p, x0)  \
  JITTER_STACK_TOS_UNDER_PUSH (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    stack  \
    , x0)
/* Wrapper definition of the drop operation for the
   TOS-optimized stack "stack". */
#define PVM_DROP_STACK(state_p)  \
  JITTER_STACK_TOS_DROP (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    stack  \
    )
/* Wrapper definition of the dup operation for the
   TOS-optimized stack "stack". */
#define PVM_DUP_STACK(state_p)  \
  JITTER_STACK_TOS_DUP (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    stack  \
    )
/* Wrapper definition of the swap operation for the
   TOS-optimized stack "stack". */
#define PVM_SWAP_STACK(state_p)  \
  JITTER_STACK_TOS_SWAP (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    stack  \
    )
/* Wrapper definition of the quake operation for the
   TOS-optimized stack "stack". */
#define PVM_QUAKE_STACK(state_p)  \
  JITTER_STACK_TOS_QUAKE (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    stack  \
    )
/* Wrapper definition of the over operation for the
   TOS-optimized stack "stack". */
#define PVM_OVER_STACK(state_p)  \
  JITTER_STACK_TOS_OVER (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    stack  \
    )
/* Wrapper definition of the tuck operation for the
   TOS-optimized stack "stack". */
#define PVM_TUCK_STACK(state_p)  \
  JITTER_STACK_TOS_TUCK (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    stack  \
    )
/* Wrapper definition of the nip operation for the
   TOS-optimized stack "stack". */
#define PVM_NIP_STACK(state_p)  \
  JITTER_STACK_TOS_NIP (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    stack  \
    )
/* Wrapper definition of the rot operation for the
   TOS-optimized stack "stack". */
#define PVM_ROT_STACK(state_p)  \
  JITTER_STACK_TOS_ROT (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    stack  \
    )
/* Wrapper definition of the mrot operation for the
   TOS-optimized stack "stack". */
#define PVM_MROT_STACK(state_p)  \
  JITTER_STACK_TOS_MROT (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    stack  \
    )
/* Wrapper definition of the roll operation for the
   TOS-optimized stack "stack". */
#define PVM_ROLL_STACK(state_p, x0)  \
  JITTER_STACK_TOS_ROLL (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    stack  \
    , x0)
/* Wrapper definition of the mroll operation for the
   TOS-optimized stack "stack". */
#define PVM_MROLL_STACK(state_p, x0)  \
  JITTER_STACK_TOS_MROLL (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    stack  \
    , x0)
/* Wrapper definition of the slide operation for the
   TOS-optimized stack "stack". */
#define PVM_SLIDE_STACK(state_p, x0, x1)  \
  JITTER_STACK_TOS_SLIDE (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    stack  \
    , x0, x1)
/* Wrapper definition of the whirl operation for the
   TOS-optimized stack "stack". */
#define PVM_WHIRL_STACK(state_p, x0)  \
  JITTER_STACK_TOS_WHIRL (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    stack  \
    , x0)
/* Wrapper definition of the bulge operation for the
   TOS-optimized stack "stack". */
#define PVM_BULGE_STACK(state_p, x0)  \
  JITTER_STACK_TOS_BULGE (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    stack  \
    , x0)
/* Wrapper definition of the height operation for the
   TOS-optimized stack "stack". */
#define PVM_HEIGHT_STACK(state_p)  \
  JITTER_STACK_TOS_HEIGHT (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    stack  \
    )
/* Wrapper definition of the set_height operation for the
   TOS-optimized stack "stack". */
#define PVM_SET_HEIGHT_STACK(state_p, x0)  \
  JITTER_STACK_TOS_SET_HEIGHT (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    stack  \
    , x0)
/* Wrapper definition of the reverse operation for the
   TOS-optimized stack "stack". */
#define PVM_REVERSE_STACK(state_p, x0)  \
  JITTER_STACK_TOS_REVERSE (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    stack  \
    , x0)
/* Wrapper definition of the unary operation for the
   TOS-optimized stack "stack". */
#define PVM_UNARY_STACK(state_p, x0)  \
  JITTER_STACK_TOS_UNARY (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    stack  \
    , x0)
/* Wrapper definition of the binary operation for the
   TOS-optimized stack "stack". */
#define PVM_BINARY_STACK(state_p, x0)  \
  JITTER_STACK_TOS_BINARY (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    stack  \
    , x0)
/* Wrapper definition of the top operation for the
   non-TOS-optimized stack "returnstack". */
#define PVM_TOP_RETURNSTACK(state_p)  \
  JITTER_STACK_NTOS_TOP (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    returnstack  \
    )
/* Wrapper definition of the under_top operation for the
   non-TOS-optimized stack "returnstack". */
#define PVM_UNDER_TOP_RETURNSTACK(state_p)  \
  JITTER_STACK_NTOS_UNDER_TOP (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    returnstack  \
    )
/* Wrapper definition of the at_depth operation for the
   non-TOS-optimized stack "returnstack". */
#define PVM_AT_DEPTH_RETURNSTACK(state_p, x0)  \
  JITTER_STACK_NTOS_AT_DEPTH (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    returnstack  \
    , x0)
/* Wrapper definition of the at_nonzero_depth operation for the
   non-TOS-optimized stack "returnstack". */
#define PVM_AT_NONZERO_DEPTH_RETURNSTACK(state_p, x0)  \
  JITTER_STACK_NTOS_AT_NONZERO_DEPTH (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    returnstack  \
    , x0)
/* Wrapper definition of the set_at_depth operation for the
   non-TOS-optimized stack "returnstack". */
#define PVM_SET_AT_DEPTH_RETURNSTACK(state_p, x0, x1)  \
  JITTER_STACK_NTOS_SET_AT_DEPTH (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    returnstack  \
    , x0, x1)
/* Wrapper definition of the set_at_nonzero_depth operation for the
   non-TOS-optimized stack "returnstack". */
#define PVM_SET_AT_NONZERO_DEPTH_RETURNSTACK(state_p, x0, x1)  \
  JITTER_STACK_NTOS_SET_AT_NONZERO_DEPTH (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    returnstack  \
    , x0, x1)
/* Wrapper definition of the push_unspecified operation for the
   non-TOS-optimized stack "returnstack". */
#define PVM_PUSH_UNSPECIFIED_RETURNSTACK(state_p)  \
  JITTER_STACK_NTOS_PUSH_UNSPECIFIED (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    returnstack  \
    )
/* Wrapper definition of the push operation for the
   non-TOS-optimized stack "returnstack". */
#define PVM_PUSH_RETURNSTACK(state_p, x0)  \
  JITTER_STACK_NTOS_PUSH (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    returnstack  \
    , x0)
/* Wrapper definition of the under_push_unspecified operation for the
   non-TOS-optimized stack "returnstack". */
#define PVM_UNDER_PUSH_UNSPECIFIED_RETURNSTACK(state_p)  \
  JITTER_STACK_NTOS_UNDER_PUSH_UNSPECIFIED (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    returnstack  \
    )
/* Wrapper definition of the under_push operation for the
   non-TOS-optimized stack "returnstack". */
#define PVM_UNDER_PUSH_RETURNSTACK(state_p, x0)  \
  JITTER_STACK_NTOS_UNDER_PUSH (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    returnstack  \
    , x0)
/* Wrapper definition of the drop operation for the
   non-TOS-optimized stack "returnstack". */
#define PVM_DROP_RETURNSTACK(state_p)  \
  JITTER_STACK_NTOS_DROP (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    returnstack  \
    )
/* Wrapper definition of the dup operation for the
   non-TOS-optimized stack "returnstack". */
#define PVM_DUP_RETURNSTACK(state_p)  \
  JITTER_STACK_NTOS_DUP (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    returnstack  \
    )
/* Wrapper definition of the swap operation for the
   non-TOS-optimized stack "returnstack". */
#define PVM_SWAP_RETURNSTACK(state_p)  \
  JITTER_STACK_NTOS_SWAP (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    returnstack  \
    )
/* Wrapper definition of the quake operation for the
   non-TOS-optimized stack "returnstack". */
#define PVM_QUAKE_RETURNSTACK(state_p)  \
  JITTER_STACK_NTOS_QUAKE (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    returnstack  \
    )
/* Wrapper definition of the over operation for the
   non-TOS-optimized stack "returnstack". */
#define PVM_OVER_RETURNSTACK(state_p)  \
  JITTER_STACK_NTOS_OVER (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    returnstack  \
    )
/* Wrapper definition of the tuck operation for the
   non-TOS-optimized stack "returnstack". */
#define PVM_TUCK_RETURNSTACK(state_p)  \
  JITTER_STACK_NTOS_TUCK (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    returnstack  \
    )
/* Wrapper definition of the nip operation for the
   non-TOS-optimized stack "returnstack". */
#define PVM_NIP_RETURNSTACK(state_p)  \
  JITTER_STACK_NTOS_NIP (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    returnstack  \
    )
/* Wrapper definition of the rot operation for the
   non-TOS-optimized stack "returnstack". */
#define PVM_ROT_RETURNSTACK(state_p)  \
  JITTER_STACK_NTOS_ROT (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    returnstack  \
    )
/* Wrapper definition of the mrot operation for the
   non-TOS-optimized stack "returnstack". */
#define PVM_MROT_RETURNSTACK(state_p)  \
  JITTER_STACK_NTOS_MROT (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    returnstack  \
    )
/* Wrapper definition of the roll operation for the
   non-TOS-optimized stack "returnstack". */
#define PVM_ROLL_RETURNSTACK(state_p, x0)  \
  JITTER_STACK_NTOS_ROLL (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    returnstack  \
    , x0)
/* Wrapper definition of the mroll operation for the
   non-TOS-optimized stack "returnstack". */
#define PVM_MROLL_RETURNSTACK(state_p, x0)  \
  JITTER_STACK_NTOS_MROLL (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    returnstack  \
    , x0)
/* Wrapper definition of the slide operation for the
   non-TOS-optimized stack "returnstack". */
#define PVM_SLIDE_RETURNSTACK(state_p, x0, x1)  \
  JITTER_STACK_NTOS_SLIDE (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    returnstack  \
    , x0, x1)
/* Wrapper definition of the whirl operation for the
   non-TOS-optimized stack "returnstack". */
#define PVM_WHIRL_RETURNSTACK(state_p, x0)  \
  JITTER_STACK_NTOS_WHIRL (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    returnstack  \
    , x0)
/* Wrapper definition of the bulge operation for the
   non-TOS-optimized stack "returnstack". */
#define PVM_BULGE_RETURNSTACK(state_p, x0)  \
  JITTER_STACK_NTOS_BULGE (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    returnstack  \
    , x0)
/* Wrapper definition of the height operation for the
   non-TOS-optimized stack "returnstack". */
#define PVM_HEIGHT_RETURNSTACK(state_p)  \
  JITTER_STACK_NTOS_HEIGHT (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    returnstack  \
    )
/* Wrapper definition of the set_height operation for the
   non-TOS-optimized stack "returnstack". */
#define PVM_SET_HEIGHT_RETURNSTACK(state_p, x0)  \
  JITTER_STACK_NTOS_SET_HEIGHT (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    returnstack  \
    , x0)
/* Wrapper definition of the reverse operation for the
   non-TOS-optimized stack "returnstack". */
#define PVM_REVERSE_RETURNSTACK(state_p, x0)  \
  JITTER_STACK_NTOS_REVERSE (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    returnstack  \
    , x0)
/* Wrapper definition of the unary operation for the
   non-TOS-optimized stack "returnstack". */
#define PVM_UNARY_RETURNSTACK(state_p, x0)  \
  JITTER_STACK_NTOS_UNARY (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    returnstack  \
    , x0)
/* Wrapper definition of the binary operation for the
   non-TOS-optimized stack "returnstack". */
#define PVM_BINARY_RETURNSTACK(state_p, x0)  \
  JITTER_STACK_NTOS_BINARY (pvm_val,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    returnstack  \
    , x0)
/* Wrapper definition of the top operation for the
   non-TOS-optimized stack "exceptionstack". */
#define PVM_TOP_EXCEPTIONSTACK(state_p)  \
  JITTER_STACK_NTOS_TOP (struct pvm_exception_handler,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    exceptionstack  \
    )
/* Wrapper definition of the under_top operation for the
   non-TOS-optimized stack "exceptionstack". */
#define PVM_UNDER_TOP_EXCEPTIONSTACK(state_p)  \
  JITTER_STACK_NTOS_UNDER_TOP (struct pvm_exception_handler,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    exceptionstack  \
    )
/* Wrapper definition of the at_depth operation for the
   non-TOS-optimized stack "exceptionstack". */
#define PVM_AT_DEPTH_EXCEPTIONSTACK(state_p, x0)  \
  JITTER_STACK_NTOS_AT_DEPTH (struct pvm_exception_handler,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    exceptionstack  \
    , x0)
/* Wrapper definition of the at_nonzero_depth operation for the
   non-TOS-optimized stack "exceptionstack". */
#define PVM_AT_NONZERO_DEPTH_EXCEPTIONSTACK(state_p, x0)  \
  JITTER_STACK_NTOS_AT_NONZERO_DEPTH (struct pvm_exception_handler,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    exceptionstack  \
    , x0)
/* Wrapper definition of the set_at_depth operation for the
   non-TOS-optimized stack "exceptionstack". */
#define PVM_SET_AT_DEPTH_EXCEPTIONSTACK(state_p, x0, x1)  \
  JITTER_STACK_NTOS_SET_AT_DEPTH (struct pvm_exception_handler,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    exceptionstack  \
    , x0, x1)
/* Wrapper definition of the set_at_nonzero_depth operation for the
   non-TOS-optimized stack "exceptionstack". */
#define PVM_SET_AT_NONZERO_DEPTH_EXCEPTIONSTACK(state_p, x0, x1)  \
  JITTER_STACK_NTOS_SET_AT_NONZERO_DEPTH (struct pvm_exception_handler,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    exceptionstack  \
    , x0, x1)
/* Wrapper definition of the push_unspecified operation for the
   non-TOS-optimized stack "exceptionstack". */
#define PVM_PUSH_UNSPECIFIED_EXCEPTIONSTACK(state_p)  \
  JITTER_STACK_NTOS_PUSH_UNSPECIFIED (struct pvm_exception_handler,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    exceptionstack  \
    )
/* Wrapper definition of the push operation for the
   non-TOS-optimized stack "exceptionstack". */
#define PVM_PUSH_EXCEPTIONSTACK(state_p, x0)  \
  JITTER_STACK_NTOS_PUSH (struct pvm_exception_handler,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    exceptionstack  \
    , x0)
/* Wrapper definition of the under_push_unspecified operation for the
   non-TOS-optimized stack "exceptionstack". */
#define PVM_UNDER_PUSH_UNSPECIFIED_EXCEPTIONSTACK(state_p)  \
  JITTER_STACK_NTOS_UNDER_PUSH_UNSPECIFIED (struct pvm_exception_handler,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    exceptionstack  \
    )
/* Wrapper definition of the under_push operation for the
   non-TOS-optimized stack "exceptionstack". */
#define PVM_UNDER_PUSH_EXCEPTIONSTACK(state_p, x0)  \
  JITTER_STACK_NTOS_UNDER_PUSH (struct pvm_exception_handler,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    exceptionstack  \
    , x0)
/* Wrapper definition of the drop operation for the
   non-TOS-optimized stack "exceptionstack". */
#define PVM_DROP_EXCEPTIONSTACK(state_p)  \
  JITTER_STACK_NTOS_DROP (struct pvm_exception_handler,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    exceptionstack  \
    )
/* Wrapper definition of the dup operation for the
   non-TOS-optimized stack "exceptionstack". */
#define PVM_DUP_EXCEPTIONSTACK(state_p)  \
  JITTER_STACK_NTOS_DUP (struct pvm_exception_handler,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    exceptionstack  \
    )
/* Wrapper definition of the swap operation for the
   non-TOS-optimized stack "exceptionstack". */
#define PVM_SWAP_EXCEPTIONSTACK(state_p)  \
  JITTER_STACK_NTOS_SWAP (struct pvm_exception_handler,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    exceptionstack  \
    )
/* Wrapper definition of the quake operation for the
   non-TOS-optimized stack "exceptionstack". */
#define PVM_QUAKE_EXCEPTIONSTACK(state_p)  \
  JITTER_STACK_NTOS_QUAKE (struct pvm_exception_handler,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    exceptionstack  \
    )
/* Wrapper definition of the over operation for the
   non-TOS-optimized stack "exceptionstack". */
#define PVM_OVER_EXCEPTIONSTACK(state_p)  \
  JITTER_STACK_NTOS_OVER (struct pvm_exception_handler,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    exceptionstack  \
    )
/* Wrapper definition of the tuck operation for the
   non-TOS-optimized stack "exceptionstack". */
#define PVM_TUCK_EXCEPTIONSTACK(state_p)  \
  JITTER_STACK_NTOS_TUCK (struct pvm_exception_handler,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    exceptionstack  \
    )
/* Wrapper definition of the nip operation for the
   non-TOS-optimized stack "exceptionstack". */
#define PVM_NIP_EXCEPTIONSTACK(state_p)  \
  JITTER_STACK_NTOS_NIP (struct pvm_exception_handler,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    exceptionstack  \
    )
/* Wrapper definition of the rot operation for the
   non-TOS-optimized stack "exceptionstack". */
#define PVM_ROT_EXCEPTIONSTACK(state_p)  \
  JITTER_STACK_NTOS_ROT (struct pvm_exception_handler,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    exceptionstack  \
    )
/* Wrapper definition of the mrot operation for the
   non-TOS-optimized stack "exceptionstack". */
#define PVM_MROT_EXCEPTIONSTACK(state_p)  \
  JITTER_STACK_NTOS_MROT (struct pvm_exception_handler,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    exceptionstack  \
    )
/* Wrapper definition of the roll operation for the
   non-TOS-optimized stack "exceptionstack". */
#define PVM_ROLL_EXCEPTIONSTACK(state_p, x0)  \
  JITTER_STACK_NTOS_ROLL (struct pvm_exception_handler,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    exceptionstack  \
    , x0)
/* Wrapper definition of the mroll operation for the
   non-TOS-optimized stack "exceptionstack". */
#define PVM_MROLL_EXCEPTIONSTACK(state_p, x0)  \
  JITTER_STACK_NTOS_MROLL (struct pvm_exception_handler,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    exceptionstack  \
    , x0)
/* Wrapper definition of the slide operation for the
   non-TOS-optimized stack "exceptionstack". */
#define PVM_SLIDE_EXCEPTIONSTACK(state_p, x0, x1)  \
  JITTER_STACK_NTOS_SLIDE (struct pvm_exception_handler,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    exceptionstack  \
    , x0, x1)
/* Wrapper definition of the whirl operation for the
   non-TOS-optimized stack "exceptionstack". */
#define PVM_WHIRL_EXCEPTIONSTACK(state_p, x0)  \
  JITTER_STACK_NTOS_WHIRL (struct pvm_exception_handler,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    exceptionstack  \
    , x0)
/* Wrapper definition of the bulge operation for the
   non-TOS-optimized stack "exceptionstack". */
#define PVM_BULGE_EXCEPTIONSTACK(state_p, x0)  \
  JITTER_STACK_NTOS_BULGE (struct pvm_exception_handler,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    exceptionstack  \
    , x0)
/* Wrapper definition of the height operation for the
   non-TOS-optimized stack "exceptionstack". */
#define PVM_HEIGHT_EXCEPTIONSTACK(state_p)  \
  JITTER_STACK_NTOS_HEIGHT (struct pvm_exception_handler,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    exceptionstack  \
    )
/* Wrapper definition of the set_height operation for the
   non-TOS-optimized stack "exceptionstack". */
#define PVM_SET_HEIGHT_EXCEPTIONSTACK(state_p, x0)  \
  JITTER_STACK_NTOS_SET_HEIGHT (struct pvm_exception_handler,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    exceptionstack  \
    , x0)
/* Wrapper definition of the reverse operation for the
   non-TOS-optimized stack "exceptionstack". */
#define PVM_REVERSE_EXCEPTIONSTACK(state_p, x0)  \
  JITTER_STACK_NTOS_REVERSE (struct pvm_exception_handler,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    exceptionstack  \
    , x0)
/* Wrapper definition of the unary operation for the
   non-TOS-optimized stack "exceptionstack". */
#define PVM_UNARY_EXCEPTIONSTACK(state_p, x0)  \
  JITTER_STACK_NTOS_UNARY (struct pvm_exception_handler,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    exceptionstack  \
    , x0)
/* Wrapper definition of the binary operation for the
   non-TOS-optimized stack "exceptionstack". */
#define PVM_BINARY_EXCEPTIONSTACK(state_p, x0)  \
  JITTER_STACK_NTOS_BINARY (struct pvm_exception_handler,  \
    (state_p)->_pvm_Vv9tlAxnoJ_state_runtime. /* not an error */,  \
    exceptionstack  \
    , x0)

/* User-specified code, late header part: beginning. */
#line 240 "../../libpoke/pvm.jitter"
#line 240 "../../libpoke/pvm.jitter"

    /* Macros to raise an exception from within an instruction.  This
       is used in the RAISE instruction itself, and also in instructions
       that can fail, such as integer division or IO.

       The code in the macro looks for the first matching exception
       handler in the exception handlers stack.  Then it restores the
       heights of the main stack and the return stack, restores the
       original dynamic environment, and then pushes the exception
       type as an integer in the main stack, before branching to the
       exception handler.  */

#define PVM_RAISE_DIRECT(EXCEPTION)                                   \
  do                                                                  \
  {                                                                   \
   int exception_code                                                 \
     = PVM_VAL_INT (pvm_ref_struct_cstr ((EXCEPTION), pvm_literal_code));\
                                                                      \
   while (1)                                                          \
   {                                                                  \
     struct pvm_exception_handler ehandler                            \
       = JITTER_TOP_EXCEPTIONSTACK ();                                \
     int handler_exception = ehandler.exception;                      \
                                                                      \
     JITTER_DROP_EXCEPTIONSTACK ();                                   \
                                                                      \
     if (handler_exception == 0                                       \
         || handler_exception == exception_code)                      \
     {                                                                \
       JITTER_SET_HEIGHT_STACK (ehandler.main_stack_height);          \
       JITTER_SET_HEIGHT_RETURNSTACK (ehandler.return_stack_height);  \
                                                                      \
       JITTER_PUSH_STACK ((EXCEPTION));                               \
                                                                      \
       PVM_STATE_RUNTIME_FIELD (env) = ehandler.env;                  \
       JITTER_BRANCH (ehandler.code);                                 \
       break;                                                         \
     }                                                                \
   }                                                                  \
 } while (0)


#define PVM_RAISE(CODE,STR,ESTATUS)                                   \
 do                                                                   \
 {                                                                    \
   pvm_val exception = pvm_make_exception ((CODE),(STR),(ESTATUS),    \
                                           NULL, NULL);               \
   PVM_RAISE_DIRECT (exception);                                      \
 } while (0)

#define PVM_RAISE_DFL(BASE)                                           \
 do                                                                   \
 {                                                                    \
   PVM_RAISE (BASE,pvm_exception_names[BASE],BASE##_ESTATUS);         \
 } while (0)

    /* Macros to implement different kind of instructions.  These are to
       avoid flagrant code replication below.  */

/* Binary numeric operations generating a boolean on the stack.
   ( TYPE TYPE -- TYPE TYPE INT ) */
# define PVM_BOOL_BINOP(TYPE,OP)                                             \
   do                                                                        \
    {                                                                        \
      pvm_val res = PVM_MAKE_INT (PVM_VAL_##TYPE (JITTER_UNDER_TOP_STACK ()) \
                                  OP PVM_VAL_##TYPE (JITTER_TOP_STACK ()), 32); \
      JITTER_PUSH_STACK (res);                                               \
    } while (0)

/* Unary numeric operations.
   ( TYPE -- TYPE TYPE) */
# define PVM_UNOP(TYPE,TYPER,TYPERLC,OP)                                     \
   do                                                                        \
    {                                                                        \
      int size = PVM_VAL_##TYPER##_SIZE (JITTER_TOP_STACK ());               \
      pvm_val res = pvm_make_##TYPERLC (OP PVM_VAL_##TYPE (JITTER_TOP_STACK ()), size); \
      JITTER_PUSH_STACK (res);                                               \
    } while (0)

/* Signed negation.
   We check for overflow, raising E_overflow whenever appropriate.  */

# define PVM_NEG_SIGNED(TYPE,CTYPE)                                          \
  do                                                                         \
  {                                                                          \
    CTYPE a = PVM_VAL_##TYPE (JITTER_TOP_STACK ());                          \
    int size = PVM_VAL_##TYPE##_SIZE (JITTER_TOP_STACK ());                  \
    int64_t a64 = ((uint64_t)(int64_t) a) << (64 - size);                    \
                                                                             \
    if (INT_NEGATE_OVERFLOW (a64))                                           \
      PVM_RAISE_DFL (PVM_E_OVERFLOW);                                        \
    else                                                                     \
      JITTER_PUSH_STACK (PVM_MAKE_##TYPE (-a, size));                        \
  } while (0)


/* Signed addition.
   The two operands and the result are assumed to be PVM integers, having
   the same bit size.
   We check for overflow, raising E_overflow whenever appropriate.  */

# define PVM_ADD_SIGNED(TYPE,CTYPE)                                          \
  do                                                                         \
  {                                                                          \
    CTYPE a = PVM_VAL_##TYPE (JITTER_UNDER_TOP_STACK ());                    \
    CTYPE b = PVM_VAL_##TYPE (JITTER_TOP_STACK ());                          \
    int size = PVM_VAL_##TYPE##_SIZE (JITTER_TOP_STACK ());                  \
    int64_t a64 = ((uint64_t)(int64_t) a) << (64 - size);                    \
    int64_t b64 = ((uint64_t)(int64_t) b) << (64 - size);                    \
                                                                             \
    if (INT_ADD_OVERFLOW (a64, b64))                                         \
      PVM_RAISE_DFL (PVM_E_OVERFLOW);                                        \
    else                                                                     \
      JITTER_PUSH_STACK (PVM_MAKE_##TYPE (a + b, size));                     \
  } while (0)

/* Signed subtraction.
   The two operands and the result are assumed to be PVM integers, having
   the same bit size.
   We check for overflow, raising E_overflow whenever appropriate.  */

# define PVM_SUB_SIGNED(TYPE,CTYPE)                                          \
  do                                                                         \
  {                                                                          \
    CTYPE a = PVM_VAL_##TYPE (JITTER_UNDER_TOP_STACK ());                    \
    CTYPE b = PVM_VAL_##TYPE (JITTER_TOP_STACK ());                          \
    int size = PVM_VAL_##TYPE##_SIZE (JITTER_TOP_STACK ());                  \
    int64_t a64 = ((uint64_t)(int64_t) a) << (64 - size);                    \
    int64_t b64 = ((uint64_t)(int64_t) b) << (64 - size);                    \
                                                                             \
    if (INT_SUBTRACT_OVERFLOW (a64, b64))                                    \
      PVM_RAISE_DFL (PVM_E_OVERFLOW);                                        \
    else                                                                     \
      JITTER_PUSH_STACK (PVM_MAKE_##TYPE (a - b, size));                     \
  } while (0)

/* Signed multiplication.
   The two operands and the result are assumed to be PVM integers, having
   the same bit size.
   We check for overflow, raising E_overflow whenever appropriate.  */

# define PVM_MUL_SIGNED(TYPE,CTYPE)                                          \
  do                                                                         \
  {                                                                          \
    CTYPE a = PVM_VAL_##TYPE (JITTER_UNDER_TOP_STACK ());                    \
    CTYPE b = PVM_VAL_##TYPE (JITTER_TOP_STACK ());                          \
    int size = PVM_VAL_##TYPE##_SIZE (JITTER_TOP_STACK ());                  \
    int64_t a64 = ((uint64_t)(int64_t) a) << (64 - size);                    \
                                                                             \
    if (INT_MULTIPLY_OVERFLOW (a64, b))                                      \
      PVM_RAISE_DFL (PVM_E_OVERFLOW);                                        \
    else                                                                     \
      JITTER_PUSH_STACK (PVM_MAKE_##TYPE (a * b, size));                     \
  } while (0)

/* Signed division.
   We check for overflow, raising E_overflow whenever appropriate.  */

# define PVM_DIV_SIGNED(TYPE,CTYPE)                                          \
   if (PVM_VAL_##TYPE (JITTER_TOP_STACK ()) == 0)                            \
   {                                                                         \
      PVM_RAISE_DFL (PVM_E_DIV_BY_ZERO);                                     \
   }                                                                         \
   else                                                                      \
   {                                                                         \
    CTYPE a = PVM_VAL_##TYPE (JITTER_UNDER_TOP_STACK ());                    \
    CTYPE b = PVM_VAL_##TYPE (JITTER_TOP_STACK ());                          \
    int size = PVM_VAL_##TYPE##_SIZE (JITTER_TOP_STACK ());                  \
    int64_t a64 = ((uint64_t)(int64_t) a) << (64 - size);                    \
                                                                             \
    if (INT_DIVIDE_OVERFLOW (a64, b))                                        \
      PVM_RAISE_DFL (PVM_E_OVERFLOW);                                        \
    else                                                                     \
      JITTER_PUSH_STACK (PVM_MAKE_##TYPE (a / b, size));                     \
   }

# define PVM_MOD_SIGNED(TYPE,CTYPE)                                          \
   if (PVM_VAL_##TYPE (JITTER_TOP_STACK ()) == 0)                            \
   {                                                                         \
      PVM_RAISE_DFL (PVM_E_DIV_BY_ZERO);                                     \
   }                                                                         \
   else                                                                      \
   {                                                                         \
    CTYPE a = PVM_VAL_##TYPE (JITTER_UNDER_TOP_STACK ());                    \
    CTYPE b = PVM_VAL_##TYPE (JITTER_TOP_STACK ());                          \
    int size = PVM_VAL_##TYPE##_SIZE (JITTER_TOP_STACK ());                  \
    int64_t a64 = ((uint64_t) (int64_t) a) << (64 - size);                   \
                                                                             \
    if (INT_DIVIDE_OVERFLOW (a64, b))                                        \
      PVM_RAISE_DFL (PVM_E_OVERFLOW);                                        \
    else                                                                     \
      JITTER_PUSH_STACK (PVM_MAKE_##TYPE (a % b, size));                     \
   }

/* Binary numeric operations.
  ( TYPE TYPE -- TYPE TYPE TYPE ) */
# define PVM_BINOP(TYPEA,TYPEB,TYPER,OP)                                     \
   do                                                                        \
    {                                                                        \
      int size = PVM_VAL_##TYPER##_SIZE (JITTER_UNDER_TOP_STACK ());       \
      pvm_val res = PVM_MAKE_##TYPER (PVM_VAL_##TYPEA (JITTER_UNDER_TOP_STACK ()) \
                                      OP PVM_VAL_##TYPEB (JITTER_TOP_STACK ()), size); \
      JITTER_PUSH_STACK (res);                                               \
    } while (0)

/* Same, but with division by zero run-time check.  */
# define PVM_CHECKED_BINOP(TYPEA,TYPEB,TYPER,OP)                             \
   if (PVM_VAL_##TYPEB (JITTER_TOP_STACK ()) == 0)                           \
   {                                                                         \
      PVM_RAISE_DFL (PVM_E_DIV_BY_ZERO);                                     \
   }                                                                         \
   else                                                                      \
   {                                                                         \
      PVM_BINOP (TYPEA, TYPEB, TYPER, OP);                                   \
   }

/* Same, but for left-shifts, which includes an overflow check on the
   bit count.  */
# define PVM_BINOP_SL(TYPEA, TYPEB,TYPER, OP)                                \
   {                                                                         \
     pvm_val type = pvm_typeof (JITTER_UNDER_TOP_STACK ());                  \
     uint64_t size = PVM_VAL_INTEGRAL (PVM_VAL_TYP_I_SIZE (type));           \
                                                                             \
     if (PVM_VAL_##TYPEB (JITTER_TOP_STACK ()) >= size)                      \
     {                                                                       \
        PVM_RAISE_DFL (PVM_E_OUT_OF_BOUNDS);                                 \
     }                                                                       \
     else                                                                    \
     {                                                                       \
        int size = PVM_VAL_##TYPER##_SIZE (JITTER_UNDER_TOP_STACK ());       \
        pvm_val res = PVM_MAKE_##TYPER ((uint64_t) PVM_VAL_##TYPEA (JITTER_UNDER_TOP_STACK ()) \
                                        << PVM_VAL_##TYPEB (JITTER_TOP_STACK ()), size); \
        JITTER_PUSH_STACK (res);                                             \
     }                                                                       \
   }

/* Unsigned exponentiation.  */

# define PVM_POWOP(TYPE,TYPEC,TYPELC)                                       \
  do                                                                        \
  {                                                                         \
     uint64_t size = PVM_VAL_##TYPE##_SIZE (JITTER_UNDER_TOP_STACK ());     \
     TYPEC res                                                              \
      = (TYPEC) pk_upow (PVM_VAL_##TYPE (JITTER_UNDER_TOP_STACK ()),        \
                         PVM_VAL_UINT (JITTER_TOP_STACK ()));               \
                                                                            \
     JITTER_PUSH_STACK (pvm_make_##TYPELC (res, size));                     \
  }                                                                         \
  while (0)

/* Signed exponentiation, with overflow check.  */

# define PVM_POWOP_SIGNED(TYPE,TYPEC,TYPELC)                                \
  do                                                                        \
  {                                                                         \
     int overflow_p;                                                        \
     uint32_t i;                                                            \
     TYPEC res;                                                             \
     uint64_t size = PVM_VAL_##TYPE##_SIZE (JITTER_UNDER_TOP_STACK ());     \
     TYPEC a = PVM_VAL_##TYPE (JITTER_UNDER_TOP_STACK ());                  \
     uint32_t b = PVM_VAL_UINT (JITTER_TOP_STACK ());                       \
     int64_t res64 = ((uint64_t) 1) << (64 - size);                         \
                                                                            \
     overflow_p = 0;                                                        \
     for (i = 0; i < b; ++i)                                                \
       {                                                                    \
         if (INT_MULTIPLY_OVERFLOW (res64, a))                              \
           {                                                                \
             PVM_RAISE_DFL (PVM_E_OVERFLOW);                                \
             overflow_p = 1;                                                \
             break;                                                         \
           }                                                                \
                                                                            \
         res64 *= a;                                                        \
        }                                                                   \
                                                                            \
     if (!overflow_p)                                                       \
       {                                                                    \
         res = res64 >> (64 - size);                                        \
         JITTER_PUSH_STACK (pvm_make_##TYPELC (res, size));                 \
       }                                                                    \
  }                                                                         \
  while (0)


/* Conversion instructions.
   ( TYPE -- TYPE RTYPE )  */
#define PVM_CONVOP(TYPE, TYPEC, RTYPELC, RTYPEC)                             \
   do                                                                        \
    {                                                                        \
      jitter_uint tsize = JITTER_ARGN0;                                      \
      TYPEC val = PVM_VAL_##TYPE (JITTER_TOP_STACK ());                      \
      JITTER_PUSH_STACK (pvm_make_##RTYPELC ((RTYPEC) val, tsize));          \
    } while (0)

/* Auxiliary macros used in PVM_PEEK and PVM_POKE below.  */
#define PVM_IOS_ARGS_INT                                                     \
  io, offset, 0, bits, endian, nenc, &value
#define PVM_IOS_ARGS_UINT                                                    \
  io, offset, 0, bits, endian, &value
#define PVM_IOS_ARGS_WRITE_INT                                               \
  io, offset, 0, bits, endian, nenc, value
#define PVM_IOS_ARGS_WRITE_UINT                                              \
  io, offset, 0, bits, endian, value

/* Integral peek instructions.
   ( IOS BOFF -- VAL )  */
#define PVM_PEEK(TYPE,IOTYPE,NENC,ENDIAN,BITS,IOARGS)                        \
  do                                                                         \
   {                                                                         \
     int ret;                                                                \
     __attribute__((unused)) enum ios_nenc nenc = (NENC);                    \
     enum ios_endian endian = (ENDIAN);                                      \
     int bits = (BITS);                                                      \
     IOTYPE##64_t value;                                                     \
     ios io;                                                                 \
     ios_off offset;                                                         \
                                                                             \
     offset = PVM_VAL_ULONG (JITTER_TOP_STACK ());                           \
     if (JITTER_UNDER_TOP_STACK () == PVM_NULL)                              \
       io = ios_cur ();                                                      \
     else                                                                    \
       io = ios_search_by_id (PVM_VAL_INT (JITTER_UNDER_TOP_STACK ()));      \
                                                                             \
     if (io == NULL)                                                         \
       PVM_RAISE_DFL (PVM_E_NO_IOS);                                         \
                                                                             \
     JITTER_DROP_STACK ();                                                   \
     if ((ret = ios_read_##IOTYPE (IOARGS)) != IOS_OK)                       \
       {                                                                     \
         if (ret == IOS_EOF)                                                 \
            PVM_RAISE_DFL (PVM_E_EOF);                                       \
         else if (ret == IOS_ENOMEM)                                         \
            PVM_RAISE (PVM_E_IO, pvm_literal_enomem, PVM_E_IO_ESTATUS);      \
         else if (ret == IOS_EPERM)                                          \
            PVM_RAISE_DFL (PVM_E_PERM);                                      \
         else                                                                \
            PVM_RAISE_DFL (PVM_E_IO);                                        \
         JITTER_TOP_STACK () = PVM_NULL;                                     \
       }                                                                     \
     else                                                                    \
       JITTER_TOP_STACK () = pvm_make_##TYPE (value, bits);                  \
   } while (0)

/* Integral poke instructions.
   ( IOS BOFF VAL -- )  */
#define PVM_POKE(TYPE,IOTYPE,NENC,ENDIAN,BITS,IOARGS)                        \
  do                                                                         \
   {                                                                         \
     int ret;                                                                \
     __attribute__((unused)) enum ios_nenc nenc = (NENC);                    \
     enum ios_endian endian = (ENDIAN);                                      \
     int bits = (BITS);                                                      \
     IOTYPE##64_t value = PVM_VAL_##TYPE (JITTER_TOP_STACK ());              \
     pvm_val offset_val = JITTER_UNDER_TOP_STACK ();                         \
     ios io;                                                                 \
     ios_off offset;                                                         \
                                                                             \
     JITTER_DROP_STACK ();                                                   \
     JITTER_DROP_STACK ();                                                   \
                                                                             \
     if (JITTER_TOP_STACK () == PVM_NULL)                                    \
       io = ios_cur ();                                                      \
     else                                                                    \
       io = ios_search_by_id (PVM_VAL_INT (JITTER_TOP_STACK ()));            \
                                                                             \
     if (io == NULL)                                                         \
       PVM_RAISE_DFL (PVM_E_NO_IOS);                                         \
     JITTER_DROP_STACK ();                                                   \
                                                                             \
     offset = PVM_VAL_ULONG (offset_val);                                    \
     if ((ret = ios_write_##IOTYPE (IOARGS)) != IOS_OK)                      \
       {                                                                     \
         if (ret == IOS_EOF)                                                 \
            PVM_RAISE_DFL (PVM_E_EOF);                                       \
         else if (ret == IOS_EPERM)                                          \
            PVM_RAISE_DFL (PVM_E_PERM);                                      \
         else                                                                \
            PVM_RAISE_DFL (PVM_E_IO);                                        \
       }                                                                     \
   } while (0)

/* Macro to call to a closure.  This is used in the instruction CALL,
   and also other instructions required to... call :D The argument
   should be a closure (surprise.)  */

#define PVM_CALL(CLS)                                                        \
   do                                                                        \
    {                                                                        \
       /* Make place for the return address in the return stack.  */         \
       /* actual value will be written by the callee. */                     \
       JITTER_PUSH_UNSPECIFIED_RETURNSTACK();                                \
                                                                             \
       /* Save the current environment and use the callee's environment. */  \
       JITTER_PUSH_RETURNSTACK (                                             \
         (jitter_uint) (uintptr_t) PVM_STATE_RUNTIME_FIELD (env));           \
       PVM_STATE_RUNTIME_FIELD (env) = PVM_VAL_CLS_ENV ((CLS));              \
                                                                             \
       /* Branch-and-link to the native code, whose first instruction will */\
       /*  be a prolog. */                                                   \
       JITTER_BRANCH_AND_LINK (PVM_VAL_CLS_ENTRY_POINT ((CLS)));           \
    } while (0)

/* Macros to implement printi* and printl* instructions.  */

#define PVM_PRINTI(TYPE,TYPEC,SIGNED_P,BASE)                                \
  do                                                                        \
  {                                                                         \
    TYPEC val = PVM_VAL_##TYPE (JITTER_UNDER_TOP_STACK ());                 \
    char fmt[16];  /* %0NNd */                                              \
    char *iformat = pvm_literal_empty;                                      \
    uint32_t mask                                                           \
        = JITTER_ARGN0 == 32 ? (uint32_t)-1                                 \
                             : (((uint32_t)1 << JITTER_ARGN0) - 1);         \
                                                                            \
    fmt[0] = '%';                                                           \
    fmt[1] = '0';                                                           \
    fmt[2] = '\0';                                                          \
    if ((BASE) == 10)                                                       \
    {                                                                       \
      iformat = SIGNED_P ? PRIi32 : PRIu32;                                 \
      pvm_strcat (fmt, iformat);                                            \
    }                                                                       \
    else                                                                    \
    {                                                                       \
      char *basefmt = pvm_literal_empty;                                    \
      int prec = 0;                                                         \
                                                                            \
      if ((BASE) == 256)                                                    \
      {                                                                     \
        iformat = pvm_literal_c;                                            \
        prec = 1;                                                           \
      }                                                                     \
      else if ((BASE) == 16)                                                \
      {                                                                     \
        iformat = PRIx32;                                                   \
        prec = (JITTER_ARGN0 / 4) + ((JITTER_ARGN0 % 4) != 0);              \
      }                                                                     \
      else if ((BASE) == 8)                                                 \
      {                                                                     \
        basefmt = PRIo32;                                                   \
        prec = (JITTER_ARGN0 / 3) + ((JITTER_ARGN0 % 3) != 0);              \
      }                                                                     \
      else if ((BASE) == 2)                                                 \
      {                                                                     \
        pk_print_binary (pk_puts, val, JITTER_ARGN0, 1, 0);                 \
        JITTER_DROP_STACK ();                                               \
        JITTER_DROP_STACK ();                                               \
        break;                                                              \
      }                                                                     \
                                                                            \
      PVM_ASSERT (prec != 0);                                               \
      fmt[2] = '0' + (prec / 10);                                           \
      fmt[3] = '0' + prec - (prec / 10 * 10);                               \
      fmt[4] = '\0';                                                        \
      pvm_strcat (fmt, iformat);                                            \
      pvm_strcat (fmt, basefmt);                                            \
    }                                                                       \
                                                                            \
    pk_printf (fmt, (BASE) == 10 ? val : val & mask);                       \
    JITTER_DROP_STACK ();                                                   \
    JITTER_DROP_STACK ();                                                   \
  } while (0)

#define PVM_PRINTL(TYPE,TYPEC,SIGNED_P,BASE)                                \
  do                                                                        \
  {                                                                         \
    TYPEC val = PVM_VAL_##TYPE (JITTER_UNDER_TOP_STACK ());                 \
    char fmt[16];  /* %0NNfff */                                            \
    char *iformat = pvm_literal_empty;                                      \
    uint64_t mask                                                           \
        = JITTER_ARGN0 == 64 ? (uint64_t)-1                                 \
                             : (((uint64_t)1 << JITTER_ARGN0) - 1);         \
                                                                            \
    fmt[0] = '%';                                                           \
    fmt[1] = '0';                                                           \
    fmt[2] = '\0';                                                          \
    if ((BASE) == 10)                                                       \
    {                                                                       \
      iformat = SIGNED_P ? PRIi64 : PRIu64;                                 \
      pvm_strcat (fmt, iformat);                                            \
    }                                                                       \
    else                                                                    \
    {                                                                       \
      char *basefmt = pvm_literal_empty;                                    \
      int prec = 0;                                                         \
                                                                            \
      if ((BASE) == 16)                                                     \
      {                                                                     \
        iformat = PRIx64;                                                   \
        prec = (JITTER_ARGN0 / 4) + ((JITTER_ARGN0 % 4) != 0);              \
      }                                                                     \
      else if ((BASE) == 8)                                                 \
      {                                                                     \
        basefmt = PRIo64;                                                   \
        prec = (JITTER_ARGN0 / 3) + ((JITTER_ARGN0 % 3) != 0);              \
      }                                                                     \
      else if ((BASE) == 2)                                                 \
      {                                                                     \
        pk_print_binary (pk_puts, val, JITTER_ARGN0, 1, 0);                 \
        JITTER_DROP_STACK ();                                               \
        JITTER_DROP_STACK ();                                               \
        break;                                                              \
      }                                                                     \
                                                                            \
      fmt[2] = '0' + (prec / 10);                                           \
      fmt[3] = '0' + prec - (prec / 10 * 10);                               \
      fmt[4] = '\0';                                                        \
      pvm_strcat (fmt, iformat);                                            \
      pvm_strcat (fmt, basefmt);                                            \
    }                                                                       \
                                                                            \
    pk_printf (fmt, (BASE) == 10 ? val : val & mask);                       \
    JITTER_DROP_STACK ();                                                   \
    JITTER_DROP_STACK ();                                                   \
  } while (0)

/* Macros to implement formati* and formatl* instructions.  */

#define PVM_FORMATI(OUT,OUTLEN,TYPE,TYPEC,SIGNED_P,BASE)                    \
  do                                                                        \
  {                                                                         \
    TYPEC val = PVM_VAL_##TYPE (JITTER_UNDER_TOP_STACK ());                 \
    char fmt[16];  /* %0NNd */                                              \
    char *iformat = pvm_literal_empty;                                      \
    int n;                                                                  \
    uint32_t mask                                                           \
        = JITTER_ARGN0 == 32 ? (uint32_t)-1                                 \
                             : (((uint32_t)1 << JITTER_ARGN0) - 1);         \
                                                                            \
    fmt[0] = '%';                                                           \
    fmt[1] = '0';                                                           \
    fmt[2] = '\0';                                                          \
    if ((BASE) == 10)                                                       \
    {                                                                       \
      iformat = SIGNED_P ? PRIi32 : PRIu32;                                 \
      pvm_strcat (fmt, iformat);                                            \
    }                                                                       \
    else                                                                    \
    {                                                                       \
      char *basefmt = pvm_literal_empty;                                    \
      int prec = 0;                                                         \
                                                                            \
      if ((BASE) == 256)                                                    \
      {                                                                     \
        iformat = pvm_literal_c;                                            \
        prec = 1;                                                           \
      }                                                                     \
      else if ((BASE) == 16)                                                \
      {                                                                     \
        iformat = PRIx32;                                                   \
        prec = (JITTER_ARGN0 / 4) + ((JITTER_ARGN0 % 4) != 0);              \
      }                                                                     \
      else if ((BASE) == 8)                                                 \
      {                                                                     \
        basefmt = PRIo32;                                                   \
        prec = (JITTER_ARGN0 / 3) + ((JITTER_ARGN0 % 3) != 0);              \
      }                                                                     \
      else if ((BASE) == 2)                                                 \
      {                                                                     \
        n = pk_format_binary ((OUT), (OUTLEN), val, JITTER_ARGN0, SIGNED_P, 0);\
        PVM_ASSERT (n == 0);                                                \
        JITTER_DROP_STACK ();                                               \
        JITTER_DROP_STACK ();                                               \
        JITTER_PUSH_STACK (pvm_make_string ((OUT)));                        \
        break;                                                              \
      }                                                                     \
                                                                            \
      PVM_ASSERT (prec != 0);                                               \
      fmt[2] = '0' + (prec / 10);                                           \
      fmt[3] = '0' + prec - (prec / 10 * 10);                               \
      fmt[4] = '\0';                                                        \
      pvm_strcat (fmt, iformat);                                            \
      pvm_strcat (fmt, basefmt);                                            \
    }                                                                       \
                                                                            \
    n = pvm_snprintf ((OUT), (OUTLEN), fmt,  (BASE) == 10 ? val : val & mask);  \
    PVM_ASSERT (n < (OUTLEN));                                              \
    JITTER_DROP_STACK ();                                                   \
    JITTER_DROP_STACK ();                                                   \
    JITTER_PUSH_STACK (pvm_make_string ((OUT)));                            \
  } while (0)

#define PVM_FORMATL(OUT,OUTLEN,TYPE,TYPEC,SIGNED_P,BASE)                    \
  do                                                                        \
  {                                                                         \
    TYPEC val = PVM_VAL_##TYPE (JITTER_UNDER_TOP_STACK ());                 \
    char fmt[16];  /* %0NNfff */                                            \
    char *iformat = pvm_literal_empty;                                      \
    int n;                                                                  \
    uint64_t mask                                                           \
        = JITTER_ARGN0 == 64 ? (uint64_t)-1                                 \
                             : (((uint64_t)1 << JITTER_ARGN0) - 1);         \
                                                                            \
    fmt[0] = '%';                                                           \
    fmt[1] = '0';                                                           \
    fmt[2] = '\0';                                                          \
    if ((BASE) == 10)                                                       \
    {                                                                       \
      iformat = SIGNED_P ? PRIi64 : PRIu64;                                 \
      pvm_strcat (fmt, iformat);                                            \
    }                                                                       \
    else                                                                    \
    {                                                                       \
      char *basefmt = pvm_literal_empty;                                    \
      int prec = 0;                                                         \
                                                                            \
      if ((BASE) == 16)                                                     \
      {                                                                     \
        iformat = PRIx64;                                                   \
        prec = (JITTER_ARGN0 / 4) + ((JITTER_ARGN0 % 4) != 0);              \
      }                                                                     \
      else if ((BASE) == 8)                                                 \
      {                                                                     \
        basefmt = PRIo64;                                                   \
        prec = (JITTER_ARGN0 / 3) + ((JITTER_ARGN0 % 3) != 0);              \
      }                                                                     \
      else if ((BASE) == 2)                                                 \
      {                                                                     \
        n = pk_format_binary ((OUT), (OUTLEN), val, JITTER_ARGN0, SIGNED_P, 0);\
        PVM_ASSERT (n == 0);                                                \
        JITTER_DROP_STACK ();                                               \
        JITTER_DROP_STACK ();                                               \
        JITTER_PUSH_STACK (pvm_make_string ((OUT)));                        \
        break;                                                              \
      }                                                                     \
                                                                            \
      fmt[2] = '0' + (prec / 10);                                           \
      fmt[3] = '0' + prec - (prec / 10 * 10);                               \
      fmt[4] = '\0';                                                        \
      pvm_strcat (fmt, iformat);                                            \
      pvm_strcat (fmt, basefmt);                                            \
    }                                                                       \
                                                                            \
    n = pvm_snprintf ((OUT), (OUTLEN), fmt,  (BASE) == 10 ? val : val & mask);  \
    PVM_ASSERT (n < (OUTLEN));                                              \
    JITTER_DROP_STACK ();                                                   \
    JITTER_DROP_STACK ();                                                   \
    JITTER_PUSH_STACK (pvm_make_string ((OUT)));                            \
  } while (0)

#define PVM_FORMATF(RESULT,NUM,PREC,STYLE,TYPEF)                            \
  do                                                                        \
    {                                                                       \
      TYPEF x;                                                              \
      int n;                                                                \
      char fmt[16];                                                         \
                                                                            \
      PVM_ASSERT (sizeof (x) == sizeof (NUM));                              \
      PVM_ASSERT ((STYLE) < 3);                                             \
                                                                            \
      pvm_memcpy (&x, &(NUM), sizeof (NUM));                                \
      n = pvm_snprintf (fmt, sizeof (fmt), pvm_literal_formatf_fmt,         \
                        (unsigned)(PREC), pvm_literal_formatf_styles[(STYLE)]); \
      if (n == -1)                                                          \
        PVM_RAISE_DFL (PVM_E_CONV);                                         \
      n = pvm_asprintf (&(RESULT), fmt, x);                                 \
      if (n == -1)                                                          \
        PVM_RAISE_DFL (PVM_E_CONV);                                         \
    }                                                                       \
  while (0)
  
/* User-specified code, late header part: end */


/* Close the multiple-inclusion guard opened in the template. */
#endif // #ifndef PVM_VM_H_
